我已经为类似
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 ; ...
表达式是prio14Expression的标签.你可以看到完整的语法@L_301_1@.
代码生成本身是成功的(没有任何错误或严重警告).它生成以下代码:
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;
哪个不构建错误“错误5错误C2065:’FOLLOW_set_in_prio2Expression962’:未声明的标识符”.
我在语法上做错了吗?没有其他规则会导致此错误,如果我在某种程度上重新制定相关规则,则生成的代码是有效的(但语法不能达到我想要的效果).我该怎么做才能解决这个问题?
谢谢你的帮助.
解决方法
我遇到了同样的问题.
我认为如果解析器规则有一部分简单的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}?”进行此修改.我相信它不会改变目标语言的语法.)