“FOLLOW_set_in _”...在生成的解析器中未定义

时间:2013-11-18 20:20:19

标签: c antlr grammar antlr3 antlrworks

我为类似Java的DSL编写了一个语法。虽然它仍然存在一些问题(它不能像我希望的那样识别所有输入),但最让我担心的是生成的C代码是不可编译的。

我使用AntlrWorks 1.5和Antlr 3.5(Antlr 4显然不支持C目标)。

问题在于表达规则。我有规则prio14Expression到prio0Expression,它处理运算符优先级。问题是优先级2,它评估前缀和后缀运算符:

...
prio3Expression: prio2Expression (('*' | '/' | '%') prio2Expression)*;

prio2Expression: ('++' | '--' | '!' | '+' | '-')* prio1Expression ('++' | '--')*;  

prio1Expression:
    prio0Expression (
        ('.' prio0Expression) |
        ('(' (expression (',' expression)*)? ')') |
        ('[' expression (',' expression)* ']')
    )*;

prio0Expression: 
    /*('(') => */('(' expression ')') |
    IDENTIFIER |
    //collectionLiteral |
    coordinateLiteral |
    'true' |
    'false' |
    NUMBER |
    STRING 
    ;
...

Expression是prio14Expression的标签。您可以看到完整的语法here

代码生成本身是成功的(没有任何错误或严重警告)。它生成以下代码:

CONSTRUCTEX();
EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
EXCEPTION->expectingSet = &FOLLOW_set_in_prio2Expression962;

RECOVERFROMMISMATCHEDSET(&FOLLOW_set_in_prio2Expression962);
goto ruleprio2ExpressionEx;

不构建错误“Error 5 error C2065: 'FOLLOW_set_in_prio2Expression962' : undeclared identifier”。

我在语法上做错了吗?没有其他规则会导致此错误,如果我在某种程度上重新制定相关规则,则生成的代码有效(但语法不能达到我想要的效果)。我该怎么做才能解决这个问题?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

我遇到了同样的问题。

我认为如果解析器规则有一部分简单的OR-ed标记就会发生这样的事情:

problem_case: problematic_rule;
problematic_rule: 'A' | 'B' ;

如果它是词法规则,则不会发生这种情况。

workaround1: As_lexer_rule;
As_lexer_rule: 'A' | 'B' ;

或者,如果它是复杂的规则(不是简单的OR-ed令牌)。

workaround2: make_it_complicated_needlessly;
make_it_complicated_needlessly: 'A' | 'B' | {false}? NeverUsedRule;
NeverUsedRule: /* don't care*/ ;

(我使用语义谓词“{false}?”进行此修改。 我相信它不会改变目标语言的语法。)

答案 1 :(得分:3)

它似乎是一个旧帖子,但是,它可能仍然对某人有用(就像我一样)。

我在antlr 3.5的C运行时遇到了同样的问题。

另一个简单的解决方法,它不会改变语法:

problem_case: problematic_rule;
problematic_rule: a='A' | b='B' ;