%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "mycalc.h"
extern int int_num;
extern char* yytext;
%}
%token TOK_NUM TOK_ID TOK_SEMICOLON TOK_VAR TOK_EQ TOK_PRINTLN TOK_LPARA TOK_RPARA TOK_ADD TOK_MUL
%union
{
int int_val;
char *id_val;
}
%type <id_val> expr TOK_ID
%type <int_val> stmt TOK_NUM
%left TOK_LPARA TOK_RPARA
%left TOK_MUL
%left TOK_ADD
%%
prog:
stmts { startit(); }
;
stmts:
| stmt TOK_SEMICOLON stmts
;
stmt:
TOK_VAR TOK_ID { defvar(presentlevel,yylval.id_val,0); }
| TOK_ID TOK_EQ expr { assignvar(presentlevel,$1,$3); }
| TOK_PRINTLN TOK_ID { printf("the value of id %d",$2); }
| TOK_LPARA stmts TOK_RPARA { if($1=="{")
{
presentlevel=presentlevel+1;
}
if($3=="}")
{
if(presentlevel>1)
{
presentlevel=presentlevel-1;
}
} };
expr:
TOK_NUM { $$=atoi($1); }
| TOK_ID { myvar *h ;
h=getvar(presentlevel,$1);
$$=h->val;
}
| expr TOK_ADD expr {$$=$1+$2;}
| expr TOK_MUL expr {$$=$1*$2;}
;
%%
int yyerror(char *s,int x)
{
printf("Syntax Error at %d",line_num);
return 0;
}
int main()
{
startit();
presentlevel=1;
yyparse();
return 0;
}
我已经在联盟下面声明了id_val和int_val的类型,你可以看到。它仍然导致错误。以下是我得到的错误。
calc.y:46.44-45: $1 of `stmt' has no declared type
calc.y:51.43-44: $3 of `stmt' has no declared type
calc.y:65.47-48: $2 of `expr' has no declared type
calc.y:66.47-48: $2 of `expr' has no declared type
make: *** [calc] Error 1
有人可以告诉我们为什么它会在声明类型时显示错误。
答案 0 :(得分:1)
嗯,错误消息几乎可以告诉您发生了什么。对于第一个,第46行是:
| TOK_LPARA stmts TOK_RPARA { if($1=="{")
这是stmt
的规则,错误告诉您$1
(来自TOK_LPARA
)没有类型。你可以从它的宣泄中看到:
%left TOK_LPARA TOK_RPARA
如果您希望能够在此处访问TOK_LPARA
中的值,则需要为其指定一个类型,可能是<id_val>
。然后你会遇到==
比较指针而不指向字符串的问题。其他错误都表明了类似的问题。
您还没有在$$
操作中设置stmt
(您已声明stmt
的类型)导致它们具有垃圾值。