我正在尝试使用Flex和Bison实现一个简单的计算器。我在Bison阶段遇到了问题,我无法弄清楚如何从符号表中检索变量值并将其分配给$$。
lex文件:
%{
#include <iostream>
#include <string.h>
#include "calc.tab.h"
using namespace std;
void Print();
int count = 0;
%}
%%
[ \t\n]+ ;
"print" {Print();}
"exit" {
exit(EXIT_SUCCESS);
}
[0-9]+ {
yylval.FLOAT = atof(yytext);
return (NUMBER);
count++;
}
[a-z][_a-zA-Z0-9]* {
yylval.NAME = yytext;
return (ID);
}
. {
return (int)yytext[0];
}
%%
void Print()
{
cout << "Printing ST..\n";
}
int yywrap()
{
return 0;
}
野牛档案:
%{
#include <iostream>
#include <string.h>
#include "table.h"
extern int count;
int yylex();
int yyerror(const char *);
int UpdateSymTable(float, char *, float);
using namespace std;
%}
%union
{
float FLOAT;
char *NAME;
}
%token NUMBER
%token ID
%type <FLOAT> NUMBER
%type <NAME> ID
%type <FLOAT> expr
%type <FLOAT> E
%left '*'
%left '/'
%left '+'
%left '-'
%right '='
%%
E: expr {cout << $$ << "\n";}
expr: NUMBER {$$ = $1;}
| expr '+' expr {$$ = $1 + $3;}
| expr '-' expr {$$ = $1 - $3;}
| expr '*' expr {$$ = $1 * $3;}
| expr '/' expr {$$ = $1 / $3;}
| ID '=' expr {
int index = UpdateSymTable($$, $1, $3);
$$ = st[index].number = $3; //The problem is here
}
%%
int yyerror(const char *msg)
{
cout << "Error: "<<msg<<"\n";
}
int UpdateSymTable(float doll_doll, char *doll_one, float doll_three)
{
int number1 = -1;
for(int i=0;i<count;i++)
{
if(!strcmp(doll_one, st[i].name) == 0)
{
strcpy(st[i].name, doll_one);
st[i].number = doll_three;
number1 = i;
}
else if(strcmp(doll_one, st[i].name) == 0)
{
number1 = i;
}
}
return number1;
}
int main()
{
yyparse();
}
符号表:
struct st
{
float number;
char name[25];
}st[25];
我得到的输出是:
a = 20
c = a+3
20
Error: syntax error
如果有人告诉我出了什么问题,我真的很感激。我很长一段时间都在努力,但我无法解决错误。
答案 0 :(得分:2)
语法错误是您的语法只接受单个expr
而不是expr
序列的结果。例如,请参阅this question。
符号表查找的一个问题是您错误地返回值yytext
作为语义值,而不是复制。例如,请参阅this question。
但是,您的UpdateSymTable
函数存在很多问题,首先是您为参数选择的名称没有意义,而且从不使用第一个参数(“doll_doll”)。我不知道你打算用!strcmp(doll_one, st[i].name) == 0
测试什么,但不管它是什么,必须有一种更简单的表达方式。无论如何,逻辑是不正确的。我建议编写一些简单的测试程序(没有bison和flex)来调试符号表处理。和/或与您的实验室顾问交谈,假设您有一个。
最后,(我注意到的)你的优先关系不正确。首先,它们是相反的:紧密结合(赋值)的算子应该首先出现。其次,+
优先于-
,反之亦然;两个运营商具有相同的优先权。与*
和/
类似。如果您没有讲义或其他信息,可以尝试阅读precedence chapter of the bison manual。