野牛多规则符号

Bison multi-rule symbol

我有一个符号 table,它包含 variable/symbol 的名称、数据和数据类型(存储为字符)。我希望它是这样的符号,如果它是整数,则被视为 iexpr;如果它是实数,则被视为 reexpr。这些是我现在的规则:

iexpr: INT_TOKEN
    | iexpr PLUS iexpr { $$ =  + ; }
    | iexpr MINUS iexpr { $$ =  - ; }
    | iexpr DIVIDE iexpr {$$ = /;}
    | iexpr MOD iexpr{$$ =  % ;}
    | LPARENT iexpr RPARENT{$$=;}
    | SYMBOL {  symrec *s;
                s = getsym();
                if(s!=0){
                    if(s->type == 'i'){
                        $$ = atoi(s->data);
                    }
                }
             }
;
rexpr: REAL_TOKEN 
    | rexpr PLUS rexpr {  $$ =  + ; }
    | rexpr MINUS rexpr { $$ =  - ; }
    | iexpr PLUS rexpr {  $$ = (double)  + ; }
    | iexpr MINUS rexpr { $$ = (double)  - ; }
    | rexpr PLUS iexpr {  $$ =  + (double) ; }
    | rexpr MINUS iexpr { $$ =  - (double) ; }
    | rexpr DIVIDE rexpr {$$ = /;}
    | rexpr MULTIPLY rexpr{$$ =  * ;}
    | rexpr DIVIDE iexpr {$$ =  / (double) ;}
    | rexpr MULTIPLY iexpr {$$=  * (double) ;}
    | iexpr DIVIDE rexpr {$$ = (double)  / ;}
    | iexpr MULTIPLY rexpr {$$ = (double)  * ;}
    | rexpr MOD rexpr {$$ = (int) % (int);}
    | rexpr MOD iexpr {$$ = (int) % ;}
    | iexpr MOD rexpr {$$ =   % (int);}
    | LPARENT rexpr RPARENT{$$ =;}
    | SYMBOL {  symrec *s;
                s = getsym();
                if(s!=0){
                    if(s->type == 'r'){
                        $$ = atof(s->data);
                    }
                }
             }
;

然而,rexpr 中的规则从未被使用,因为它只将它视为 iexpr。我怎样才能根据类型描述符将其视为该类型而不仅仅是整数?

编辑:所以我尝试更改我的 lex 文件,以便它将 return 每种类型的不同标记。为此,我需要包含我的符号 table 头文件,以便我可以检查该名称和 return 基于其类型的不同符号。这是代码:

[a-zA-Z]+ { yylval.string = strdup(yytext);
            symrec *s;
            s = getsym(yylval.string);
            if(s!=0){
                if(s->type == 'r'){
                    return RSYMBOL;
                }else if(s->type == 'i'){
                    return ISYMBOL;
                }
            }else{
             return SYMBOL;
            }
          }

但是现在我有一个错误说我有多个头函数定义,因为我将它包含在两个文件中。

如果你想这样做,你需要为 ISYMBOLRSYMBOL 设置词法分析器 return 不同的标记,否则你会在 reduce/reduce 之间发生冲突SYMBOL 的两个缩减,因为解析器不知道它是哪个。这意味着您需要在词法分析器操作中查找符号表,而不是在解析器操作中。

一般来说,尝试在解析器中进行这样的类型检查不是一个好主意,因为它会使语法变得更加复杂并导致许多难以解决的冲突。

如果您希望令牌类型根据符号的声明类型而变化,您需要在词法分析器中查找符号(因为这是生成令牌类型的原因)。

您实际上需要 return 三种不同的令牌类型之一:

  • INT_SYMBOL
  • REAL_SYMBOL
  • UNDECLARED_SYMBOL

一般来说,解析完成后,最好在 AST 的单独传递中进行类型检查。 (或者,如果您不生成 AST,则可以在进行归约时在语义操作中执行此操作。)这将使您产生更好的错误消息,并且在类型错误后更容易继续解析。