[英]can't make work multiple assignments in bison/flex
Hi everyone I'm trying to learn bison. 大家好,我想学习野牛。 I found on github an simple working expression parser, that can do the following:
我在github上发现了一个简单的工作表达式解析器,可以执行以下操作:
assignments (like a = 34; b = a;) 分配(例如a = 34; b = a;)
printing (like print a;) 打印(如打印a;)
exiting (type exit; and it will terminate) 退出(类型为退出;它将终止)
I think to understand how the the basic rules work. 我想了解基本规则是如何工作的。 So I've tried to modify the rules to make possible doing multiple assignments (like this one : a = b = c = 5;).
因此,我尝试了修改规则,以便可以进行多次分配(例如:a = b = c = 5;)。
To do so, I add a new line rule that works like this: 为此,我添加了一个新的行规则,其工作方式如下:
line : assegn ';' {;}
| exit_command ';' {exit(EXIT_SUCCESS);}
| print exp ';' {printf("Printing %d\n", $2);}
| line assignment ';' {;}
| line print exp ';' {printf("Printing %d\n", $3);}
| line exit_command ';' {exit(EXIT_SUCCESS);}
;
then I added the following new rules 然后我添加了以下新规则
assegn : assignment {;}
| identifiers {;}
;
identifiers : assignment {$$=$1;}
| identifier '=' identifiers {updateSymbolVal($1,$3);}
;
and assignment works like this 和作业是这样的
assignment : identifier '=' exp {$$=$3; updateSymbolVal($1,$3); }
;
In the end I was able to compile files generate by bison and flex, but when I try to make multiple assignment it returns me syntax error. 最后,我能够编译由bison和flex生成的文件,但是当我尝试进行多次赋值时,它会返回语法错误。
Can somebody explain me,where I commit an error, please? 有人可以向我解释,如果我犯了一个错误? This is the original example I started from.
这是我开始的原始示例。 https://github.com/jengelsma/yacc-tutorial.git
https://github.com/jengelsma/yacc-tutorial.git
This is the code of my bison file: 这是我的野牛文件的代码:
%{
void yyerror (char *s);
#include <stdio.h> /* C declarations used in actions */
#include <stdlib.h>
int symbols[52];
int symbolVal(char symbol);
void updateSymbolVal(char symbol, int val);
int val;
%}
%union {int num; char id;} /* Yacc definitions */
%start line
%token print
%token exit_command
%token <num> number
%token <id> identifier
%type <num> line exp term
%type <id> assignment
%type <num> identifiers
%%
/*the original line was line : assignment ';' {;}*/
line : assegn ';' {;}
| exit_command ';' {exit(EXIT_SUCCESS);}
| print exp ';' {printf("Printing %d\n", $2);}
| line assignment ';' {;}
| line print exp ';' {printf("Printing %d\n", $3);}
| line exit_command ';' {exit(EXIT_SUCCESS);}
;
assegn : assignment {;}
| identifiers {;}
;
identifiers : assignment {$$=$1;}
| identifier '=' identifiers {updateSymbolVal($1,$3);}
;
assignment : identifier '=' exp {$$=$3; updateSymbolVal($1,$3); }
;
exp : term {$$ = $1;}
| exp '+' term {$$ = $1 + $3;}
| exp '-' term {$$ = $1 - $3;}
;
term : number {$$ = $1;}
| identifier {$$ = symbolVal($1);}
;
%% /* C code */
int computeSymbolIndex(char token)
{
int idx = -1;
if(islower(token)) {
idx = token - 'a' + 26;
} else if(isupper(token)) {
idx = token - 'A';
}
return idx;
}
/* returns the value of a given symbol */
int symbolVal(char symbol)
{
int bucket = computeSymbolIndex(symbol);
return symbols[bucket];
}
/* updates the value of a given symbol */
void updateSymbolVal(char symbol, int val)
{
int bucket = computeSymbolIndex(symbol);
symbols[bucket] = val;
}
int main (void) {
/* init symbol table */
int i;
for(i=0; i<52; i++) {
symbols[i] = 0;
}
return yyparse ( );
}
void yyerror (char *s) {fprintf (stderr, "%s\n", s);}
this is my flex file: 这是我的弹性文件:
%{
#include "exppars.tab.h"
%}
%%
"print" {return print;}
"exit" {return exit_command;}
[a-zA-Z] {yylval.id = yytext[0]; return identifier;}
[0-9]+ {yylval.num = atoi(yytext); return number;}
[ \t\n] ;
[-+=;] {return yytext[0];}
. {ECHO; yyerror ("unexpected character");}
%%
int yywrap (void) {return 1;}
Ok it looks like I have found a kind of answer. 好的,看来我找到了答案。
to solve this one I added a new rule. 为了解决这一问题,我添加了一条新规则。 Now rules block looks like this:
现在,规则块如下所示:
line : assegn ';' {;}
| exit_command ';' {exit(EXIT_SUCCESS);}
| print exp ';' {printf("Printing %d\n", $2);}
| line assegn ';' {;}
| line print exp ';' {printf("Printing %d\n", $3);}
| line exit_command ';' {exit(EXIT_SUCCESS);}
;
the next problem appeared when I tried to do long multiple assignment, like this one for example : a = b = c = d = 5;. 当我尝试进行长时间多重分配时,出现了下一个问题,例如:a = b = c = d = 5;。 I just assign the value to c and d, not to the others.
我只是将值分配给c和d,而不是其他值。 It seems like the code { $$ = $1} didn't work as I have expected.
代码{$$ = $ 1}似乎没有按我期望的那样工作。 So I add a new int variable to store the value of last assignment.
因此,我添加了一个新的int变量来存储最后一次赋值。 The production rules now look like this:
现在,生产规则如下所示:
identifiers : assignment { val = $1;} | identifier '=' identifiers {updateSymbolVal($1,val);} ; assignment : identifier '=' exp {$$=$3; updateSymbolVal($1,$3);} ; exp : term { $$ = $1; @1;} | exp '+' term { $$ = $1 + $3; } | exp '-' term { $$ = $1 - $3; } ; term : number {$$ = $1;} | identifier {$$ = symbolVal($1);} ;
Now it's work. 现在工作了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.