2015-10-10 142 views
-1

我正在做一個簡單的計算器與flex和野牛,當我編譯它說我「$ 1 ...沒有聲明的類型」 我必須打印表達式的類型,它的結果。 表達式的類型可以是float整數或字符串。 這是我的野牛代碼:flex與野牛計算器

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