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



我在示例文件中遇到无关输入的问题。我得到了以下词法分析器:

lexer grammar CtoLexer;
ENUM:               'enum';
NAMESPACE:          'namespace';
LBRACE:             '{';
RBRACE:             '}';
DOT:                '.';
VAR:                'o ';
IDENTIFIER:         LetterOrDigit+;
fragment LetterOrDigit
   : [a-zA-Z$_] | [0-9];
WS:                 [ trnu000C]+ -> 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>)

当我将示例中的第一个枚举更改为其他内容时,假设"enum"更改为"enumi",几乎整个树都搞砸了。解析器仅识别命名空间,其余部分似乎是标识符。

(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>)

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

据我所知,这是预测引擎的限制。我也看到在像这个MySQL查询这样的情况下:

select * from sakila.actor where

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

相关内容

  • 没有找到相关文章

最新更新