0

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

在弹性:

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

我怎样才能让它做加法?

4

2 回答 2

4
{pn}?{dig}+

不要使加号或减号 ( {pn?}) 成为数字标记的一部分。将它们视为两个单独的标记,+并且2. 那么 flex 就没有任何歧义需要解决了。

{dig}+

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

| PLUS_SIGN expr
  {
    $$ = +$2;
    printf(" $$=%f\n",$$);
  }
| MINUS_SIGN expr
  {
    $$ = -$2;
    printf(" $$=%f\n",$$);
  }
于 2012-09-22T04:47:50.193 回答
1

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

expr: expr PLUS_SIGN expr2
      {
         $$ = $1 + $3;
         printf("$$=%f\n", $$);
      }
    | expr2
     {
        $$ = $1;
     }
;
expr2: TYPE_INT
     {     
        $$ = (int)$1;
        printf(" $$=%f\n",$$);
     }
;
于 2012-09-22T08:45:53.730 回答