来自ANTLR语法的剥离动作改变了其解析算法

时间:2011-12-08 22:43:12

标签: antlr grammar antlr3 xtext

我有一个语法Foo.xtext(太复杂了,不能在这里包含它)。 Xtext从中生成InternalFoo.gAfter some tweaking它还生成DebugInternalFoo.g,声称在没有操作的情况下是同一件事。现在,我直接用ANTLR剥离行动

java -cp antlr-3.4.jar org.antlr.tool.Strip Internal.g > Stripped.g

当我检查它们时,我希望这三种语法的行为方式相同。但这是我的经历

  • InternalFoo.g - 错误,规则分配具有非LL(*)决策
  • DebugInternalFoo.g - 没问题,解析得很好
  • Stripped.g - 规则分配时的警告,决策可以使用多个备选方案进行匹配。它无法正确解析。

语法是否有可能以不同的动作解析文本?或者它是任何动作 - 移除工具中的错误? (有问题的规则有句法谓词,没有它们,它实际上会有非LL(*)决定。)

更新:

我部分地发现了导致问题的原因。有问题的规则是这样的

trickyRule:
  ({ some complex action})
  (expression '=')=>...

剥离Antlr删除了操作,但在那里留下了一个空组:

// Stripped.g
trickyRule:
  () (expression '=')=>...

调试语法的生成将删除操作以及围绕它的现在为空的组:

// DebugInternalFoo.g
trickyRule:
  (expression '=')=>...

所以吸取的教训是:在句法谓词之前的空组与根本没有相同。

1 个答案:

答案 0 :(得分:0)

  

语法是否有可能以不同的动作解析文本?

是的,这是可能的。 org.antlr.tool.Strip留下句法谓词 1 ,但删除了验证 2 - 和门控 3 语义谓词(和member部分这些语义谓词可能会使用)。

例如,以下规则仅匹配A_TOKEN

parser_rule1
  :  (parser_rule2)=> parser_rule2
  ;

parser_rule2
  :  {input.LT(1).getType() == A_TOKEN}? .
  ;

但如果您使用Strip工具,则会留下以下内容:

parser_rule1
  :  (parser_rule2)=> parser_rule2
  ;

parser_rule2
  :  /*{input.LT(1).getType() == A_TOKEN}?*/ .
  ;

使其匹配任何令牌。

换句话说,Strip可能会改变生成的词法分析器或解析器的行为。


1 句法谓词:( ... )=>
2 验证语义谓词{ ... }?
3 门控语义谓词{ ... }?=>