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

📄 parser.y

📁 一个编译器的实现
💻 Y
字号:

%{
#define YYPARSER /* distinguishes Yacc output from other code files */

#include "globals.h"
#include "util.h"
#include "scan.h"
#include "parse.h"
#include <stdlib.h>

#define YYSTYPE TreeNode *
static char * savedName; /* for use in assignments */
static int savedLineNo; /* ditto */
static TreeNode * savedTree; /* stores syntax tree for later return */

%}

%token IF ELSE WHILE DO MAIN FOR GOTO CONTINUE BREAK RINT RFLOAT RCHAR  
%token ID FLOAT INT CHAR
%token ASSIGN EQ NE LT MT LE ME PLUS MINUS TIMES OVER AND OR NOT LP RP LB RB LS RS SEMI COMMA
%token ERROR 

%% /* Grammar for TINY */

program     : MAIN LP RP LB stmt_seq RB      { savedTree = $5;} 
            ;
stmt_seq    : stmt_seq stmt 
                 { YYSTYPE t = $1;
                   if (t != NULL)
                   { while (t->sibling != NULL)
                        t = t->sibling;
                     t->sibling = $2;
                     $$ = $1; }
                     else $$ = $2;
                 }
            | {$$ = NULL;}
            ;
stmt        : if_stmt { $$ = $1; }
            | while_stmt { $$ = $1; }
            | exp_stmt { $$ = $1; }
            | decl_stmt { $$ = $1; }
            | BREAK SEMI{ $$ = newStmtNode(BreakK); }
            | error  { $$ = NULL; }
            ;
if_stmt     : IF LP exp RP LB stmt_seq RB 
                 { $$ = newStmtNode(IfK);
                   $$->child[0] = $3;
                   $$->child[1] = $6;
                 }
            | IF LP exp RP LB stmt_seq RB  ELSE LB stmt_seq RB 
                 { $$ = newStmtNode(IfK);
                   $$->child[0] = $3;
                   $$->child[1] = $6;
                   $$->child[2] = $10;
                 }
            ;
while_stmt  : WHILE LP exp RP LB stmt_seq RB
                 { $$ = newStmtNode(WhileK);
                   $$->child[0] = $3;
                   $$->child[1] = $6;
                 }
            ;
exp_stmt    : gen_exp SEMI 
                 { $$ = newStmtNode(ExK);
                   $$->child[0] = $1;
                 }
            | SEMI
                 { $$ = newStmtNode(ExK);
                 }
            ;
decl_stmt   : type var_list SEMI
			     { YYSTYPE t = $2;
			       while (t!= NULL){
			       		if($1->kind.type == IntK)
			       			t->type = Integer;
			       		else if($1->kind.type == FloatK)
			       			t->type = Float;
			       	    else if($1->kind.type == CharK)
			       			t->type = Char;
			       		else t->type = Void;
			       		t = t->sibling;
			       	}
			       $$ = newStmtNode(DeclK);
			       $$->child[0] = $1;
			       $$->child[1] = $2;
			       
			     }
			;

var_list    : var_list COMMA var
                { YYSTYPE t = $1;
                  $3->attr.isDecl = TRUE;
                   if (t != NULL)
                   { while (t->sibling != NULL)
                        t = t->sibling;
                     t->sibling = $3;
                     $$ = $1; }
                     else $$ = $3;
                 } 
			| var 
                {  $$ = $1;
                   $$->attr.isDecl = TRUE;
                }
			;
