yacc和lex中的类型/联合的目的是什么?

时间:2019-06-16 02:33:57

标签: yacc lex

我正在通过一些教程代码来学习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); }
       }
     ;
%%

所以我的问题是为什么我们需要右值和左值类型?为什么要把它放在工会里?为什么还要将规则声明为特定类型?

0 个答案:

没有答案