ANTLR规则单独工作,但在包含在另一个规则中时失败

时间:2012-09-20 16:56:55

标签: antlr antlrworks

我正在尝试为经过重新分析和重新标记的kconfig文件编写一个ANTLR语法(重新设计以解决一些歧义)。语法的简化版本是:

grammar FailureExample;

options {
language = Java;
}


@lexer::header {
package parse.failure.example;
}

reload 
:   configStatement*
EOF
;

configStatement
: CONFIG IDENT
configOptions
;

configOptions
:   (type 
| defConfigStatement
| dependsOnStatement
| helpStatement
| rangeStatement
| defaultStatement
| selectStatement
| visibleIfStatement
| prompt
)*
;

type :  FAKE1;
dependsOnStatement: FAKE2;
helpStatement:  FAKE3;
rangeStatement: FAKE4;
defaultStatement:   FAKE5;
selectStatement:FAKE6;
visibleIfStatement:FAKE7;
prompt:FAKE8;   

defConfigStatement
: defConfigType expression
;

defConfigType
: DEF_BOOL
;

//expression parsing
primative
: IDENT
| L_PAREN expression R_PAREN
;

negationExpression
: NOT* primative
;

orExpression
: negationExpression (OR negationExpression)*
;

andExpression
: orExpression (AND orExpression)*
;

unequalExpression
: andExpression (NOT_EQUAL andExpression)?
;

equalExpression
: unequalExpression (EQUAL unequalExpression)?
;

expression
: equalExpression (BECOMES equalExpression)?
;

DEF_BOOL:    'def_bool';
CONFIG : 'config';  
COMMENT     : '#' .* ('\n'|'\r') {$channel = HIDDEN;};
AND         : '&&';
OR      : '||';
NOT         : '!';
L_PAREN     : '(';
R_PAREN     : ')';
BECOMES     : '::=';
EQUAL       :  '=';
NOT_EQUAL   : '!=';

FAKE1 : 'fake1';
FAKE2:   'fake2';
FAKE3:   'fake3';
FAKE4:   'fake4';
FAKE5:   'fake5';
FAKE6:   'fake6';
FAKE7:   'fake7';
FAKE8:   'fake8';

IDENT       : (LETTER | DIGIT | '_')*;
WS  :   ( ' '
    | '\t'
    | '\r'
    | '\n'
    ) {$channel=HIDDEN;}
;

fragment LETTER : ('a'..'z' | 'A'..'Z') ;
fragment DIGIT : '0'..'9';

输入:

config HAVE_DEBUG_RAM_SETUP
def_bool n

我可以设置antlrworks来解析第二行(注释掉第一行),然后我得到正确的defConfigStatement标记,并带有正确的表达式。但是,如果我运行configOptions规则或configStatement规则(第一行取消注释),我的configOptions会产生一个空集,并抛出NoViableAlt异常。

什么会导致这种行为?我知道defConfigStatement规则是准确的并且可以正确解析,但是一旦它作为另一个规则中的潜在选项添加,它就会失败。我知道我没有冲突的规则,并且我已经将DEF_BOOL和DEF_TRISTATE规则放在我的词法分析器规则列表的顶部,因此它们优先于其他词法分析器规则。

/ 自编辑后添加 / 为了进一步使问题复杂化,如果我在configOptions规则中移动defConfigStatement选项,它将起作用,但其他规则将失败。

编辑:使用完整,简化的语法。

简而言之,为什么规则本身有效,但在configOptions中失败(特别是因为configOptions是(A | B | C)*形式)?

1 个答案:

答案 0 :(得分:1)

当我解析输入时:

config HAVE_DEBUG_RAM_SETUP
def_bool n

使用语法生成的解析器,我得到以下解析树:

enter image description here

所以,我认为这里没有问题。我的猜测是你正在使用ANTLRWorks'口译员:不要。它的马车。总是用自己的课程测试你的语法,或者使用ANTLWorks'调试器(按 CTRL + D 启动)。调试器就像一个魅力(没有包声明,顺便说一句)。我上面发布的图像是调试器的导出。

修改

如果调试器不起作用,请尝试(暂时)删除包声明(请注意,您只是为词法分析器而不是解析器声明包,但这可能是由于发布了最小的语法)。您还可以尝试更改调试器应连接的端口号。可能是端口已在使用中(请参阅:文件 -> 首选项 -> 调试器 -tab)。