我正在尝试找出如何将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一起使用?
答案 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 }},然后返回令牌。