将ocamlyacc与sedlex一起使用

时间:2018-09-24 06:57:46

标签: ocaml ocamllex ocamlyacc

我正在尝试找出如何将ocamlyacc与sedlex一起使用。

lexer.ml(使用sedlex):

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

我还有一个名为parser.mly的ocamlyacc文件,其中包含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一起使用?

1 个答案:

答案 0 :(得分:1)

如果您没有使用ocamlyacc而不是Menhir的特殊理由,则使用Menhir并将解析函数转换为修订的API可能要简单得多,因为它只需要类型{{1的令牌生产者函数}}:

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,该函数将虚拟lexbuf作为输入,在sedlex缓冲区上应用真正的lexing函数,将位置信息复制到虚拟{{1 }},然后返回令牌。