2

我正在尝试为重新解析和重新标记的 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)* 形式)?

4

1 回答 1

1

当我解析输入时:

config HAVE_DEBUG_RAM_SETUP
def_bool n

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

在此处输入图像描述

所以,我认为这里没有问题。我的猜测是您使用的是 ANTLRWorks 的解释器:不要。是马车。始终使用您自己的类来测试您的语法,或使用 ANTLWorks 的调试器(按CTRL+D启动 is)。调试器就像一个魅力(没有包声明,顺便说一句)。我在上面发布的图像是从调试器导出的。

编辑

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

于 2012-09-20T19:09:44.600 回答