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その場合は、キューを使用して2つのタイプ間のコンバーターを簡単に作成できます。

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.lexbufLexing.from_stringトークンの固定シーケンスではなく、固定文字列をフィードするために使用することを検討できます。Menhirも見ることができます。私はそれを使ったことがありませんが、誰かがOCamlパーサジェネレータについて言及するときはいつでもここで素晴らしいレビューを得ます。より柔軟な字句解析インターフェースがあるかもしれません。

于 2012-06-05T15:12:43.953 に答える