我是野牛的新手,并且不幸需要为一种语言编写一个解析器,这种语言本来可能是变量名中的运算符。例如,根据上下文,表达式
FOO = BAR-BAZ
可以解释为:
"FOO"
被赋予变量"BAR"
的值减去变量"BAZ"
的值,或者"FOO"
被赋予变量"BAR-BAZ"
幸运的是,语言需要提前进行变量声明,因此我可以通过我实现的函数确定给定字符串是否为有效变量:
bool isVariable(char* name);
如果给定的字符串是有效的变量名,则返回true,否则返回false。
如何告诉bison首先尝试上面的第二个场景,并且只有当(通过使用isVariable()
)该路径失败时,返回并尝试上面的第一个场景?我已经读过你可以让bison尝试多个解析路径并在遇到YYERROR
时剔除无效的路径,所以我尝试了一组类似的规则:
variable:
STRING { if(!isVariable($1)) YYERROR; }
;
expression:
expression '-' expression
| variable
;
但是当给定"BAR-BAZ"
时,解析器将其作为单个变量进行尝试,当它到达YYERROR
时完全停止,而不是像我期望的那样探索"BAR" - "BAZ"
路径。我做错了什么?
编辑:
我开始认为STRING
的我的弹性规则可能是罪魁祸首:
((A-Z0-9][-A-Z0-9_///.]+)|([A-Z])) {yylval.sval = strdup(yytext); return STRING;}
在这种情况下,如果' - '出现在字母数字字符的中间,整个批次将被视为1 STRING
,而不可能被解析器细分(因此只探索了一条路径)。我想我可以在解析器操作中手动解析STRING
,但似乎应该有更好的方法。也许flex可以返回备用令牌流(一个用于"BAR-BAZ"
情况,另一个用于"BAR"-"BAZ"
情况),这些流被转移到不同的解析器堆栈进行探索?有可能吗?