2015-10-10 4 views
-1

Я делаю простой калькулятор с flex и bison, а когда компилирую, он говорит, что «$ 1 из ... не имеет объявленного типа» Мне нужно напечатать тип выражения и его результат , Тип выражения может быть float целым числом или строкой. это мой бизон код:Калькулятор с flex и bison

%{  
    #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;  
} 

ответ

0

Это всегда полезно при поиске объяснения сообщения об ошибке процитировать сообщение об ошибке в полного и указать, какую линию он применяется к.

Итак, вот только одна из строк, которая вызовет ошибку, аналогичную той, что в вопросе. Несомненно, их больше.

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

Здесь $1 относится к семантическому значению первого символа (OP SUM); $2 будет ссылаться на второй символ (expr). OP_SUM не имеет объявленного типа, что неудивительно, поскольку оно не представляет собой символ со значением.

Очевидно, что намерение состояло в том, чтобы использовать семантическое значение expr, который будет $2

Смежные вопросы