tiger 抽象语法树生成

来源:互联网 发布:淘宝权重值是什么意思 编辑:程序博客网 时间:2024/05/16 16:21

在语法分析基础上添加语义动作,生成tiger语言抽象语法树。

官网给出框架和构造函数代码,仅仅需要在tiger.y添加相应语义动作,实现比较容易。

文法:
文法稍作改变,增加了tydecs和fundecs来对应书中要求的nametylist和functionlist。由此产生了两个新shift/reduce conflict, 但均无害。

/********************************************************** * Author        : lh * Email         : lhcoder@163.com * Create time   : 2017-03-01 16:27 * Last modified : 2017-03-02 09:51 * Filename      : tiger.y * Description   :  * *******************************************************/%{#include <stdio.h>#include "util.h"#include "symbol.h" #include "errormsg.h"#include "absyn.h"#define YYDEBUG 1int yylex(void); /* function prototype */void yyerror(char *s){    EM_error(EM_tokPos, "%s", s);}A_exp absyn_root;%}%union {    int pos;    int ival;    string sval;    A_exp exp;    A_var var;    A_expList expList;    A_efieldList efieldList;    A_decList decList;    A_dec dec;    A_ty ty;    A_nametyList nametyList;    A_fundecList fundecList;    A_namety namety;    A_fundec fundec;    A_fieldList fieldList;    A_field field;}%token <sval> ID STRING%token <ival> INT%token   COMMA COLON SEMICOLON LPAREN RPAREN LBRACK RBRACK   LBRACE RBRACE DOT   PLUS MINUS TIMES DIVIDE EQ NEQ LT LE GT GE  AND OR ASSIGN  ARRAY IF THEN ELSE WHILE FOR TO DO LET IN END OF   BREAK NIL  FUNCTION VAR TYPE %left SEMICOLON%right THEN ELSE DOT DO OF%right ASSIGN%left OR%left AND%nonassoc EQ NEQ LT LE GT GE%left PLUS MINUS%left TIMES DIVIDE%left UMINUS%type <exp> program exp funcall%type <var> lvalue%type <expList> expseq paraseq%type <efieldList> asseq%type <decList> decs%type <dec> dec vardec%type <nametyList> tydecs%type <fundecList> fundecs%type <namety> tydec%type <fundec> fundec%type <ty> ty%type <fieldList> tyfields tyfield%start program%%program : exp    {absyn_root=$1;}exp : lvalue            {$$ = A_VarExp(EM_tokPos, $1);}| lvalue ASSIGN exp {$$ = A_AssignExp(EM_tokPos, $1, $3);}| INT{$$ = A_IntExp(EM_tokPos, $1);}| STRING{$$ = A_StringExp(EM_tokPos, $1);}| NIL{$$ = A_NilExp(EM_tokPos);}    | LPAREN RPAREN         {$$ = A_SeqExp(EM_tokPos, NULL);}| LPAREN expseq RPAREN{$$ = A_SeqExp(EM_tokPos, $2);}    | MINUS exp %prec UMINUS {$$ = A_OpExp(EM_tokPos, A_minusOp, A_IntExp(EM_tokPos, 0), $2);}| exp PLUS exp{$$ = A_OpExp(EM_tokPos, A_plusOp, $1, $3);}| exp MINUS exp{$$ = A_OpExp(EM_tokPos, A_minusOp, $1, $3);}| exp TIMES exp{$$ = A_OpExp(EM_tokPos, A_timesOp, $1, $3);}| exp DIVIDE exp{$$ = A_OpExp(EM_tokPos, A_divideOp, $1, $3);}    | exp EQ exp    {$$ = A_OpExp(EM_tokPos, A_eqOp, $1, $3);}| exp NEQ exp{$$ = A_OpExp(EM_tokPos, A_neqOp, $1, $3);}| exp LT exp{$$ = A_OpExp(EM_tokPos, A_ltOp, $1, $3);}| exp LE exp{$$ = A_OpExp(EM_tokPos, A_leOp, $1, $3);}| exp GT exp{$$ = A_OpExp(EM_tokPos, A_gtOp, $1, $3);}| exp GE exp{$$ = A_OpExp(EM_tokPos, A_geOp, $1, $3);}    | exp AND exp   {$$ = A_IfExp(EM_tokPos, $1, $3, A_IntExp(EM_tokPos, 0));}| exp OR exp{$$ = A_IfExp(EM_tokPos, $1, A_IntExp(EM_tokPos, 1), $3);}    | funcall   {$$ = $1;}    | ID LBRACK exp RBRACK OF exp   {$$ = A_ArrayExp(EM_tokPos, S_Symbol($1), $3, $6);}| ID LBRACE RBRACE{$$ = A_RecordExp(EM_tokPos, S_Symbol($1), NULL);}| ID LBRACE asseq RBRACE{$$ = A_RecordExp(EM_tokPos, S_Symbol($1), $3);}    | IF exp THEN exp                   {$$ = A_IfExp(EM_tokPos, $2, $4, NULL);}| IF exp THEN exp ELSE exp{$$ = A_IfExp(EM_tokPos, $2, $4, $6);}| WHILE exp DO exp{$$ = A_WhileExp(EM_tokPos, $2, $4);}| FOR ID ASSIGN exp TO exp DO exp{$$ = A_ForExp(EM_tokPos, S_Symbol($2), $4, $6, $8);}| BREAK{$$ = A_BreakExp(EM_tokPos);}    | LET decs IN END           {$$ = A_LetExp(EM_tokPos, $2, A_SeqExp(EM_tokPos, NULL));}| LET decs IN expseq END{$$ = A_LetExp(EM_tokPos, $2, A_SeqExp(EM_tokPos, $4));}    | LPAREN error RPAREN   {$$ = A_SeqExp(EM_tokPos, NULL);}| error SEMICOLON exp{$$ = $3;}    ;lvalue  : ID                        {$$ = A_SimpleVar(EM_tokPos,S_Symbol($1));}| lvalue DOT ID{$$ = A_FieldVar(EM_tokPos, $1, S_Symbol($3));}| lvalue LBRACK exp RBRACK{$$ = A_SubscriptVar(EM_tokPos, $1, $3);}| ID LBRACK exp RBRACK{$$ = A_SubscriptVar(EM_tokPos, A_SimpleVar(EM_tokPos, S_Symbol($1)), $3);}        ;   expseq  : exp                   {$$ = A_ExpList($1, NULL);}| exp SEMICOLON expseq{$$ = A_ExpList($1, $3);}        ;funcall : ID LPAREN RPAREN          {$$ = A_CallExp(EM_tokPos, S_Symbol($1), NULL);}| ID LPAREN paraseq RPAREN{$$ = A_CallExp(EM_tokPos, S_Symbol($1), $3);}        ;paraseq : exp               {$$ = A_ExpList($1, NULL);}| exp COMMA paraseq{$$ = A_ExpList($1, $3);}        ;asseq   : ID EQ exp             {$$ = A_EfieldList(A_Efield(S_Symbol($1), $3), NULL);}| ID EQ exp COMMA asseq{$$ = A_EfieldList(A_Efield(S_Symbol($1), $3), $5);}        ;decs    : dec decs  {$$ = A_DecList($1, $2);}|{$$ = NULL;}        ;dec : tydecs    {$$ = A_TypeDec(EM_tokPos, $1);}| vardec{$$ = $1;}| fundecs{$$ = A_FunctionDec(EM_tokPos, $1);}    ;tydecs  : tydec         {$$ = A_NametyList($1, NULL);}| tydec tydecs{$$ = A_NametyList($1, $2);}        ;tydec   : TYPE ID EQ ty {$$ = A_Namety(S_Symbol($2), $4);}        ;ty  : ID                        {$$ = A_NameTy(EM_tokPos, S_Symbol($1));}| LBRACE tyfields RBRACE{$$ = A_RecordTy(EM_tokPos, $2);}| ARRAY OF ID{$$ = A_ArrayTy(EM_tokPos, S_Symbol($3));}    ; tyfields: tyfield   {$$ = $1;}|{$$ = NULL;}        ;tyfield : ID COLON ID                   {$$ = A_FieldList(A_Field(EM_tokPos, S_Symbol($1), S_Symbol($3)), NULL);}| ID COLON ID COMMA tyfield{$$ = A_FieldList(A_Field(EM_tokPos, S_Symbol($1), S_Symbol($3)), $5);}        ;vardec  : VAR ID ASSIGN exp             {$$ = A_VarDec(EM_tokPos, S_Symbol($2), NULL, $4);}| VAR ID COLON ID ASSIGN exp{$$ = A_VarDec(EM_tokPos, S_Symbol($2), S_Symbol($4), $6);}        ;fundecs : fundec            {$$ = A_FundecList($1, NULL);}| fundec fundecs{$$ = A_FundecList($1, $2);}        ;fundec  : FUNCTION ID LPAREN tyfields RPAREN EQ exp             {$$ = A_Fundec(EM_tokPos, S_Symbol($2), $4, NULL, $7);}| FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp{$$ = A_Fundec(EM_tokPos, S_Symbol($2), $4, S_Symbol($7), $9);}        ;
0 0