当规则的意图实际上相同时,Antlr3在两个不同的规则中表现不同

时间:2018-03-13 12:53:23

标签: antlr3

在使用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会采用这种方式,这是正确的。

1 个答案:

答案 0 :(得分:0)

您可能没有增加超前大小(在ANTLR3中默认为1)。使用一个令牌预测,新的对象名称规则无法解决ambiquity(所有alts都以相同的标记开头)。你也应该对此发出警告。

使用ANTLR3有3个选项可以解决这个问题(虽然我也建议切换到版本4):

  • 启用回溯功能(请参阅backgtrack选项),但我并非100%确定这是否真的有用。
  • 增加预测尺寸(请参阅k选项)。
  • 使用句法谓词强制ANTLR向前看整个alt。

有关详细信息,请阅读ANTLR3 documentation