在使用Antlr3语法时,我遇到的情况是规则的意图实际上是相同但行为不同。
我创建了一个小例子 -
我想解析一个合格的对象名称,该名称可能是3部分或2部分或不合格(Dot是分隔符)。
Test Input-
1. SCH.LIB.TAB1;
2. LIB.TAB1;
3. TAB1;
我将以下规则从选项变为备选(ORed规则)。
Before State-
qualified_object_name
:
( identifier ( ( DOT identifier )? DOT identifier )? )
;
After State-
qualified_object_name_new
:
( identifier DOT identifier DOT identifier ) // 3 part name
| ( identifier DOT identifier ) // 2 part name
| ( identifier ) // 1 part name
;
两个规则都正确解析了输入1,但新规则在解析输入2和3时出错。
line 1:22 no viable alternative at input ';'
我认为Antlr会尝试匹配qualified_object_name_new的替代1,但是当完全匹配替代1时,则会尝试匹配替代2,依此类推。
因此,对于输入' LIB.TAB1'它最终将匹配qualified_object_name_new的替代2。
但是,它不会以这种方式工作,并在削减2部分名称或不合格名称时出错。
有趣的是,当我设置选项k = 1时,新规则正确解析了所有3个输入。 但是对于k的任何其他值,它会给出错误。
我想了解为什么Antlr会采用这种方式,这是正确的。
答案 0 :(得分:0)
您可能没有增加超前大小(在ANTLR3中默认为1)。使用一个令牌预测,新的对象名称规则无法解决ambiquity(所有alts都以相同的标记开头)。你也应该对此发出警告。
使用ANTLR3有3个选项可以解决这个问题(虽然我也建议切换到版本4):
backgtrack
选项),但我并非100%确定这是否真的有用。k
选项)。有关详细信息,请阅读ANTLR3 documentation。