在第一个位置的ANTLR无关输入不会构建树

时间:2018-12-29 13:28:59

标签: parsing antlr4

我的示例文件中的多余输入有问题。我得到了以下词法分析器:

lexer grammar CtoLexer;

ENUM:               'enum';
NAMESPACE:          'namespace';
LBRACE:             '{';
RBRACE:             '}';
DOT:                '.';
VAR:                'o ';
IDENTIFIER:         LetterOrDigit+;

fragment LetterOrDigit
   : [a-zA-Z$_] | [0-9];

WS:                 [ \t\r\n\u000C]+ -> skip;

...和解析器:

parser grammar CtoParser;

options { tokenVocab=CtoLexer; }

modelUnit
   : namespaceDeclaration enumDeclaration* EOF;

namespaceDeclaration
   : NAMESPACE IDENTIFIER ('.' IDENTIFIER)*;

enumDeclaration
   : ENUM IDENTIFIER '{' enumConstant* '}';

enumConstant
   : VAR IDENTIFIER;

这是我的示例cto文件:

namespace org.basic.sample

enum FooType {
  o FOO
}

enum BarType {
  o BAR
}

enum BazType {
 o BAZ
}

此示例文件的树如下所示:

(modelUnit 
  (namespaceDeclaration namespace org . basic . sample) 
  (enumDeclaration enum FooType { (enumConstant o  FOO) }) 
  (enumDeclaration enum BarType { (enumConstant o  BAR) }) 
  (enumDeclaration enum BazType { (enumConstant o  BAZ) }) 
<EOF>)

当我将样本中的第一个枚举更改为其他枚举时,比如说“枚举”改为“枚举”,几乎整个树都被弄乱了。解析器仅识别名称空间,其余的似乎是IDENTIFIER。

(modelUnit 
 (namespaceDeclaration namespace org . basic . sample) 
  enumi FooType { o  FOO } 
  enum BarType { o  BAR } 
  enum BazType { o  BAZ })

但是,当我对第二个枚举执行相同的操作时,某种程度上只能识别无效的枚举,其余的都可以。

(modelUnit 
 (namespaceDeclaration namespace org . basic . sample)
 (enumDeclaration enum FooType { (enumConstant o  FOO) }) 
 enumi BarType { o  BAR } 
 (enumDeclaration enum BazType { (enumConstant o  BAZ) }) <EOF>)

我该怎么做,也可以跳过第一个错误输入并识别其余错误?我尝试使用换行符,但是当我想在命名空间之后引入新的声明时,这会导致问题。

1 个答案:

答案 0 :(得分:0)

据我所知,这是预测引擎的局限性。我也看到这种情况,例如MySQL查询:

select * from sakila.actor where

select关键字标记为错误,而不是缺少的where表达式。这里发生的是,ALL(*)预测在规则链中看起来太远了。如果存在错误,则不允许解析正确的输入直到该错误,但是有时会使整个输入失败。我没有找到解决此问题的好方法。一切似乎都取决于语法结构。