/*decl_stmt   :  type ID 
				{
				   savedName=copyString(tokenString);
				   savedLineNo = lineno;
				}
				SEMI
				{  $$ = newStmtNode(DeclK);
			       $$->child[0] = $1;
			       $$->child[1] = newExpNode(IdK);
				   $$->child[1]->attr.name = savedName;
				   $$->child[1]->lineno = savedLineNo;
				   $$->child[1]->attr.isDecl = TRUE;
				   if($1->kind.type==IntK)
				   		$$->child[1]->type = Integer;
				   else if($1->kind.type==FloatK)
				   		$$->child[1]->type = Float;
                }	
            |  type ID 
            	{  savedName=
                         copyString(tokenString);
                   savedLineNo = lineno;
                }
              LS INT 
                {  savedLength = atoi(lookAhead);
                }
              RS SEMI
                {  $$ = newStmtNode(DeclK);
            	   $$->child[0] = $1;
			       $$->child[1] = newExpNode(ArrK);
            	   $$->child[1]->attr.name =savedName;
                   $$->child[1]->attr.length = savedLength;
                   $$->child[1]->lineno = savedLineNo;
                   $$->child[1]->attr.isDecl = TRUE;
                   if($1->kind.type==IntK)
				   		$$->child[1]->type = Integer;
				   else if($1->kind.type==FloatK)
				   		$$->child[1]->type = Float;
                }
            ;*/
type        : RINT
				{  $$ = newTypeNode(IntK);
				} 
			| RFLOAT
			    {  $$ = newTypeNode(FloatK);
				} 
			| RCHAR
			    {  $$ = newTypeNode(CharK);
				} 
			;

gen_exp     : var ASSIGN gen_exp
                 { $$ = newExpNode(AssignK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;

                 }
            | exp{ $$ = $1;}
            ; 
exp         : exp AND comp_exp
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = AND;
                  }
             |exp OR comp_exp
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = OR;
                  }
			 |comp_exp { $$ = $1;}            
            ;
comp_exp    : comp_exp LT simple_exp 
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = LT;
                 }
            | comp_exp MT simple_exp
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = MT;
                 }
            | comp_exp LE simple_exp
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = LE;
                 }
            | comp_exp ME simple_exp
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = ME;
                 }
            | comp_exp EQ simple_exp
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = EQ;
                 }
            | comp_exp NE simple_exp
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = NE;
                 }
            | simple_exp { $$ = $1; }
            ;
simple_exp  : simple_exp PLUS term 
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = PLUS;
                 }
            | simple_exp MINUS term
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = MINUS;
                 } 
            | term { $$ = $1; }
            ;
term        : term TIMES factor 
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = TIMES;
                 }
            | term OVER factor
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $1;
                   $$->child[1] = $3;
                   $$->attr.op = OVER;
                 }
            | factor { $$ = $1; }
            ;
factor      : LP gen_exp RP
                 { $$ = $2; }
            | INT
                 { $$ = newExpNode(IK);
                   $$->attr.val.i = atoi(lookAhead);
                   $$->type = Integer;
                 }
            | FLOAT
                 { $$ = newExpNode(FK);
                   $$->attr.val.f = atof(lookAhead);
                   $$->type = Float;
                 }
            | CHAR
                 {
                   $$ = newExpNode(CK);
                   $$->attr.val.c = lookAhead[1];
                   $$->type = Char;
                 }   
            | var{ $$ = $1;}
            | NOT factor
                 { $$ = newExpNode(OpK);
                   $$->child[0] = $2;
                   $$->attr.op = NOT;
                  }
            | error { $$ = NULL; }
            ;
var       : | ID { $$ = newExpNode(IdK);
                   $$->attr.name =
                         copyString(tokenString);
                   $$->lineno = lineno;
                   $$->attr.isDecl = FALSE;
                 }
            | ID { savedName=
                         copyString(tokenString);
                   savedLineNo = lineno;
                 }
              LS gen_exp RS                
               {   $$ = newExpNode(ArrK);
                   $$->attr.name = savedName;
                   $$->child[0] = $4;                   
                   $$->lineno = savedLineNo;
                   $$->attr.isDecl = FALSE;
                 } 
            ;

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

/* 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 int yylex(void)
{ return getToken(); }

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

⌨️ 快捷键说明

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