有flex和北美野牛的计算器

时间:2015-10-10 20:25:41

标签: bison flex-lexer

我正在做一个带有flex和bison的简单计算器,当我编译它时,我说“$ 1 of ...没有声明类型” 我必须打印表达式的类型及其结果。 表达式的类型可以是float整数或字符串。 这是我的野牛代码:

%{    
    #include <stdio.h>    
    #include <stdlib.h>    
    #include <math.h>    
    #include <symtab.h>    
    extern int yylex(void);    
    extern char *yytext;    
    extern int nlines;    
    extern FILE *yyin;    
    void yyerror(char *s);    
%}    

%union {    
    char *str;    
}    
%union{    
    struct{    
        char *lexema;    
        int lenght;    
        int line;    
    }ident;    
}    
%union{    
    struct{    
        int integer;    
        float real;    
        char *string;    
        int type;    
        }num    
}    
%token <num> IDENT    
%token <num> LIT_INT    
%token <num> LIT_FLOAT    
%token <num> CADENA    
%token PARENTESIS1    
%token PARENTESIS2    
%token OP_SUM    
%token OP_REST    
%token OP_MULT    
%token OP_DIV    
%token OP_MOD    
%token OP_POW    
%token ASSIGN    

%type <num> expr    
%type <num> term    
%type <num> factor    
%type <num> primary    
%type <num> linea    

%%    
linea   :   IDENT ASSIGN expr '\n'  {sym_enter($1,$3);}    
        |   OP_SUM expr '\n'    {if($1.type==0) {    
                            printf("El valor es %d. \n", $1.integer);    
                        } else if($1.type==1) {    
                            printf("El valor es %f. \n", $1.real);    
                        }}    
        |   OP_REST expr '\n'   {if($1.type==0) {    
                            printf("El valor es %d. \n", -$1.integer);    
                        } else if($1.type==1) {    
                            printf("El valor es %f. \n", -$1.real);    
                        }}    
        |   expr '\n'   {if($1.type==0) {    
                            printf("El valor es %d. \n", $1.integer);    
                        } else if($1.type==1) {    
                            printf("El valor es %f. \n", $1.real);    
                        }}    
        ;    
expr    :   expr OP_SUM term    {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1+$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1+$3;    
                                    } else if($1.type==0 $$ $3.type==1 {    
                                        $$.type=1;    
                                        $$.real=$1+$3;    
                                    } else if($1.type==1 && $3.type==0) {    
                                        $$.type=0;    
                                        $$.real=$1+$3;    
                                    }}    
        |   expr OP_REST term   {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1-$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1-$3;    
                                    } else if($1.type==0 $$ $3.type==1 {   
                                        $$.type=1;    
                                        $$.real=$1-$3;    
                                    } else if($1.type==1 && $3.type==0) {    
                                        $$.type=0;    
                                        $$.real=$1-$3;    
                                    }}    
        |   OP_SUM term         {$$=$2;}    
        |   OP_REST term        {$$=-$2;}    
        |   term                {$$=$1;}    
        ;    
term    :   term OP_MULT factor {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1*$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1*$3;    
                                    } else if($1.type==0 $$ $3.type==1 {    
                                        $$.type=1;    
                                        $$.real=$1*$3;    
                                    } else if($1.type==1 && $3.type==0) {    
                                        $$.type=0;    
                                        $$.real=$1*$3;    
                                    }}    
        |   term OP_DIV factor {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1/$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1/$3;    
                                    } else if($1.type==0 $$ $3.type==1 {    
                                        $$.type=1;    
                                        $$.real=$1/$3;    
                                    } else if($1.type==1 && $3.type==0) {    
                                        $$.type=0;   
                                        $$.real=$1/$3;    
                                    }}    
        |   term OP_MOD factor {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=$1%$3;    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=$1%$3;    
                                    }}    
        |   factor              {$$=$1;}    
        ;    
factor  :   primary             {$$=$1;}    
        |   primary OP_POW factor   {if($1.type==0 && $3.type==0) {    
                                            $$.type=0;    
                                            $$.integer=Math.pow($1,$3);    
                                    } else if($1.type==1 && $3.type==1) {    
                                        $$.type=1;    
                                        $$.real=Math.pow($1,$3)    
                                    }}    
        ;    
primary :   PARENTESIS1 expr PARENTESIS2    {$$=$2;}    
        |   PARENTESIS1 OP_REST expr PARENTESIS2    {$$=-$3;}    
        |   PARENTESIS1 OP_SUM expr PARENTESIS2 {$$=$3;}    
        |   LIT_INT {$$=inicializarEntero($1);}    
        |   LIT_FLOAT   {$$=inicializarReal($1);}    
        |   CADENA  {$$=$1;}    
        |   IDENT   {sym_lookup($1,$$);}    
        ;    

%%    

num* inicializarReal(float real) {    
    num *n;    
    n=(num *)malloc(sizeof(int)+sizeof(float));    
    *n.real=real;    
    *n.type=1;    
    return n;    
}    
num* inicializarEntero(int entero) {    
    num *n;    
    n=(num *)malloc(2*sizeof(int));    
    *n.integer=entero;    
    *n.type=0;    
    return n;    
}    

void yyerror(char *s)    
{    
    printf("Error %s",s);    
}    
int main(int argc,char **argv)    
{
    if (argc>1)    
        yyin=fopen(argv[1],"rt");    
    else    
        yyin=stdin;    
    yyparse();    
    printf("FIN del Analisis. Entrada CORRECTA\n");    
    printf("Numero lineas analizadas: %d\n", nlines);    
    return 0;    
}

1 个答案:

答案 0 :(得分:0)

在寻找错误消息的解释以引用完整错误消息时,它总是有用的,并指出它适用于哪一行。

所以这里只是其中一行会触发与问题中的错误类似的错误。毫无疑问还有更多。

OP_SUM expr '\n'    {if($1.type==0) ...

这里,$1指的是第一个符号(OP SUM)的语义值; $2会引用第二个符号(expr)。 OP_SUM没有声明的类型,这并不奇怪,因为它不代表带有值的符号。

显然,目的是使用expr的语义值,$2