代码之家  ›  专栏  ›  技术社区  ›  footy

如何解决2+2和2++2冲突

  •  0
  • footy  · 技术社区  · 13 年前

    在更大的程序中,我给出了以下内容(flex/bison)

    在flex中:

    pn [\+|\-]
    dig [0-9]+
    exp [e|E]{dig}+
    

    "+"             {printf("+ detected\n");
                    return PLUS_SIGN;}
    
    
    
    
    {pn}?{dig}+         { printf("digit detected - %s\n",yytext);
                    sscanf(yytext, "%d", (int*)&yylval);
                    return TYPE_INT;}
    

    在野牛:

    expr:
        expr PLUS_SIGN expr
          {
            $$ = $1 + $3;
            printf(" $$=%f\n",$$);
          }
        | TYPE_INT
          {     
            $$ = (int)$1;
            printf(" $$=%f\n",$$);
          }
    ;
    

    问题在于:

    当我给出2+2时,它识别2和+2,而不是2,+,2

    我该怎么做加法?

    2 回复  |  直到 13 年前
        1
  •  4
  •   John Kugelman Michael Hodel    13 年前
    {pn}?{dig}+
    

    不要做加号或减号( {pn?} )数字标记的一部分。将它们视为两个独立的令牌, + 2 。那么flex就不会有任何歧义需要解决。

    {dig}+
    

    相反,让bison处理一元加号和减号运算符。让它成为解析器的工作,而不是lexer的工作。

    | PLUS_SIGN expr
      {
        $$ = +$2;
        printf(" $$=%f\n",$$);
      }
    | MINUS_SIGN expr
      {
        $$ = -$2;
        printf(" $$=%f\n",$$);
      }
    
        2
  •  1
  •   MYMNeo    13 年前

    语法显示PLUS_SIGN的左部分和右部分在减少符号时具有相同的优先级。PLUS_SIGN是左组合,因此新语法如下:

    expr: expr PLUS_SIGN expr2
          {
             $$ = $1 + $3;
             printf("$$=%f\n", $$);
          }
        | expr2
         {
            $$ = $1;
         }
    ;
    expr2: TYPE_INT
         {     
            $$ = (int)$1;
            printf(" $$=%f\n",$$);
         }
    ;