我的示例文件中的多余输入有问题。我得到了以下词法分析器:
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>)
我该怎么做,也可以跳过第一个错误输入并识别其余错误?我尝试使用换行符,但是当我想在命名空间之后引入新的声明时,这会导致问题。
答案 0 :(得分:0)
据我所知,这是预测引擎的局限性。我也看到这种情况,例如MySQL查询:
select * from sakila.actor where
将select
关键字标记为错误,而不是缺少的where
表达式。这里发生的是,ALL(*)预测在规则链中看起来太远了。如果存在错误,则不允许解析正确的输入直到该错误,但是有时会使整个输入失败。我没有找到解决此问题的好方法。一切似乎都取决于语法结构。