tiger 语法分析实现(无语义)

来源:互联网 发布:初中校园网络文化活动 编辑:程序博客网 时间:2024/05/16 06:52

用bison实现tiger语言的语法分析,只判断语法是否出错,无语义动作。

shift/reduce conflict:
按照书上给的语法规则完成tiger.y文件,出现了三类shift/reduce conflict

一、else悬挂

   exp : IF exp THEN exp .       | IF exp THEN exp . ELSE exp

可以通过给else赋比then高的优先级消除,但要注意不要比运算符号等级高。

二、:=、. 、 of

exp: exp . PLUS exp   | exp . MINUS exp   ....   | lvalue ASSIGN exp . PLUS    shift, and go to state 38 MINUS   shift, and go to state 39 .... PLUS      [reduce using rule 42 (exp)] MINUS     [reduce using rule 42 (exp)]

当遇到+、-之类的运算符时,分析器不知道该移进还是该归约。
. 、of情况类似
可以给:= . of赋比运算符低的优先级消除冲突

三、id[exp]

      exp: ID . LBRACK exp RBRACK OF exp      ....      ;      lvalue: ID .    LBRACK  shift, and go to state 19    ....    LBRACK    [reduce using rule 60 (lvalue)]    ....

出现这种状态时,分析器无法仅仅根据”[“判断使用那条规则,这还取决于后面的of是否存在。
分析器会默认进行移进,然而此时不管是移进还是规约,都有可能出错。

可以加上一条产生式规则解决矛盾。
lvalue: ID . LBRACK exp RBRACK
此时状态如下:

      exp: ID . LBRACK exp RBRACK OF exp      ....      lvalue: ID .            | ID . LBRACK exp RBRACK    LBRACE  shift, and go to state 20    ...    LBRACK    [reduce using rule 60 (lvalue)]

虽然s/r冲突依然存在,但分析器会默认进行移近,符合我们的预期,lvalue还是exp的决策将等到”]”后是否有of时进行。

结果:
测试样例均无误。

参考:

官网框架代码

bison用户手册:非运算符优先级使用

stackoverflow大神解答

tiger.y实现:

%{#include <stdio.h>#include "util.h"#include "errormsg.h"#define YYDEBUG 1int yylex();void yyerror(char *s){     EM_error(EM_tokPos, "%s", s);}%}%union {    int pos;    int ival;    string sval;}%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%start program%%program : exp        ;decs    : dec decs           |        ;dec     : tydec             | vardec            | fundec        ;tydec   : TYPE ID EQ ty        ;ty      : ID        | LBRACE tyfields RBRACE        | ARRAY OF ID        ;tyfields: tyfield        |        ;tyfield: ID COLON ID         | tyfield COMMA ID COLON ID        ;vardec  : VAR ID ASSIGN exp                 | VAR ID COLON ID ASSIGN exp        ;fundec  : FUNCTION ID LPAREN tyfields RPAREN EQ exp        | FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp        ;exp : lvalue    | INT           | STRING    | NIL    | LPAREN expseq RPAREN    | LPAREN RPAREN    | MINUS exp  %prec UMINUS    | exp PLUS exp    | exp MINUS exp    | exp TIMES exp    | exp DIVIDE exp    | exp EQ exp    | exp NEQ exp    | exp LT exp    | exp LE exp    | exp GT exp    | exp GE exp    | exp AND exp    | exp OR exp    | funcall    | ID LBRACK exp RBRACK OF exp    | ID LBRACE RBRACE    | ID LBRACE ass RBRACE    | lvalue ASSIGN exp    | IF exp THEN exp    | IF exp THEN exp ELSE exp    | WHILE exp DO exp    | FOR ID ASSIGN exp TO exp DO exp    | BREAK    | LET decs IN END    | LET decs IN expseq END        | LPAREN error RPAREN    | error SEMICOLON exp    ;funcall : ID LPAREN RPAREN        | ID LPAREN para RPAREN        ;para    : exp        | exp COMMA para        ;ass     : ID EQ exp        | ID EQ exp COMMA ass        ;expseq  : exp                       | exp SEMICOLON expseq          ;lvalue  : ID            | lvalue DOT ID        | lvalue LBRACK exp RBRACK         | ID LBRACK exp RBRACK         ;
0 0
原创粉丝点击