是否可以爲OCamlYacc生成的解析器提供一個明確的標記列表供分析?從顯式標記列表中輸入ocamlyacc分析器?
我想使用OCamlLex顯式生成一個令牌列表,然後我使用Yacc生成的分析器進行分析。但是,標準用例會生成一個分析器,爲下一個標記隱式調用詞法分析器。這裏的令牌是在yacc分析期間而不是之前計算的。從概念上講,解析器只能處理令牌,但是Yacc生成的解析器提供了一個依賴於詞法分析器的接口,這在我的情況下並不需要。
是否可以爲OCamlYacc生成的解析器提供一個明確的標記列表供分析?從顯式標記列表中輸入ocamlyacc分析器?
我想使用OCamlLex顯式生成一個令牌列表,然後我使用Yacc生成的分析器進行分析。但是,標準用例會生成一個分析器,爲下一個標記隱式調用詞法分析器。這裏的令牌是在yacc分析期間而不是之前計算的。從概念上講,解析器只能處理令牌,但是Yacc生成的解析器提供了一個依賴於詞法分析器的接口,這在我的情況下並不需要。
如果您已經有一個令牌列表,那麼您可以採用醜陋的方式,完全忽略lexing緩衝區。畢竟,您的解析器預計解析 - 從 - 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
OCamlYacc接口看起來很複雜;它似乎需要一個Lexing.lexbuf
。也許你可以考慮使用Lexing.from_string
來提供一個固定的字符串,而不是固定的令牌序列。你也可以看看Menhir。我沒有使用它,但是當有人提到OCaml解析器生成器時,它會在這裏得到極好的評論。它可能有一個更靈活的lexing接口。
巨石看起來像一個很好的替代OCamlYacc爲很多原因。但是,它似乎與詞法分析器非常緊密地聯繫在一起。 'Lexing.from_string'不是一種替代方案,因爲基本問題是某些詞法分析器動作產生了兩個令牌而不是一個,因爲我只能識別出跟隨任意字符串的令牌,並以字符串令牌和跟隨它的字符串結束。因此,我計劃先建立一個令牌列表。也許我必須引入奇怪的混合標記來解決這個限制。 –
已經由Jeffrey提到,Menhir特別提供,其運行時庫的一部分,一個模塊的解析器與任何類型的令牌流(它只是要求一個unit -> token
函數):MenhirLib.Convert。
(你甚至可以使用此代碼,而無需使用巨石,與ocamlyacc來代替。在實踐中,轉換並不十分複雜,所以你甚至可以自己重新實現它。)
這非常有用。我從來沒有使用過Menhir,但手冊看起來非常有說服力(雖然我忽略了Convert模塊),它的作者在OCaml社區中備受尊敬。 –
yacc生成的解析器提供語義操作訪問隱藏在'lexbuf'狀態中的位置信息。因此,我不確定'放氣'會起作用,但它給了我一個想法。 –