⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.y

📁 大3编译原理课程设计 绝对符合老师要求 报告代码一应俱全 很详细 很靠谱
💻 Y
字号:
%{ 
#define YYPARSER /* distinguishes Yacc output from other code files */ 

#include "globals.h" 
#include "util.h" 
#include "scan.h" 
#include "parse.h" 


static char * savedFunName; /* for use in assignments */ 
static char * savedIdName; 
static int savedLineNo; /* ditto */ 
static TreeNode * savedTree; /* stores syntax tree for later return */ 

%} 

%token ENDFILE ERROR 
%token INT CHAR FLOAT IF ELSE WHILE VOID RETURN BREAK CONTINUE 
%token ID NUM FNUM SCHAR 
%token PLUS SUB MUT DIV LT LE GT GE EQ NEQ AND OR NOT ASSIGN SEMI COMMA LP RP LSP RSP LFP RFP 


%union { TreeNode * ptree; 
Type type; 
} 

%type <ptree> program dec_list dec var_dec fun_dec fun_def params param_list param comp_stmt local_dec stmt_list stmt 
exp_stmt sele_stmt iter_stmt return_stmt exp var simple_exp factor call args arg_list 
id_list 
%type <type> type_spec 

%left COMMA 
%right ASSIGN 
%left OR 
%left AND 
%left EQ NEQ 
%left LT LE GT GE 
%left PLUS SUB 
%left MUT DIV 
%left LP RP LSP RSP LFP RFP 

%right ELSE 

%include { 
void yyerror(const char * message); 
TreeNode * parse(void); 
} 

%% /* Grammar for C_minus */ 

program : dec_list 
{ savedTree = $1;} 
; 
dec_list : dec_list dec 
{ TreeNode * t = $1; 
if (t != NULL) 
{ while (t->sibling != NULL) 
t = t->sibling; 
t->sibling = $2; 
$$ = $1; } 
else $$ = $2; 
} 
| dec 
{ $$ = $1; } 
; 
dec : var_dec { $$ = $1; } 
| fun_dec { $$ = $1; } 
| fun_def { $$ = $1; } 
; 
id : ID { savedIdName = copyString(tokenString); } 
; 
fid : { savedFunName = savedIdName; } 
; 
var_dec : type_spec id_list SEMI 
{ if($1 == Void) 
; 
// err 
else 
{ 
$$ = newDecNode(VarK); 
$$ -> type = $1; 
$$ -> child[0] = $2; 
} 
} 
; 
id_list : id_list COMMA var 
{ 
TreeNode * t = $1; 
if (t != NULL) 
{ while (t->sibling != NULL) 
t = t->sibling; 
t->sibling = $3; 
$$ = $1; } 
else $$ = $3; 
} // i,str[5],j 
| var { $$ = $1; } 
| id_list COMMA id ASSIGN simple_exp 
{ 
TreeNode * new_node = newStmtNode(AssignK); 
TreeNode * t = $1; 
if (t != NULL) 
{ while (t->sibling != NULL) 
t = t->sibling; 
t->sibling = new_node; 
$$ = $1; } 
else $$ = new_node; 
} 
| id ASSIGN simple_exp 
{ 
$$ = newStmtNode(AssignK); 
$$ -> child[0] = newExpNode(IdK); 
$$ -> child[0] -> attr.name = savedIdName; 
$$ -> child[1] = $3; 
} 
; 
type_spec : INT { $$ = Integer; } 
| FLOAT { $$ = Float; } 
| CHAR { $$ = Char; } 
| VOID { $$ = Void; } 
; 
fun_def : type_spec id fid LP params RP comp_stmt 
{ $$ = newDecNode(FunDefK); 
$$ -> attr.name = savedFunName; 
$$ -> type = $1; 
$$ -> child[0] = $5; 
$$ -> child[1] = $7; 
} 
| id fid LP params RP comp_stmt 
{ $$ = newDecNode(FunDefK); 
$$ -> attr.name = savedFunName; 
$$ -> type = Void; 
$$ -> child[0] = $4; 
$$ -> child[1] = $6; 
} 
; 
fun_dec : type_spec id fid LP params RP SEMI 
{ $$ = newDecNode(FunDecK); 
$$ -> attr.name = savedFunName; 
$$ -> type = $1; 
$$ -> child[0] = $5; 
$$ -> child[1] = NULL; 
} 
| id fid LP params RP SEMI 
{ $$ = newDecNode(FunDecK); 
$$ -> attr.name = savedFunName; 
$$ -> type = Void; 
$$ -> child[0] = $4; 
$$ -> child[1] = NULL; 
} 
; 
params : param_list 
{ $$ = $1; } 
| 
{ $$ = NULL; } 
; 
param_list : param_list COMMA param 
{ TreeNode * t = $1; 
if (t != NULL) 
{ while (t->sibling != NULL) 
t = t->sibling; 
t->sibling = $3; 
$$ = $1; } 
else $$ = $3; 
} 
| param 
{ $$ = $1; } 
; 
param : type_spec 
{ $$ = newDecNode(ParamK); 
$$ -> type = $1; 
} 
| type_spec id 
{ $$ = newDecNode(ParamK); 
$$ -> type = $1; 
$$ -> attr.name = savedIdName; 
} 
| type_spec id LSP RSP 
{ $$ = newDecNode(ParamK); 
$$ -> type = $1; 
$$ -> attr.name = savedIdName; 
} 
| type_spec id LSP simple_exp RSP 
{ $$ = newDecNode(ParamK); 
$$ -> type = $1; 
$$ -> attr.name = savedIdName; 
$$ -> child[0] = $4; 
} 
; 
comp_stmt : LFP local_dec stmt_list RFP 
{ $$ = newDecNode(CompK); 
$$ -> child[0] = $2; 
$$ -> child[1] = $3; 
} 
; 
local_dec : local_dec var_dec 
{ TreeNode * t = $1; 
if (t != NULL) 
{ while (t->sibling != NULL) 
t = t->sibling; 
t->sibling = $2; 
$$ = $1; } 
else $$ = $2; 
} 
| 
{ $$ = NULL; } 
; 
stmt_list : stmt_list stmt 
{ TreeNode * t = $1; 
if (t != NULL) 
{ while (t->sibling != NULL) 
t = t->sibling; 
t->sibling = $2; 
$$ = $1; } 
else $$ = $2; 
} 
| 
{ $$ = NULL; } 
; 
stmt : exp_stmt { $$ = $1; } 
| sele_stmt { $$ = $1; } 
| iter_stmt { $$ = $1; } 
| return_stmt { $$ = $1; } 
| comp_stmt { $$ = $1; } 
| CONTINUE SEMI { $$ = newStmtNode(ContinueK); } 
| BREAK SEMI { $$ = newStmtNode(BreakK); } 
; 
exp_stmt : exp SEMI 
{ $$ = $1; } 
| SEMI 
{ $$ = NULL; } 
; 
sele_stmt : IF LP exp RP stmt %prec ELSE 
{ $$ = newStmtNode(IfK); 
$$ -> child[0] = $3; 
$$ -> child[1] = $5; 
} 
| IF LP exp RP stmt ELSE stmt 
{ $$ = newStmtNode(IfK); 
$$ -> child[0] = $3; 
$$ -> child[1] = $5; 
$$ -> child[2] = $7; 
} 
; 
iter_stmt : WHILE LP exp RP stmt 
{ $$ = newStmtNode(WhileK); 
$$ -> child[0] = $3; 
$$ -> child[1] = $5; 
} 
; 
return_stmt : RETURN SEMI 
{ $$ = newStmtNode(ReturnK); 
$$ -> child[0] = NULL; 
} 
| RETURN exp SEMI 
{ $$ = newStmtNode(ReturnK); 
$$ -> child[0] = $2; 
} 
; 
exp : var ASSIGN exp 
{ $$ = newStmtNode(AssignK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
} 
| simple_exp 
{ $$ = $1; } 
; 
var : id 
{ $$ = newExpNode(IdK); 
$$ -> attr.name = savedIdName; 
} 
| id LSP simple_exp RSP 
{ $$ = newExpNode(IdK); 
$$ -> attr.name = savedIdName; 
$$ -> child[0] = $3; 
} 
; 
simple_exp : simple_exp OR simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = OR; 
} 
|simple_exp AND simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = AND; 
} 
|simple_exp LT simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = LT; 
$$ -> type = Boolean; 
} 
|simple_exp LE simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = LE; 
$$ -> type = Boolean; 
} 
|simple_exp GT simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = GT; 
$$ -> type = Boolean; 
} 
|simple_exp GE simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = GE; 
$$ -> type = Boolean; 
} 
|simple_exp EQ simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = EQ; 
$$ -> type = Boolean; 
} 
|simple_exp NEQ simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = NEQ; 
$$ -> type = Boolean; 
} 
|simple_exp PLUS simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = PLUS; 
} 
|simple_exp SUB simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = SUB; 
} 
|simple_exp MUT simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = MUT; 
} 
|simple_exp DIV simple_exp 
{ $$ = newExpNode(OpK); 
$$ -> child[0] = $1; 
$$ -> child[1] = $3; 
$$ -> attr.op = DIV; 
} 
| factor 
{ $$ = $1; } 
; 

