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

📄 parser.y.bak

📁 编译原理课程设计之pp2语法分析程序
💻 BAK
字号:
/* File: parser.y * -------------- * Yacc input file to generate the parser for the compiler. * * pp2: your job is to write a parser that will construct the parse tree *      and if no parse errors were found, print it.  The parser should  *      accept the language as described in specification, and as augmented  *      in the pp2 handout. */%{/* Just like lex, the text within this first region delimited by %{ and %} * is assumed to be C/C++ code and will be copied verbatim to the y.tab.c * file ahead of the definitions of the yyparse() function. Add other header * file inclusions or C++ variable declarations/prototypes that are needed * by your code here. */#include "scanner.h" // for yylex#include "parser.h"#include "errors.h"Program *program;void yyerror(char *msg); // standard error-handling routine%}/* * The section before the first %% is the Definitions section of the yacc * input file. Here is where you declare tokens and types, add precedence * and associativity options, and so on. */ /* * yylval  * ------ * Here we define the type of the yylval global variable that is used by * the scanner to store attibute information about the token just scanned * and thus communicate that information to the parser. You will need to * add new fields to this union as you add different attributes to your * non-terminal symbols. */%union {    int integerConstant;    bool boolConstant;    char *stringConstant;    double doubleConstant;    char identifier[MaxIdentLen+1]; // +1 for terminating null    Decl *decl;    List<Decl*> *declList;    List<VarDecl*> *varDeclList;    List<Expr*> *exprList;    VarDecl *varDecl;    Type *type;    Identifier	*ident;    FnDecl *fnDecl;    Stmt *stmt;    List<Stmt*> *stmtList;    StmtBlock *stmtBlock;    IfStmt *ifStmt;    WhileStmt *whileStmt;    ForStmt *forStmt;    ReturnStmt *returnStmt;    BreakStmt *breakStmt;    PrintStmt *printStmt;    TryStmt *tryStmt;    CatchStmt *catchStmt;    ThrowStmt *throwStmt;    SwitchStmt *switchStmt;                                     CaseStmt *caseStmt;                                         DefaultStmt *defaultStmt;     SwitchBody *switchBody;    List<CatchStmt*> *catchStmtList;    List<CaseStmt*>  *caseStmtList;    Expr *expr;    LValue *LV;    Call *call;}/* Tokens * ------ * Here we tell yacc about all the token types that we are using. * Yacc will assign unique numbers to these and export the #define * in the generated y.tab.h header file. */%token   T_Void T_Bool T_Int T_Double T_String T_Class %token   T_LessEqual T_GreaterEqual T_Equal T_NotEqual T_Dims%token   T_And T_Or T_Null T_Extends T_This%token   T_While T_For T_If T_Else T_Return T_Break%token   T_New T_NewArray T_Print T_ReadInteger T_ReadLine%token	 T_Try T_Catch T_Throw T_Switch T_Case T_Default%token   <identifier> T_Identifier %token   <stringConstant> T_StringConstant %token   <integerConstant> T_IntConstant%token   <doubleConstant> T_DoubleConstant%token   <boolConstant> T_BoolConstant/* No T_ClassIdentifier *//* Non-terminal types * ------------------ * In order for yacc to assign/access the correct field of $$, $1, we * must to declare which field is appropriate for the non-terminal. * As an example, this first type declaration establishes that the DeclList * non-terminal uses the field named "declList" in the yylval union. This * means that when we are setting $$ for a reduction for DeclList ore reading * $n which corresponds to a DeclList nonterminal we are accessing the field * of the union named "declList" which is of type List<Decl*>. * pp2: You'll need to add many of these of your own. */%type <declList>	DeclList Fieldlist%type <decl>		Decl	Field	ClassDecl%type <varDecl>		VariableDecl	Variable%type <fnDecl>		FunctionDecl%type <varDeclList>	Formals NonEmptyVList %type <type>		Type%type <stmt>		Stmt%type <stmtList>	NonEmptySList StmtList%type <stmtBlock>	StmtBlock%type <switchBody>      SwitchBody%type <defaultStmt>     DefaultStmt%type <caseStmt>        CaseStmt%type <switchStmt>      SwitchStmt%type <ifStmt>		IfStmt%type <whileStmt>	WhileStmt%type <forStmt>		ForStmt%type <returnStmt>	ReturnStmt%type <breakStmt>	BreakStmt%type <printStmt>	PrintStmt%type <tryStmt>		TryCatchBlock%type <catchStmt>	CatchBlock%type <throwStmt>	ThrowStmt%type <catchStmtList>	CatchBlockList NonEmptyCBList%type <caseStmtList>    CaseStmtList%type <expr>		Expr Constant IntConstant Expr_Em%type <LV>		LValue%type <call>		Call%type <exprList>	Actuals NonEmptyActuals%type <ident>		Ident%left ','%right '='%left ':' '?'%left T_Or %left T_And%left T_Equal T_NotEqual%left '<' '>' T_LessEqual T_GreaterEqual%left '-' '+'%left '*' '/' '%'%right '!'%left '.' '[' %nonassoc UMINUS%nonassoc Lower_Else%nonassoc T_Else%%/* * All productions and actions should be placed between the start and stop * %% markers which delimit the Rules section. */	 Program :DeclList	{ 	@1;         /* pp2: The @1 is needed to convince          * yacc to set up yylloc. You can remove          * it oncde you have other uses of @n*/        program = new Program($1);	/*        if (ReportError::NumErrors() == 0)		program->Print(0);	*/	program->Check();        }	;                  DeclList  :    DeclList Decl        { ($$=$1)->Append($2); }          |    Decl                 { ($$ = new List<Decl*>)->Append($1); }          ;Decl      :VariableDecl { $$ = $1; }	  |ClassDecl	{ $$ = $1; }	  |FunctionDecl	{ $$ = $1; }          ;VariableDecl	:Variable ';'	{ $$ = $1; }		;Variable	:Type Ident	{ $$ = new VarDecl($2,$1); }		;Ident		:T_Identifier	{ $$ = new Identifier(@1,$1);}		;Type		:T_Bool		{ $$ = Type::boolType; }		|T_Int		{ $$ = Type::intType; }		|T_Double	{ $$ = Type::doubleType; }		|T_String	{ $$ = Type::stringType; }		|Ident	{ NamedType *nameType = new NamedType($1);$$ = nameType;}		|Type T_Dims	{$$ = new ArrayType(@1, $1);}		;ClassDecl	:T_Class Ident '{' Fieldlist '}'	{ $$ = new ClassDecl($2,NULL,$4);}		|T_Class Ident T_Extends Ident '{' Fieldlist '}' { 			$$ = new ClassDecl($2,new NamedType($4),$6); 			}		;Fieldlist	:Fieldlist Field	{ ($$ = $1)->Append($2);}		|			{ $$ = new List<Decl*>; }		;Field		:VariableDecl	{ $$ = $1; }		|FunctionDecl	{ $$ = $1; }		;FunctionDecl	:Type Ident '(' Formals ')' StmtBlock {$$ = new FnDecl($2,$1,$4);$$->SetFunctionBody($6);}		|T_Void Ident '(' Formals ')' StmtBlock {			$$ = new FnDecl($2,Type::voidType,$4);$$->SetFunctionBody($6);}		|Type Ident '('')' StmtBlock {$$ = new FnDecl($2,$1,new List<VarDecl*>);$$->SetFunctionBody($5);}		|T_Void Ident '(' ')' StmtBlock {			$$ = new FnDecl($2,Type::voidType,new List<VarDecl*>);$$->SetFunctionBody($5);}		;Formals		:Variable		{ ($$ = new List<VarDecl*>)->Append($1); }		|Formals ',' Variable	{ ($$ = $1)->Append($3); }		;StmtBlock	:'{' NonEmptyVList NonEmptySList '}' {$$ = new StmtBlock($2,$3);}		|'{' NonEmptyVList '}'	{						List<Stmt*> *emptySList = new List<Stmt*>;						$$ = new StmtBlock($2,emptySList);					}		|'{' NonEmptySList '}'	{						List<VarDecl*> *emptyVList = new List<VarDecl*>;						$$ = new StmtBlock(emptyVList,$2);					}		|'{' '}'		{List<Stmt*> *emptyStmtList = new List<Stmt*>;					 List<VarDecl*> *emptyVarList = new List<VarDecl*>;					 $$ = new StmtBlock(emptyVarList,emptyStmtList);}		;NonEmptyVList	:VariableDecl			{ ($$ = new List<VarDecl*>)->Append($1); }		|NonEmptyVList VariableDecl	{ ($$ = $1)->Append($2);}		;NonEmptySList	:Stmt			{($$=new List<Stmt*>)->Append($1);}		|NonEmptySList Stmt	{($$=$1)->Append($2);}		;Stmt		:';'			{$$=new ExprStmt(@1,NULL);}		|Expr ';'		{$$=new ExprStmt(@1,$1);}		|StmtBlock		{$$=$1;}		|IfStmt			{$$=$1;}		|SwitchStmt             {$$=$1;}		|WhileStmt		{$$=$1;}		|ForStmt		{$$=$1;}		|ReturnStmt		{$$=$1;}		|BreakStmt		{$$=$1;}		|PrintStmt		{$$=$1;}		|TryCatchBlock		{$$=$1;}		|ThrowStmt		{$$=$1;}		;ThrowStmt	:T_Throw Expr ';'	{$$ = new ThrowStmt(@2,$2);}		;TryCatchBlock	:T_Try '{' StmtList '}' CatchBlockList	{$$ = new TryStmt($3,$5);}		;StmtList	:NonEmptySList		{$$=$1;}		|			{$$=new List<Stmt*>;}		;NonEmptyCBList	:CatchBlock			{($$=new List<CatchStmt*>)->Append($1);}		|NonEmptyCBList CatchBlock	{($$=$1)->Append($2);}		;CatchBlockList	:NonEmptyCBList		{$$ = $1;}		|			{$$=new List<CatchStmt*>;}		;CatchBlock	:T_Catch '(' Variable ')' '{' StmtList '}'	{$$ = new CatchStmt($3,$6);}		;PrintStmt	:T_Print '(' NonEmptyActuals ')' ';'	{$$ = new PrintStmt($3);}		;BreakStmt	:T_Break ';'		{$$ = new BreakStmt(@1);}		;ReturnStmt	:T_Return Expr ';'	{$$ = new ReturnStmt(@2,$2);}		|T_Return ';'		{$$ = new ReturnStmt(@1,new EmptyExpr());}		;IfStmt		:T_If '(' Expr ')' Stmt %prec Lower_Else	{$$ = new IfStmt($3,$5,NULL);}		|T_If '(' Expr ')' Stmt T_Else Stmt		{$$ = new IfStmt($3,$5,$7);}		;SwitchStmt	:T_Switch '(' Expr ')' SwitchBody	{$$ = new SwitchStmt($3,$5);}		;SwitchBody	:'{' CaseStmtList DefaultStmt '}'	{$$ = new SwitchBody($2,$3);}		|'{' CaseStmtList '}'			{$$ = new SwitchBody($2,NULL);}		|'{' DefaultStmt '}'	{			List<CaseStmt*> *emptyCaseList = new List<CaseStmt*>;			$$ = new SwitchBody(emptyCaseList,$2);					}		|'{' '}'		{			List<CaseStmt*> *emptyCaseList = new List<CaseStmt*>;                        $$ = new SwitchBody(emptyCaseList,NULL);					}		;CaseStmtList	:CaseStmt			{($$=new List<CaseStmt*>)->Append($1);}		|CaseStmtList CaseStmt		{($$=$1)->Append($2);}		;CaseStmt	:T_Case IntConstant ':' Stmt		{$$ = new CaseStmt($2, $4);}		;DefaultStmt	:T_Default ':' Stmt		{$$ = new DefaultStmt($3);}		;WhileStmt	:T_While '(' Expr ')' Stmt	{$$ = new WhileStmt($3,$5);}		;ForStmt		:T_For '(' Expr_Em ';' Expr ';' Expr_Em ')' Stmt	{$$ = new ForStmt($3,$5,$7,$9);}		;Expr_Em		:Expr	{$$ = $1;}		|	{$$ = new EmptyExpr();}		;Expr		:Constant		{$$ = $1;}		|Expr '+' Expr		{$$ = new ArithmeticExpr($1,new Operator(@2,"+"),$3);}		|Expr '*' Expr		{$$ = new ArithmeticExpr($1,new Operator(@2,"*"),$3);}		|Expr '/' Expr		{$$ = new ArithmeticExpr($1,new Operator(@2,"/"),$3);}		|Expr '%' Expr		{$$ = new ArithmeticExpr($1,new Operator(@2,"%"),$3);}		|Expr '>' Expr		{$$ = new RelationalExpr($1,new Operator(@2,">"),$3);}		|Expr '<' Expr		{$$ = new RelationalExpr($1,new Operator(@2,"<"),$3);}		|'-'Expr %prec '!'	{$$ = new ArithmeticExpr(new Operator(@1,"-"),$2);}		|Expr '-' Expr          {$$ = new ArithmeticExpr($1,new Operator(@2,"-"),$3);}		|Expr T_LessEqual Expr	{$$ = new RelationalExpr($1,new Operator(@2,"<="),$3);}		|Expr T_GreaterEqual Expr	{$$ = new RelationalExpr($1,new Operator(@2,">="),$3);}		|Expr T_Equal Expr	{$$ = new EqualityExpr($1,new Operator(@2,"=="),$3);}		|Expr T_NotEqual Expr	{$$ = new EqualityExpr($1,new Operator(@2,"!="),$3);}		|Expr T_Or Expr		{$$ = new LogicalExpr($1,new Operator(@2,"||"),$3);}		|Expr T_And Expr	{$$ = new LogicalExpr($1,new Operator(@2,"&&"),$3);}		|'!' Expr		{$$ = new LogicalExpr(new Operator(@1,"!"),$2);}		|'(' Expr ')'		{$$ = $2;}		|LValue			{$$ = $1;}		|LValue '=' Expr	{$$ = new AssignExpr($1,new Operator(@2,"="),$3);}		|T_New '(' Ident ')'	{$$ = new NewExpr(@1,new NamedType($3));}		|T_NewArray '(' Expr ',' Type ')'	{$$ = new NewArrayExpr(@1,$3,$5);}		|T_ReadLine '(' ')'	{$$ = new ReadLineExpr(@1);}		|T_ReadInteger '(' ')'	{$$ = new ReadIntegerExpr(@1);}		|T_This			{$$ = new This(@1);}		|Call			{$$ = $1;}		|Expr '?' Expr ':' Expr {                        $$ = new ConditionalExpr($1,new Operator(@2,"?"),$3,new Operator(@4,":"),$5);                                        }		;Call		:Ident '(' Actuals ')'	{$$ = new Call(@1,NULL,$1,$3);}		|Expr '.' Ident '(' Actuals ')'	{$$ = new Call(@1,$1,$3,$5);}		;NonEmptyActuals	:Expr			{($$ = new List<Expr*>)->Append($1);}		|NonEmptyActuals ',' Expr	{($$ = $1)->Append($3);}		;Actuals		:NonEmptyActuals	{$$ = $1;}		|			{$$ = new List<Expr*>;}		;LValue		:Ident			{$$ = new FieldAccess(NULL,$1);}		|Expr '.' Ident		{$$ = new FieldAccess($1,$3);}		|Expr '[' Expr ']'	{$$ = new ArrayAccess(@1,$1,$3);}		;IntConstant	:T_IntConstant          {$$ = new IntConstant(@1,$1);}		;Constant	:IntConstant		{$$ = $1;}		|T_DoubleConstant	{$$ = new DoubleConstant(@1,$1);}		|T_BoolConstant		{$$ = new BoolConstant(@1,$1);}		|T_StringConstant	{$$ = new StringConstant(@1,$1);}		|T_Null			{$$ = new NullConstant(@1);}		;%%/* The closing %% above marks the end of the Rules section and the beginning * of the User Subroutines section. All text from here to the end of the * file is copied verbatim to the end of the generated y.tab.c file. * This section is where you put definitions of helper functions. *//* * Function: InitParser * -------------------- * This function will be called before any calls to yyparse().  It is designed * to give you an opportunity to do anything that must be done to initialize * the parser (set global variables, configure starting state, etc.). One * thing it already does for you is assign the value of the global variable * yydebug that controls whether yacc prints debugging information about * parser actions (shift/reduce) and contents of state stack during parser. * If set to false, no information is printed. Setting it to true will give * you a running trail that might be helpful when debugging your parser. * Please be sure the variable is set to false when submitting your final * version. */void InitParser(){  PrintDebug("parser", "Initializing parser");  yydebug = false;}

⌨️ 快捷键说明

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