%{ #include #include "tree.h" /* syntax tree building functions, imported from tree.c */ extern tree MakeLeaf(); extern tree MakeTree(); extern tree MkLeftC(); extern tree MkRightC(); extern tree NullExp(); extern tree AssignTypeL(); extern tree AssignTypeR(); extern tree SetRightTreeOp(); extern void checktree(); extern void printtree(); extern int IsNull(); extern int NodeOp(); extern int trace; /* flag: print out trace info or not? from driver2.c */ extern tree Root; /* syntax tree root, imported from tree.c */ tree p, ttp; /* tempory tree pointer */ %} %union { int semantic_value; tree tptr; } %token EOFnumber 0 %token SEMInumber 301 %token COLONnumber 302 %token COMMAnumber 303 %token DOTnumber 304 %token LPARENnumber 305 %token RPARENnumber 306 %token LTnumber 307 %token GTnumber 308 %token EQnumber 309 %token MINUSnumber 310 %token PLUSnumber 311 %token TIMESnumber 312 %token DOTDOTnumber 313 %token COLEQnumber 314 %token LEnumber 315 %token GEnumber 316 %token NEnumber 317 %token IDnumber 318 %token ICONSTnumber 319 %token CCONSTnumber 320 %token SCONSTnumber 321 %token ANDnumber 322 %token ARRAYnumber 323 %token BEGINnumber 324 %token CONSTnumber 325 %token DIVIDEnumber 326 %token DOWNTOnumber 327 %token ELSEnumber 328 %token ELSIFnumber 329 %token ENDnumber 330 %token ENDIFnumber 331 %token ENDLOOPnumber 332 %token ENDRECnumber 333 %token EXITnumber 334 %token FORnumber 335 %token FORWARDnumber 336 %token FUNCTIONnumber 337 %token IFnumber 338 %token ISnumber 339 %token LOOPnumber 340 %token NOTnumber 341 %token OFnumber 342 %token ORnumber 343 %token PROCEDUREnumber 344 %token PROGRAMnumber 345 %token RECORDnumber 346 %token REPEATnumber 347 %token RETURNnumber 348 %token THENnumber 349 %token TOnumber 350 %token TYPEnumber 351 %token UNTILnumber 352 %token VARnumber 353 %token WHILEnumber 354 %type program %type declaration_part %type simple_declaration_list %type simple_declaration %type constant_definition_list %type constant_definition %type constant %type type_definition_list %type type_definition %type variable_definition_list %type variable_definition %type var_list %type type %type subrange_type %type subrange %type index %type integer_constant %type array_type %type subrange_list %type record_type %type recomp_dec_list %type recomp_dec %type reid_list %type f_p_declaration_list %type f_declaration %type p_declaration %type f_p_choice %type formal_argu_list %type formal_argu_option %type formal_argu %type ref_var_dec %type ref_var_list %type value_var_dec %type value_var_list %type compound_statement %type statement_list %type statement %type assignment_statement %type variable_assign_list %type procedure_statement %type return_statement %type exit_statement %type if_statement %type ifelse_loop %type if_tail %type for_statement %type for_iterator %type while_statement %type repeat_statement %type exp %type relation_op %type simple_exp %type b_op1 %type term %type b_op2 %type factor %type unsigned_constant %type variable %type variable_tail %type v_exp_list %% /* grammar specifications */ program : PROGRAMnumber IDnumber ISnumber declaration_part compound_statement DOTnumber { if (trace) printf("program\n"); Root=MakeTree(ProgramOp, $4, $5); } ; declaration_part : simple_declaration_list f_p_declaration_list { if (trace) printf("declaration_part\n"); if (IsNull($2)) $$=$1; else $$=MkLeftC($1, $2); } ; simple_declaration_list : simple_declaration_list simple_declaration { if (trace) printf("simple_declaration_list 1\n"); $$=MkLeftC($1, $2); } | { if (trace) printf("simple_declaration_list 2\n"); $$=NullExp(); } ; simple_declaration : CONSTnumber constant_definition_list { if (trace) printf("simple_declaration 1\n"); $$=$2; } | TYPEnumber type_definition_list { if (trace) printf("simple_declaration 2\n"); $$=$2; } | VARnumber variable_definition_list { if (trace) printf("simple_declaration 3\n"); $$=$2; } ; constant_definition_list : constant_definition_list constant_definition SEMInumber { if (trace) printf("constant_declaration_list 1\n"); $$=MakeTree(BodyOp, $1, $2); } | constant_definition SEMInumber { if (trace) printf("constant_declaration_list 2\n"); $$=MakeTree(BodyOp, NullExp(), $1); } ; constant_definition : IDnumber EQnumber constant { if (trace) printf("constant_declaration\n"); $$=MakeTree(ConstantIdOp, MakeLeaf(IDNode, $1), $3); } ; constant : SCONSTnumber { if (trace) printf("constant 1\n"); $$=MakeLeaf(STRINGNode, $1); } | CCONSTnumber { if (trace) printf("constant 2\n"); $$=MakeLeaf(CHARNode, $1); } | ICONSTnumber { if (trace) printf("constant 3\n"); $$=MakeLeaf(NUMNode, $1); } | PLUSnumber ICONSTnumber { if (trace) printf("constant 4\n"); $$=MakeLeaf(NUMNode, $2); } | MINUSnumber ICONSTnumber { if (trace) printf("constant 5\n"); $$=MakeLeaf(NUMNode, -$2); } ; type_definition_list : type_definition_list type_definition SEMInumber { if (trace) printf("type_definition_list 1\n"); $$=MakeTree(BodyOp, $1, $2); } | type_definition SEMInumber { if (trace) printf("type_definition_list 2\n"); $$=MakeTree(BodyOp, NullExp(), $1); } ; type_definition : IDnumber EQnumber type { if (trace) printf("type_definition\n"); $$=MakeTree(TypeIdOp, MakeLeaf(IDNode, $1), $3); } ; variable_definition_list : variable_definition_list variable_definition SEMInumber { if (trace) printf("variable_definition_list 1\n"); $$=MakeTree(BodyOp, $1, $2); } | variable_definition SEMInumber { if (trace) printf("variable_definition_list 2\n"); $$=MakeTree(BodyOp, NullExp(), $1); } ; variable_definition : var_list COLONnumber type { if (trace) printf("variable_definition\n"); $$=AssignTypeL($1, $3); /* Added tree routine in tree.c */ } ; var_list : var_list COMMAnumber IDnumber { if (trace) printf("var_list 1\n"); p=MakeLeaf(IDNode, $3); $$=MakeTree(DeclOp, $1, MakeTree(CommaOp, p, NullExp())); } | IDnumber { if (trace) printf("var_list 2\n"); p =MakeLeaf(IDNode, $1); $$=MakeTree(DeclOp, NullExp(), MakeTree(CommaOp, p, NullExp())); } ; type : IDnumber { if (trace) printf("type 1\n"); $$=MakeLeaf(IDNode, $1); } | subrange_type { if (trace) printf("type 2\n"); $$=$1; } | array_type { if (trace) printf("type 3\n"); $$=$1; } | record_type { if (trace) printf("type 4\n"); $$=$1; } ; subrange_type : subrange { if (trace) printf("subrange_type\n"); $$=$1; } ; subrange : index DOTDOTnumber index { if (trace) printf("subrange\n"); $$=MakeTree(SubrangeOp, $1, $3); } ; index : integer_constant { if (trace) printf("index 1\n"); $$=$1; } | IDnumber { if (trace) printf("index 2\n"); $$=MakeLeaf(IDNode, $1); } ; integer_constant : PLUSnumber ICONSTnumber { if (trace) printf("integer_constant 1\n"); $$=MakeLeaf(NUMNode, $2); } | MINUSnumber ICONSTnumber { if (trace) printf("integer_constant 2\n"); $$=MakeLeaf(NUMNode, -$2); } | ICONSTnumber { if (trace) printf("integer_constant 3\n"); $$=MakeLeaf(NUMNode, $1); } ; array_type : ARRAYnumber LPARENnumber subrange_list RPARENnumber OFnumber type { if (trace) printf("array_type\n"); $$=MakeTree(ArrayTypeOp, $3, $6); } ; subrange_list : subrange_list COMMAnumber subrange { if (trace) printf("subrange_list 1\n"); $$=MakeTree(BoundOp, $1, $3); } | subrange { if (trace) printf("subrange_list 2\n"); $$=MakeTree(BoundOp, NullExp(), $1); } ; record_type : RECORDnumber recomp_dec_list ENDRECnumber { if (trace) printf("record_type\n"); $$= $2; } ; recomp_dec_list : recomp_dec_list SEMInumber recomp_dec { if (trace) printf("recomp_dec_list 1\n"); $$=MkLeftC($1, $3); } | recomp_dec { if (trace) printf("recomp_dec_list 2\n"); $$=$1; } ; recomp_dec : reid_list COLONnumber type { if (trace) printf("recomp_dec\n"); $$=AssignTypeL($1, $3); /* Added tree routine in tree.c */ } ; reid_list : reid_list COMMAnumber IDnumber { if (trace) printf("reid_list 1\n"); p = MakeLeaf(IDNode, $3); $$=MakeTree(RecompOp, $1, MakeTree(CommaOp, p, NullExp())); } | IDnumber { if (trace) printf("reid_list 2\n"); p = MakeLeaf(IDNode, $1); $$=MakeTree(RecompOp, NullExp(), MakeTree(CommaOp, p, NullExp())); } ; f_p_declaration_list : f_p_declaration_list f_declaration SEMInumber { if (trace) printf("f_p_declaration_list 1\n"); $$=MakeTree(BodyOp, $1, $2); } | f_p_declaration_list p_declaration SEMInumber { if (trace) printf("f_p_declaration_list 2\n"); $$=MakeTree(BodyOp, $1, $2); } | { if (trace) printf("f_p_declaration_list 3\n"); $$=NullExp(); } ; f_declaration : FUNCTIONnumber IDnumber formal_argu_option RETURNnumber type ISnumber f_p_choice { if (trace) printf("f_declaration\n"); p=MakeTree(SpecOp, $3, $5); $$=MakeTree(FuncOp, MakeTree(HeadOp, MakeLeaf(IDNode, $2), p), $7); } ; p_declaration : PROCEDUREnumber IDnumber formal_argu_option ISnumber f_p_choice { if (trace) printf("p_declaration\n"); p = MakeTree(SpecOp, $3, NullExp()); $$=MakeTree(ProceOp, MakeTree(HeadOp, MakeLeaf(IDNode, $2), p), $5); } ; formal_argu_option : LPARENnumber formal_argu_list RPARENnumber { if (trace) printf("formal_argu_option 1\n"); $$=$2; } | { if (trace) printf("formal_argu_option 2\n"); $$=NullExp(); } ; f_p_choice : simple_declaration_list compound_statement { if (trace) printf("f_p_choice 1\n"); $$=MakeTree(BodyOp, $1, $2); } | FORWARDnumber { if (trace) printf("f_p_choice 2\n"); $$=NullExp(); } ; formal_argu_list : formal_argu_list SEMInumber formal_argu { if (trace) printf("formal_argu_list 1\n"); $$=MkRightC($3, $1); } | formal_argu { if (trace) printf("formal_argu_list 2\n"); $$=$1; } ; formal_argu : VARnumber ref_var_dec { if (trace) printf("formal_argu 1\n"); $$=$2; } | value_var_dec { if (trace) printf("formal_argu 2\n"); $$=$1; } ; ref_var_dec : ref_var_list COLONnumber type { if (trace) printf("ref_var_dec\n"); $$=AssignTypeR($1, $3); /* Added tree routine in tree.c */ } ; ref_var_list : IDnumber COMMAnumber ref_var_list { if (trace) printf("ref_var_list 1\n"); p=MakeLeaf(IDNode, $1); $$=MakeTree(RArgTypeOp, MakeTree(CommaOp, p, NullExp()), $3); } | IDnumber { if (trace) printf("ref_var_list 2\n"); p=MakeLeaf(IDNode, $1); $$=MakeTree(RArgTypeOp, MakeTree(CommaOp, p, NullExp()), NullExp()); } ; value_var_dec : value_var_list COLONnumber type { if (trace) printf("value_var_dec\n"); $$=AssignTypeR($1, $3); /* Added tree routine in tree.c */ } ; value_var_list : IDnumber COMMAnumber value_var_list { if (trace) printf("value_var_list 1\n"); p = MakeLeaf(IDNode, $1); $$=MakeTree(VArgTypeOp, MakeTree(CommaOp, p, NullExp()), $3); } | IDnumber { if (trace) printf("value_var_list 2\n"); p = MakeLeaf(IDNode, $1); $$=MakeTree(VArgTypeOp, MakeTree(CommaOp, p, NullExp()), NullExp()); } ; compound_statement : BEGINnumber statement_list ENDnumber { if (trace) printf("compound_statement \n"); $$=$2; } ; statement_list : statement_list SEMInumber statement { if (trace) printf("statement_list 1\n"); $$=MakeTree(StmtOp, $1, $3); } | statement { if (trace) printf("statement_list 2\n"); $$=MakeTree(StmtOp, NullExp(), $1); } ; statement : { if (trace) printf("statement 1\n"); $$=NullExp(); } | assignment_statement { if (trace) printf("statement 2\n"); $$=$1; } | procedure_statement { if (trace) printf("statement 3\n"); $$=$1; } | return_statement { if (trace) printf("statement 4\n"); $$=$1; } | if_statement { if (trace) printf("statement 5\n"); $$=$1; } | while_statement { if (trace) printf("statement 6\n"); $$=$1; } | for_statement { if (trace) printf("statement 7\n"); $$=$1; } | repeat_statement { if (trace) printf("statement 8\n"); $$=$1; } | exit_statement { if (trace) printf("statement 9\n"); $$=$1; } ; assignment_statement : variable_assign_list exp { if (trace) printf("assignment_statment\n"); $$=MakeTree(AssignOp, $1, $2); } ; variable_assign_list : variable_assign_list variable COLEQnumber { if (trace) printf("variable_assign_list 1\n"); $$=MakeTree(AssignOp, $1, $2); } | variable COLEQnumber { if (trace) printf("variable_assign_list 2\n"); $$=MakeTree(AssignOp, NullExp(), $1); } ; procedure_statement : IDnumber { if (trace) printf("procedure_statement 1\n"); $$=MakeTree(RoutineCallOp, MakeLeaf(IDNode, $1), NullExp()); } | IDnumber LPARENnumber v_exp_list RPARENnumber { if (trace) printf("procedure_statement 2\n"); $$=MakeTree(RoutineCallOp, MakeLeaf(IDNode, $1), SetRightTreeOp($3, CommaOp)); } ; return_statement : RETURNnumber { if (trace) printf("return_statement 1\n"); $$=MakeTree(ReturnOp, NullExp(), NullExp()); } | RETURNnumber exp { if (trace) printf("return_statement 2\n"); $$=MakeTree(ReturnOp, $2, NullExp()); } ; exit_statement : EXITnumber { if (trace) printf("exit_statement\n"); $$=MakeTree(ExitOp, NullExp(), NullExp()); } ; if_statement : ifelse_loop if_tail { if (trace) printf("if_statement\n"); $$=MakeTree(IfElseOp, $1, $2); } ; ifelse_loop : ifelse_loop ELSIFnumber exp THENnumber statement_list { if (trace) printf("ifelse_loop 1\n"); $$=MakeTree(IfElseOp, $1, MakeTree(CommaOp, $3, $5)); } | IFnumber exp THENnumber statement_list { if (trace) printf("ifelse_loop 2\n"); $$=MakeTree(IfElseOp, NullExp(), MakeTree(CommaOp, $2, $4)); } ; if_tail : ENDIFnumber { if (trace) printf("if_tail 1\n"); $$=NullExp(); } | ELSEnumber statement_list ENDIFnumber { if (trace) printf("if_tail 2\n"); $$=$2; } ; for_statement : for_iterator LOOPnumber statement_list ENDLOOPnumber { if (trace) printf("for_statement\n"); $$=MakeTree(LoopOp, $1, $3); } ; for_iterator : FORnumber IDnumber COLEQnumber exp TOnumber exp { if (trace) printf("for_iterator 1\n"); $$=MakeTree(CommaOp, MakeLeaf(IDNode, $2), MakeTree(ToOp, $4, $6)); } | FORnumber IDnumber COLEQnumber exp DOWNTOnumber exp { if (trace) printf("for_iterator 2\n"); $$=MakeTree(CommaOp, MakeLeaf(IDNode, $2), MakeTree(DownToOp, $4, $6)); } ; while_statement : WHILEnumber exp LOOPnumber statement_list ENDLOOPnumber { if (trace) printf("while_statement\n"); $$=MakeTree(LoopOp, $2, $4); } ; repeat_statement : REPEATnumber statement_list UNTILnumber exp { if (trace) printf("repeat_statement\n"); $$=MakeTree(LoopOp, $2, $4); } ; exp : simple_exp { if (trace) printf("exp 1 \n"); $$=$1; } | simple_exp relation_op simple_exp { if (trace) printf("exp 2 \n"); $$=MakeTree(NodeOp($2), $1, $3); } ; relation_op : LTnumber { if (trace) printf("relation_op 1\n"); $$=MakeTree(LTOp, NullExp(), NullExp()); } | GTnumber { if (trace) printf("relation_op 2\n"); $$=MakeTree(GTOp, NullExp(), NullExp()); } | LEnumber { if (trace) printf("relation_op 3\n"); $$=MakeTree(LEOp, NullExp(), NullExp()); } | GEnumber { if (trace) printf("relation_op 4\n"); $$=MakeTree(GEOp, NullExp(), NullExp()); } | EQnumber { if (trace) printf("relation_op 5\n"); $$=MakeTree(EQOp, NullExp(), NullExp()); } | NEnumber { if (trace) printf("relation_op 6\n"); $$=MakeTree(NEOp, NullExp(), NullExp()); } ; simple_exp : simple_exp b_op1 term { if (trace) printf("simple_exp 1\n"); $$=MakeTree(NodeOp($2), $1, $3); } | term { if (trace) printf("simple_exp 2\n"); $$=$1; } | MINUSnumber term { if (trace) printf("simple_exp 3\n"); $$=MakeTree(UnaryNegOp, $2, NullExp()); } | PLUSnumber term { if (trace) printf("simple_exp 4\n"); $$=$2; } ; b_op1 : PLUSnumber { if (trace) printf("b_op1 1\n"); $$=MakeTree(AddOp, NullExp(), NullExp()); } | MINUSnumber { if (trace) printf("b_op1 2\n"); $$=MakeTree(SubOp, NullExp(), NullExp()); } | ORnumber { if (trace) printf("b_op1 3\n"); $$=MakeTree(OrOp, NullExp(), NullExp()); } ; term : term b_op2 factor { if (trace) printf("term 1\n"); $$=MakeTree(NodeOp($2), $1, $3); } | factor { if (trace) printf("term 2\n"); $$=$1; } ; b_op2 : TIMESnumber { if (trace) printf("b_op2 1\n"); $$=MakeTree(MultOp, NullExp(), NullExp()); } | DIVIDEnumber { if (trace) printf("b_op2 2\n"); $$=MakeTree(DivOp, NullExp(), NullExp()); } | ANDnumber { if (trace) printf("b_op2 3\n"); $$=MakeTree(AndOp, NullExp(), NullExp()); } ; factor : unsigned_constant { if (trace) printf("factor 1\n"); $$=$1; } | variable { if (trace) printf("factor 2\n"); $$=$1; } | LPARENnumber exp RPARENnumber { if (trace) printf("factor 3\n"); $$=$2; } | NOTnumber factor { if (trace) printf("factor 4\n"); $$=MakeTree(NotOp, $2, NullExp()); } ; unsigned_constant : ICONSTnumber { if (trace) printf("unsigned_constant 1\n"); $$=MakeLeaf(NUMNode, $1); } | CCONSTnumber { if (trace) printf("unsigned_constant 2\n"); $$=MakeLeaf(CHARNode, $1); } | SCONSTnumber { if (trace) printf("unsigned_constant 3\n"); $$= MakeLeaf(STRINGNode, $1); } ; variable : IDnumber { if (trace) printf("variable 1\n"); $$=MakeTree(VarOp, MakeLeaf(IDNode, $1), NullExp()); ttp=$$; } | IDnumber variable_tail { if (trace) printf("variable 2\n"); $$=MakeTree(VarOp, MakeLeaf(IDNode, $1), $2); ttp=$$; } ; variable_tail : LPARENnumber v_exp_list RPARENnumber variable_tail { if (trace) printf("variable_tail 1\n"); $$=MakeTree(SelectOp, $2, $4); } | DOTnumber IDnumber variable_tail { if (trace) printf("variable_tail 2\n"); $$=MakeTree(SelectOp, MakeTree(FieldOp,MakeLeaf(IDNode, $2), NullExp()), $3); } | LPARENnumber v_exp_list RPARENnumber { if (trace) printf("variable_tail 3\n"); $$=MakeTree(SelectOp, $2, NullExp()); } | DOTnumber IDnumber { if (trace) printf("variable_tail 4\n"); $$=MakeTree(SelectOp, MakeTree(FieldOp, MakeLeaf(IDNode,$2), NullExp()), NullExp()); } ; v_exp_list : exp COMMAnumber v_exp_list { if (trace) printf("v_exp_list 1\n"); $$=MakeTree(IndexOp, $1, $3); } | exp { if (trace) printf("v_exp_list 2\n"); $$=MakeTree(IndexOp, $1, NullExp()); } ; %% #include "lex.yy.c" yyerror(str) char *str; { printf("Parse error: %s at line %d, column %d\n", str, yyline, yycolumn-yyleng); }