-
酱紫编译的 authored6f79f641
%{
#include<stdlib.h>
#include "include/def.h"
#include <stdio.h>
#include <math.h>
extern int yylineno;
extern FILE *yyin;
extern char *yytext;
int yylex(void);
void yyerror(char* s, ...);
%}
%union{
int type_int;
struct node * ptr;
char type_id[32];
};
//非终结符
%type <ptr> compunit decl constdecl constdef constinitval vardecl vardef funcdef initval eqexp
%type <ptr> funcfparams funcfparam block blockitem stmt exp cond lval primaryexp
%type <ptr> number unaryexp unaryop funcrparams mulexp addexp relexp landexp lorexp constexp
%type <ptr> constdecl_ constinitval_ block_ vardecl_ funcfparam_ constdef_ vardef_ lval_
%type <ptr> program btype defone defarray initvalarray initvalarraylist
%left TOK_OR TOK_AND TOK_ADD TOK_SUB TOK_MUL TOK_DIV TOK_MODULO
%left TOK_LESS TOK_LESSEQ TOK_GREAT TOK_GREATEQ TOK_NOTEQ TOK_EQ
%right TOK_ASSIGN TOK_NOT
//终结符
%token <type_int> INTCONST
%token <type_id> IDENT
//relop
%token <type_id> TOK_LESS TOK_LESSEQ TOK_GREAT TOK_GREATEQ TOK_NOTEQ TOK_EQ // < > >= <= == !=
//TYPE
%token <type_id> TOK_CONST
//标识符
%token TOK_LPAR TOK_RPAR TOK_LBRACKET TOK_RBRACKET TOK_LSQUARE TOK_RSQUARE TOK_COMMA TOK_SEMICOLON TOK_BREAK TOK_CONTINUE
%token TOK_ADD TOK_SUB TOK_MUL TOK_DIV TOK_ASSIGN
%token TOK_AND TOK_OR TOK_NOT TOK_IF TOK_ELSE TOK_WHILE TOK_RETURN TOK_INT TOK_VOID TOK_FLOAT
%%
program: compunit {$$ = $1;Driver($1);}
;
compunit: decl compunit {$$ = mknode(COMPUNIT_LIST,$1,$2,NULL,yylineno);}
| funcdef compunit {$$ = mknode(COMPUNIT_LIST,$1,$2,NULL,yylineno);}
| decl {$$ = $1;}
| funcdef {$$ = $1;}
;
decl: constdecl TOK_SEMICOLON {$$ = $1;}
| vardecl TOK_SEMICOLON {$$ = $1;}
;
//常量声明
constdecl: TOK_CONST TOK_INT constdef constdecl_ {$3->type = CONST_INT;if($3->kind == ID)$3->kind = VAR_DECL;
if($4 != NULL)
{$$ = mknode(VAR_DECL_LIST,$3,$4,NULL,yylineno);}
else
{$$ = $3;}}
;
constdecl_: TOK_COMMA constdef constdecl_ {$2->type=CONST_INT;$2->kind = VAR_DEF;$$ = mknode(VAR_DECL_LIST,$2,$3,NULL,yylineno);}
| {$$ = NULL;}
;
constdef: IDENT constdef_ TOK_ASSIGN constinitval {struct node *temp;if($2 == NULL){temp=mknode(ID,NULL,NULL,NULL,yylineno);strcpy(temp->type_id,$1);}
else{temp = mkparray(ARRAY_DEC,$1,$2,yylineno);temp->type = TOK_INT;strcpy(temp->type_id,$1);}
temp->ptr[0]=$4;$$ = temp;}
;
constdef_: TOK_LSQUARE INTCONST TOK_RSQUARE constdef_ {struct node * temp = mknode(TOK_INT,$4,NULL,NULL,yylineno);temp->type_int = $2;$$ =temp;}
| {$$ = NULL;}
;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
btype: TOK_INT {$$ = mknode(TOK_INT,NULL,NULL,NULL,yylineno);}
| TOK_FLOAT {$$ = mknode(TOK_FLOAT,NULL,NULL,NULL,yylineno);}
;
constinitval: constexp {$$ = $1;}
| TOK_LBRACKET TOK_RBRACKET {$$ = NULL;}
| TOK_LBRACKET constinitval constinitval_ TOK_RBRACKET {$$ = mknode(CONSTINITVAL_LIST,$2,$3,NULL,yylineno);}
;
constinitval_:TOK_COMMA constinitval constinitval_ {$$ = mknode(CONSTINITVAL_LIST,$2,$3,NULL,yylineno);}
| {$$ = NULL;}
;
vardecl: btype vardef vardecl_ {
$2->type = $1->kind;if($2->kind == ID)$2->kind = VAR_DECL;
if($3 != NULL)
{struct node * temp = mknode(VAR_DECL_LIST,$2,$3,NULL,yylineno);temp->type = $1->kind;$$ = temp;}
else
{$$=$2;}
}
;
vardecl_: TOK_COMMA vardef vardecl_ {$2->kind = VAR_DECL;$$ = mknode(VAR_DECL_LIST,$2,$3,NULL,yylineno);}
| {$$ = NULL;}
;
vardef: defone {$$ = $1;}
| defarray {$$ = $1;}
;
defone: IDENT {$$ = mknode(ID,NULL,NULL,NULL,yylineno);strcpy($$->type_id,$1);}
| IDENT TOK_ASSIGN initval {struct node *temp = mknode(ID,NULL,NULL,NULL,yylineno);strcpy(temp->type_id,$1);temp->ptr[0] = $3;$$ = temp;}
;
defarray: IDENT TOK_LSQUARE constexp TOK_RSQUARE vardef_ {struct node * temp = mknode(TOK_INT,$5,NULL,NULL,yylineno);temp->type_int = const_exp($3);$$ = mkparray(ARRAY_DEC,$1,temp,yylineno);strcpy($$->type_id,$1);}
| IDENT TOK_LSQUARE constexp TOK_RSQUARE vardef_ TOK_ASSIGN initvalarray {struct node * temp = mknode(TOK_INT,$5,NULL,NULL,yylineno);temp->type_int = const_exp($3);$$ = mkparray(ARRAY_DEC,$1,temp,yylineno);strcpy($$->type_id,$1);$$->ptr[0] = $7;}
;
vardef_: TOK_LSQUARE constexp TOK_RSQUARE vardef_ {struct node * temp = mknode(TOK_INT,$4,NULL,NULL,yylineno);temp->type_int = const_exp($2);$$ =temp;}
| {$$ = NULL;}
;
initval: exp {$$ = $1;}
;
initvalarray: TOK_LBRACKET TOK_RBRACKET {$$ = mknode(INITARRAY,NULL,NULL,NULL,yylineno);}
| TOK_LBRACKET initvalarraylist TOK_RBRACKET {$$ = mknode(INITARRAY,$2,NULL,NULL,yylineno);}
;
initvalarraylist: initvalarray {$$ = $1;} //多一层大括号
| initvalarraylist TOK_COMMA initvalarray {push_initarray($1,$3);$$ = $1;} //
| initval {$$ = $1;}
| initvalarraylist TOK_COMMA initval {push_initarray($1,$3);$$ = $1;}
;
funcdef: btype IDENT TOK_LPAR funcfparams TOK_RPAR block {struct node* temp = mknode(FUNC_DEF,$4,$6,NULL,yylineno);strcpy(temp->type_id,$2);
temp->type = TOK_INT;$$ = temp;}//该结点对应一个函数定义
| TOK_VOID IDENT TOK_LPAR funcfparams TOK_RPAR block {struct node* temp = mknode(FUNC_DEF,$4,$6,NULL,yylineno);strcpy(temp->type_id,$2);
temp->type = TOK_VOID;$$ = temp;}//该结点对应一个函数定义
| btype IDENT TOK_LPAR TOK_RPAR block {struct node* temp = mknode(FUNC_DEF,NULL,$5,NULL,yylineno);strcpy(temp->type_id,$2);
temp->type = TOK_INT;$$ = temp;}//该结点对应一个函数定义
| TOK_VOID IDENT TOK_LPAR TOK_RPAR block {struct node* temp = mknode(FUNC_DEF,NULL,$5,NULL,yylineno);strcpy(temp->type_id,$2);
temp->type = TOK_VOID;$$ = temp;}//该结点对应一个函数定义
;
funcfparams: funcfparam TOK_COMMA funcfparams {$$ = mknode(PARAM_LIST,$1,$3,NULL,yylineno);}
| funcfparam {$$ = mknode(PARAM_LIST,$1,NULL,NULL,yylineno);}
;
funcfparam: btype IDENT TOK_LSQUARE TOK_RSQUARE funcfparam_ {struct node*temp = mkparray(PARAM_ARRAY,$2,$5,yylineno);temp->type = $1->kind;strcpy(temp->type_id,$2);$$ = temp;}
| btype IDENT {struct node*temp = mknode(PARAM_DEC,NULL,NULL,NULL,yylineno); strcpy(temp->type_id,$2);temp->type = $1->type;$$ = temp;}
;
funcfparam_: TOK_LSQUARE INTCONST TOK_RSQUARE funcfparam_ {struct node * temp = mknode(TOK_INT,NULL,NULL,NULL,yylineno);temp->type_int = $2;temp->ptr[0] = $4;$$= temp;}
| {$$ = NULL;}
;
block: TOK_LBRACKET block_ TOK_RBRACKET {$$ = mknode(BLOCK,$2,NULL,NULL,yylineno);}
;
block_: blockitem block_ {$$ = mknode(BLOCK_LIST,$1,$2,NULL,yylineno);}
| {$$ = NULL;}
;
blockitem: decl {$$ = $1;}
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
| stmt {$$ = $1;}
;
stmt: lval TOK_ASSIGN exp TOK_SEMICOLON {$$ = mknode(TOK_ASSIGN,$1,$3,NULL,yylineno);}//$$结点type_id空置未用,正好存放运算符
| TOK_SEMICOLON {$$ = NULL;}
| exp TOK_SEMICOLON {$$ = $1;}
| block {$$ = $1;}
| TOK_IF TOK_LPAR cond TOK_RPAR stmt {$$ = mknode(IF_THEN,$3,$5,NULL,yylineno);}
| TOK_IF TOK_LPAR cond TOK_RPAR stmt TOK_ELSE stmt {$$ = mknode(IF_THEN_ELSE,$3,$5,$7,yylineno);}
| TOK_WHILE TOK_LPAR cond TOK_RPAR stmt {$$ = mknode(TOK_WHILE,$3,$5,NULL,yylineno);}
| TOK_BREAK TOK_SEMICOLON {$$ = mknode(TOK_BREAK,NULL,NULL,NULL,yylineno);}
| TOK_CONTINUE TOK_SEMICOLON {$$ = mknode(TOK_CONTINUE,NULL,NULL,NULL,yylineno);}
| TOK_RETURN TOK_SEMICOLON {$$ = mknode(TOK_RETURN,NULL,NULL,NULL,yylineno);}
| TOK_RETURN exp TOK_SEMICOLON {$$ = mknode(TOK_RETURN,$2,NULL,NULL,yylineno);}
;
exp: addexp {$$ = $1;}
;
cond: lorexp {$$ = $1;}
;
//左值表达式
lval: IDENT lval_ {$$ = mknode(ID,NULL,NULL,NULL,yylineno);strcpy($$->type_id,$1);if($2 != NULL){$$->kind = EXP_ARRAY;$$->ptr[0] = $2;}}
;
lval_: TOK_LSQUARE exp TOK_RSQUARE lval_ {$$ = mknode(EXP_ARRAY,$2,$4,NULL,yylineno);}
| {$$ = NULL;}
;
primaryexp: TOK_LPAR exp TOK_RPAR {$$ = $2;}
| lval {$$ = $1;}
| number {$$ = $1;}
;
number: INTCONST {$$ = mknode(LITERAL,NULL,NULL,NULL,yylineno);$$->type_int = $1;$$->type = INT;}
;
unaryexp: primaryexp {$$ = $1;}
| IDENT TOK_LPAR funcrparams TOK_RPAR {$$ = mknode(FUNC_CALL,$3,NULL,NULL,yylineno);strcpy($$->type_id,$1);}
| IDENT TOK_LPAR TOK_RPAR {$$ = mknode(FUNC_CALL,NULL,NULL,NULL,yylineno);strcpy($$->type_id,$1);}
| unaryop unaryexp {$$ = mknode(UNARYEXP,$1,$2,NULL,yylineno);}
;
unaryop: TOK_ADD {$$ = mknode(TOK_ADD,NULL,NULL,NULL,yylineno);strcpy($$->type_id,"TOK_ADD");}
| TOK_SUB {$$ = mknode(TOK_SUB,NULL,NULL,NULL,yylineno);strcpy($$->type_id,"TOK_SUB");}
| TOK_NOT {$$ = mknode(TOK_NOT,NULL,NULL,NULL,yylineno);strcpy($$->type_id,"TOK_NOT");}
;
funcrparams: exp TOK_COMMA funcrparams {$$ = mknode(ARGS,$1,$3,NULL,yylineno);}
| exp {$$ = mknode(ARGS,$1,NULL,NULL,yylineno);}
;
mulexp: unaryexp {$$ = $1;}
| mulexp TOK_MUL unaryexp {$$ = mkopnode(TOK_MUL,$1,$3,yylineno);}
| mulexp TOK_DIV unaryexp {$$ = mkopnode(TOK_DIV,$1,$3,yylineno);}
| mulexp TOK_MODULO unaryexp {$$ = mkopnode(TOK_MODULO,$1,$3,yylineno);}
;
addexp: mulexp {$$ = $1;}
| addexp TOK_ADD addexp {$$ = mkopnode(TOK_ADD,$1,$3,yylineno);}
| addexp TOK_SUB addexp {$$ = mkopnode(TOK_SUB,$1,$3,yylineno);}
;
relexp: addexp {$$ = $1;}
| relexp TOK_LESS addexp {$$ = mknode(TOK_LESS,$1,$3,NULL,yylineno);strcpy($$->type_id,$2);}////词法分析关系运算符号自身值保存在$2中
| relexp TOK_GREAT addexp {$$ = mknode(TOK_GREAT,$1,$3,NULL,yylineno);strcpy($$->type_id,$2);}
| relexp TOK_LESSEQ addexp {$$ = mknode(TOK_LESSEQ,$1,$3,NULL,yylineno);strcpy($$->type_id,$2);}
| relexp TOK_GREATEQ addexp {$$ = mknode(TOK_GREATEQ,$1,$3,NULL,yylineno);strcpy($$->type_id,$2);}
;
eqexp: relexp {$$ = $1;}
| eqexp TOK_EQ relexp {$$ = mknode(TOK_EQ,$1,$3,NULL,yylineno);strcpy($$->type_id,$2);}////词法分析关系运算符号自身值保存在$2中
| eqexp TOK_NOTEQ relexp {$$ = mknode(TOK_NOTEQ,$1,$3,NULL,yylineno);strcpy($$->type_id,$2);}////词法分析关系运算符号自身值保存在$2中
;
landexp: eqexp {$$ = $1;}
| landexp TOK_AND eqexp {$$=mknode(TOK_AND,$1,$3,NULL,yylineno);strcpy($$->type_id,"TOK_AND");}
;
lorexp: landexp {$$ = $1;}
| lorexp TOK_OR landexp {$$=mknode(TOK_OR,$1,$3,NULL,yylineno);strcpy($$->type_id,"TOK_OR");;}
;
constexp: addexp {$$ = $1;}
;
211212213214215216217218219220221222223
%%
#include<stdarg.h>
void yyerror(char* s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "%d:error:", yylineno); //错误行号
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
}