具有变量名

时间:2015-05-08 18:29:42

标签: operators bison glr

我是野牛的新手,并且不幸需要为一种语言编写一个解析器,这种语言本来可能是变量名中的运算符。例如,根据上下文,表达式

FOO = BAR-BAZ

可以解释为:

  1. 变量"FOO"被赋予变量"BAR"的值减去变量"BAZ"的值,或者
  2. 变量"FOO"被赋予变量"BAR-BAZ"
  3. 的值

    幸运的是,语言需要提前进行变量声明,因此我可以通过我实现的函数确定给定字符串是否为有效变量:

    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"情况),这些流被转移到不同的解析器堆栈进行探索?有可能吗?

0 个答案:

没有答案