我正在通过一些教程代码来学习yacc和lex,这些代码构建了一个解析器,使您可以执行以下操作: 1.将整数分配给单字母变量 2.使用数字和变量进行加法和减法 3.输出变量的值
在本教程中,它说要允许将数字分配给变量,我们需要lex文件返回两种不同类型的值,然后在yacc文件中的并集中声明它们。
我不知道为什么这是必要的。实际上,我已经进行了更改,更改了教程代码,因此无需使用类型/联合就可以正常工作(我只是使用NAME的值将symtbl中的索引设置为其所分配的整数)。所以我很困惑的是为什么还要使用类型和联合呢?下面是教程中的代码。
%{
...
int symtbl[26];
bool issym[26];
%}
%union {
int rvalue; /* value of evaluated expression */
int lvalue; /* index into symtbl for variable name */
}
%token <rvalue> NUMBER
%token <lvalue> NAME
%type <rvalue> expression
%type <rvalue> const
%%
statement_list : statement '\n'
| statement_list statement '\n'
;
statement: NAME '=' expression { symtbl[$1] = $3; issym[$1] = true; }
| expression { printf("%d\n", $1); }
;
expression: expression '+' const { $$ = $1 + $3; }
| expression '-' const { $$ = $1 - $3; }
| const { $$ = $1; }
;
const: NUMBER { $$ = $1; }
| NAME
{
if (issym[$1]) { $$ = symtbl[$1]; }
else { fprintf(stderr, "Error: variable %c not previously defined\n", $1+'a'); exit(1); }
}
;
%%
所以我的问题是为什么我们需要右值和左值类型?为什么要把它放在工会里?为什么还要将规则声明为特定类型?