6

是否可以为 OCamlYacc 生成的解析器提供显式令牌列表以进行分析?

我想使用 OCamlLex 显式生成一个令牌列表,然后我稍后使用 Yacc 生成的解析器对其进行分析。但是,标准用例会生成一个解析器,该解析器会为下一个标记隐式调用词法分析器。这里的令牌是在 yacc 分析期间而不是之前计算的。从概念上讲,解析器应该只处理标记,但 Yacc 生成的解析器提供了一个依赖于词法分析器的接口,在我的情况下我不需要。

4

3 回答 3

7

正如 Jeffrey 已经提到的,作为其运行时库的一部分,Menhir特别为解析器提供了一个具有任何类型令牌流的模块(它只要求一个unit -> token函数):MenhirLib.Convert

(您甚至可以在不使用 Menhir 的情况下使用此代码,而使用 ocamlyacc。实际上,转换并不是非常复杂,因此您甚至可以自己重新实现它。)

于 2012-06-05T19:35:50.880 回答
5

如果您已经有一个标记列表,您可以采取丑陋的方式并完全忽略词法分析缓冲区。毕竟,解析器期望的 parse-from-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
于 2012-06-05T17:28:23.377 回答
1

OCamlYacc 界面看起来确实很复杂。它似乎需要一个Lexing.lexbuf. 也许您可以考虑使用Lexing.from_string固定的字符串而不是固定的标记序列。你也可以看看Menhir。我没有用过它,但只要有人提到 OCaml 解析器生成器,它就会在这里得到很好的评价。它可能有一个更灵活的词法接口。

于 2012-06-05T15:12:43.953 回答