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

📄 parse_yy.y

📁 大3编译原理课程设计 绝对符合老师要求 报告代码一应俱全 很详细 很靠谱
💻 Y
字号:
/****************************************************/
/* File: parse.y                                    */
/* The CMINUS Yacc specification file               */
/****************************************************/
%{ 
#define YYPARSER                          /* distinguishes Yacc output from other code files */ 
 
#include "globals.h" 
#include "util.h" 
#include "scan.h" 
#include "scan_lex.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 IF,ELSE,RETURN,WHILE,INT,VOID
%token ID NUM
%token PLUS,MINUS,TIMES,OVER,LT,LTEQ,GT,GTEQ,EQ,NOEQ,ASSIGN,SEMI,COMMA,LPAREN,RPAREN,LBRA,RBRA,LBRACE,RBRACE  
 	 
%union { TreeNode * ptree; 
         TokenType type;  
       } 
        
%left	COMMA 
%right	ASSIGN 
%left EQ NOEQ 
%left LT LTEQ GT GTEQ 
%left PLUS MINUS 
%left TIMES OVER 
%left LPAREN,RPAREN,LBRA,RBRA,LBRACE,RBRACE
%right ELSE 
 
%include { 
    void yyerror(const char * message); 
	TreeNode * parse(void); 
} 
 
%% /* Grammar for CMINUS */ 
 
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 = newExpNode(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 
              {  
				 $$ = newExpNode(AssignK); 
				 $$ -> child[0] = newExpNode(IdK); 
				 $$ -> child[0] -> attr.name = savedIdName; 
				 $$ -> child[1] = $3; 
              } 
            ;  
type_spec   : INT { $$ = Integer; }           
            | VOID { $$ = Void; }          
            ; 
fun_def     : type_spec id fid LPAREN params RPAREN comp_stmt  
				{ $$ = newDecNode(FunK); 
				  $$ -> attr.name = savedFunName; 
				  $$ -> type = $1; 
				  $$ -> child[0] = $5; 
				  $$ -> child[1] = $7;  
				} 
            | id fid LPAREN params RPAREN comp_stmt 
				{ $$ = newDecNode(FunK); 
				  $$ -> attr.name = savedFunName; 
				  $$ -> type = Void; 
				  $$ -> child[0] = $4; 
				  $$ -> child[1] = $6;  
				} 
            ; 
fun_dec     : type_spec id fid LPAREN params RPAREN SEMI 
				{ $$ = newDecNode(FunK); 
				  $$ -> attr.name = savedFunName; 
				  $$ -> type = $1; 
				  $$ -> child[0] = $5; 
				  $$ -> child[1] = NULL; 
				} 
			| id fid LPAREN params RPAREN SEMI 
				{ $$ = newDecNode(FunK); 
				  $$ -> 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  
                { $$ = newParamNode(VarK); 
                  $$ -> type = $1; 
                }             
			| type_spec id 
                { $$ = newParamNode(VarK); 
                  $$ -> type = $1; 
                  $$ -> attr.name = savedIdName; 
                }             
            | type_spec id LBRA RBRA 
                { $$ = newParamNode(ArrayK); 
                  $$ -> type = $1; 
                  $$ -> attr.name = savedIdName; 
                }             
            | type_spec id LBRA simple_exp RBRA 
                { $$ = newParamNode(ArrayK); 
                  $$ -> type = $1; 
                  $$ -> attr.name = savedIdName; 
                  $$ -> child[0] = $4; 
                }             
            ; 
comp_stmt   : LBRACE local_dec stmt_list RBRACE 
                { $$ = newStmtNode(CompoundK); 
                  $$ -> 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; } 
            ; 
exp_stmt    : exp SEMI 
                { $$ = $1; } 
            | SEMI 
                { $$ = NULL; }             
            ; 
sele_stmt   : IF LPAREN exp RPAREN stmt %prec ELSE 
                { $$ = newStmtNode(SelectionK); 
                  $$ -> child[0] = $3; 
                  $$ -> child[1] = $5; 
                }             
            | IF LPAREN exp RPAREN stmt ELSE stmt 
                { $$ = newStmtNode(SelectionK); 
                  $$ -> child[0] = $3; 
                  $$ -> child[1] = $5; 
				  $$ -> child[2] = $7; 
                } 
            ; 
iter_stmt   : WHILE LPAREN exp RPAREN stmt 
				{ $$ = newStmtNode(IterationK); 
                  $$ -> 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 
                { $$ = newExpNode(AssignK); 
                  $$ -> child[0] = $1; 
                  $$ -> child[1] = $3; 
                } 
            | simple_exp 
                { $$ = $1; } 
            ; 
var         : id 
                { $$ = newExpNode(IdK); 
                  $$ -> attr.name = savedIdName; 
                }             
            | id LBRA simple_exp RBRA 
				{ $$ = newExpNode(IdK); 
				  $$ -> attr.name = savedIdName; 
                  $$ -> child[0] = $3; 
                }            
            ; 
simple_exp : simple_exp LT simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = LT; 
				  $$ -> type = Boolean; 
				} 
			|simple_exp LTEQ simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = LTEQ; 
				  $$ -> type = Boolean; 
				} 
			|simple_exp GT simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = GT; 
				  $$ -> type = Boolean; 
				} 
			|simple_exp GTEQ simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = GTEQ; 
				  $$ -> type = Boolean; 
				} 
			|simple_exp EQ simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = EQ; 
				  $$ -> type = Boolean; 
				} 
			|simple_exp NOEQ simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = NOEQ; 
				  $$ -> type = Boolean; 
				} 
			|simple_exp PLUS simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = PLUS; 
				} 
			|simple_exp MINUS simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = MINUS; 
				} 
			|simple_exp TIMES simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = TIMES; 
				} 
			|simple_exp OVER simple_exp  
				{ $$ = newExpNode(OpK); 
				  $$ -> child[0] = $1; 
				  $$ -> child[1] = $3; 
				  $$ -> attr.op = OVER; 
				} 
			| factor 
			    { $$ = $1; } 
			; 
 
factor      : LPAREN exp RPAREN 
                { $$ = $2; }			 
            | var 
                { $$ = $1; }			 
			| call 
			    { $$ = $1; }			 
			| NUM 
			    { $$ = newExpNode(ConstK); 
			      $$ -> type = Integer; 
			      $$ -> attr.val.i = atoi(tokenString); 
			    } 
			; 
call        : var LPAREN args RPAREN 
                { $$ = newExpNode(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 output 
 * compatible with ealier versions of the CMINUS 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 + -