factor : LP exp RP 
{ $$ = $2; } 
| var 
{ $$ = $1; } 
| call 
{ $$ = $1; } 
| NUM 
{ $$ = newExpNode(NumK); 
$$ -> type = Integer; 
$$ -> attr.val.i = atoi(tokenString); 
} 
| FNUM 
{ $$ = newExpNode(FnumK); 
$$ -> type = Float; 
$$ -> attr.val.f = atof(tokenString); 
} 
| SCHAR 
{ $$ = newExpNode(CharK); 
$$ -> type = Char; 
$$ -> attr.val.i = *(tokenString + 1); 
} 
| NOT factor 
{ $$ = $2; 
$$ -> attr.op = NOT; 
} 
; 
call : var LP args RP 
{ $$ = newStmtNode(CallK); 
$$ -> attr.name = $1 -> attr.name; 
$$ -> child[0] = $3; 
} 
; 
arg_list : arg_list COMMA exp 
{ TreeNode * t = $1; 
if (t != NULL) 
{ while (t->sibling != NULL) 
t = t->sibling; 
t->sibling = $3; 
$$ = $1; } 
else $$ = $3; 
} 
| exp 
{ $$ = $1; } 
; 
args : arg_list 
{ $$ = $1; } 
| 
{ $$ = NULL; } 
; 
%% 

void yyerror(const char * message) 
{ fprintf(listing,"Syntax error at line %d: %s\n",lineno,message); 
fprintf(listing,"Current token: "); 
printToken(yychar,tokenString); 
Error = TRUE; 
} 

/* yylex calls getToken to make Yacc/Bison output 
* compatible with ealier versions of the TINY scanner 
*/ 
#ifdef YYPROTOTYPE 
int YYCDECL yygettoken(void) 
#else 
int YYCDECL yygettoken() 
#endif 
{ 
return yylex(); 
} 

static TokenType yylex(void) 
{ return getToken(); } 

TreeNode * parse(void) 
{ yyparse(); 
return savedTree; 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -