我正在尝试编写一个解析器语法,目前有一个LL语法(在Antlr中)的以下作品,我试图解析一个或多个(数字或字符串),它由一个右边的“#”分隔关联。如何修改产品,以便它可以解析一个或多个由“#”分隔的字符串,而不仅仅是一个?
A ::= B
| Number
| String
B ::= C "->" A
C ::= Number
| String
此语法的语言示例:
ABC # 123
123 # ABC
ABC # DEF # 123
ABC # DEF # (123 # 456)
ABC # (DEF # 123) # 456
我尝试使用EBNF表格
A ::= B
| Number
| String
| "(" A ")"
B ::= C ("#" A)?
C ::= Number
| String
但这导致我的语法模棱两可。我该如何解决这种歧义?
答案 0 :(得分:0)
歧义来自于您可以通过两种方式推导Number
或String
这一事实 - 直接A
- > Number
或A
- > B
- > C
- > Number
(同样适用于String
)。明显的解决方法是摆脱直接制作:
A ::= B
| "(" A ")"
B ::= C ("#" A)?
C ::= Number
| String
答案 1 :(得分:0)
我认为你正在寻找的东西要简单得多:
A ::= B ( "#" B )*
B ::= Number | String | "(" A ")"
不是ANTLR专家,我不确定如何将#
标记为右关联,但规则的目的是生成B
s的列表,所以你可以将它们与语义规则中的权利联系起来。
将带括号的表达式规则放在层次结构的底部是很重要的(可以这么说);否则,你将无法解析( first # second ) # third
。