2

我试图弄清楚如何将 ocamlyacc 与 sedlex 一起使用。

lexer.ml(使用 sedlex):

let rec lex (lexbuf: Sedlexing.lexbuf) =
    match%sedlex lexbuf with
    | white_space -> lex lexbuf
    (* ... other lexing rules ... *)
    | _ -> failwith "Unrecognized."

我还有一个名为 的 ocamlyacc 文件parser.mly,其中包含parse语法规则之一。

为了解析一个字符串,我使用了这个:

let lexbuf = Sedlexing.Utf8.from_string s in
let parsed = (Parser.parse Lexer.lex) lexbuf in
(* ... do things ... *)

但是在编译过程中,出现了这个错误(由Lexer.lex上面引起):

错误:此表达式的类型为 Sedlexing.lexbuf -> Parser.token,但预期的表达式类型为 Lexing.lexbuf -> Parser.token 类型 Sedlexing.lexbuf 与类型 Lexing.lexbuf 不兼容

据我了解,出现此错误是因为 ocamlyacc 期望词法分析器由 ocamllex 生成,而不是由 sedlex 生成。所以问题是:如何将 ocamlyacc 与 sedlex 一起使用?

4

1 回答 1

2

如果您没有非常具体的理由使用 ocamlyacc 而不是 Menhir,那么使用 Menhir 并将解析函数转换为修改后的 API 可能要简单得多,因为它只需要一个 token producer 函数类型unit -> token * position * position

 let provider lexbuf () =
    let tok = generated_lexer lexbuf in
    let start, stop =  Sedlexing.lexing_positions lexbuf in
    tok, start, stop

 let parser_result = MenhirLib.Convert.Simplified.traditional2revised
     generated_parser_entry_point
     (provider lexbuf)

否则,您需要Lexing.lexbuf -> token从您的函数创建函数,Sedlexing.lexbuf -> token该函数将虚拟 lexbuf 作为输入,在 sedlex 缓冲区上应用真正的词法分析函数,将位置信息复制到虚拟对象Lexing.lexbuf,然后返回令牌。

于 2018-09-24T16:16:04.033 回答