从显性标记列表订阅ocamlyacc解析器?(Feed ocamlyacc parser from

2019-09-17 18:55发布

是否有可能养活OCamlYacc生成的解析器用于分析一个明确的标记列表?

我想使用OCamlLex明确生成令牌列表,然后我分析后使用yacc生成解析器。 然而,标准的使用情况下产生隐式调用词法分析器下一个标记解析器。 这里令牌的yacc的分析,而不是以前期间计算。 从概念上讲,解析器应该只标记工作,但与Yacc生成的解析器提供了依靠这在我来说,我并不需要一个词法分析器的接口。

Answer 1:

如果您已经拥有令牌的列表,你可以去丑陋的方式完全忽略词法缓冲区。 毕竟,解析 - 从 - lexbuf您的解析器预计功能是一个非纯函数:

let my_tokens = ref [ (* WHATEVER *) ]
let token lexbuf = 
  match !my_tokens with 
    | []     -> EOF 
    | h :: t -> my_tokens := t ; h 

let ast = Parser.parse token (Lexbuf.from_string "")

在另一方面,它看起来与你的意见,你实际上有类型的函数Lexing.lexbuf -> token list ,你想融入Lexing.lexbuf -> token解析器的签名。 如果是这样的话,你可以很容易地使用队列写两种类型之间的转换器:

let deflate token = 
  let q = Queue.create () in
  fun lexbuf -> 
    if not (Queue.is_empty q) then Queue.pop q else   
      match token lexbuf with 
        | [   ] -> EOF 
        | [tok] -> tok
        | hd::t -> List.iter (fun tok -> Queue.add tok q) t ; hd 

let ast = Parser.parse (deflate my_lexer) lexbuf


Answer 2:

正如杰弗里已经提到, 巨石特别提供,其运行时库的一部分,一个模块与任何类型的令牌流的解析器(它只是要求一个unit -> token功能): MenhirLib.Convert 。

(你甚至可以使用此代码,而无需使用巨石,与ocamlyacc来代替。在实践中,转换并不十分复杂,所以你甚至可以自己重新实现它。)



Answer 3:

该OCamlYacc界面看起来的确相当复杂; 它似乎需要一个Lexing.lexbuf 。 也许你可以考虑使用Lexing.from_string养活一个固定的字符串,而不是令牌的固定顺序。 您还可以看看巨石 。 我没有用它,但每当有人提到的OCaml解析器生成这里得到极高的评价。 它可能有一个更灵活的词法接口。



文章来源: Feed ocamlyacc parser from explicit token list?