解决简单Instaparse语法中的歧义

时间:2015-03-21 16:41:02

标签: clojure grammar instaparse

[也发布在Instaparse mailing list上,但也发布在这里,因为我猜这是一个相当普遍的问题]

考虑语法

 D = (B|S)*
 S = 'S' B*
 B = 'B'

(这是Instaparse的BNF版本......)

B可以单独发生,也可以发生在S之后;如果是后者,它应该被认为是呃S表达的一部分(没有双关语意)。

示例:

(-> "D = (B|S)*
     S = 'S' B*
     B = 'B'"
    parser
    (parses "BSBB"))

;;=>
([:D [:B "B"] [:S "S"] [:B "B"] [:B "B"]]
 [:D [:B "B"] [:S "S" [:B "B"] [:B "B"]]]    ;; <------
 [:D [:B "B"] [:S "S" [:B "B"]] [:B "B"]])

我想只匹配第二个结果 - 这样B可能会包含在S中,并删除其他选项。我的解析器需要做些什么来进行此更改?

this gist中显示的更多示例表达式。

1 个答案:

答案 0 :(得分:2)

您可以使用否定前瞻来假设S的匹配不得跟随有效的B

(-> "

D = (B|S)*
S = 'S' B* !B
B = 'B'

"
insta/parser
(insta/parses "BSBB"))
;= ([:D [:B "B"] [:S "S" [:B "B"] [:B "B"]]])

这适用于你的要点(当前版本)的所有例子。

相关问题