lex+yacc 构造语法树(二)

上一章我们已经写好了lex.l文件,接下来我们还要根据归约规则来确定所得到的token是由上一级的哪些token展开而成。

我们需要构造的small C语言的语法规则如下:


归约规则的声明格式参照yacc的格式,需要注意的是声明符号的左结合或右结合的时候要注意符号的优先级。

%{
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "lex.yy.c"
#include "Node.h"
#include "brothertree.c"

Node* p;
void yyerror(char *s);
FILE *fout;
%}
%union{
         struct Node *token_p;
}
%type <token_p> program extdefs extdef extvars spec stspec opttag var func paras para stmtblock stmts stmt estmt defs def decs dec init exp arrs args
%token<token_p> INT ID SEMI COMMA LC RC STRUCT RETURN IF ELSE BREAK CONT FOR READ WRITE
%left<token_p>	SUB
%right<token_p>	MINUS TYPE ASSIGNOP BINARYOP11
%left<token_p>  BINARYOP10
%left<token_p>  BINARYOP9
%left<token_p>  BINARYOP8
%left<token_p>  BINARYOP7
%left<token_p>  BINARYOP6
%left<token_p>  BINARYOP5
%left<token_p>  BINARYOP4
%left<token_p>  BINARYOP3
%left<token_p>  BINARYOP2
%left<token_p>  BINARYOP1
%right<token_p>	UNARYOP 
%left<token_p>  DOT  LP RP LB RB
%%
program : 
           extdefs    { p=newNode("program",$1->No_Line);
                       insert(p,$1);
                       $$ =p;}
        ;
extdefs : 
           extdef extdefs  { p=newNode("extdefs",$1->No_Line);
                            insert(p,$1);
                            insert(p,$2);
                            $$=p;}
        |                   { p=newNode("NULL",0);
                                $$=p;}
        ;
extdef  :  
           spec extvars SEMI  { p=newNode("extdef",$1->No_Line);
                                insert(p,$1);
                                insert(p,$2);
                                insert(p,$3);
                                $$=p;}
        |  spec func stmtblock { p=newNode("extdef",$1->No_Line);
                                insert(p,$1);
                                insert(p,$2);
                                insert(p,$3);
                                $$=p;}
        ;
extvars :
           dec                 { p=newNode("extvars",$1->No_Line);
                                 insert(p,$1);
                                 $$=p;}
        |  dec COMMA extvars   { p=newNode("extvars",$1->No_Line);
                                insert(p,$1);
                                insert(p,$2);
                                insert(p,$3);
                                $$=p;}
        |                       { p=newNode("NULL",0);
                                $$=p;}
        ;
spec    :
           TYPE                 { p=newNode("spec",$1->No_Line);
                                 insert(p,$1);
                                 $$=p;} 
        |  stspec               { p=newNode("spec",$1->No_Line);
                                 insert(p,$1);
                                 $$=p;}      
        ;
stspec  :
           STRUCT opttag LC defs RC { p=newNode(
  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值