我正在做一个带有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;
}
答案 0 :(得分:0)
在寻找错误消息的解释以引用完整错误消息时,它总是有用的,并指出它适用于哪一行。
所以这里只是其中一行会触发与问题中的错误类似的错误。毫无疑问还有更多。
OP_SUM expr '\n' {if($1.type==0) ...
这里,$1
指的是第一个符号(OP SUM
)的语义值; $2
会引用第二个符号(expr
)。 OP_SUM
没有声明的类型,这并不奇怪,因为它不代表带有值的符号。
显然,目的是使用expr
的语义值,$2