📄 parser.y
字号:
/* 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); */ } ; DeclList : DeclList Decl { printf("rule: DeclList->DeclList Decl\n");($$=$1)->Append($2); } | Decl {printf("rule: DeclList->Decl\n"); ($$ = new List<Decl*>)->Append($1); } ;Decl :VariableDecl { printf("rule:Decl->VariableDecl\n");$$ = $1; } |ClassDecl { printf("rule:Decl->ClassDecl\n");$$ = $1; } |FunctionDecl { printf("rule:Decl->FunctionDecl\n");$$ = $1; } ;VariableDecl :Variable ';' { printf("rule:VariableDecl->Variable\n"); $$ = $1; } ;Variable :Type Ident {printf("rule:Variable->Type Ident\n"); $$ = new VarDecl($2,$1); } ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -