From 9137038f8ef00449e4f9537eb6026a780b42f571 Mon Sep 17 00:00:00 2001 From: dorley174 Date: Wed, 5 Nov 2025 04:41:03 +0300 Subject: [PATCH 1/6] adding more slots for ast --- ast.hpp | 70 ++++++++++++++++++++++--- lexer.l | 79 +++++++++++++++++++++------- parser.y | 149 ++++++++++++++++++++++++++++++++++++++++++++--------- tokens.hpp | 21 ++++++-- 4 files changed, 265 insertions(+), 54 deletions(-) diff --git a/ast.hpp b/ast.hpp index dba43ba..ebd7b44 100644 --- a/ast.hpp +++ b/ast.hpp @@ -25,6 +25,14 @@ struct IntLiteral : Expr { } }; +struct StringLiteral : Expr { + std::string value; + explicit StringLiteral(std::string v) : value(std::move(v)) {} + void print(std::ostream& os, int indent) const override { + doIndent(os, indent); os << "String(" << value << ")\n"; + } +}; + struct BoolLiteral : Expr { bool value; explicit BoolLiteral(bool v) : value(v) {} @@ -41,7 +49,7 @@ struct Identifier : Expr { } }; -enum class BinOp { Add, Sub, Mul, Div, Assign }; +enum class BinOp { Add, Sub, Mul, Div, Assign, Gt }; struct Binary : Expr { BinOp op; @@ -55,7 +63,8 @@ struct Binary : Expr { case BinOp::Sub: return "-"; case BinOp::Mul: return "*"; case BinOp::Div: return "/"; - case BinOp::Assign: return "="; + case BinOp::Assign: return ":="; + case BinOp::Gt: return ">"; } return "?"; } @@ -80,8 +89,42 @@ struct Unary : Expr { } }; +struct MemberAccess : Expr { + Expr* object; + std::string member; + MemberAccess(Expr* o, std::string m) : object(o), member(std::move(m)) {} + ~MemberAccess() { delete object; } + void print(std::ostream& os, int indent) const override { + doIndent(os, indent); os << "Member\n"; + object->print(os, indent + 1); + doIndent(os, indent + 1); os << member << "\n"; + } +}; + +struct Call : Expr { + Expr* callee; + std::vector args; + explicit Call(Expr* c) : callee(c) {} + ~Call() { delete callee; for (auto* a : args) delete a; } + void print(std::ostream& os, int indent) const override { + doIndent(os, indent); os << "Call\n"; + callee->print(os, indent + 1); + for (auto* a : args) a->print(os, indent + 1); + } +}; + struct Stmt : Node { }; +struct ExprStmt : Stmt { + Expr* expr; + explicit ExprStmt(Expr* e) : expr(e) {} + ~ExprStmt() { delete expr; } + void print(std::ostream& os, int indent) const override { + doIndent(os, indent); os << "expr\n"; + expr->print(os, indent + 1); + } +}; + struct ReturnStmt : Stmt { Expr* value; explicit ReturnStmt(Expr* v) : value(v) {} @@ -108,12 +151,19 @@ struct IfStmt : Stmt { } }; +struct Block : Stmt { + std::vector stmts; + ~Block() { for (auto* s : stmts) delete s; } + void print(std::ostream& os, int indent) const override { + for (auto* s : stmts) s->print(os, indent); + } +}; + struct VarDecl : Node { std::string name; std::string typeName; Expr* init; - VarDecl(std::string n, std::string t, Expr* i) - : name(std::move(n)), typeName(std::move(t)), init(i) {} + VarDecl(std::string n, std::string t, Expr* i) : name(std::move(n)), typeName(std::move(t)), init(i) {} ~VarDecl() { delete init; } void print(std::ostream& os, int indent) const override { doIndent(os, indent); @@ -127,6 +177,15 @@ struct VarDecl : Node { } }; +struct VarDeclStmt : Stmt { + VarDecl* decl; + explicit VarDeclStmt(VarDecl* d) : decl(d) {} + ~VarDeclStmt() { delete decl; } + void print(std::ostream& os, int indent) const override { + decl->print(os, indent); + } +}; + struct Param { std::string name; std::string typeName; @@ -138,8 +197,7 @@ struct MethodDecl : Node { std::vector params; std::string returnType; Stmt* body; - MethodDecl(std::string n, std::string rt, Stmt* b) - : name(std::move(n)), returnType(std::move(rt)), body(b) {} + MethodDecl(std::string n, std::string rt, Stmt* b) : name(std::move(n)), returnType(std::move(rt)), body(b) {} ~MethodDecl() { for (auto* p : params) delete p; delete body; } void print(std::ostream& os, int indent) const override { doIndent(os, indent); diff --git a/lexer.l b/lexer.l index 4655ae5..7d5e433 100644 --- a/lexer.l +++ b/lexer.l @@ -3,12 +3,18 @@ #include #include #include +#include #include "parser.hpp" #include "tokens.hpp" int yycolumn = 1; extern int yylineno; +static int expectClassName = 0; +static int expectMethodName = 0; +static int expectVarName = 0; +static int expectMemberName = 0; + static inline void push_kw(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; @@ -17,6 +23,9 @@ static inline void push_sym(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; } +static inline int is_upper(const char* s) { + return std::isupper((unsigned char)s[0]); +} %} %option noyywrap @@ -25,16 +34,18 @@ static inline void push_sym(TokenKind k, const char* text) { ID [A-Za-z_][A-Za-z0-9_]* INT [0-9]+ +ESC \\. +STR \"([^\\\"]|{ESC})*\" WS [ \t\r]+ %% -"class" { push_kw(TokenKind::CLASS, yytext); return CLASS; } -"var" { push_kw(TokenKind::VAR, yytext); return VAR; } +"class" { push_kw(TokenKind::CLASS, yytext); expectClassName = 1; return CLASS; } +"var" { push_kw(TokenKind::VAR, yytext); expectVarName = 1; return VAR; } "is" { push_kw(TokenKind::IS, yytext); return IS; } "end" { push_kw(TokenKind::END, yytext); return END; } -"method" { push_kw(TokenKind::METHOD, yytext); return METHOD; } +"method" { push_kw(TokenKind::METHOD, yytext); expectMethodName = 1; return METHOD; } "return" { push_kw(TokenKind::RETURN, yytext); return RETURN; } "if" { push_kw(TokenKind::IF, yytext); return IF; } "then" { push_kw(TokenKind::THEN, yytext); return THEN; } @@ -50,27 +61,55 @@ WS [ \t\r]+ yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } "Float" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +"Void" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); + yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } -{ID} { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } +{STR} { std::string s(yytext); + EmitToken(std::make_unique(yytext, s, yylineno, yycolumn)); + yylval.cstr = strdup(s.c_str()); yycolumn += yyleng; return STRING_LITERAL; } -{INT} { long long v = atoll(yytext); - EmitToken(std::make_unique(yytext, v, yylineno, yycolumn)); - yylval.ival = v; yycolumn += yyleng; return INT_LITERAL; } +{ID} { + if (expectClassName) { expectClassName = 0; + EmitToken(std::make_unique(yytext, yylineno, yycolumn)); + yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; + } + if (expectMethodName) { expectMethodName = 0; + EmitToken(std::make_unique(yytext, yylineno, yycolumn)); + yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; + } + if (expectVarName) { expectVarName = 0; + EmitToken(std::make_unique(yytext, yylineno, yycolumn)); + yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; + } + if (expectMemberName) { expectMemberName = 0; + EmitToken(std::make_unique(yytext, yylineno, yycolumn)); + yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; + } + if (is_upper(yytext)) { + EmitToken(std::make_unique(yytext, yylineno, yycolumn)); + yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; + } else { + EmitToken(std::make_unique(yytext, yylineno, yycolumn)); + yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; + } + } +":=" { push_sym(TokenKind::ASSIGN, yytext); return ASSIGN; } "=>" { push_sym(TokenKind::ARROW, yytext); return ARROW; } -":" { push_sym(TokenKind::COLON, yytext); return COLON; } -";" { push_sym(TokenKind::SEMICOLON, yytext); return SEMICOLON; } -"," { push_sym(TokenKind::COMMA, yytext); return COMMA; } -"(" { push_sym(TokenKind::LPAREN, yytext); return LPAREN; } -")" { push_sym(TokenKind::RPAREN, yytext); return RPAREN; } -"{" { push_sym(TokenKind::LBRACE, yytext); return LBRACE; } -"}" { push_sym(TokenKind::RBRACE, yytext); return RBRACE; } -"=" { push_sym(TokenKind::ASSIGN, yytext); return ASSIGN; } -"+" { push_sym(TokenKind::PLUS, yytext); return PLUS; } -"-" { push_sym(TokenKind::MINUS, yytext); return MINUS; } -"*" { push_sym(TokenKind::STAR, yytext); return STAR; } -"/" { push_sym(TokenKind::SLASH, yytext); return SLASH; } +":" { push_sym(TokenKind::COLON, yytext); return COLON; } +";" { push_sym(TokenKind::SEMICOLON, yytext); return SEMICOLON; } +"," { push_sym(TokenKind::COMMA, yytext); return COMMA; } +"(" { push_sym(TokenKind::LPAREN, yytext); return LPAREN; } +")" { push_sym(TokenKind::RPAREN, yytext); return RPAREN; } +"{" { push_sym(TokenKind::LBRACE, yytext); return LBRACE; } +"}" { push_sym(TokenKind::RBRACE, yytext); return RBRACE; } +"=" { push_sym(TokenKind::EQUAL, yytext); return EQUAL; } +"+" { push_sym(TokenKind::PLUS, yytext); return PLUS; } +"-" { push_sym(TokenKind::MINUS, yytext); return MINUS; } +"*" { push_sym(TokenKind::STAR, yytext); return STAR; } +"/" { push_sym(TokenKind::SLASH, yytext); return SLASH; } +"." { push_sym(TokenKind::DOT, yytext); expectMemberName = 1; return DOT; } +">" { push_sym(TokenKind::GT, yytext); return GT; } "//".* { yycolumn += yyleng; } {WS} { yycolumn += yyleng; } diff --git a/parser.y b/parser.y index 06c0439..36834b0 100644 --- a/parser.y +++ b/parser.y @@ -25,6 +25,7 @@ AST::Program* g_program = nullptr; struct Stmt; struct MethodDecl; struct Param; + struct Block; } } @@ -32,20 +33,22 @@ AST::Program* g_program = nullptr; %define parse.error verbose %union { - long long ival; - char* cstr; - AST::Program* program; - AST::ClassDecl* classdecl; - AST::VarDecl* vardecl; - AST::Expr* expr; - AST::Stmt* stmt; - AST::MethodDecl* methoddecl; - AST::Param* param; - AST::Node* node; - std::vector* classlist; - std::vector* memberlist; - std::vector* varlist; - std::vector* paramlist; + long long ival; + char* cstr; + AST::Program* program; + AST::ClassDecl* classdecl; + AST::VarDecl* vardecl; + AST::Expr* expr; + AST::Stmt* stmt; + AST::MethodDecl* methoddecl; + AST::Param* param; + AST::Node* node; + std::vector* classlist; + std::vector* memberlist; + std::vector* varlist; + std::vector* paramlist; + std::vector* stmtlist; + std::vector* exprlist; } %token CLASS VAR IS END @@ -54,9 +57,11 @@ AST::Program* g_program = nullptr; %token COLON SEMICOLON COMMA %token LPAREN RPAREN LBRACE RBRACE %token ASSIGN ARROW PLUS MINUS STAR SLASH +%token DOT GT EQUAL %token IDENTIFIER %token TYPE_NAME %token INT_LITERAL +%token STRING_LITERAL %type program %type class_list @@ -67,8 +72,10 @@ AST::Program* g_program = nullptr; %type method_decl %type opt_params param_list %type param -%type method_body stmt if_stmt -%type expr additive_expr multiplicative_expr unary_expr primary_expr +%type method_body stmt simple_stmt if_stmt +%type stmt_list +%type expr assign_expr relational_expr additive_expr multiplicative_expr unary_expr postfix_expr primary_expr lvalue +%type arg_list opt_args %% @@ -125,6 +132,11 @@ var_decl $$ = new AST::VarDecl($2, $4, nullptr); free($2); free($4); } + | VAR IDENTIFIER COLON TYPE_NAME EQUAL expr SEMICOLON + { + $$ = new AST::VarDecl($2, $4, $6); + free($2); free($4); + } | VAR IDENTIFIER COLON TYPE_NAME ASSIGN expr SEMICOLON { $$ = new AST::VarDecl($2, $4, $6); @@ -162,26 +174,80 @@ param ; method_body - : expr - { $$ = new AST::ReturnStmt($1); } - | stmt - { $$ = $1; } + : stmt_list + { + auto* b = new AST::Block(); + for (auto* s : *$1) b->stmts.push_back(s); + delete $1; + $$ = b; + } + ; + +stmt_list + : stmt_list simple_stmt SEMICOLON + { $$ = $1; $1->push_back($2); } + | stmt_list if_stmt + { $$ = $1; $1->push_back($2); } + | simple_stmt SEMICOLON + { $$ = new std::vector(); $$->push_back($1); } + | if_stmt + { $$ = new std::vector(); $$->push_back($1); } + | simple_stmt + { $$ = new std::vector(); $$->push_back($1); } ; stmt - : RETURN expr - { $$ = new AST::ReturnStmt($2); } + : simple_stmt + { $$ = $1; } | if_stmt { $$ = $1; } ; +simple_stmt + : RETURN expr + { $$ = new AST::ReturnStmt($2); } + | VAR IDENTIFIER COLON TYPE_NAME + { + $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, nullptr)); + free($2); free($4); + } + | VAR IDENTIFIER COLON TYPE_NAME EQUAL expr + { + $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, $6)); + free($2); free($4); + } + | VAR IDENTIFIER COLON TYPE_NAME ASSIGN expr + { + $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, $6)); + free($2); free($4); + } + | lvalue ASSIGN expr + { $$ = new AST::ExprStmt(new AST::Binary(AST::BinOp::Assign, $1, $3)); } + | expr + { $$ = new AST::ExprStmt($1); } + ; + if_stmt - : IF expr THEN stmt ELSE stmt + : IF expr THEN stmt ELSE stmt END { $$ = new AST::IfStmt($2, $4, $6); } ; expr - : additive_expr { $$ = $1; } + : assign_expr { $$ = $1; } + ; + +assign_expr + : lvalue ASSIGN assign_expr + { $$ = new AST::Binary(AST::BinOp::Assign, $1, $3); } + | relational_expr + { $$ = $1; } + ; + +relational_expr + : relational_expr GT additive_expr + { $$ = new AST::Binary(AST::BinOp::Gt, $1, $3); } + | additive_expr + { $$ = $1; } ; additive_expr @@ -205,13 +271,41 @@ multiplicative_expr unary_expr : MINUS unary_expr { $$ = new AST::Unary(AST::Unary::Op::Neg, $2); } + | postfix_expr + { $$ = $1; } + ; + +postfix_expr + : postfix_expr LPAREN opt_args RPAREN + { + auto* call = new AST::Call($1); + for (auto* e : *$3) call->args.push_back(e); + delete $3; + $$ = call; + } + | postfix_expr DOT IDENTIFIER + { $$ = new AST::MemberAccess($1, $3); free($3); } | primary_expr { $$ = $1; } ; +opt_args + : arg_list { $$ = $1; } + | { $$ = new std::vector(); } + ; + +arg_list + : arg_list COMMA expr + { $$ = $1; $1->push_back($3); } + | expr + { $$ = new std::vector(); $$->push_back($1); } + ; + primary_expr : INT_LITERAL { $$ = new AST::IntLiteral($1); } + | STRING_LITERAL + { $$ = new AST::StringLiteral($1); free($1); } | TRUE { $$ = new AST::BoolLiteral(true); } | FALSE @@ -222,6 +316,13 @@ primary_expr { $$ = $2; } ; +lvalue + : IDENTIFIER + { $$ = new AST::Identifier($1); free($1); } + | lvalue DOT IDENTIFIER + { $$ = new AST::MemberAccess($1, $3); free($3); } + ; + %% void yyerror(const char* s) { diff --git a/tokens.hpp b/tokens.hpp index 5571070..4b66a43 100644 --- a/tokens.hpp +++ b/tokens.hpp @@ -9,18 +9,19 @@ enum class TokenKind { CLASS, VAR, IS, END, METHOD, RETURN, IF, THEN, ELSE, TRUEKW, FALSEKW, - IDENTIFIER, TYPE_NAME, INT_LITERAL, + IDENTIFIER, TYPE_NAME, INT_LITERAL, STRING_LITERAL, COLON, SEMICOLON, COMMA, LPAREN, RPAREN, LBRACE, RBRACE, ASSIGN, ARROW, PLUS, MINUS, STAR, SLASH, + DOT, GT, EQUAL, END_OF_FILE }; struct Token { - TokenKind kind; + TokenKind kind; std::string lexeme; - int line; - int column; + int line; + int column; Token(TokenKind k, std::string lx, int ln, int col) : kind(k), lexeme(std::move(lx)), line(ln), column(col) {} virtual ~Token() = default; @@ -47,6 +48,12 @@ struct IntegerToken : Token { : Token(TokenKind::INT_LITERAL, lx, ln, col), value(v) {} }; +struct StringToken : Token { + std::string value; + StringToken(const std::string& lx, std::string v, int ln, int col) + : Token(TokenKind::STRING_LITERAL, lx, ln, col), value(std::move(v)) {} +}; + struct SymbolToken : Token { SymbolToken(TokenKind k, const std::string& lx, int ln, int col) : Token(k, lx, ln, col) {} @@ -68,6 +75,7 @@ inline const char* TokenKindToString(TokenKind k) { case TokenKind::IDENTIFIER: return "IDENTIFIER"; case TokenKind::TYPE_NAME: return "TYPE_NAME"; case TokenKind::INT_LITERAL: return "INT_LITERAL"; + case TokenKind::STRING_LITERAL: return "STRING_LITERAL"; case TokenKind::COLON: return "COLON"; case TokenKind::SEMICOLON: return "SEMICOLON"; case TokenKind::COMMA: return "COMMA"; @@ -81,6 +89,9 @@ inline const char* TokenKindToString(TokenKind k) { case TokenKind::MINUS: return "MINUS"; case TokenKind::STAR: return "STAR"; case TokenKind::SLASH: return "SLASH"; + case TokenKind::DOT: return "DOT"; + case TokenKind::GT: return "GT"; + case TokenKind::EQUAL: return "EQUAL"; case TokenKind::END_OF_FILE: return "EOF"; } return "UNKNOWN"; @@ -95,6 +106,8 @@ inline void EmitToken(std::unique_ptr t) { } else if (t->kind == TokenKind::INT_LITERAL) { auto* it = static_cast(t.get()); std::cout << "(" << it->value << ")"; + } else if (t->kind == TokenKind::STRING_LITERAL) { + std::cout << "(" << t->lexeme << ")"; } std::cout << "\n"; g_tokens.emplace_back(std::move(t)); From d09c424905b7abafad0583890cdc278e2b85fb84 Mon Sep 17 00:00:00 2001 From: dorley174 Date: Wed, 5 Nov 2025 05:18:01 +0300 Subject: [PATCH 2/6] adding more slots for ast --- ast.hpp | 156 ++++++++------------------- lexer.l | 105 +++++++----------- parser.y | 260 ++++++++++++++++++++------------------------- tests/old/test.o | 2 +- tests/old/test11.o | 4 +- tokens.hpp | 11 +- 6 files changed, 209 insertions(+), 329 deletions(-) diff --git a/ast.hpp b/ast.hpp index ebd7b44..76c9029 100644 --- a/ast.hpp +++ b/ast.hpp @@ -6,111 +6,75 @@ namespace AST { -struct Node { - virtual ~Node() = default; - virtual void print(std::ostream& os, int indent = 0) const = 0; -}; +struct Node { virtual ~Node() = default; virtual void print(std::ostream& os, int indent = 0) const = 0; }; -inline void doIndent(std::ostream& os, int n) { - for (int i = 0; i < n; ++i) os << " "; -} +inline void doIndent(std::ostream& os, int n) { for (int i = 0; i < n; ++i) os << " "; } struct Expr : Node { }; struct IntLiteral : Expr { std::int64_t value; explicit IntLiteral(std::int64_t v) : value(v) {} - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); os << "Int(" << value << ")\n"; - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "Int(" << value << ")\n"; } }; struct StringLiteral : Expr { std::string value; explicit StringLiteral(std::string v) : value(std::move(v)) {} - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); os << "String(" << value << ")\n"; - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "String(" << value << ")\n"; } }; struct BoolLiteral : Expr { bool value; explicit BoolLiteral(bool v) : value(v) {} - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); os << "Bool(" << (value ? "true" : "false") << ")\n"; - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "Bool(" << (value ? "true" : "false") << ")\n"; } }; struct Identifier : Expr { std::string name; explicit Identifier(std::string n) : name(std::move(n)) {} - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); os << "Id(" << name << ")\n"; - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "Id(" << name << ")\n"; } }; -enum class BinOp { Add, Sub, Mul, Div, Assign, Gt }; +enum class BinOp { Add, Sub, Mul, Div, Assign, Gt, Lt, Eq }; struct Binary : Expr { - BinOp op; - Expr* lhs; - Expr* rhs; + BinOp op; Expr* lhs; Expr* rhs; Binary(BinOp o, Expr* l, Expr* r) : op(o), lhs(l), rhs(r) {} ~Binary() { delete lhs; delete rhs; } static const char* opToStr(BinOp o) { - switch (o) { - case BinOp::Add: return "+"; - case BinOp::Sub: return "-"; - case BinOp::Mul: return "*"; - case BinOp::Div: return "/"; - case BinOp::Assign: return ":="; - case BinOp::Gt: return ">"; - } + switch (o) { case BinOp::Add: return "+"; case BinOp::Sub: return "-"; case BinOp::Mul: return "*"; case BinOp::Div: return "/"; case BinOp::Assign: return ":="; case BinOp::Gt: return ">"; case BinOp::Lt: return "<"; case BinOp::Eq: return "=="; } return "?"; } - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); - os << "BinOp(" << opToStr(op) << ")\n"; - lhs->print(os, indent + 1); - rhs->print(os, indent + 1); - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "BinOp(" << opToStr(op) << ")\n"; lhs->print(os, indent + 1); rhs->print(os, indent + 1); } }; struct Unary : Expr { - enum class Op { Neg }; - Op op; - Expr* rhs; + enum class Op { Neg }; Op op; Expr* rhs; Unary(Op o, Expr* e) : op(o), rhs(e) {} ~Unary() { delete rhs; } - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); - os << "Unary(-)\n"; - rhs->print(os, indent + 1); - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "Unary(-)\n"; rhs->print(os, indent + 1); } }; struct MemberAccess : Expr { - Expr* object; - std::string member; + Expr* object; std::string member; MemberAccess(Expr* o, std::string m) : object(o), member(std::move(m)) {} ~MemberAccess() { delete object; } - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); os << "Member\n"; - object->print(os, indent + 1); - doIndent(os, indent + 1); os << member << "\n"; - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "Member\n"; object->print(os, indent + 1); doIndent(os, indent + 1); os << member << "\n"; } +}; + +struct Index : Expr { + Expr* base; Expr* index; + Index(Expr* b, Expr* i) : base(b), index(i) {} + ~Index() { delete base; delete index; } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "Index\n"; base->print(os, indent + 1); index->print(os, indent + 1); } }; struct Call : Expr { - Expr* callee; - std::vector args; + Expr* callee; std::vector args; explicit Call(Expr* c) : callee(c) {} ~Call() { delete callee; for (auto* a : args) delete a; } - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); os << "Call\n"; - callee->print(os, indent + 1); - for (auto* a : args) a->print(os, indent + 1); - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "Call\n"; callee->print(os, indent + 1); for (auto* a : args) a->print(os, indent + 1); } }; struct Stmt : Node { }; @@ -119,61 +83,45 @@ struct ExprStmt : Stmt { Expr* expr; explicit ExprStmt(Expr* e) : expr(e) {} ~ExprStmt() { delete expr; } - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); os << "expr\n"; - expr->print(os, indent + 1); - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "expr\n"; expr->print(os, indent + 1); } }; struct ReturnStmt : Stmt { Expr* value; explicit ReturnStmt(Expr* v) : value(v) {} ~ReturnStmt() { delete value; } - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); os << "return\n"; - value->print(os, indent + 1); - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "return\n"; value->print(os, indent + 1); } }; struct IfStmt : Stmt { - Expr* cond; - Stmt* thenS; - Stmt* elseS; + Expr* cond; Stmt* thenS; Stmt* elseS; IfStmt(Expr* c, Stmt* t, Stmt* e) : cond(c), thenS(t), elseS(e) {} ~IfStmt() { delete cond; delete thenS; delete elseS; } - void print(std::ostream& os, int indent) const override { - doIndent(os, indent); os << "if\n"; - cond->print(os, indent + 1); - doIndent(os, indent); os << "then\n"; - thenS->print(os, indent + 1); - doIndent(os, indent); os << "else\n"; - elseS->print(os, indent + 1); - } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "if\n"; cond->print(os, indent + 1); doIndent(os, indent); os << "then\n"; thenS->print(os, indent + 1); doIndent(os, indent); os << "else\n"; elseS->print(os, indent + 1); } +}; + +struct WhileStmt : Stmt { + Expr* cond; Stmt* body; + WhileStmt(Expr* c, Stmt* b) : cond(c), body(b) {} + ~WhileStmt() { delete cond; delete body; } + void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "while\n"; cond->print(os, indent + 1); body->print(os, indent + 1); } }; struct Block : Stmt { std::vector stmts; ~Block() { for (auto* s : stmts) delete s; } - void print(std::ostream& os, int indent) const override { - for (auto* s : stmts) s->print(os, indent); - } + void print(std::ostream& os, int indent) const override { for (auto* s : stmts) s->print(os, indent); } }; struct VarDecl : Node { - std::string name; - std::string typeName; - Expr* init; + std::string name; std::string typeName; Expr* init; VarDecl(std::string n, std::string t, Expr* i) : name(std::move(n)), typeName(std::move(t)), init(i) {} ~VarDecl() { delete init; } void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "var " << name << " : " << typeName; - if (init) { - os << " =\n"; - init->print(os, indent + 1); - } else { - os << "\n"; - } + if (init) { os << " =\n"; init->print(os, indent + 1); } + else { os << "\n"; } } }; @@ -181,40 +129,26 @@ struct VarDeclStmt : Stmt { VarDecl* decl; explicit VarDeclStmt(VarDecl* d) : decl(d) {} ~VarDeclStmt() { delete decl; } - void print(std::ostream& os, int indent) const override { - decl->print(os, indent); - } + void print(std::ostream& os, int indent) const override { decl->print(os, indent); } }; -struct Param { - std::string name; - std::string typeName; - Param(std::string n, std::string t) : name(std::move(n)), typeName(std::move(t)) {} -}; +struct Param { std::string name; std::string typeName; Param(std::string n, std::string t) : name(std::move(n)), typeName(std::move(t)) {} }; struct MethodDecl : Node { - std::string name; - std::vector params; - std::string returnType; - Stmt* body; + std::string name; std::vector params; std::string returnType; Stmt* body; MethodDecl(std::string n, std::string rt, Stmt* b) : name(std::move(n)), returnType(std::move(rt)), body(b) {} ~MethodDecl() { for (auto* p : params) delete p; delete body; } void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "method " << name << "("; - for (size_t i = 0; i < params.size(); ++i) { - os << params[i]->name << " : " << params[i]->typeName; - if (i + 1 < params.size()) os << ", "; - } + for (size_t i = 0; i < params.size(); ++i) { os << params[i]->name << " : " << params[i]->typeName; if (i + 1 < params.size()) os << ", "; } os << ") : " << returnType << "\n"; if (body) body->print(os, indent + 1); } }; struct ClassDecl : Node { - std::string name; - std::vector fields; - std::vector methods; + std::string name; std::vector fields; std::vector methods; explicit ClassDecl(std::string n) : name(std::move(n)) {} ~ClassDecl() { for (auto* v : fields) delete v; for (auto* m : methods) delete m; } void print(std::ostream& os, int indent) const override { @@ -228,9 +162,7 @@ struct ClassDecl : Node { struct Program : Node { std::vector classes; ~Program() { for (auto* c : classes) delete c; } - void print(std::ostream& os, int indent = 0) const override { - for (auto* c : classes) c->print(os, indent); - } + void print(std::ostream& os, int indent = 0) const override { for (auto* c : classes) c->print(os, indent); } }; } diff --git a/lexer.l b/lexer.l index 7d5e433..227afe7 100644 --- a/lexer.l +++ b/lexer.l @@ -15,17 +15,9 @@ static int expectMethodName = 0; static int expectVarName = 0; static int expectMemberName = 0; -static inline void push_kw(TokenKind k, const char* text) { - EmitToken(std::make_unique(k, text, yylineno, yycolumn)); - yycolumn += yyleng; -} -static inline void push_sym(TokenKind k, const char* text) { - EmitToken(std::make_unique(k, text, yylineno, yycolumn)); - yycolumn += yyleng; -} -static inline int is_upper(const char* s) { - return std::isupper((unsigned char)s[0]); -} +static inline void push_kw(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; } +static inline void push_sym(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; } +static inline int is_upper(const char* s) { return std::isupper((unsigned char)s[0]); } %} %option noyywrap @@ -33,7 +25,7 @@ static inline int is_upper(const char* s) { %option yylineno ID [A-Za-z_][A-Za-z0-9_]* -INT [0-9]+ +NUM [0-9]+ ESC \\. STR \"([^\\\"]|{ESC})*\" WS [ \t\r]+ @@ -50,72 +42,55 @@ WS [ \t\r]+ "if" { push_kw(TokenKind::IF, yytext); return IF; } "then" { push_kw(TokenKind::THEN, yytext); return THEN; } "else" { push_kw(TokenKind::ELSE, yytext); return ELSE; } +"while" { push_kw(TokenKind::WHILE, yytext); return WHILE; } +"do" { push_kw(TokenKind::DO, yytext); return DO; } "true" { push_kw(TokenKind::TRUEKW, yytext); return TRUE; } "false" { push_kw(TokenKind::FALSEKW, yytext); return FALSE; } -"Int" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } -"String" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } -"Bool" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } -"Float" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } -"Void" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } - -{STR} { std::string s(yytext); - EmitToken(std::make_unique(yytext, s, yylineno, yycolumn)); - yylval.cstr = strdup(s.c_str()); yycolumn += yyleng; return STRING_LITERAL; } +"Int" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +"String" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +"Bool" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +"Float" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +"Void" { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } + +{STR} { std::string s(yytext); EmitToken(std::make_unique(yytext, s, yylineno, yycolumn)); yylval.cstr = strdup(s.c_str()); yycolumn += yyleng; return STRING_LITERAL; } {ID} { - if (expectClassName) { expectClassName = 0; - EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; - } - if (expectMethodName) { expectMethodName = 0; - EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; - } - if (expectVarName) { expectVarName = 0; - EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; - } - if (expectMemberName) { expectMemberName = 0; - EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; - } - if (is_upper(yytext)) { - EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; - } else { - EmitToken(std::make_unique(yytext, yylineno, yycolumn)); - yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; - } + if (expectClassName) { expectClassName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (expectMethodName) { expectMethodName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (expectVarName) { expectVarName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (expectMemberName) { expectMemberName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (is_upper(yytext)) { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } + EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } +{NUM} { long long v = atoll(yytext); EmitToken(std::make_unique(yytext, v, yylineno, yycolumn)); yylval.ival = v; yycolumn += yyleng; return INT_LITERAL; } + ":=" { push_sym(TokenKind::ASSIGN, yytext); return ASSIGN; } "=>" { push_sym(TokenKind::ARROW, yytext); return ARROW; } -":" { push_sym(TokenKind::COLON, yytext); return COLON; } -";" { push_sym(TokenKind::SEMICOLON, yytext); return SEMICOLON; } -"," { push_sym(TokenKind::COMMA, yytext); return COMMA; } -"(" { push_sym(TokenKind::LPAREN, yytext); return LPAREN; } -")" { push_sym(TokenKind::RPAREN, yytext); return RPAREN; } -"{" { push_sym(TokenKind::LBRACE, yytext); return LBRACE; } -"}" { push_sym(TokenKind::RBRACE, yytext); return RBRACE; } -"=" { push_sym(TokenKind::EQUAL, yytext); return EQUAL; } -"+" { push_sym(TokenKind::PLUS, yytext); return PLUS; } -"-" { push_sym(TokenKind::MINUS, yytext); return MINUS; } -"*" { push_sym(TokenKind::STAR, yytext); return STAR; } -"/" { push_sym(TokenKind::SLASH, yytext); return SLASH; } -"." { push_sym(TokenKind::DOT, yytext); expectMemberName = 1; return DOT; } -">" { push_sym(TokenKind::GT, yytext); return GT; } +"==" { push_sym(TokenKind::EQEQ, yytext); return EQEQ; } +":" { push_sym(TokenKind::COLON, yytext); return COLON; } +";" { push_sym(TokenKind::SEMICOLON, yytext); return SEMICOLON; } +"," { push_sym(TokenKind::COMMA, yytext); return COMMA; } +"(" { push_sym(TokenKind::LPAREN, yytext); return LPAREN; } +")" { push_sym(TokenKind::RPAREN, yytext); return RPAREN; } +"{" { push_sym(TokenKind::LBRACE, yytext); return LBRACE; } +"}" { push_sym(TokenKind::RBRACE, yytext); return RBRACE; } +"[" { push_sym(TokenKind::LBRACKET, yytext); return LBRACKET; } +"]" { push_sym(TokenKind::RBRACKET, yytext); return RBRACKET; } +"=" { push_sym(TokenKind::EQUAL, yytext); return EQUAL; } +"+" { push_sym(TokenKind::PLUS, yytext); return PLUS; } +"-" { push_sym(TokenKind::MINUS, yytext); return MINUS; } +"*" { push_sym(TokenKind::STAR, yytext); return STAR; } +"/" { push_sym(TokenKind::SLASH, yytext); return SLASH; } +"." { push_sym(TokenKind::DOT, yytext); expectMemberName = 1; return DOT; } +">" { push_sym(TokenKind::GT, yytext); return GT; } +"<" { push_sym(TokenKind::LT, yytext); return LT; } "//".* { yycolumn += yyleng; } {WS} { yycolumn += yyleng; } \n { yycolumn = 1; } -. { std::fprintf(stderr, "Unknown char '%s' at %d:%d\n", yytext, yylineno, yycolumn); - yycolumn += yyleng; } +. { std::fprintf(stderr, "Unknown char '%s' at %d:%d\n", yytext, yylineno, yycolumn); yycolumn += yyleng; } %% diff --git a/parser.y b/parser.y index 36834b0..bfca388 100644 --- a/parser.y +++ b/parser.y @@ -17,15 +17,7 @@ AST::Program* g_program = nullptr; %code requires { #include namespace AST { - struct Node; - struct Program; - struct ClassDecl; - struct VarDecl; - struct Expr; - struct Stmt; - struct MethodDecl; - struct Param; - struct Block; + struct Node; struct Program; struct ClassDecl; struct VarDecl; struct Expr; struct Stmt; struct MethodDecl; struct Param; struct Block; } } @@ -49,15 +41,17 @@ AST::Program* g_program = nullptr; std::vector* paramlist; std::vector* stmtlist; std::vector* exprlist; + std::vector* strlist; } %token CLASS VAR IS END %token METHOD RETURN IF THEN ELSE +%token WHILE DO %token TRUE FALSE %token COLON SEMICOLON COMMA -%token LPAREN RPAREN LBRACE RBRACE +%token LPAREN RPAREN LBRACE RBRACE LBRACKET RBRACKET %token ASSIGN ARROW PLUS MINUS STAR SLASH -%token DOT GT EQUAL +%token DOT GT LT EQEQ EQUAL %token IDENTIFIER %token TYPE_NAME %token INT_LITERAL @@ -72,80 +66,81 @@ AST::Program* g_program = nullptr; %type method_decl %type opt_params param_list %type param -%type method_body stmt simple_stmt if_stmt +%type type_spec type_list +%type method_body stmt simple_stmt if_stmt while_stmt %type stmt_list -%type expr assign_expr relational_expr additive_expr multiplicative_expr unary_expr postfix_expr primary_expr lvalue +%type expr assign_expr equality_expr relational_expr additive_expr multiplicative_expr unary_expr postfix_expr primary_expr lvalue type_as_expr %type arg_list opt_args %% program : class_list - { - g_program = new AST::Program(); - for (auto* c : *$1) g_program->classes.push_back(c); - delete $1; - } + { g_program = new AST::Program(); for (auto* c : *$1) g_program->classes.push_back(c); delete $1; } ; class_list - : class_list class_decl - { $$ = $1; $1->push_back($2); } - | class_decl - { $$ = new std::vector(); $$->push_back($1); } + : class_list class_decl { $$ = $1; $1->push_back($2); } + | class_decl { $$ = new std::vector(); $$->push_back($1); } ; class_decl : CLASS IDENTIFIER IS class_body END { $$ = new AST::ClassDecl($2); - for (auto* n : *$4) { - if (auto* v = dynamic_cast(n)) $$->fields.push_back(v); - else if (auto* m = dynamic_cast(n)) $$->methods.push_back(m); - else delete n; - } - free($2); - delete $4; + for (auto* n : *$4) { if (auto* v = dynamic_cast(n)) $$->fields.push_back(v); else if (auto* m = dynamic_cast(n)) $$->methods.push_back(m); else delete n; } + free($2); delete $4; } ; class_body : member_list { $$ = $1; } - | { $$ = new std::vector(); } + | { $$ = new std::vector(); } ; member_list - : member_list member - { $$ = $1; $1->push_back($2); } - | member - { $$ = new std::vector(); $$->push_back($1); } + : member_list member { $$ = $1; $1->push_back($2); } + | member { $$ = new std::vector(); $$->push_back($1); } ; member - : var_decl { $$ = $1; } - | method_decl { $$ = $1; } + : var_decl { $$ = $1; } + | method_decl { $$ = $1; } ; -var_decl - : VAR IDENTIFIER COLON TYPE_NAME SEMICOLON - { - $$ = new AST::VarDecl($2, $4, nullptr); - free($2); free($4); - } - | VAR IDENTIFIER COLON TYPE_NAME EQUAL expr SEMICOLON +type_spec + : TYPE_NAME + { $$ = $1; } + | TYPE_NAME LT type_list GT { - $$ = new AST::VarDecl($2, $4, $6); - free($2); free($4); + std::string s = std::string($1) + "<" + std::string($3) + ">"; + $$ = strdup(s.c_str()); + free($1); free($3); } - | VAR IDENTIFIER COLON TYPE_NAME ASSIGN expr SEMICOLON + ; + +type_list + : type_spec + { $$ = $1; } + | type_list COMMA type_spec { - $$ = new AST::VarDecl($2, $4, $6); - free($2); free($4); + std::string s = std::string($1) + "," + std::string($3); + $$ = strdup(s.c_str()); + free($1); free($3); } ; +var_decl + : VAR IDENTIFIER COLON type_spec SEMICOLON + { $$ = new AST::VarDecl($2, $4, nullptr); free($2); free($4); } + | VAR IDENTIFIER COLON type_spec EQUAL expr SEMICOLON + { $$ = new AST::VarDecl($2, $4, $6); free($2); free($4); } + | VAR IDENTIFIER COLON type_spec ASSIGN expr SEMICOLON + { $$ = new AST::VarDecl($2, $4, $6); free($2); free($4); } + ; + method_decl - : METHOD IDENTIFIER LPAREN opt_params RPAREN COLON TYPE_NAME ARROW method_body + : METHOD IDENTIFIER LPAREN opt_params RPAREN COLON type_spec ARROW method_body { $$ = new AST::MethodDecl($2, $7, $9); if ($4) { for (auto* p : *$4) $$->params.push_back(p); delete $4; } @@ -155,22 +150,17 @@ method_decl opt_params : param_list { $$ = $1; } - | { $$ = new std::vector(); } + | { $$ = new std::vector(); } ; param_list - : param_list COMMA param - { $$ = $1; $1->push_back($3); } - | param - { $$ = new std::vector(); $$->push_back($1); } + : param_list COMMA param { $$ = $1; $1->push_back($3); } + | param { $$ = new std::vector(); $$->push_back($1); } ; param - : IDENTIFIER COLON TYPE_NAME - { - $$ = new AST::Param($1, $3); - free($1); free($3); - } + : IDENTIFIER COLON type_spec + { $$ = new AST::Param($1, $3); free($1); free($3); } ; method_body @@ -184,47 +174,27 @@ method_body ; stmt_list - : stmt_list simple_stmt SEMICOLON - { $$ = $1; $1->push_back($2); } - | stmt_list if_stmt - { $$ = $1; $1->push_back($2); } - | simple_stmt SEMICOLON - { $$ = new std::vector(); $$->push_back($1); } - | if_stmt - { $$ = new std::vector(); $$->push_back($1); } - | simple_stmt - { $$ = new std::vector(); $$->push_back($1); } + : stmt_list simple_stmt SEMICOLON { $$ = $1; $1->push_back($2); } + | stmt_list if_stmt { $$ = $1; $1->push_back($2); } + | stmt_list simple_stmt { $$ = $1; $1->push_back($2); } + | simple_stmt SEMICOLON { $$ = new std::vector(); $$->push_back($1); } + | if_stmt { $$ = new std::vector(); $$->push_back($1); } + | simple_stmt { $$ = new std::vector(); $$->push_back($1); } ; stmt - : simple_stmt - { $$ = $1; } - | if_stmt - { $$ = $1; } + : simple_stmt { $$ = $1; } + | if_stmt { $$ = $1; } + | while_stmt { $$ = $1; } ; simple_stmt - : RETURN expr - { $$ = new AST::ReturnStmt($2); } - | VAR IDENTIFIER COLON TYPE_NAME - { - $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, nullptr)); - free($2); free($4); - } - | VAR IDENTIFIER COLON TYPE_NAME EQUAL expr - { - $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, $6)); - free($2); free($4); - } - | VAR IDENTIFIER COLON TYPE_NAME ASSIGN expr - { - $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, $6)); - free($2); free($4); - } - | lvalue ASSIGN expr - { $$ = new AST::ExprStmt(new AST::Binary(AST::BinOp::Assign, $1, $3)); } - | expr - { $$ = new AST::ExprStmt($1); } + : RETURN expr { $$ = new AST::ReturnStmt($2); } + | VAR IDENTIFIER COLON type_spec { $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, nullptr)); free($2); free($4); } + | VAR IDENTIFIER COLON type_spec EQUAL expr { $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, $6)); free($2); free($4); } + | VAR IDENTIFIER COLON type_spec ASSIGN expr { $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, $6)); free($2); free($4); } + | lvalue ASSIGN expr { $$ = new AST::ExprStmt(new AST::Binary(AST::BinOp::Assign, $1, $3)); } + | expr { $$ = new AST::ExprStmt($1); } ; if_stmt @@ -232,99 +202,95 @@ if_stmt { $$ = new AST::IfStmt($2, $4, $6); } ; +while_stmt + : WHILE expr DO stmt_list END + { + auto* b = new AST::Block(); + for (auto* s : *$4) b->stmts.push_back(s); + delete $4; + $$ = new AST::WhileStmt($2, b); + } + ; + expr : assign_expr { $$ = $1; } ; assign_expr - : lvalue ASSIGN assign_expr - { $$ = new AST::Binary(AST::BinOp::Assign, $1, $3); } - | relational_expr - { $$ = $1; } + : lvalue ASSIGN assign_expr { $$ = new AST::Binary(AST::BinOp::Assign, $1, $3); } + | equality_expr { $$ = $1; } + ; + +equality_expr + : equality_expr EQEQ relational_expr { $$ = new AST::Binary(AST::BinOp::Eq, $1, $3); } + | relational_expr { $$ = $1; } ; relational_expr - : relational_expr GT additive_expr - { $$ = new AST::Binary(AST::BinOp::Gt, $1, $3); } - | additive_expr - { $$ = $1; } + : relational_expr GT additive_expr { $$ = new AST::Binary(AST::BinOp::Gt, $1, $3); } + | relational_expr LT additive_expr { $$ = new AST::Binary(AST::BinOp::Lt, $1, $3); } + | additive_expr { $$ = $1; } ; additive_expr - : additive_expr PLUS multiplicative_expr - { $$ = new AST::Binary(AST::BinOp::Add, $1, $3); } - | additive_expr MINUS multiplicative_expr - { $$ = new AST::Binary(AST::BinOp::Sub, $1, $3); } - | multiplicative_expr - { $$ = $1; } + : additive_expr PLUS multiplicative_expr { $$ = new AST::Binary(AST::BinOp::Add, $1, $3); } + | additive_expr MINUS multiplicative_expr { $$ = new AST::Binary(AST::BinOp::Sub, $1, $3); } + | multiplicative_expr { $$ = $1; } ; multiplicative_expr - : multiplicative_expr STAR unary_expr - { $$ = new AST::Binary(AST::BinOp::Mul, $1, $3); } - | multiplicative_expr SLASH unary_expr - { $$ = new AST::Binary(AST::BinOp::Div, $1, $3); } - | unary_expr - { $$ = $1; } + : multiplicative_expr STAR unary_expr { $$ = new AST::Binary(AST::BinOp::Mul, $1, $3); } + | multiplicative_expr SLASH unary_expr { $$ = new AST::Binary(AST::BinOp::Div, $1, $3); } + | unary_expr { $$ = $1; } ; unary_expr - : MINUS unary_expr - { $$ = new AST::Unary(AST::Unary::Op::Neg, $2); } - | postfix_expr - { $$ = $1; } + : MINUS unary_expr { $$ = new AST::Unary(AST::Unary::Op::Neg, $2); } + | postfix_expr { $$ = $1; } ; postfix_expr : postfix_expr LPAREN opt_args RPAREN - { - auto* call = new AST::Call($1); - for (auto* e : *$3) call->args.push_back(e); - delete $3; - $$ = call; - } + { auto* call = new AST::Call($1); for (auto* e : *$3) call->args.push_back(e); delete $3; $$ = call; } | postfix_expr DOT IDENTIFIER { $$ = new AST::MemberAccess($1, $3); free($3); } + | postfix_expr LBRACKET expr RBRACKET + { $$ = new AST::Index($1, $3); } | primary_expr { $$ = $1; } ; opt_args : arg_list { $$ = $1; } - | { $$ = new std::vector(); } + | { $$ = new std::vector(); } ; arg_list - : arg_list COMMA expr - { $$ = $1; $1->push_back($3); } - | expr - { $$ = new std::vector(); $$->push_back($1); } + : arg_list COMMA expr { $$ = $1; $1->push_back($3); } + | expr { $$ = new std::vector(); $$->push_back($1); } ; primary_expr - : INT_LITERAL - { $$ = new AST::IntLiteral($1); } - | STRING_LITERAL - { $$ = new AST::StringLiteral($1); free($1); } - | TRUE - { $$ = new AST::BoolLiteral(true); } - | FALSE - { $$ = new AST::BoolLiteral(false); } - | IDENTIFIER + : INT_LITERAL { $$ = new AST::IntLiteral($1); } + | STRING_LITERAL { $$ = new AST::StringLiteral($1); free($1); } + | TRUE { $$ = new AST::BoolLiteral(true); } + | FALSE { $$ = new AST::BoolLiteral(false); } + | IDENTIFIER { $$ = new AST::Identifier($1); free($1); } + | type_as_expr { $$ = $1; } + | LPAREN expr RPAREN { $$ = $2; } + ; + +type_as_expr + : type_spec { $$ = new AST::Identifier($1); free($1); } - | LPAREN expr RPAREN - { $$ = $2; } ; lvalue - : IDENTIFIER - { $$ = new AST::Identifier($1); free($1); } - | lvalue DOT IDENTIFIER - { $$ = new AST::MemberAccess($1, $3); free($3); } + : IDENTIFIER { $$ = new AST::Identifier($1); free($1); } + | lvalue DOT IDENTIFIER { $$ = new AST::MemberAccess($1, $3); free($3); } + | lvalue LBRACKET expr RBRACKET { $$ = new AST::Index($1, $3); } ; %% -void yyerror(const char* s) { - std::fprintf(stderr, "Parse error at line %d: %s\n", yylineno, s); -} +void yyerror(const char* s) { std::fprintf(stderr, "Parse error at line %d: %s\n", yylineno, s); } diff --git a/tests/old/test.o b/tests/old/test.o index d1a85d7..1043f59 100644 --- a/tests/old/test.o +++ b/tests/old/test.o @@ -17,6 +17,6 @@ end class Main is method main() : Void => var d : Dog; - d.Foo(0); # для примера, так как вызовы методов надо упрощать + d.Foo(0); d.bark() end diff --git a/tests/old/test11.o b/tests/old/test11.o index 0873c64..53674d7 100644 --- a/tests/old/test11.o +++ b/tests/old/test11.o @@ -12,6 +12,6 @@ class Main is var a : Animal; var d : Dog; method main() : Void => - a := d; # полиморфизм - a.speak() # должен вызвать Dog.speak() + a := d; + a.speak() end \ No newline at end of file diff --git a/tokens.hpp b/tokens.hpp index 4b66a43..c673391 100644 --- a/tokens.hpp +++ b/tokens.hpp @@ -8,12 +8,13 @@ enum class TokenKind { CLASS, VAR, IS, END, METHOD, RETURN, IF, THEN, ELSE, + WHILE, DO, TRUEKW, FALSEKW, IDENTIFIER, TYPE_NAME, INT_LITERAL, STRING_LITERAL, COLON, SEMICOLON, COMMA, - LPAREN, RPAREN, LBRACE, RBRACE, + LPAREN, RPAREN, LBRACE, RBRACE, LBRACKET, RBRACKET, ASSIGN, ARROW, PLUS, MINUS, STAR, SLASH, - DOT, GT, EQUAL, + DOT, GT, LT, EQEQ, EQUAL, END_OF_FILE }; @@ -70,6 +71,8 @@ inline const char* TokenKindToString(TokenKind k) { case TokenKind::IF: return "IF"; case TokenKind::THEN: return "THEN"; case TokenKind::ELSE: return "ELSE"; + case TokenKind::WHILE: return "WHILE"; + case TokenKind::DO: return "DO"; case TokenKind::TRUEKW: return "TRUE"; case TokenKind::FALSEKW: return "FALSE"; case TokenKind::IDENTIFIER: return "IDENTIFIER"; @@ -83,6 +86,8 @@ inline const char* TokenKindToString(TokenKind k) { case TokenKind::RPAREN: return "RPAREN"; case TokenKind::LBRACE: return "LBRACE"; case TokenKind::RBRACE: return "RBRACE"; + case TokenKind::LBRACKET: return "LBRACKET"; + case TokenKind::RBRACKET: return "RBRACKET"; case TokenKind::ASSIGN: return "ASSIGN"; case TokenKind::ARROW: return "ARROW"; case TokenKind::PLUS: return "PLUS"; @@ -91,6 +96,8 @@ inline const char* TokenKindToString(TokenKind k) { case TokenKind::SLASH: return "SLASH"; case TokenKind::DOT: return "DOT"; case TokenKind::GT: return "GT"; + case TokenKind::LT: return "LT"; + case TokenKind::EQEQ: return "EQEQ"; case TokenKind::EQUAL: return "EQUAL"; case TokenKind::END_OF_FILE: return "EOF"; } From 6614df503da84146aa4cdcc6ea3f212a4a7ea307 Mon Sep 17 00:00:00 2001 From: Ilyas Khatipov Date: Wed, 5 Nov 2025 16:11:26 +0300 Subject: [PATCH 3/6] added semantic analyzer --- Makefile | 4 +- lexer.cpp | 2109 ++++++++++++++++++++++++++++++++++++++++++++++ main.cpp | 54 +- mycompiler | Bin 0 -> 106568 bytes parser.cpp | 2224 +++++++++++++++++++++++++++++++++++++++++++++++++ parser.hpp | 146 ++++ semantic.cpp | 474 +++++++++++ semantic.hpp | 54 ++ tests/test3.o | 14 +- 9 files changed, 5060 insertions(+), 19 deletions(-) create mode 100644 lexer.cpp create mode 100644 mycompiler create mode 100644 parser.cpp create mode 100644 parser.hpp create mode 100644 semantic.cpp create mode 100644 semantic.hpp diff --git a/Makefile b/Makefile index 8e1418e..40c0c3c 100644 --- a/Makefile +++ b/Makefile @@ -9,8 +9,8 @@ parser.cpp parser.hpp: parser.y lexer.cpp: lexer.l parser.hpp flex -o lexer.cpp lexer.l -mycompiler: parser.cpp lexer.cpp main.cpp - $(CXX) $(CXXFLAGS) -o $@ parser.cpp lexer.cpp main.cpp -lfl +mycompiler: parser.cpp lexer.cpp main.cpp semantic.cpp + $(CXX) $(CXXFLAGS) -o $@ parser.cpp lexer.cpp main.cpp semantic.cpp -lfl clean: rm -f parser.cpp parser.hpp lexer.cpp mycompiler diff --git a/lexer.cpp b/lexer.cpp new file mode 100644 index 0000000..90c144f --- /dev/null +++ b/lexer.cpp @@ -0,0 +1,2109 @@ +#line 2 "lexer.cpp" + +#line 4 "lexer.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + #define YY_LINENO_REWIND_TO(dst) \ + do {\ + const char *p;\ + for ( p = yy_cp-1; p >= (dst); --p)\ + if ( *p == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap() (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 46 +#define YY_END_OF_BUFFER 47 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[109] = + { 0, + 0, 0, 47, 45, 43, 44, 45, 28, 29, 37, + 35, 27, 36, 39, 38, 21, 25, 26, 41, 34, + 40, 20, 20, 20, 20, 20, 20, 32, 33, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 30, + 31, 43, 0, 19, 0, 42, 21, 22, 24, 23, + 20, 20, 20, 20, 20, 20, 20, 11, 20, 20, + 20, 7, 3, 20, 20, 20, 20, 20, 20, 42, + 20, 20, 14, 20, 20, 20, 20, 4, 20, 20, + 20, 20, 20, 2, 20, 16, 20, 20, 18, 20, + 9, 20, 20, 20, 8, 12, 20, 17, 20, 1, + + 13, 20, 20, 10, 15, 5, 6, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 4, 1, 1, 1, 1, 1, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 14, 15, 16, + 17, 18, 1, 1, 19, 20, 19, 19, 19, 21, + 19, 19, 22, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 23, 19, 19, 24, 19, 19, 19, 19, + 25, 26, 27, 1, 19, 1, 28, 19, 29, 30, + + 31, 32, 33, 34, 35, 19, 19, 36, 37, 38, + 39, 19, 19, 40, 41, 42, 43, 44, 45, 19, + 19, 19, 46, 1, 47, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const YY_CHAR yy_meta[48] = + { 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 1, 1, 1, 1, 1, 3, 3, + 3, 3, 3, 3, 1, 1, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 1, 1 + } ; + +static const flex_int16_t yy_base[112] = + { 0, + 0, 0, 122, 123, 119, 123, 44, 123, 123, 123, + 123, 123, 123, 123, 108, 106, 101, 123, 123, 32, + 123, 0, 78, 80, 77, 72, 74, 123, 123, 76, + 72, 15, 82, 20, 78, 77, 20, 79, 72, 123, + 123, 103, 51, 123, 101, 0, 90, 123, 123, 123, + 0, 63, 62, 58, 59, 63, 69, 0, 55, 65, + 58, 0, 0, 51, 50, 60, 47, 49, 53, 0, + 51, 58, 0, 50, 54, 41, 45, 0, 34, 40, + 30, 34, 40, 0, 33, 0, 26, 29, 0, 25, + 0, 34, 25, 23, 0, 0, 31, 0, 26, 0, + + 0, 28, 19, 0, 0, 0, 0, 123, 77, 53, + 80 + } ; + +static const flex_int16_t yy_def[112] = + { 0, + 108, 1, 108, 108, 108, 108, 109, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 110, 110, 110, 110, 110, 110, 108, 108, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 108, + 108, 108, 109, 108, 109, 111, 108, 108, 108, 108, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + + 110, 110, 110, 110, 110, 110, 110, 0, 108, 108, + 108 + } ; + +static const flex_int16_t yy_nxt[171] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 4, 29, 22, 30, 31, + 32, 33, 22, 22, 34, 22, 35, 22, 22, 36, + 22, 37, 22, 38, 39, 40, 41, 44, 49, 50, + 59, 62, 60, 66, 44, 51, 107, 106, 105, 67, + 63, 104, 103, 102, 101, 100, 99, 98, 97, 45, + 96, 95, 94, 93, 92, 91, 45, 43, 43, 43, + 70, 90, 70, 89, 88, 87, 86, 85, 84, 83, + 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, + + 72, 71, 47, 108, 42, 69, 68, 65, 64, 61, + 58, 57, 56, 55, 54, 53, 52, 48, 47, 46, + 42, 108, 3, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108 + } ; + +static const flex_int16_t yy_chk[171] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 7, 20, 20, + 32, 34, 32, 37, 43, 110, 103, 102, 99, 37, + 34, 97, 94, 93, 92, 90, 88, 87, 85, 7, + 83, 82, 81, 80, 79, 77, 43, 109, 109, 109, + 111, 76, 111, 75, 74, 72, 71, 69, 68, 67, + 66, 65, 64, 61, 60, 59, 57, 56, 55, 54, + + 53, 52, 47, 45, 42, 39, 38, 36, 35, 33, + 31, 30, 27, 26, 25, 24, 23, 17, 16, 15, + 5, 3, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108 + } ; + +/* Table of booleans, true if rule could match eol. */ +static const flex_int32_t yy_rule_can_match_eol[47] = + { 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, }; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "lexer.l" +#line 2 "lexer.l" +#include +#include +#include +#include +#include +#include "parser.hpp" +#include "tokens.hpp" + +int yycolumn = 1; +extern int yylineno; + +static int expectClassName = 0; +static int expectMethodName = 0; +static int expectVarName = 0; +static int expectMemberName = 0; + +static inline void push_kw(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; } +static inline void push_sym(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; } +static inline int is_upper(const char* s) { return std::isupper((unsigned char)s[0]); } +#line 564 "lexer.cpp" +#line 565 "lexer.cpp" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + + static void yyunput ( int c, char *buf_ptr ); + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 33 "lexer.l" + + +#line 785 "lexer.cpp" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 109 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 123 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 35 "lexer.l" +{ push_kw(TokenKind::CLASS, yytext); expectClassName = 1; return CLASS; } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 36 "lexer.l" +{ push_kw(TokenKind::VAR, yytext); expectVarName = 1; return VAR; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 37 "lexer.l" +{ push_kw(TokenKind::IS, yytext); return IS; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 38 "lexer.l" +{ push_kw(TokenKind::END, yytext); return END; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 40 "lexer.l" +{ push_kw(TokenKind::METHOD, yytext); expectMethodName = 1; return METHOD; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 41 "lexer.l" +{ push_kw(TokenKind::RETURN, yytext); return RETURN; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 42 "lexer.l" +{ push_kw(TokenKind::IF, yytext); return IF; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 43 "lexer.l" +{ push_kw(TokenKind::THEN, yytext); return THEN; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 44 "lexer.l" +{ push_kw(TokenKind::ELSE, yytext); return ELSE; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 45 "lexer.l" +{ push_kw(TokenKind::WHILE, yytext); return WHILE; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 46 "lexer.l" +{ push_kw(TokenKind::DO, yytext); return DO; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 47 "lexer.l" +{ push_kw(TokenKind::TRUEKW, yytext); return TRUE; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 48 "lexer.l" +{ push_kw(TokenKind::FALSEKW, yytext); return FALSE; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 50 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 51 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 52 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 53 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 54 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } + YY_BREAK +case 19: +/* rule 19 can match eol */ +YY_RULE_SETUP +#line 56 "lexer.l" +{ std::string s(yytext); EmitToken(std::make_unique(yytext, s, yylineno, yycolumn)); yylval.cstr = strdup(s.c_str()); yycolumn += yyleng; return STRING_LITERAL; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 58 "lexer.l" +{ + if (expectClassName) { expectClassName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (expectMethodName) { expectMethodName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (expectVarName) { expectVarName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (expectMemberName) { expectMemberName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (is_upper(yytext)) { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } + EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; + } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 67 "lexer.l" +{ long long v = atoll(yytext); EmitToken(std::make_unique(yytext, v, yylineno, yycolumn)); yylval.ival = v; yycolumn += yyleng; return INT_LITERAL; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 69 "lexer.l" +{ push_sym(TokenKind::ASSIGN, yytext); return ASSIGN; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 70 "lexer.l" +{ push_sym(TokenKind::ARROW, yytext); return ARROW; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 71 "lexer.l" +{ push_sym(TokenKind::EQEQ, yytext); return EQEQ; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 72 "lexer.l" +{ push_sym(TokenKind::COLON, yytext); return COLON; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 73 "lexer.l" +{ push_sym(TokenKind::SEMICOLON, yytext); return SEMICOLON; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 74 "lexer.l" +{ push_sym(TokenKind::COMMA, yytext); return COMMA; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 75 "lexer.l" +{ push_sym(TokenKind::LPAREN, yytext); return LPAREN; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 76 "lexer.l" +{ push_sym(TokenKind::RPAREN, yytext); return RPAREN; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 77 "lexer.l" +{ push_sym(TokenKind::LBRACE, yytext); return LBRACE; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 78 "lexer.l" +{ push_sym(TokenKind::RBRACE, yytext); return RBRACE; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 79 "lexer.l" +{ push_sym(TokenKind::LBRACKET, yytext); return LBRACKET; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 80 "lexer.l" +{ push_sym(TokenKind::RBRACKET, yytext); return RBRACKET; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 81 "lexer.l" +{ push_sym(TokenKind::EQUAL, yytext); return EQUAL; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 82 "lexer.l" +{ push_sym(TokenKind::PLUS, yytext); return PLUS; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 83 "lexer.l" +{ push_sym(TokenKind::MINUS, yytext); return MINUS; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 84 "lexer.l" +{ push_sym(TokenKind::STAR, yytext); return STAR; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 85 "lexer.l" +{ push_sym(TokenKind::SLASH, yytext); return SLASH; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 86 "lexer.l" +{ push_sym(TokenKind::DOT, yytext); expectMemberName = 1; return DOT; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 87 "lexer.l" +{ push_sym(TokenKind::GT, yytext); return GT; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 88 "lexer.l" +{ push_sym(TokenKind::LT, yytext); return LT; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 90 "lexer.l" +{ yycolumn += yyleng; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 91 "lexer.l" +{ yycolumn += yyleng; } + YY_BREAK +case 44: +/* rule 44 can match eol */ +YY_RULE_SETUP +#line 92 "lexer.l" +{ yycolumn = 1; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 94 "lexer.l" +{ std::fprintf(stderr, "Unknown char '%s' at %d:%d\n", yytext, yylineno, yycolumn); yycolumn += yyleng; } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 96 "lexer.l" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +#line 1091 "lexer.cpp" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 109 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 109 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 108); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp ) +{ + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + if ( c == '\n' ){ + --yylineno; + } + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + if ( c == '\n' ) + + yylineno++; +; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + /* We do not touch yylineno unless the option is enabled. */ + yylineno = 1; + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 96 "lexer.l" + + diff --git a/main.cpp b/main.cpp index 0e358f5..07c691d 100644 --- a/main.cpp +++ b/main.cpp @@ -2,8 +2,9 @@ #include #include "ast.hpp" #include "tokens.hpp" +#include "semantic.hpp" // добавлено -extern int yyparse(void); +extern int yyparse(void); extern FILE* yyin; extern AST::Program* g_program; @@ -12,24 +13,57 @@ int main(int argc, char** argv) { std::cerr << "Usage: " << argv[0] << " \n"; return 1; } + yyin = std::fopen(argv[1], "r"); if (!yyin) { std::perror("fopen"); return 1; } + std::cout << "=== LEXER TOKENS ===\n"; int rc = yyparse(); std::fclose(yyin); - if (rc == 0) { - std::cout << "\n=== AST ===\n"; - if (g_program) { - g_program->print(std::cout); - delete g_program; - g_program = nullptr; - } - return 0; - } else { + + if (rc != 0) { std::cerr << "Parse failed.\n"; return 2; } + + if (!g_program) { + std::cerr << "No AST generated.\n"; + return 2; + } + + // === SEMANTIC ANALYSIS === + std::cout << "\n=== Semantic Analysis ===\n"; + SemanticAnalyzer analyzer; + auto res = analyzer.analyze(g_program); + + if (!res.ok) { + std::cerr << "Semantic errors found:\n"; + for (auto& e : res.errors) + std::cerr << " - " << e << "\n"; + delete g_program; + g_program = nullptr; + return 3; + } else { + std::cout << "Semantic analysis completed successfully.\n"; + if (!res.warnings.empty()) { + std::cout << "Warnings:\n"; + for (auto& w : res.warnings) + std::cout << " - " << w << "\n"; + } + if (!res.optimizations.empty()) { + std::cout << "Optimizations applied:\n"; + for (auto& o : res.optimizations) + std::cout << " * " << o << "\n"; + } + } + + // === PRINT FINAL AST === + std::cout << "\n=== Final AST (After Semantic Analysis) ===\n"; + g_program->print(std::cout); + delete g_program; + g_program = nullptr; + return 0; } diff --git a/mycompiler b/mycompiler new file mode 100644 index 0000000000000000000000000000000000000000..7a85c1f017a3efbc7e37c06d4e3692d29ff00363 GIT binary patch literal 106568 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 B0T}=Q literal 0 HcmV?d00001 diff --git a/parser.cpp b/parser.cpp new file mode 100644 index 0000000..5d3bc18 --- /dev/null +++ b/parser.cpp @@ -0,0 +1,2224 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output, and Bison version. */ +#define YYBISON 30802 + +/* Bison version string. */ +#define YYBISON_VERSION "3.8.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* First part of user prologue. */ +#line 1 "parser.y" + +#include +#include +#include +#include +#include +#include "ast.hpp" +#include "tokens.hpp" + +extern int yylex(void); +extern int yylineno; +void yyerror(const char* s); + +AST::Program* g_program = nullptr; + +#line 87 "parser.cpp" + +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +#include "parser.hpp" +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_CLASS = 3, /* CLASS */ + YYSYMBOL_VAR = 4, /* VAR */ + YYSYMBOL_IS = 5, /* IS */ + YYSYMBOL_END = 6, /* END */ + YYSYMBOL_METHOD = 7, /* METHOD */ + YYSYMBOL_RETURN = 8, /* RETURN */ + YYSYMBOL_IF = 9, /* IF */ + YYSYMBOL_THEN = 10, /* THEN */ + YYSYMBOL_ELSE = 11, /* ELSE */ + YYSYMBOL_WHILE = 12, /* WHILE */ + YYSYMBOL_DO = 13, /* DO */ + YYSYMBOL_TRUE = 14, /* TRUE */ + YYSYMBOL_FALSE = 15, /* FALSE */ + YYSYMBOL_COLON = 16, /* COLON */ + YYSYMBOL_SEMICOLON = 17, /* SEMICOLON */ + YYSYMBOL_COMMA = 18, /* COMMA */ + YYSYMBOL_LPAREN = 19, /* LPAREN */ + YYSYMBOL_RPAREN = 20, /* RPAREN */ + YYSYMBOL_LBRACE = 21, /* LBRACE */ + YYSYMBOL_RBRACE = 22, /* RBRACE */ + YYSYMBOL_LBRACKET = 23, /* LBRACKET */ + YYSYMBOL_RBRACKET = 24, /* RBRACKET */ + YYSYMBOL_ASSIGN = 25, /* ASSIGN */ + YYSYMBOL_ARROW = 26, /* ARROW */ + YYSYMBOL_PLUS = 27, /* PLUS */ + YYSYMBOL_MINUS = 28, /* MINUS */ + YYSYMBOL_STAR = 29, /* STAR */ + YYSYMBOL_SLASH = 30, /* SLASH */ + YYSYMBOL_DOT = 31, /* DOT */ + YYSYMBOL_GT = 32, /* GT */ + YYSYMBOL_LT = 33, /* LT */ + YYSYMBOL_EQEQ = 34, /* EQEQ */ + YYSYMBOL_EQUAL = 35, /* EQUAL */ + YYSYMBOL_IDENTIFIER = 36, /* IDENTIFIER */ + YYSYMBOL_TYPE_NAME = 37, /* TYPE_NAME */ + YYSYMBOL_INT_LITERAL = 38, /* INT_LITERAL */ + YYSYMBOL_STRING_LITERAL = 39, /* STRING_LITERAL */ + YYSYMBOL_YYACCEPT = 40, /* $accept */ + YYSYMBOL_program = 41, /* program */ + YYSYMBOL_class_list = 42, /* class_list */ + YYSYMBOL_class_decl = 43, /* class_decl */ + YYSYMBOL_class_body = 44, /* class_body */ + YYSYMBOL_member_list = 45, /* member_list */ + YYSYMBOL_member = 46, /* member */ + YYSYMBOL_type_spec = 47, /* type_spec */ + YYSYMBOL_type_list = 48, /* type_list */ + YYSYMBOL_var_decl = 49, /* var_decl */ + YYSYMBOL_method_decl = 50, /* method_decl */ + YYSYMBOL_opt_params = 51, /* opt_params */ + YYSYMBOL_param_list = 52, /* param_list */ + YYSYMBOL_param = 53, /* param */ + YYSYMBOL_method_body = 54, /* method_body */ + YYSYMBOL_stmt_list = 55, /* stmt_list */ + YYSYMBOL_stmt = 56, /* stmt */ + YYSYMBOL_simple_stmt = 57, /* simple_stmt */ + YYSYMBOL_if_stmt = 58, /* if_stmt */ + YYSYMBOL_while_stmt = 59, /* while_stmt */ + YYSYMBOL_expr = 60, /* expr */ + YYSYMBOL_assign_expr = 61, /* assign_expr */ + YYSYMBOL_equality_expr = 62, /* equality_expr */ + YYSYMBOL_relational_expr = 63, /* relational_expr */ + YYSYMBOL_additive_expr = 64, /* additive_expr */ + YYSYMBOL_multiplicative_expr = 65, /* multiplicative_expr */ + YYSYMBOL_unary_expr = 66, /* unary_expr */ + YYSYMBOL_postfix_expr = 67, /* postfix_expr */ + YYSYMBOL_opt_args = 68, /* opt_args */ + YYSYMBOL_arg_list = 69, /* arg_list */ + YYSYMBOL_primary_expr = 70, /* primary_expr */ + YYSYMBOL_type_as_expr = 71, /* type_as_expr */ + YYSYMBOL_lvalue = 72 /* lvalue */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; + + + + +#ifdef short +# undef short +#endif + +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif +#endif + +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; +#else +typedef short yytype_int16; +#endif + +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_uint8 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define YY_ATTRIBUTE_PURE +# endif +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YY_USE(E) ((void) (E)) +#else +# define YY_USE(E) /* empty */ +#endif + +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ +# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") +# else +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# endif +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if 1 + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* 1 */ + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 6 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 162 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 40 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 33 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 77 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 142 + +/* YYMAXUTOK -- Last valid token kind. */ +#define YYMAXUTOK 294 + + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_int8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39 +}; + +#if YYDEBUG +/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_int16 yyrline[] = +{ + 0, 78, 78, 83, 84, 88, 97, 98, 102, 103, + 107, 108, 112, 114, 123, 125, 134, 136, 138, 143, + 152, 153, 157, 158, 162, 167, 177, 178, 179, 180, + 181, 182, 186, 187, 188, 192, 193, 194, 195, 196, + 197, 201, 206, 216, 220, 221, 225, 226, 230, 231, + 232, 236, 237, 238, 242, 243, 244, 248, 249, 253, + 255, 257, 259, 264, 265, 269, 270, 274, 275, 276, + 277, 278, 279, 280, 284, 289, 290, 291 +}; +#endif + +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if 1 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "\"end of file\"", "error", "\"invalid token\"", "CLASS", "VAR", "IS", + "END", "METHOD", "RETURN", "IF", "THEN", "ELSE", "WHILE", "DO", "TRUE", + "FALSE", "COLON", "SEMICOLON", "COMMA", "LPAREN", "RPAREN", "LBRACE", + "RBRACE", "LBRACKET", "RBRACKET", "ASSIGN", "ARROW", "PLUS", "MINUS", + "STAR", "SLASH", "DOT", "GT", "LT", "EQEQ", "EQUAL", "IDENTIFIER", + "TYPE_NAME", "INT_LITERAL", "STRING_LITERAL", "$accept", "program", + "class_list", "class_decl", "class_body", "member_list", "member", + "type_spec", "type_list", "var_decl", "method_decl", "opt_params", + "param_list", "param", "method_body", "stmt_list", "stmt", "simple_stmt", + "if_stmt", "while_stmt", "expr", "assign_expr", "equality_expr", + "relational_expr", "additive_expr", "multiplicative_expr", "unary_expr", + "postfix_expr", "opt_args", "arg_list", "primary_expr", "type_as_expr", + "lvalue", YY_NULLPTR +}; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + return yytname[yysymbol]; +} +#endif + +#define YYPACT_NINF (-106) + +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) + +#define YYTABLE_NINF (-76) + +#define yytable_value_is_error(Yyn) \ + 0 + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 9, -11, 28, 9, -106, 25, -106, -106, 13, 5, + 14, 50, 13, -106, -106, -106, 56, 73, -106, -106, + 32, 44, 62, -14, 84, 91, 94, -106, 32, -106, + 95, 95, 32, 97, 44, -106, -8, -106, -106, 95, + 101, 93, -106, -106, -106, 102, -106, 87, -28, 38, + 61, -106, -5, -106, -106, 48, 105, -106, 32, -106, + 32, -106, 104, -106, -106, -106, 101, 101, 101, 101, + 101, 101, 101, 95, 95, 99, 95, 95, 100, -106, + 115, -106, -106, -28, 38, 38, 61, 61, -106, -106, + -106, 110, 124, 119, -106, 120, -106, -106, 89, -106, + 95, -106, -106, 109, 95, 95, -106, 89, 129, -106, + -106, 53, -106, 131, -106, 138, 132, -106, -106, 95, + 32, 23, -106, -106, -106, -2, 95, 139, -106, -106, + -106, 95, 95, 140, 23, -106, -106, 89, 145, 49, + -106, -106 +}; + +/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_int8 yydefact[] = +{ + 0, 0, 0, 2, 4, 0, 1, 3, 7, 0, + 0, 0, 6, 9, 10, 11, 0, 0, 5, 8, + 0, 21, 12, 0, 0, 0, 20, 23, 0, 16, + 0, 0, 0, 0, 0, 14, 0, 69, 70, 0, + 0, 71, 67, 68, 74, 0, 43, 45, 47, 50, + 53, 56, 58, 62, 72, 0, 0, 24, 0, 22, + 0, 13, 0, 71, 57, 18, 0, 0, 0, 0, + 0, 0, 0, 64, 0, 0, 0, 0, 0, 17, + 0, 15, 73, 46, 48, 49, 51, 52, 54, 55, + 66, 0, 63, 0, 60, 0, 44, 76, 0, 59, + 0, 61, 77, 0, 0, 0, 19, 25, 31, 30, + 40, 0, 65, 0, 35, 0, 28, 27, 29, 0, + 0, 0, 26, 39, 43, 36, 0, 0, 32, 33, + 34, 0, 0, 0, 0, 38, 37, 0, 0, 0, + 41, 42 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -106, -106, -106, 149, -106, -106, 142, -13, -106, -106, + -106, -106, -106, 121, -106, 19, 24, -105, -40, -106, + -30, -71, -106, 96, 15, 36, -32, -106, -106, -106, + -106, -106, -85 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_uint8 yydefgoto[] = +{ + 0, 2, 3, 4, 11, 12, 13, 44, 36, 14, + 15, 25, 26, 27, 106, 107, 127, 108, 109, 130, + 110, 46, 47, 48, 49, 50, 51, 52, 91, 92, + 53, 54, 55 +}; + +/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 45, 56, 116, 29, 67, 68, 96, 23, 64, 62, + 60, 30, 1, 111, 73, 35, 128, 9, 74, 57, + 10, 31, 111, 131, 61, 5, 75, 103, 6, 128, + 8, 104, 105, 132, 116, 126, 111, 37, 38, 88, + 89, 16, 39, 90, 93, 80, 95, 81, 124, 111, + 17, 40, 111, 103, 111, 141, 18, 104, 105, 41, + 22, 42, 43, 37, 38, 69, 70, 117, 39, 22, + 112, 76, 20, 77, 114, 115, 76, 40, 119, 78, + 24, 129, 84, 85, 78, 41, 22, 42, 43, 123, + 71, 72, 21, 103, 129, 28, 133, 104, 105, 117, + 32, 135, 136, 37, 38, 86, 87, 125, 39, 37, + 38, 33, 34, 58, 39, 37, 38, 40, -75, 65, + 39, 66, 79, 40, 82, 41, 22, 42, 43, 40, + 99, 41, 22, 42, 43, 94, 97, 63, 22, 42, + 43, 98, 100, 101, 102, 113, 118, 120, 121, 122, + 134, 140, 7, 137, 19, 59, 139, 0, 138, 0, + 0, 0, 83 +}; + +static const yytype_int16 yycheck[] = +{ + 30, 31, 107, 17, 32, 33, 77, 20, 40, 39, + 18, 25, 3, 98, 19, 28, 121, 4, 23, 32, + 7, 35, 107, 25, 32, 36, 31, 4, 0, 134, + 5, 8, 9, 35, 139, 12, 121, 14, 15, 71, + 72, 36, 19, 73, 74, 58, 76, 60, 119, 134, + 36, 28, 137, 4, 139, 6, 6, 8, 9, 36, + 37, 38, 39, 14, 15, 27, 28, 107, 19, 37, + 100, 23, 16, 25, 104, 105, 23, 28, 25, 31, + 36, 121, 67, 68, 31, 36, 37, 38, 39, 119, + 29, 30, 19, 4, 134, 33, 126, 8, 9, 139, + 16, 131, 132, 14, 15, 69, 70, 120, 19, 14, + 15, 20, 18, 16, 19, 14, 15, 28, 25, 17, + 19, 34, 17, 28, 20, 36, 37, 38, 39, 28, + 20, 36, 37, 38, 39, 36, 36, 36, 37, 38, + 39, 26, 18, 24, 24, 36, 17, 16, 10, 17, + 11, 6, 3, 13, 12, 34, 137, -1, 134, -1, + -1, -1, 66 +}; + +/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of + state STATE-NUM. */ +static const yytype_int8 yystos[] = +{ + 0, 3, 41, 42, 43, 36, 0, 43, 5, 4, + 7, 44, 45, 46, 49, 50, 36, 36, 6, 46, + 16, 19, 37, 47, 36, 51, 52, 53, 33, 17, + 25, 35, 16, 20, 18, 47, 48, 14, 15, 19, + 28, 36, 38, 39, 47, 60, 61, 62, 63, 64, + 65, 66, 67, 70, 71, 72, 60, 47, 16, 53, + 18, 32, 60, 36, 66, 17, 34, 32, 33, 27, + 28, 29, 30, 19, 23, 31, 23, 25, 31, 17, + 47, 47, 20, 63, 64, 64, 65, 65, 66, 66, + 60, 68, 69, 60, 36, 60, 61, 36, 26, 20, + 18, 24, 24, 4, 8, 9, 54, 55, 57, 58, + 60, 72, 60, 36, 60, 60, 57, 58, 17, 25, + 16, 10, 17, 60, 61, 47, 12, 56, 57, 58, + 59, 25, 35, 60, 11, 60, 60, 13, 56, 55, + 6, 6 +}; + +/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr1[] = +{ + 0, 40, 41, 42, 42, 43, 44, 44, 45, 45, + 46, 46, 47, 47, 48, 48, 49, 49, 49, 50, + 51, 51, 52, 52, 53, 54, 55, 55, 55, 55, + 55, 55, 56, 56, 56, 57, 57, 57, 57, 57, + 57, 58, 59, 60, 61, 61, 62, 62, 63, 63, + 63, 64, 64, 64, 65, 65, 65, 66, 66, 67, + 67, 67, 67, 68, 68, 69, 69, 70, 70, 70, + 70, 70, 70, 70, 71, 72, 72, 72 +}; + +/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr2[] = +{ + 0, 2, 1, 2, 1, 5, 1, 0, 2, 1, + 1, 1, 1, 4, 1, 3, 5, 7, 7, 9, + 1, 0, 3, 1, 3, 1, 3, 2, 2, 2, + 1, 1, 1, 1, 1, 2, 4, 6, 6, 3, + 1, 7, 5, 1, 3, 1, 3, 1, 3, 3, + 1, 3, 3, 1, 3, 3, 1, 2, 1, 4, + 3, 4, 1, 1, 0, 3, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 3, 4 +}; + + +enum { YYENOMEM = -2 }; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab +#define YYNOMEM goto yyexhaustedlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + + + + +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Kind, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YY_USE (yyoutput); + if (!yyvaluep) + return; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); + + yy_symbol_value_print (yyo, yykind, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule) +{ + int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)]); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +/* Context of a parse error. */ +typedef struct +{ + yy_state_t *yyssp; + yysymbol_kind_t yytoken; +} yypcontext_t; + +/* Put in YYARG at most YYARGN of the expected tokens given the + current YYCTX, and return the number of tokens stored in YYARG. If + YYARG is null, return the number of expected tokens (guaranteed to + be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. + Return 0 if there are more than YYARGN expected tokens, yet fill + YYARG up to YYARGN. */ +static int +yypcontext_expected_tokens (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) +{ + /* Actual size of YYARG. */ + int yycount = 0; + int yyn = yypact[+*yyctx->yyssp]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (!yyarg) + ++yycount; + else if (yycount == yyargn) + return 0; + else + yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); + } + } + if (yyarg && yycount == 0 && 0 < yyargn) + yyarg[0] = YYSYMBOL_YYEMPTY; + return yycount; +} + + + + +#ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) +# else +/* Return the length of YYSTR. */ +static YYPTRDIFF_T +yystrlen (const char *yystr) +{ + YYPTRDIFF_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +#endif + +#ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +#endif + +#ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYPTRDIFF_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYPTRDIFF_T yyn = 0; + char const *yyp = yystr; + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (yyres) + return yystpcpy (yyres, yystr) - yyres; + else + return yystrlen (yystr); +} +#endif + + +static int +yy_syntax_error_arguments (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) +{ + /* Actual size of YYARG. */ + int yycount = 0; + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yyctx->yytoken != YYSYMBOL_YYEMPTY) + { + int yyn; + if (yyarg) + yyarg[yycount] = yyctx->yytoken; + ++yycount; + yyn = yypcontext_expected_tokens (yyctx, + yyarg ? yyarg + 1 : yyarg, yyargn - 1); + if (yyn == YYENOMEM) + return YYENOMEM; + else + yycount += yyn; + } + return yycount; +} + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, + const yypcontext_t *yyctx) +{ + enum { YYARGS_MAX = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat: reported tokens (one for the "unexpected", + one per "expected"). */ + yysymbol_kind_t yyarg[YYARGS_MAX]; + /* Cumulated lengths of YYARG. */ + YYPTRDIFF_T yysize = 0; + + /* Actual size of YYARG. */ + int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); + if (yycount == YYENOMEM) + return YYENOMEM; + + switch (yycount) + { +#define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +#undef YYCASE_ + } + + /* Compute error message size. Don't count the "%s"s, but reserve + room for the terminator. */ + yysize = yystrlen (yyformat) - 2 * yycount + 1; + { + int yyi; + for (yyi = 0; yyi < yycount; ++yyi) + { + YYPTRDIFF_T yysize1 + = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return YYENOMEM; + } + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return -1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); + yyformat += 2; + } + else + { + ++yyp; + ++yyformat; + } + } + return 0; +} + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep) +{ + YY_USE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/* Lookahead token kind. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + yy_state_fast_t yystate = 0; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus = 0; + + /* Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; + + /* The state stack: array, bottom, top. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; + + /* The semantic value stack: array, bottom, top. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; + + int yyn; + /* The return value of yyparse. */ + int yyresult; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yychar = YYEMPTY; /* Cause a token to be read. */ + + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + YYNOMEM; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYPTRDIFF_T yysize = yyssp - yyss + 1; + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + YYNOMEM; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) + YYNOMEM; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token\n")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + /* Discard the shifted token. */ + yychar = YYEMPTY; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: /* program: class_list */ +#line 79 "parser.y" + { g_program = new AST::Program(); for (auto* c : *(yyvsp[0].classlist)) g_program->classes.push_back(c); delete (yyvsp[0].classlist); } +#line 1518 "parser.cpp" + break; + + case 3: /* class_list: class_list class_decl */ +#line 83 "parser.y" + { (yyval.classlist) = (yyvsp[-1].classlist); (yyvsp[-1].classlist)->push_back((yyvsp[0].classdecl)); } +#line 1524 "parser.cpp" + break; + + case 4: /* class_list: class_decl */ +#line 84 "parser.y" + { (yyval.classlist) = new std::vector(); (yyval.classlist)->push_back((yyvsp[0].classdecl)); } +#line 1530 "parser.cpp" + break; + + case 5: /* class_decl: CLASS IDENTIFIER IS class_body END */ +#line 89 "parser.y" + { + (yyval.classdecl) = new AST::ClassDecl((yyvsp[-3].cstr)); + for (auto* n : *(yyvsp[-1].memberlist)) { if (auto* v = dynamic_cast(n)) (yyval.classdecl)->fields.push_back(v); else if (auto* m = dynamic_cast(n)) (yyval.classdecl)->methods.push_back(m); else delete n; } + free((yyvsp[-3].cstr)); delete (yyvsp[-1].memberlist); + } +#line 1540 "parser.cpp" + break; + + case 6: /* class_body: member_list */ +#line 97 "parser.y" + { (yyval.memberlist) = (yyvsp[0].memberlist); } +#line 1546 "parser.cpp" + break; + + case 7: /* class_body: %empty */ +#line 98 "parser.y" + { (yyval.memberlist) = new std::vector(); } +#line 1552 "parser.cpp" + break; + + case 8: /* member_list: member_list member */ +#line 102 "parser.y" + { (yyval.memberlist) = (yyvsp[-1].memberlist); (yyvsp[-1].memberlist)->push_back((yyvsp[0].node)); } +#line 1558 "parser.cpp" + break; + + case 9: /* member_list: member */ +#line 103 "parser.y" + { (yyval.memberlist) = new std::vector(); (yyval.memberlist)->push_back((yyvsp[0].node)); } +#line 1564 "parser.cpp" + break; + + case 10: /* member: var_decl */ +#line 107 "parser.y" + { (yyval.node) = (yyvsp[0].vardecl); } +#line 1570 "parser.cpp" + break; + + case 11: /* member: method_decl */ +#line 108 "parser.y" + { (yyval.node) = (yyvsp[0].methoddecl); } +#line 1576 "parser.cpp" + break; + + case 12: /* type_spec: TYPE_NAME */ +#line 113 "parser.y" + { (yyval.cstr) = (yyvsp[0].cstr); } +#line 1582 "parser.cpp" + break; + + case 13: /* type_spec: TYPE_NAME LT type_list GT */ +#line 115 "parser.y" + { + std::string s = std::string((yyvsp[-3].cstr)) + "<" + std::string((yyvsp[-1].cstr)) + ">"; + (yyval.cstr) = strdup(s.c_str()); + free((yyvsp[-3].cstr)); free((yyvsp[-1].cstr)); + } +#line 1592 "parser.cpp" + break; + + case 14: /* type_list: type_spec */ +#line 124 "parser.y" + { (yyval.cstr) = (yyvsp[0].cstr); } +#line 1598 "parser.cpp" + break; + + case 15: /* type_list: type_list COMMA type_spec */ +#line 126 "parser.y" + { + std::string s = std::string((yyvsp[-2].cstr)) + "," + std::string((yyvsp[0].cstr)); + (yyval.cstr) = strdup(s.c_str()); + free((yyvsp[-2].cstr)); free((yyvsp[0].cstr)); + } +#line 1608 "parser.cpp" + break; + + case 16: /* var_decl: VAR IDENTIFIER COLON type_spec SEMICOLON */ +#line 135 "parser.y" + { (yyval.vardecl) = new AST::VarDecl((yyvsp[-3].cstr), (yyvsp[-1].cstr), nullptr); free((yyvsp[-3].cstr)); free((yyvsp[-1].cstr)); } +#line 1614 "parser.cpp" + break; + + case 17: /* var_decl: VAR IDENTIFIER COLON type_spec EQUAL expr SEMICOLON */ +#line 137 "parser.y" + { (yyval.vardecl) = new AST::VarDecl((yyvsp[-5].cstr), (yyvsp[-3].cstr), (yyvsp[-1].expr)); free((yyvsp[-5].cstr)); free((yyvsp[-3].cstr)); } +#line 1620 "parser.cpp" + break; + + case 18: /* var_decl: VAR IDENTIFIER COLON type_spec ASSIGN expr SEMICOLON */ +#line 139 "parser.y" + { (yyval.vardecl) = new AST::VarDecl((yyvsp[-5].cstr), (yyvsp[-3].cstr), (yyvsp[-1].expr)); free((yyvsp[-5].cstr)); free((yyvsp[-3].cstr)); } +#line 1626 "parser.cpp" + break; + + case 19: /* method_decl: METHOD IDENTIFIER LPAREN opt_params RPAREN COLON type_spec ARROW method_body */ +#line 144 "parser.y" + { + (yyval.methoddecl) = new AST::MethodDecl((yyvsp[-7].cstr), (yyvsp[-2].cstr), (yyvsp[0].stmt)); + if ((yyvsp[-5].paramlist)) { for (auto* p : *(yyvsp[-5].paramlist)) (yyval.methoddecl)->params.push_back(p); delete (yyvsp[-5].paramlist); } + free((yyvsp[-7].cstr)); free((yyvsp[-2].cstr)); + } +#line 1636 "parser.cpp" + break; + + case 20: /* opt_params: param_list */ +#line 152 "parser.y" + { (yyval.paramlist) = (yyvsp[0].paramlist); } +#line 1642 "parser.cpp" + break; + + case 21: /* opt_params: %empty */ +#line 153 "parser.y" + { (yyval.paramlist) = new std::vector(); } +#line 1648 "parser.cpp" + break; + + case 22: /* param_list: param_list COMMA param */ +#line 157 "parser.y" + { (yyval.paramlist) = (yyvsp[-2].paramlist); (yyvsp[-2].paramlist)->push_back((yyvsp[0].param)); } +#line 1654 "parser.cpp" + break; + + case 23: /* param_list: param */ +#line 158 "parser.y" + { (yyval.paramlist) = new std::vector(); (yyval.paramlist)->push_back((yyvsp[0].param)); } +#line 1660 "parser.cpp" + break; + + case 24: /* param: IDENTIFIER COLON type_spec */ +#line 163 "parser.y" + { (yyval.param) = new AST::Param((yyvsp[-2].cstr), (yyvsp[0].cstr)); free((yyvsp[-2].cstr)); free((yyvsp[0].cstr)); } +#line 1666 "parser.cpp" + break; + + case 25: /* method_body: stmt_list */ +#line 168 "parser.y" + { + auto* b = new AST::Block(); + for (auto* s : *(yyvsp[0].stmtlist)) b->stmts.push_back(s); + delete (yyvsp[0].stmtlist); + (yyval.stmt) = b; + } +#line 1677 "parser.cpp" + break; + + case 26: /* stmt_list: stmt_list simple_stmt SEMICOLON */ +#line 177 "parser.y" + { (yyval.stmtlist) = (yyvsp[-2].stmtlist); (yyvsp[-2].stmtlist)->push_back((yyvsp[-1].stmt)); } +#line 1683 "parser.cpp" + break; + + case 27: /* stmt_list: stmt_list if_stmt */ +#line 178 "parser.y" + { (yyval.stmtlist) = (yyvsp[-1].stmtlist); (yyvsp[-1].stmtlist)->push_back((yyvsp[0].stmt)); } +#line 1689 "parser.cpp" + break; + + case 28: /* stmt_list: stmt_list simple_stmt */ +#line 179 "parser.y" + { (yyval.stmtlist) = (yyvsp[-1].stmtlist); (yyvsp[-1].stmtlist)->push_back((yyvsp[0].stmt)); } +#line 1695 "parser.cpp" + break; + + case 29: /* stmt_list: simple_stmt SEMICOLON */ +#line 180 "parser.y" + { (yyval.stmtlist) = new std::vector(); (yyval.stmtlist)->push_back((yyvsp[-1].stmt)); } +#line 1701 "parser.cpp" + break; + + case 30: /* stmt_list: if_stmt */ +#line 181 "parser.y" + { (yyval.stmtlist) = new std::vector(); (yyval.stmtlist)->push_back((yyvsp[0].stmt)); } +#line 1707 "parser.cpp" + break; + + case 31: /* stmt_list: simple_stmt */ +#line 182 "parser.y" + { (yyval.stmtlist) = new std::vector(); (yyval.stmtlist)->push_back((yyvsp[0].stmt)); } +#line 1713 "parser.cpp" + break; + + case 32: /* stmt: simple_stmt */ +#line 186 "parser.y" + { (yyval.stmt) = (yyvsp[0].stmt); } +#line 1719 "parser.cpp" + break; + + case 33: /* stmt: if_stmt */ +#line 187 "parser.y" + { (yyval.stmt) = (yyvsp[0].stmt); } +#line 1725 "parser.cpp" + break; + + case 34: /* stmt: while_stmt */ +#line 188 "parser.y" + { (yyval.stmt) = (yyvsp[0].stmt); } +#line 1731 "parser.cpp" + break; + + case 35: /* simple_stmt: RETURN expr */ +#line 192 "parser.y" + { (yyval.stmt) = new AST::ReturnStmt((yyvsp[0].expr)); } +#line 1737 "parser.cpp" + break; + + case 36: /* simple_stmt: VAR IDENTIFIER COLON type_spec */ +#line 193 "parser.y" + { (yyval.stmt) = new AST::VarDeclStmt(new AST::VarDecl((yyvsp[-2].cstr), (yyvsp[0].cstr), nullptr)); free((yyvsp[-2].cstr)); free((yyvsp[0].cstr)); } +#line 1743 "parser.cpp" + break; + + case 37: /* simple_stmt: VAR IDENTIFIER COLON type_spec EQUAL expr */ +#line 194 "parser.y" + { (yyval.stmt) = new AST::VarDeclStmt(new AST::VarDecl((yyvsp[-4].cstr), (yyvsp[-2].cstr), (yyvsp[0].expr))); free((yyvsp[-4].cstr)); free((yyvsp[-2].cstr)); } +#line 1749 "parser.cpp" + break; + + case 38: /* simple_stmt: VAR IDENTIFIER COLON type_spec ASSIGN expr */ +#line 195 "parser.y" + { (yyval.stmt) = new AST::VarDeclStmt(new AST::VarDecl((yyvsp[-4].cstr), (yyvsp[-2].cstr), (yyvsp[0].expr))); free((yyvsp[-4].cstr)); free((yyvsp[-2].cstr)); } +#line 1755 "parser.cpp" + break; + + case 39: /* simple_stmt: lvalue ASSIGN expr */ +#line 196 "parser.y" + { (yyval.stmt) = new AST::ExprStmt(new AST::Binary(AST::BinOp::Assign, (yyvsp[-2].expr), (yyvsp[0].expr))); } +#line 1761 "parser.cpp" + break; + + case 40: /* simple_stmt: expr */ +#line 197 "parser.y" + { (yyval.stmt) = new AST::ExprStmt((yyvsp[0].expr)); } +#line 1767 "parser.cpp" + break; + + case 41: /* if_stmt: IF expr THEN stmt ELSE stmt END */ +#line 202 "parser.y" + { (yyval.stmt) = new AST::IfStmt((yyvsp[-5].expr), (yyvsp[-3].stmt), (yyvsp[-1].stmt)); } +#line 1773 "parser.cpp" + break; + + case 42: /* while_stmt: WHILE expr DO stmt_list END */ +#line 207 "parser.y" + { + auto* b = new AST::Block(); + for (auto* s : *(yyvsp[-1].stmtlist)) b->stmts.push_back(s); + delete (yyvsp[-1].stmtlist); + (yyval.stmt) = new AST::WhileStmt((yyvsp[-3].expr), b); + } +#line 1784 "parser.cpp" + break; + + case 43: /* expr: assign_expr */ +#line 216 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1790 "parser.cpp" + break; + + case 44: /* assign_expr: lvalue ASSIGN assign_expr */ +#line 220 "parser.y" + { (yyval.expr) = new AST::Binary(AST::BinOp::Assign, (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1796 "parser.cpp" + break; + + case 45: /* assign_expr: equality_expr */ +#line 221 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1802 "parser.cpp" + break; + + case 46: /* equality_expr: equality_expr EQEQ relational_expr */ +#line 225 "parser.y" + { (yyval.expr) = new AST::Binary(AST::BinOp::Eq, (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1808 "parser.cpp" + break; + + case 47: /* equality_expr: relational_expr */ +#line 226 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1814 "parser.cpp" + break; + + case 48: /* relational_expr: relational_expr GT additive_expr */ +#line 230 "parser.y" + { (yyval.expr) = new AST::Binary(AST::BinOp::Gt, (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1820 "parser.cpp" + break; + + case 49: /* relational_expr: relational_expr LT additive_expr */ +#line 231 "parser.y" + { (yyval.expr) = new AST::Binary(AST::BinOp::Lt, (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1826 "parser.cpp" + break; + + case 50: /* relational_expr: additive_expr */ +#line 232 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1832 "parser.cpp" + break; + + case 51: /* additive_expr: additive_expr PLUS multiplicative_expr */ +#line 236 "parser.y" + { (yyval.expr) = new AST::Binary(AST::BinOp::Add, (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1838 "parser.cpp" + break; + + case 52: /* additive_expr: additive_expr MINUS multiplicative_expr */ +#line 237 "parser.y" + { (yyval.expr) = new AST::Binary(AST::BinOp::Sub, (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1844 "parser.cpp" + break; + + case 53: /* additive_expr: multiplicative_expr */ +#line 238 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1850 "parser.cpp" + break; + + case 54: /* multiplicative_expr: multiplicative_expr STAR unary_expr */ +#line 242 "parser.y" + { (yyval.expr) = new AST::Binary(AST::BinOp::Mul, (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1856 "parser.cpp" + break; + + case 55: /* multiplicative_expr: multiplicative_expr SLASH unary_expr */ +#line 243 "parser.y" + { (yyval.expr) = new AST::Binary(AST::BinOp::Div, (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1862 "parser.cpp" + break; + + case 56: /* multiplicative_expr: unary_expr */ +#line 244 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1868 "parser.cpp" + break; + + case 57: /* unary_expr: MINUS unary_expr */ +#line 248 "parser.y" + { (yyval.expr) = new AST::Unary(AST::Unary::Op::Neg, (yyvsp[0].expr)); } +#line 1874 "parser.cpp" + break; + + case 58: /* unary_expr: postfix_expr */ +#line 249 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1880 "parser.cpp" + break; + + case 59: /* postfix_expr: postfix_expr LPAREN opt_args RPAREN */ +#line 254 "parser.y" + { auto* call = new AST::Call((yyvsp[-3].expr)); for (auto* e : *(yyvsp[-1].exprlist)) call->args.push_back(e); delete (yyvsp[-1].exprlist); (yyval.expr) = call; } +#line 1886 "parser.cpp" + break; + + case 60: /* postfix_expr: postfix_expr DOT IDENTIFIER */ +#line 256 "parser.y" + { (yyval.expr) = new AST::MemberAccess((yyvsp[-2].expr), (yyvsp[0].cstr)); free((yyvsp[0].cstr)); } +#line 1892 "parser.cpp" + break; + + case 61: /* postfix_expr: postfix_expr LBRACKET expr RBRACKET */ +#line 258 "parser.y" + { (yyval.expr) = new AST::Index((yyvsp[-3].expr), (yyvsp[-1].expr)); } +#line 1898 "parser.cpp" + break; + + case 62: /* postfix_expr: primary_expr */ +#line 260 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1904 "parser.cpp" + break; + + case 63: /* opt_args: arg_list */ +#line 264 "parser.y" + { (yyval.exprlist) = (yyvsp[0].exprlist); } +#line 1910 "parser.cpp" + break; + + case 64: /* opt_args: %empty */ +#line 265 "parser.y" + { (yyval.exprlist) = new std::vector(); } +#line 1916 "parser.cpp" + break; + + case 65: /* arg_list: arg_list COMMA expr */ +#line 269 "parser.y" + { (yyval.exprlist) = (yyvsp[-2].exprlist); (yyvsp[-2].exprlist)->push_back((yyvsp[0].expr)); } +#line 1922 "parser.cpp" + break; + + case 66: /* arg_list: expr */ +#line 270 "parser.y" + { (yyval.exprlist) = new std::vector(); (yyval.exprlist)->push_back((yyvsp[0].expr)); } +#line 1928 "parser.cpp" + break; + + case 67: /* primary_expr: INT_LITERAL */ +#line 274 "parser.y" + { (yyval.expr) = new AST::IntLiteral((yyvsp[0].ival)); } +#line 1934 "parser.cpp" + break; + + case 68: /* primary_expr: STRING_LITERAL */ +#line 275 "parser.y" + { (yyval.expr) = new AST::StringLiteral((yyvsp[0].cstr)); free((yyvsp[0].cstr)); } +#line 1940 "parser.cpp" + break; + + case 69: /* primary_expr: TRUE */ +#line 276 "parser.y" + { (yyval.expr) = new AST::BoolLiteral(true); } +#line 1946 "parser.cpp" + break; + + case 70: /* primary_expr: FALSE */ +#line 277 "parser.y" + { (yyval.expr) = new AST::BoolLiteral(false); } +#line 1952 "parser.cpp" + break; + + case 71: /* primary_expr: IDENTIFIER */ +#line 278 "parser.y" + { (yyval.expr) = new AST::Identifier((yyvsp[0].cstr)); free((yyvsp[0].cstr)); } +#line 1958 "parser.cpp" + break; + + case 72: /* primary_expr: type_as_expr */ +#line 279 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 1964 "parser.cpp" + break; + + case 73: /* primary_expr: LPAREN expr RPAREN */ +#line 280 "parser.y" + { (yyval.expr) = (yyvsp[-1].expr); } +#line 1970 "parser.cpp" + break; + + case 74: /* type_as_expr: type_spec */ +#line 285 "parser.y" + { (yyval.expr) = new AST::Identifier((yyvsp[0].cstr)); free((yyvsp[0].cstr)); } +#line 1976 "parser.cpp" + break; + + case 75: /* lvalue: IDENTIFIER */ +#line 289 "parser.y" + { (yyval.expr) = new AST::Identifier((yyvsp[0].cstr)); free((yyvsp[0].cstr)); } +#line 1982 "parser.cpp" + break; + + case 76: /* lvalue: lvalue DOT IDENTIFIER */ +#line 290 "parser.y" + { (yyval.expr) = new AST::MemberAccess((yyvsp[-2].expr), (yyvsp[0].cstr)); free((yyvsp[0].cstr)); } +#line 1988 "parser.cpp" + break; + + case 77: /* lvalue: lvalue LBRACKET expr RBRACKET */ +#line 291 "parser.y" + { (yyval.expr) = new AST::Index((yyvsp[-3].expr), (yyvsp[-1].expr)); } +#line 1994 "parser.cpp" + break; + + +#line 1998 "parser.cpp" + + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; + { + yypcontext_t yyctx + = {yyssp, yytoken}; + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == -1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = YY_CAST (char *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); + if (yymsg) + { + yysyntax_error_status + = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); + yymsgp = yymsg; + } + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = YYENOMEM; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == YYENOMEM) + YYNOMEM; + } + } + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + ++yynerrs; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + /* Pop stack until we find a state that shifts the error token. */ + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + YY_ACCESSING_SYMBOL (yystate), yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturnlab; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturnlab; + + +/*-----------------------------------------------------------. +| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | +`-----------------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + goto yyreturnlab; + + +/*----------------------------------------------------------. +| yyreturnlab -- parsing is finished, clean up and return. | +`----------------------------------------------------------*/ +yyreturnlab: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + return yyresult; +} + +#line 294 "parser.y" + + +void yyerror(const char* s) { std::fprintf(stderr, "Parse error at line %d: %s\n", yylineno, s); } diff --git a/parser.hpp b/parser.hpp new file mode 100644 index 0000000..8d28e61 --- /dev/null +++ b/parser.hpp @@ -0,0 +1,146 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +#ifndef YY_YY_PARSER_HPP_INCLUDED +# define YY_YY_PARSER_HPP_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif +/* "%code requires" blocks. */ +#line 17 "parser.y" + + #include + namespace AST { + struct Node; struct Program; struct ClassDecl; struct VarDecl; struct Expr; struct Stmt; struct MethodDecl; struct Param; struct Block; + } + +#line 56 "parser.hpp" + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + CLASS = 258, /* CLASS */ + VAR = 259, /* VAR */ + IS = 260, /* IS */ + END = 261, /* END */ + METHOD = 262, /* METHOD */ + RETURN = 263, /* RETURN */ + IF = 264, /* IF */ + THEN = 265, /* THEN */ + ELSE = 266, /* ELSE */ + WHILE = 267, /* WHILE */ + DO = 268, /* DO */ + TRUE = 269, /* TRUE */ + FALSE = 270, /* FALSE */ + COLON = 271, /* COLON */ + SEMICOLON = 272, /* SEMICOLON */ + COMMA = 273, /* COMMA */ + LPAREN = 274, /* LPAREN */ + RPAREN = 275, /* RPAREN */ + LBRACE = 276, /* LBRACE */ + RBRACE = 277, /* RBRACE */ + LBRACKET = 278, /* LBRACKET */ + RBRACKET = 279, /* RBRACKET */ + ASSIGN = 280, /* ASSIGN */ + ARROW = 281, /* ARROW */ + PLUS = 282, /* PLUS */ + MINUS = 283, /* MINUS */ + STAR = 284, /* STAR */ + SLASH = 285, /* SLASH */ + DOT = 286, /* DOT */ + GT = 287, /* GT */ + LT = 288, /* LT */ + EQEQ = 289, /* EQEQ */ + EQUAL = 290, /* EQUAL */ + IDENTIFIER = 291, /* IDENTIFIER */ + TYPE_NAME = 292, /* TYPE_NAME */ + INT_LITERAL = 293, /* INT_LITERAL */ + STRING_LITERAL = 294 /* STRING_LITERAL */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 27 "parser.y" + + long long ival; + char* cstr; + AST::Program* program; + AST::ClassDecl* classdecl; + AST::VarDecl* vardecl; + AST::Expr* expr; + AST::Stmt* stmt; + AST::MethodDecl* methoddecl; + AST::Param* param; + AST::Node* node; + std::vector* classlist; + std::vector* memberlist; + std::vector* varlist; + std::vector* paramlist; + std::vector* stmtlist; + std::vector* exprlist; + std::vector* strlist; + +#line 132 "parser.hpp" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + + +int yyparse (void); + + +#endif /* !YY_YY_PARSER_HPP_INCLUDED */ diff --git a/semantic.cpp b/semantic.cpp new file mode 100644 index 0000000..0ddcfe7 --- /dev/null +++ b/semantic.cpp @@ -0,0 +1,474 @@ +#include "semantic.hpp" +#include +#include +#include + +// Helper to get node position (best-effort, using identifiers not storing positions) +std::string SemanticAnalyzer::curPos(AST::Node* n) { + (void)n; + return ""; // AST nodes currently don't store line/column, so empty +} + +SemanticAnalyzer::SemanticAnalyzer() { + classes.clear(); + curClass = nullptr; + curMethod = nullptr; + localsStack.clear(); +} + +// Build class index +void SemanticAnalyzer::indexClasses(AST::Program* p) { + for (auto* c : p->classes) { + classes[c->name] = c; + } +} + +SemanticResult SemanticAnalyzer::analyze(AST::Program* p) { + result = SemanticResult(); + indexClasses(p); + // analyze each class + for (auto* c : p->classes) analyzeClass(c); + return result; +} + +void SemanticAnalyzer::analyzeClass(AST::ClassDecl* c) { + curClass = c; + // fields become available as "locals" inside methods + for (auto* m : c->methods) analyzeMethod(m); + curClass = nullptr; +} + +void SemanticAnalyzer::analyzeMethod(AST::MethodDecl* m) { + curMethod = m; + pushScope(); + // declare parameters + for (auto* p : m->params) { + declareLocal(p->name, p->typeName); + } + // declare fields (accessible as locals too) + for (auto* f : curClass->fields) { + declareLocal(f->name, f->typeName); + } + // optimize/mutate body before or after checks? We'll do folding first, then checks & other optimizations + if (m->body) { + // perform constant folding for expressions inside this method body + analyzeBlock(dynamic_cast(m->body)); + } else { + result.addError("Method " + m->name + " has empty body"); + } + popScope(); + curMethod = nullptr; +} + +void SemanticAnalyzer::pushScope() { + localsStack.emplace_back(); +} +void SemanticAnalyzer::popScope() { + if (!localsStack.empty()) localsStack.pop_back(); +} + +void SemanticAnalyzer::declareLocal(const std::string& name, const std::string& type) { + if (localsStack.empty()) pushScope(); + localsStack.back()[name] = type; +} + +std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { + if (!e) return ""; + if (auto* il = dynamic_cast(e)) return std::string("Int"); + if (auto* sl = dynamic_cast(e)) return std::string("String"); + if (auto* bl = dynamic_cast(e)) return std::string("Bool"); + if (auto* id = dynamic_cast(e)) { + // lookup locals stack from top + for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { + auto found = it->find(id->name); + if (found != it->end()) return found->second; + } + // not found — maybe it's a type-as-expr stored as Identifier node, but in general we warn + result.addError("Use of undeclared identifier '" + id->name + "'"); + return ""; + } + if (auto* bin = dynamic_cast(e)) { + auto lhs = typeOfExpr(bin->lhs); + auto rhs = typeOfExpr(bin->rhs); + switch (bin->op) { + case AST::BinOp::Add: case AST::BinOp::Sub: case AST::BinOp::Mul: case AST::BinOp::Div: + if (lhs != "Int" || rhs != "Int") { + result.addError("Arithmetic operator used with non-Int operands"); + return ""; + } + return "Int"; + case AST::BinOp::Gt: case AST::BinOp::Lt: + if (lhs != "Int" || rhs != "Int") { + result.addError("Relational operator used with non-Int operands"); + return ""; + } + return "Bool"; + case AST::BinOp::Eq: + if (lhs == "" || rhs == "" || lhs != rhs) { + result.addError("Equality operator used with incompatible types"); + return ""; + } + return "Bool"; + case AST::BinOp::Assign: + // lhs should be lvalue: here we take rhs type and compare to declared lhs type if identifier + if (auto* lid = dynamic_cast(bin->lhs)) { + // find declared type + std::string lhs_type; + for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { + auto found = it->find(lid->name); + if (found != it->end()) { lhs_type = found->second; break; } + } + if (lhs_type.empty()) { + result.addError("Assignment to undeclared variable '" + lid->name + "'"); + return ""; + } + if (lhs_type != rhs) { + result.addError("Type mismatch in assignment to '" + lid->name + "'"); + return ""; + } + return lhs_type; + } + // assignment to member/index not deeply typed here + return rhs; + } + } + if (auto* un = dynamic_cast(e)) { + auto rt = typeOfExpr(un->rhs); + if (un->op == AST::Unary::Op::Neg) { + if (rt != "Int") { + result.addError("Unary - applied to non-Int"); + return ""; + } + return "Int"; + } + } + if (auto* call = dynamic_cast(e)) { + // if callee is identifier, check method existence in current class + if (auto* id = dynamic_cast(call->callee)) { + auto it = classes.find(curClass->name); + if (it != classes.end()) { + bool found = false; + for (auto* m : it->second->methods) { + if (m->name == id->name) { found = true; break; } + } + if (!found) { + result.addError("Call to undeclared method '" + id->name + "' in class '" + curClass->name + "'"); + } + } + // we don't know return type, return empty + return ""; + } + return ""; + } + if (auto* ma = dynamic_cast(e)) { + // try to deduce member type if object has class and field exists (simple) + if (auto* objid = dynamic_cast(ma->object)) { + // find name in locals -> type is class name? + std::string t; + for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { + auto found = it->find(objid->name); + if (found != it->end()) { t = found->second; break; } + } + if (t.empty()) { + result.addError("Unknown object '" + objid->name + "' for member access"); + return ""; + } + // if t matches a class name, look for field + auto cit = classes.find(t); + if (cit != classes.end()) { + for (auto* f : cit->second->fields) if (f->name == ma->member) return f->typeName; + } + } + return ""; + } + if (auto* idx = dynamic_cast(e)) { + // index expression type inference is complex; skip + typeOfExpr(idx->base); + typeOfExpr(idx->index); + return ""; + } + return ""; +} + +void SemanticAnalyzer::analyzeBlock(AST::Block* b) { + if (!b) return; + // First – recursively fold constants inside expressions and statements + for (auto*& s : b->stmts) { + analyzeStmt(s); // analyzeStmt will call analyzeExpr and optimizations + } + // Remove unreachable code after returns + removeUnreachableInBlock(b); +} + +void SemanticAnalyzer::analyzeStmt(AST::Stmt*& s) { + if (!s) return; + // IfStmt + if (auto* ifs = dynamic_cast(s)) { + analyzeExpr(ifs->cond); + analyzeStmt(ifs->thenS); + analyzeStmt(ifs->elseS); + // after analyzing cond, maybe it's folded to literal; try to simplify + simplifyIf(s); + return; + } + if (auto* w = dynamic_cast(s)) { + analyzeExpr(w->cond); + analyzeBlock(dynamic_cast(w->body)); + return; + } + if (auto* ret = dynamic_cast(s)) { + if (!curMethod) { + result.addError("Return used outside of method"); + } else { + analyzeExpr(ret->value); + auto rv = typeOfExpr(ret->value); + if (!curMethod->returnType.empty()) { + if (rv != "" && curMethod->returnType != rv) { + result.addError("Return type mismatch in method '" + curMethod->name + "': expected " + curMethod->returnType + ", got " + rv); + } + } + } + return; + } + if (auto* es = dynamic_cast(s)) { + analyzeExpr(es->expr); + return; + } + if (auto* vds = dynamic_cast(s)) { + // var declaration - register local + if (vds->decl) { + declareLocal(vds->decl->name, vds->decl->typeName); + if (vds->decl->init) analyzeExpr(vds->decl->init); + // check init type matches declared type + if (vds->decl->init) { + auto it = typeOfExpr(vds->decl->init); + if (it != "" && it != vds->decl->typeName) { + result.addError("Initializer type mismatch for variable '" + vds->decl->name + "'"); + } + } + } + return; + } + if (auto* blk = dynamic_cast(s)) { + pushScope(); + analyzeBlock(blk); + popScope(); + return; + } +} + +void SemanticAnalyzer::analyzeExpr(AST::Expr*& e) { + if (!e) return; + // try constant folding first + bool folded = foldConstantsInExpr(e); + if (folded) { + // folded expression replaced e; still do type checks on new e + } + // then recurse into structure if not literal + if (auto* bin = dynamic_cast(e)) { + analyzeExpr(bin->lhs); + analyzeExpr(bin->rhs); + // assignment: ensure lvalue exists + if (bin->op == AST::BinOp::Assign) { + if (auto* lid = dynamic_cast(bin->lhs)) { + // must be declared + bool found = false; + for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { + if (it->find(lid->name) != it->end()) { found = true; break; } + } + if (!found) result.addError("Assignment to undeclared variable '" + lid->name + "'"); + } + } + return; + } + if (auto* un = dynamic_cast(e)) { + analyzeExpr(un->rhs); + return; + } + if (auto* call = dynamic_cast(e)) { + // check callee + if (auto* id = dynamic_cast(call->callee)) { + // check method exists in current class + bool found = false; + for (auto* m : curClass->methods) if (m->name == id->name) { found = true; break; } + if (!found) result.addError("Call to undeclared method '" + id->name + "'"); + } else { + analyzeExpr(call->callee); + } + for (auto*& a : call->args) analyzeExpr(a); + return; + } + if (auto* ma = dynamic_cast(e)) { + analyzeExpr(ma->object); + return; + } + if (auto* idx = dynamic_cast(e)) { + analyzeExpr(idx->base); + analyzeExpr(idx->index); + return; + } + if (auto* id = dynamic_cast(e)) { + // identifier use check + bool found = false; + for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { + if (it->find(id->name) != it->end()) { found = true; break; } + } + if (!found) result.addError("Use of undeclared identifier '" + id->name + "'"); + return; + } + // literals: nothing to do +} + +bool SemanticAnalyzer::isLiteral(AST::Expr* e) { + return dynamic_cast(e) || dynamic_cast(e) || dynamic_cast(e); +} + +// constant folding implementation +bool SemanticAnalyzer::foldConstantsInExpr(AST::Expr*& e) { + if (!e) return false; + // recursively fold children first + if (auto* bin = dynamic_cast(e)) { + bool l = foldConstantsInExpr(bin->lhs); + bool r = foldConstantsInExpr(bin->rhs); + // after children folded, try fold this node + if (auto* L = dynamic_cast(bin->lhs)) { + if (auto* R = dynamic_cast(bin->rhs)) { + long long a = L->value; + long long b = R->value; + if (bin->op == AST::BinOp::Add || bin->op == AST::BinOp::Sub || bin->op == AST::BinOp::Mul || bin->op == AST::BinOp::Div) { + long long res = 0; + switch (bin->op) { + case AST::BinOp::Add: res = a + b; break; + case AST::BinOp::Sub: res = a - b; break; + case AST::BinOp::Mul: res = a * b; break; + case AST::BinOp::Div: if (b == 0) { result.addError("Division by zero in constant expression"); return false; } res = a / b; break; + default: break; + } + delete e; + e = new AST::IntLiteral(res); + return true; + } + if (bin->op == AST::BinOp::Gt || bin->op == AST::BinOp::Lt) { + bool rr = false; + if (bin->op == AST::BinOp::Gt) rr = (a > b); + else rr = (a < b); + delete e; + e = new AST::BoolLiteral(rr); + return true; + } + if (bin->op == AST::BinOp::Eq) { + bool rr = (a == b); + delete e; + e = new AST::BoolLiteral(rr); + return true; + } + } + } + // bool equality folding + if (auto* LB = dynamic_cast(bin->lhs)) { + if (auto* RB = dynamic_cast(bin->rhs)) { + if (bin->op == AST::BinOp::Eq) { + bool rr = (LB->value == RB->value); + delete e; + e = new AST::BoolLiteral(rr); + return true; + } + } + } + return l || r; + } + if (auto* un = dynamic_cast(e)) { + bool r = foldConstantsInExpr(un->rhs); + if (auto* R = dynamic_cast(un->rhs)) { + if (un->op == AST::Unary::Op::Neg) { + long long val = -R->value; + delete e; + e = new AST::IntLiteral(val); + return true; + } + } + return r; + } + if (auto* call = dynamic_cast(e)) { + bool changed = false; + changed |= foldConstantsInExpr(call->callee); + for (auto*& a : call->args) changed |= foldConstantsInExpr(a); + return changed; + } + if (auto* ma = dynamic_cast(e)) { + bool changed = foldConstantsInExpr(ma->object); + return changed; + } + if (auto* idx = dynamic_cast(e)) { + bool b = foldConstantsInExpr(idx->base); + bool i = foldConstantsInExpr(idx->index); + return b || i; + } + return false; +} + +void SemanticAnalyzer::simplifyIf(AST::Stmt*& s) { + if (!s) return; + if (auto* ifs = dynamic_cast(s)) { + // attempt to see if cond is BoolLiteral + if (auto* bl = dynamic_cast(ifs->cond)) { + if (bl->value) { + // replace s with thenS (which may be a Block or single stmt) + AST::Stmt* newstmt = nullptr; + // if thenS is a Block, keep it + if (auto* tb = dynamic_cast(ifs->thenS)) { + // replace by block + // clone pointer ownership: delete whole if-stmt and use thenS pointer + newstmt = tb; + ifs->thenS = nullptr; + ifs->elseS = nullptr; + delete ifs->cond; // cond is BoolLiteral + // replace s + s = newstmt; + // NOTE: caller must not double-delete thenS (we transferred) + } else { + newstmt = ifs->thenS; + ifs->thenS = nullptr; + ifs->elseS = nullptr; + delete ifs; // cond already deleted inside destructor? destructor deletes cond and thenS/elseS - we moved pointers so careful + s = newstmt; + } + } else { + // cond is false -> replace with elseS or empty block + if (ifs->elseS) { + AST::Stmt* newstmt = ifs->elseS; + ifs->elseS = nullptr; + ifs->thenS = nullptr; + delete ifs; + s = newstmt; + } else { + // replace with empty block + delete ifs; + s = new AST::Block(); + } + } + } + } else if (auto* blk = dynamic_cast(s)) { + // walk statements and try simplify nested ifs + for (auto*& st : blk->stmts) { + simplifyIf(st); + } + } +} + +void SemanticAnalyzer::removeUnreachableInBlock(AST::Block* b) { + if (!b) return; + std::vector newstmts; + bool seenReturn = false; + for (auto* s : b->stmts) { + if (seenReturn) { + // unreachable: free s + delete s; + continue; + } + newstmts.push_back(s); + if (dynamic_cast(s)) seenReturn = true; + // if we simplified an if into block that contains return at end, this will handle later + } + b->stmts = std::move(newstmts); +} diff --git a/semantic.hpp b/semantic.hpp new file mode 100644 index 0000000..5c9a183 --- /dev/null +++ b/semantic.hpp @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include +#include "ast.hpp" + +struct SemanticResult { + bool ok; + std::vector errors; + void addError(const std::string& s) { errors.push_back(s); ok = false; } + SemanticResult() : ok(true) {} +}; + +class SemanticAnalyzer { +public: + SemanticAnalyzer(); + SemanticResult analyze(AST::Program* p); + +private: + // class name -> pointer + std::unordered_map classes; + + // state while traversing + AST::ClassDecl* curClass = nullptr; + AST::MethodDecl* curMethod = nullptr; + + // locals: name -> type + std::vector> localsStack; + + SemanticResult result; + + // helpers + void indexClasses(AST::Program* p); + void analyzeClass(AST::ClassDecl* c); + void analyzeMethod(AST::MethodDecl* m); + void analyzeBlock(AST::Block* b); + void analyzeStmt(AST::Stmt*& s); + void analyzeExpr(AST::Expr*& e); + + // optimizations + bool foldConstantsInExpr(AST::Expr*& e); // returns true if replaced/changed + void simplifyIf(AST::Stmt*& s); + void removeUnreachableInBlock(AST::Block* b); + + // types + std::string typeOfExpr(AST::Expr* e); + bool isLiteral(AST::Expr* e); + void pushScope(); + void popScope(); + void declareLocal(const std::string& name, const std::string& type); + + // utilities + std::string curPos(AST::Node* n); +}; diff --git a/tests/test3.o b/tests/test3.o index d1cdeed..163be32 100644 --- a/tests/test3.o +++ b/tests/test3.o @@ -1,7 +1,7 @@ -class Main is - method Run() : Int => - if true then - return 42 - else - return 0 -end +class Main is + method Run() : Int => + if true then + return 42 + else + return 0 +end \ No newline at end of file From 4099cd3ff8e1ffb42bcd65f536c9f675d250c65b Mon Sep 17 00:00:00 2001 From: dorley174 Date: Wed, 19 Nov 2025 18:51:06 +0300 Subject: [PATCH 4/6] added inter v1.0 --- Makefile | 4 +- interpreter.cpp | 249 ++++++++++++++++++++++++++++++++++++++++++++++++ interpreter.hpp | 79 +++++++++++++++ main.cpp | 10 +- parser.y | 68 +++++++++++-- semantic.cpp | 16 +++- semantic.hpp | 11 +-- 7 files changed, 409 insertions(+), 28 deletions(-) create mode 100644 interpreter.cpp create mode 100644 interpreter.hpp diff --git a/Makefile b/Makefile index 40c0c3c..e6ea536 100644 --- a/Makefile +++ b/Makefile @@ -9,8 +9,8 @@ parser.cpp parser.hpp: parser.y lexer.cpp: lexer.l parser.hpp flex -o lexer.cpp lexer.l -mycompiler: parser.cpp lexer.cpp main.cpp semantic.cpp - $(CXX) $(CXXFLAGS) -o $@ parser.cpp lexer.cpp main.cpp semantic.cpp -lfl +mycompiler: parser.cpp lexer.cpp main.cpp semantic.cpp interpreter.cpp + $(CXX) $(CXXFLAGS) -o $@ parser.cpp lexer.cpp main.cpp semantic.cpp interpreter.cpp -lfl clean: rm -f parser.cpp parser.hpp lexer.cpp mycompiler diff --git a/interpreter.cpp b/interpreter.cpp new file mode 100644 index 0000000..a814245 --- /dev/null +++ b/interpreter.cpp @@ -0,0 +1,249 @@ +#include "interpreter.hpp" +#include + +Interpreter::Interpreter(AST::Program* p) : program(p), mainInstance(nullptr) { + indexClasses(); +} + +void Interpreter::indexClasses() { + classes.clear(); + for (auto* c : program->classes) { + classes[c->name] = c; + } +} + +Value Interpreter::defaultValueForType(const std::string& typeName) { + if (typeName == "Int") return Value::makeInt(0); + if (typeName == "Bool") return Value::makeBool(false); + if (typeName == "String") return Value::makeString(""); + return Value::makeVoid(); +} + +AST::MethodDecl* Interpreter::findMethod(AST::ClassDecl* c, const std::string& name) { + for (auto* m : c->methods) { + if (m->name == name) return m; + } + return nullptr; +} + +Value Interpreter::evalExpr(AST::Expr* e, Frame& frame) { + if (!e) return Value::makeVoid(); + + if (auto* il = dynamic_cast(e)) { + return Value::makeInt(il->value); + } + if (auto* sl = dynamic_cast(e)) { + return Value::makeString(sl->value); + } + if (auto* bl = dynamic_cast(e)) { + return Value::makeBool(bl->value); + } + if (auto* id = dynamic_cast(e)) { + auto it = frame.locals.find(id->name); + if (it != frame.locals.end()) return it->second; + if (frame.self) { + auto fit = frame.self->fields.find(id->name); + if (fit != frame.self->fields.end()) return fit->second; + } + return Value::makeVoid(); + } + if (auto* bin = dynamic_cast(e)) { + if (bin->op == AST::BinOp::Assign) { + Value rv = evalExpr(bin->rhs, frame); + if (auto* lid = dynamic_cast(bin->lhs)) { + auto it = frame.locals.find(lid->name); + if (it != frame.locals.end()) { + it->second = rv; + return rv; + } + if (frame.self) { + auto fit = frame.self->fields.find(lid->name); + if (fit != frame.self->fields.end()) { + fit->second = rv; + return rv; + } + frame.self->fields[lid->name] = rv; + return rv; + } + frame.locals[lid->name] = rv; + return rv; + } + return rv; + } + Value lv = evalExpr(bin->lhs, frame); + Value rv = evalExpr(bin->rhs, frame); + if (bin->op == AST::BinOp::Add && lv.type == Value::Type::Int && rv.type == Value::Type::Int) { + return Value::makeInt(lv.i + rv.i); + } + if (bin->op == AST::BinOp::Sub && lv.type == Value::Type::Int && rv.type == Value::Type::Int) { + return Value::makeInt(lv.i - rv.i); + } + if (bin->op == AST::BinOp::Mul && lv.type == Value::Type::Int && rv.type == Value::Type::Int) { + return Value::makeInt(lv.i * rv.i); + } + if (bin->op == AST::BinOp::Div && lv.type == Value::Type::Int && rv.type == Value::Type::Int) { + if (rv.i == 0) return Value::makeInt(0); + return Value::makeInt(lv.i / rv.i); + } + if (bin->op == AST::BinOp::Gt && lv.type == Value::Type::Int && rv.type == Value::Type::Int) { + return Value::makeBool(lv.i > rv.i); + } + if (bin->op == AST::BinOp::Lt && lv.type == Value::Type::Int && rv.type == Value::Type::Int) { + return Value::makeBool(lv.i < rv.i); + } + if (bin->op == AST::BinOp::Eq) { + if (lv.type == rv.type) { + if (lv.type == Value::Type::Int) return Value::makeBool(lv.i == rv.i); + if (lv.type == Value::Type::Bool) return Value::makeBool(lv.b == rv.b); + if (lv.type == Value::Type::String) return Value::makeBool(lv.s == rv.s); + } + return Value::makeBool(false); + } + return Value::makeVoid(); + } + if (auto* un = dynamic_cast(e)) { + Value rv = evalExpr(un->rhs, frame); + if (un->op == AST::Unary::Op::Neg && rv.type == Value::Type::Int) { + return Value::makeInt(-rv.i); + } + return Value::makeVoid(); + } + if (auto* call = dynamic_cast(e)) { + if (auto* id = dynamic_cast(call->callee)) { + if (id->name == "output" || id->name == "print") { + std::vector args; + for (auto* a : call->args) args.push_back(evalExpr(a, frame)); + for (size_t i = 0; i < args.size(); ++i) { + if (i > 0) std::cout << " "; + std::cout << args[i].toString(); + } + std::cout << std::endl; + return Value::makeVoid(); + } + if (frame.self && frame.self->cls) { + AST::MethodDecl* m = findMethod(frame.self->cls, id->name); + if (m) { + std::vector args; + for (auto* a : call->args) args.push_back(evalExpr(a, frame)); + return callMethod(frame.self, m, args); + } + } + return Value::makeVoid(); + } + return Value::makeVoid(); + } + if (auto* ma = dynamic_cast(e)) { + Value obj = evalExpr(ma->object, frame); + return Value::makeVoid(); + } + if (auto* idx = dynamic_cast(e)) { + Value base = evalExpr(idx->base, frame); + Value ind = evalExpr(idx->index, frame); + return Value::makeVoid(); + } + return Value::makeVoid(); +} + +void Interpreter::execBlock(AST::Block* b, Frame& frame, bool& returned, Value& retVal) { + if (!b) return; + for (auto* s : b->stmts) { + if (returned) return; + execStmt(s, frame, returned, retVal); + } +} + +void Interpreter::execStmt(AST::Stmt* s, Frame& frame, bool& returned, Value& retVal) { + if (!s || returned) return; + + if (auto* ifs = dynamic_cast(s)) { + Value cv = evalExpr(ifs->cond, frame); + bool cond = false; + if (cv.type == Value::Type::Bool) cond = cv.b; + if (cond) { + execStmt(ifs->thenS, frame, returned, retVal); + } else { + execStmt(ifs->elseS, frame, returned, retVal); + } + return; + } + if (auto* w = dynamic_cast(s)) { + while (!returned) { + Value cv = evalExpr(w->cond, frame); + bool cond = false; + if (cv.type == Value::Type::Bool) cond = cv.b; + if (!cond) break; + if (auto* blk = dynamic_cast(w->body)) { + execBlock(blk, frame, returned, retVal); + } else { + execStmt(w->body, frame, returned, retVal); + } + } + return; + } + if (auto* ret = dynamic_cast(s)) { + retVal = evalExpr(ret->value, frame); + returned = true; + return; + } + if (auto* es = dynamic_cast(s)) { + evalExpr(es->expr, frame); + return; + } + if (auto* vds = dynamic_cast(s)) { + if (vds->decl) { + Value v; + if (vds->decl->init) v = evalExpr(vds->decl->init, frame); + else v = defaultValueForType(vds->decl->typeName); + frame.locals[vds->decl->name] = v; + } + return; + } + if (auto* blk = dynamic_cast(s)) { + execBlock(blk, frame, returned, retVal); + return; + } +} + +Value Interpreter::callMethod(Instance* inst, AST::MethodDecl* m, const std::vector& args) { + Frame f; + f.self = inst; + for (size_t i = 0; i < m->params.size() && i < args.size(); ++i) { + f.locals[m->params[i]->name] = args[i]; + } + bool returned = false; + Value ret = Value::makeVoid(); + if (auto* blk = dynamic_cast(m->body)) { + execBlock(blk, f, returned, ret); + } else { + execStmt(m->body, f, returned, ret); + } + return ret; +} + +void Interpreter::run() { + auto it = classes.find("Main"); + if (it == classes.end()) return; + AST::ClassDecl* mainClass = it->second; + mainInstance = new Instance(mainClass); + for (auto* f : mainClass->fields) { + mainInstance->fields[f->name] = defaultValueForType(f->typeName); + } + Frame fieldFrame; + fieldFrame.self = mainInstance; + for (auto* f : mainClass->fields) { + if (f->init) { + Value v = evalExpr(f->init, fieldFrame); + mainInstance->fields[f->name] = v; + } + } + AST::MethodDecl* mainMethod = findMethod(mainClass, "main"); + if (!mainMethod) { + delete mainInstance; + mainInstance = nullptr; + return; + } + std::vector args; + callMethod(mainInstance, mainMethod, args); + delete mainInstance; + mainInstance = nullptr; +} diff --git a/interpreter.hpp b/interpreter.hpp new file mode 100644 index 0000000..1ff97e5 --- /dev/null +++ b/interpreter.hpp @@ -0,0 +1,79 @@ +#pragma once +#include "ast.hpp" +#include +#include +#include +#include + +struct Value { + enum class Type { Int, Bool, String, Void }; + Type type; + std::int64_t i; + bool b; + std::string s; + + Value() : type(Type::Void), i(0), b(false) {} + + static Value makeInt(std::int64_t v) { + Value r; + r.type = Type::Int; + r.i = v; + return r; + } + + static Value makeBool(bool v) { + Value r; + r.type = Type::Bool; + r.b = v; + return r; + } + + static Value makeString(const std::string& v) { + Value r; + r.type = Type::String; + r.s = v; + return r; + } + + static Value makeVoid() { + return Value(); + } + + std::string toString() const { + if (type == Type::Int) return std::to_string(i); + if (type == Type::Bool) return b ? "true" : "false"; + if (type == Type::String) return s; + return ""; + } +}; + +class Interpreter { +public: + explicit Interpreter(AST::Program* p); + void run(); + +private: + struct Instance { + AST::ClassDecl* cls; + std::unordered_map fields; + explicit Instance(AST::ClassDecl* c) : cls(c) {} + }; + + struct Frame { + Instance* self; + std::unordered_map locals; + Frame() : self(nullptr) {} + }; + + AST::Program* program; + std::unordered_map classes; + Instance* mainInstance; + + void indexClasses(); + Value evalExpr(AST::Expr* e, Frame& frame); + void execStmt(AST::Stmt* s, Frame& frame, bool& returned, Value& retVal); + void execBlock(AST::Block* b, Frame& frame, bool& returned, Value& retVal); + AST::MethodDecl* findMethod(AST::ClassDecl* c, const std::string& name); + Value callMethod(Instance* inst, AST::MethodDecl* m, const std::vector& args); + Value defaultValueForType(const std::string& typeName); +}; diff --git a/main.cpp b/main.cpp index 07c691d..661c5bb 100644 --- a/main.cpp +++ b/main.cpp @@ -2,7 +2,8 @@ #include #include "ast.hpp" #include "tokens.hpp" -#include "semantic.hpp" // добавлено +#include "semantic.hpp" +#include "interpreter.hpp" extern int yyparse(void); extern FILE* yyin; @@ -34,7 +35,6 @@ int main(int argc, char** argv) { return 2; } - // === SEMANTIC ANALYSIS === std::cout << "\n=== Semantic Analysis ===\n"; SemanticAnalyzer analyzer; auto res = analyzer.analyze(g_program); @@ -60,9 +60,13 @@ int main(int argc, char** argv) { } } - // === PRINT FINAL AST === std::cout << "\n=== Final AST (After Semantic Analysis) ===\n"; g_program->print(std::cout); + + std::cout << "\n=== Interpretation ===\n"; + Interpreter interp(g_program); + interp.run(); + delete g_program; g_program = nullptr; return 0; diff --git a/parser.y b/parser.y index bfca388..f2dae88 100644 --- a/parser.y +++ b/parser.y @@ -67,8 +67,8 @@ AST::Program* g_program = nullptr; %type opt_params param_list %type param %type type_spec type_list -%type method_body stmt simple_stmt if_stmt while_stmt -%type stmt_list +%type method_body stmt simple_stmt if_stmt while_stmt opt_else +%type stmt_list elseif_list %type expr assign_expr equality_expr relational_expr additive_expr multiplicative_expr unary_expr postfix_expr primary_expr lvalue type_as_expr %type arg_list opt_args @@ -88,8 +88,13 @@ class_decl : CLASS IDENTIFIER IS class_body END { $$ = new AST::ClassDecl($2); - for (auto* n : *$4) { if (auto* v = dynamic_cast(n)) $$->fields.push_back(v); else if (auto* m = dynamic_cast(n)) $$->methods.push_back(m); else delete n; } - free($2); delete $4; + for (auto* n : *$4) { + if (auto* v = dynamic_cast(n)) $$->fields.push_back(v); + else if (auto* m = dynamic_cast(n)) $$->methods.push_back(m); + else delete n; + } + free($2); + delete $4; } ; @@ -115,7 +120,8 @@ type_spec { std::string s = std::string($1) + "<" + std::string($3) + ">"; $$ = strdup(s.c_str()); - free($1); free($3); + free($1); + free($3); } ; @@ -126,7 +132,8 @@ type_list { std::string s = std::string($1) + "," + std::string($3); $$ = strdup(s.c_str()); - free($1); free($3); + free($1); + free($3); } ; @@ -143,8 +150,12 @@ method_decl : METHOD IDENTIFIER LPAREN opt_params RPAREN COLON type_spec ARROW method_body { $$ = new AST::MethodDecl($2, $7, $9); - if ($4) { for (auto* p : *$4) $$->params.push_back(p); delete $4; } - free($2); free($7); + if ($4) { + for (auto* p : *$4) $$->params.push_back(p); + delete $4; + } + free($2); + free($7); } ; @@ -198,8 +209,45 @@ simple_stmt ; if_stmt - : IF expr THEN stmt ELSE stmt END - { $$ = new AST::IfStmt($2, $4, $6); } + : IF expr THEN stmt END + { + $$ = new AST::IfStmt($2, $4, new AST::Block()); + } + | IF expr THEN stmt ELSE stmt END + { + $$ = new AST::IfStmt($2, $4, $6); + } + | IF expr THEN stmt elseif_list opt_else END + { + AST::Stmt* tail = $6 ? $6 : static_cast(new AST::Block()); + for (auto it = $5->rbegin(); it != $5->rend(); ++it) { + auto* ifs = dynamic_cast(*it); + if (ifs) { + ifs->elseS = tail; + tail = ifs; + } + } + delete $5; + $$ = new AST::IfStmt($2, $4, tail); + } + ; + +opt_else + : ELSE stmt { $$ = $2; } + | { $$ = nullptr; } + ; + +elseif_list + : elseif_list ELSE IF expr THEN stmt + { + $$ = $1; + $$->push_back(new AST::IfStmt($4, $6, new AST::Block())); + } + | ELSE IF expr THEN stmt + { + $$ = new std::vector(); + $$->push_back(new AST::IfStmt($3, $5, new AST::Block())); + } ; while_stmt diff --git a/semantic.cpp b/semantic.cpp index 0ddcfe7..4c05ab2 100644 --- a/semantic.cpp +++ b/semantic.cpp @@ -143,8 +143,11 @@ std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { } } if (auto* call = dynamic_cast(e)) { - // if callee is identifier, check method existence in current class if (auto* id = dynamic_cast(call->callee)) { + if (id->name == "output" || id->name == "print") { + for (auto* a : call->args) typeOfExpr(a); + return ""; + } auto it = classes.find(curClass->name); if (it != classes.end()) { bool found = false; @@ -155,11 +158,11 @@ std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { result.addError("Call to undeclared method '" + id->name + "' in class '" + curClass->name + "'"); } } - // we don't know return type, return empty return ""; } return ""; } + if (auto* ma = dynamic_cast(e)) { // try to deduce member type if object has class and field exists (simple) if (auto* objid = dynamic_cast(ma->object)) { @@ -285,10 +288,12 @@ void SemanticAnalyzer::analyzeExpr(AST::Expr*& e) { analyzeExpr(un->rhs); return; } - if (auto* call = dynamic_cast(e)) { - // check callee + if (auto* call = dynamic_cast(e)) { if (auto* id = dynamic_cast(call->callee)) { - // check method exists in current class + if (id->name == "output" || id->name == "print") { + for (auto*& a : call->args) analyzeExpr(a); + return; + } bool found = false; for (auto* m : curClass->methods) if (m->name == id->name) { found = true; break; } if (!found) result.addError("Call to undeclared method '" + id->name + "'"); @@ -298,6 +303,7 @@ void SemanticAnalyzer::analyzeExpr(AST::Expr*& e) { for (auto*& a : call->args) analyzeExpr(a); return; } + if (auto* ma = dynamic_cast(e)) { analyzeExpr(ma->object); return; diff --git a/semantic.hpp b/semantic.hpp index 5c9a183..086d797 100644 --- a/semantic.hpp +++ b/semantic.hpp @@ -7,6 +7,8 @@ struct SemanticResult { bool ok; std::vector errors; + std::vector warnings; + std::vector optimizations; void addError(const std::string& s) { errors.push_back(s); ok = false; } SemanticResult() : ok(true) {} }; @@ -17,19 +19,15 @@ class SemanticAnalyzer { SemanticResult analyze(AST::Program* p); private: - // class name -> pointer std::unordered_map classes; - // state while traversing AST::ClassDecl* curClass = nullptr; AST::MethodDecl* curMethod = nullptr; - // locals: name -> type std::vector> localsStack; SemanticResult result; - // helpers void indexClasses(AST::Program* p); void analyzeClass(AST::ClassDecl* c); void analyzeMethod(AST::MethodDecl* m); @@ -37,18 +35,15 @@ class SemanticAnalyzer { void analyzeStmt(AST::Stmt*& s); void analyzeExpr(AST::Expr*& e); - // optimizations - bool foldConstantsInExpr(AST::Expr*& e); // returns true if replaced/changed + bool foldConstantsInExpr(AST::Expr*& e); void simplifyIf(AST::Stmt*& s); void removeUnreachableInBlock(AST::Block* b); - // types std::string typeOfExpr(AST::Expr* e); bool isLiteral(AST::Expr* e); void pushScope(); void popScope(); void declareLocal(const std::string& name, const std::string& type); - // utilities std::string curPos(AST::Node* n); }; From 808a70554075b0ddb2013c756ff040b3a2c09a5f Mon Sep 17 00:00:00 2001 From: dorley174 Date: Wed, 19 Nov 2025 21:26:36 +0300 Subject: [PATCH 5/6] huge changes for inter v1.1 --- lexer.cpp | 407 +++++++++++----------- lexer.l | 2 +- main.cpp | 43 ++- mycompiler | Bin 106568 -> 172664 bytes parser.cpp | 922 ++++++++++++++++++++++++++------------------------ parser.hpp | 107 +++--- parser.y | 59 ++-- tests/test.o | 21 ++ tests/test1.o | 11 +- tests/test2.o | 11 +- tests/test3.o | 17 +- tests/test4.o | 11 + tests/test5.o | 7 + tokens.hpp | 3 +- 14 files changed, 875 insertions(+), 746 deletions(-) create mode 100644 tests/test.o create mode 100644 tests/test4.o create mode 100644 tests/test5.o diff --git a/lexer.cpp b/lexer.cpp index 90c144f..3000dd2 100644 --- a/lexer.cpp +++ b/lexer.cpp @@ -374,8 +374,8 @@ static void yynoreturn yy_fatal_error ( const char* msg ); (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 46 -#define YY_END_OF_BUFFER 47 +#define YY_NUM_RULES 47 +#define YY_END_OF_BUFFER 48 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -383,20 +383,21 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[109] = +static const flex_int16_t yy_accept[112] = { 0, - 0, 0, 47, 45, 43, 44, 45, 28, 29, 37, - 35, 27, 36, 39, 38, 21, 25, 26, 41, 34, - 40, 20, 20, 20, 20, 20, 20, 32, 33, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 30, - 31, 43, 0, 19, 0, 42, 21, 22, 24, 23, - 20, 20, 20, 20, 20, 20, 20, 11, 20, 20, - 20, 7, 3, 20, 20, 20, 20, 20, 20, 42, - 20, 20, 14, 20, 20, 20, 20, 4, 20, 20, - 20, 20, 20, 2, 20, 16, 20, 20, 18, 20, - 9, 20, 20, 20, 8, 12, 20, 17, 20, 1, - - 13, 20, 20, 10, 15, 5, 6, 0 + 0, 0, 48, 46, 44, 45, 46, 29, 30, 38, + 36, 28, 37, 40, 39, 22, 26, 27, 42, 35, + 41, 21, 21, 21, 21, 21, 21, 33, 34, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 31, + 32, 44, 0, 20, 0, 43, 22, 23, 25, 24, + 21, 21, 21, 21, 21, 21, 21, 12, 21, 21, + 21, 8, 4, 21, 21, 21, 21, 21, 21, 43, + 21, 21, 15, 21, 21, 21, 21, 5, 21, 21, + 21, 21, 21, 3, 21, 17, 21, 21, 19, 21, + 10, 21, 21, 21, 9, 13, 21, 18, 21, 2, + + 0, 14, 21, 21, 11, 16, 0, 6, 7, 1, + 0 } ; static const YY_CHAR yy_ec[256] = @@ -440,90 +441,92 @@ static const YY_CHAR yy_meta[48] = 3, 3, 3, 3, 3, 1, 1 } ; -static const flex_int16_t yy_base[112] = +static const flex_int16_t yy_base[115] = { 0, - 0, 0, 122, 123, 119, 123, 44, 123, 123, 123, - 123, 123, 123, 123, 108, 106, 101, 123, 123, 32, - 123, 0, 78, 80, 77, 72, 74, 123, 123, 76, - 72, 15, 82, 20, 78, 77, 20, 79, 72, 123, - 123, 103, 51, 123, 101, 0, 90, 123, 123, 123, - 0, 63, 62, 58, 59, 63, 69, 0, 55, 65, - 58, 0, 0, 51, 50, 60, 47, 49, 53, 0, - 51, 58, 0, 50, 54, 41, 45, 0, 34, 40, - 30, 34, 40, 0, 33, 0, 26, 29, 0, 25, - 0, 34, 25, 23, 0, 0, 31, 0, 26, 0, - - 0, 28, 19, 0, 0, 0, 0, 123, 77, 53, - 80 + 0, 0, 128, 129, 125, 129, 44, 129, 129, 129, + 129, 129, 129, 129, 114, 112, 107, 129, 129, 32, + 129, 0, 84, 86, 83, 78, 80, 129, 129, 82, + 78, 15, 88, 20, 84, 83, 20, 85, 78, 129, + 129, 109, 51, 129, 107, 0, 96, 129, 129, 129, + 0, 69, 68, 64, 65, 69, 75, 0, 61, 71, + 64, 0, 0, 57, 56, 65, 47, 49, 53, 0, + 51, 58, 0, 50, 54, 42, 51, 0, 40, 46, + 36, 40, 45, 0, 39, 0, 32, 35, 0, 31, + 54, 40, 30, 28, 0, 0, 36, 0, 33, 0, + + 56, 0, 35, 26, 0, 0, 31, 0, 0, 129, + 129, 91, 59, 94 } ; -static const flex_int16_t yy_def[112] = +static const flex_int16_t yy_def[115] = { 0, - 108, 1, 108, 108, 108, 108, 109, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 110, 110, 110, 110, 110, 110, 108, 108, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 108, - 108, 108, 109, 108, 109, 111, 108, 108, 108, 108, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - - 110, 110, 110, 110, 110, 110, 110, 0, 108, 108, - 108 + 111, 1, 111, 111, 111, 111, 112, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 113, 113, 113, 113, 113, 113, 111, 111, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 111, + 111, 111, 112, 111, 112, 114, 111, 111, 111, 111, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 114, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + + 111, 113, 113, 113, 113, 113, 111, 113, 113, 111, + 0, 111, 111, 111 } ; -static const flex_int16_t yy_nxt[171] = +static const flex_int16_t yy_nxt[177] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 4, 29, 22, 30, 31, 32, 33, 22, 22, 34, 22, 35, 22, 22, 36, 22, 37, 22, 38, 39, 40, 41, 44, 49, 50, - 59, 62, 60, 66, 44, 51, 107, 106, 105, 67, - 63, 104, 103, 102, 101, 100, 99, 98, 97, 45, - 96, 95, 94, 93, 92, 91, 45, 43, 43, 43, - 70, 90, 70, 89, 88, 87, 86, 85, 84, 83, - 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, - - 72, 71, 47, 108, 42, 69, 68, 65, 64, 61, - 58, 57, 56, 55, 54, 53, 52, 48, 47, 46, - 42, 108, 3, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108 + 59, 62, 60, 66, 44, 101, 101, 101, 101, 67, + 63, 51, 110, 109, 108, 106, 105, 104, 103, 45, + 102, 100, 99, 98, 97, 96, 45, 95, 94, 93, + 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, + 107, 43, 43, 43, 70, 82, 70, 81, 80, 79, + + 78, 77, 76, 75, 74, 73, 72, 71, 47, 111, + 42, 69, 68, 65, 64, 61, 58, 57, 56, 55, + 54, 53, 52, 48, 47, 46, 42, 111, 3, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111 } ; -static const flex_int16_t yy_chk[171] = +static const flex_int16_t yy_chk[177] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 20, 20, - 32, 34, 32, 37, 43, 110, 103, 102, 99, 37, - 34, 97, 94, 93, 92, 90, 88, 87, 85, 7, - 83, 82, 81, 80, 79, 77, 43, 109, 109, 109, - 111, 76, 111, 75, 74, 72, 71, 69, 68, 67, - 66, 65, 64, 61, 60, 59, 57, 56, 55, 54, - - 53, 52, 47, 45, 42, 39, 38, 36, 35, 33, - 31, 30, 27, 26, 25, 24, 23, 17, 16, 15, - 5, 3, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108 + 32, 34, 32, 37, 43, 91, 91, 101, 101, 37, + 34, 113, 107, 104, 103, 99, 97, 94, 93, 7, + 92, 90, 88, 87, 85, 83, 43, 82, 81, 80, + 79, 77, 76, 75, 74, 72, 71, 69, 68, 67, + 101, 112, 112, 112, 114, 66, 114, 65, 64, 61, + + 60, 59, 57, 56, 55, 54, 53, 52, 47, 45, + 42, 39, 38, 36, 35, 33, 31, 30, 27, 26, + 25, 24, 23, 17, 16, 15, 5, 3, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111 } ; /* Table of booleans, true if rule could match eol. */ -static const flex_int32_t yy_rule_can_match_eol[47] = +static const flex_int32_t yy_rule_can_match_eol[48] = { 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, }; +1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, }; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; @@ -541,27 +544,27 @@ int yy_flex_debug = 0; char *yytext; #line 1 "lexer.l" #line 2 "lexer.l" -#include -#include -#include -#include -#include -#include "parser.hpp" -#include "tokens.hpp" - -int yycolumn = 1; -extern int yylineno; - -static int expectClassName = 0; -static int expectMethodName = 0; -static int expectVarName = 0; -static int expectMemberName = 0; - -static inline void push_kw(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; } -static inline void push_sym(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; } -static inline int is_upper(const char* s) { return std::isupper((unsigned char)s[0]); } -#line 564 "lexer.cpp" -#line 565 "lexer.cpp" +#include +#include +#include +#include +#include +#include "parser.hpp" +#include "tokens.hpp" + +int yycolumn = 1; +extern int yylineno; + +static int expectClassName = 0; +static int expectMethodName = 0; +static int expectVarName = 0; +static int expectMemberName = 0; + +static inline void push_kw(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; } +static inline void push_sym(TokenKind k, const char* text) { EmitToken(std::make_unique(k, text, yylineno, yycolumn)); yycolumn += yyleng; } +static inline int is_upper(const char* s) { return std::isupper((unsigned char)s[0]); } +#line 567 "lexer.cpp" +#line 568 "lexer.cpp" #define INITIAL 0 @@ -780,8 +783,8 @@ YY_DECL { #line 33 "lexer.l" - -#line 785 "lexer.cpp" + +#line 788 "lexer.cpp" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -808,13 +811,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 109 ) + if ( yy_current_state >= 112 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 123 ); + while ( yy_base[yy_current_state] != 129 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -849,245 +852,251 @@ YY_DECL goto yy_find_action; case 1: +/* rule 1 can match eol */ YY_RULE_SETUP #line 35 "lexer.l" -{ push_kw(TokenKind::CLASS, yytext); expectClassName = 1; return CLASS; } +{ push_kw(TokenKind::ELSEIF, yytext); return ELSEIF; } YY_BREAK case 2: YY_RULE_SETUP #line 36 "lexer.l" -{ push_kw(TokenKind::VAR, yytext); expectVarName = 1; return VAR; } +{ push_kw(TokenKind::CLASS, yytext); expectClassName = 1; return CLASS; } YY_BREAK case 3: YY_RULE_SETUP #line 37 "lexer.l" -{ push_kw(TokenKind::IS, yytext); return IS; } +{ push_kw(TokenKind::VAR, yytext); expectVarName = 1; return VAR; } YY_BREAK case 4: YY_RULE_SETUP #line 38 "lexer.l" -{ push_kw(TokenKind::END, yytext); return END; } +{ push_kw(TokenKind::IS, yytext); return IS; } YY_BREAK case 5: YY_RULE_SETUP -#line 40 "lexer.l" -{ push_kw(TokenKind::METHOD, yytext); expectMethodName = 1; return METHOD; } +#line 39 "lexer.l" +{ push_kw(TokenKind::END, yytext); return END; } YY_BREAK case 6: YY_RULE_SETUP -#line 41 "lexer.l" -{ push_kw(TokenKind::RETURN, yytext); return RETURN; } +#line 40 "lexer.l" +{ push_kw(TokenKind::METHOD, yytext); expectMethodName = 1; return METHOD; } YY_BREAK case 7: YY_RULE_SETUP -#line 42 "lexer.l" -{ push_kw(TokenKind::IF, yytext); return IF; } +#line 41 "lexer.l" +{ push_kw(TokenKind::RETURN, yytext); return RETURN; } YY_BREAK case 8: YY_RULE_SETUP -#line 43 "lexer.l" -{ push_kw(TokenKind::THEN, yytext); return THEN; } +#line 42 "lexer.l" +{ push_kw(TokenKind::IF, yytext); return IF; } YY_BREAK case 9: YY_RULE_SETUP -#line 44 "lexer.l" -{ push_kw(TokenKind::ELSE, yytext); return ELSE; } +#line 43 "lexer.l" +{ push_kw(TokenKind::THEN, yytext); return THEN; } YY_BREAK case 10: YY_RULE_SETUP -#line 45 "lexer.l" -{ push_kw(TokenKind::WHILE, yytext); return WHILE; } +#line 44 "lexer.l" +{ push_kw(TokenKind::ELSE, yytext); return ELSE; } YY_BREAK case 11: YY_RULE_SETUP -#line 46 "lexer.l" -{ push_kw(TokenKind::DO, yytext); return DO; } +#line 45 "lexer.l" +{ push_kw(TokenKind::WHILE, yytext); return WHILE; } YY_BREAK case 12: YY_RULE_SETUP -#line 47 "lexer.l" -{ push_kw(TokenKind::TRUEKW, yytext); return TRUE; } +#line 46 "lexer.l" +{ push_kw(TokenKind::DO, yytext); return DO; } YY_BREAK case 13: YY_RULE_SETUP -#line 48 "lexer.l" -{ push_kw(TokenKind::FALSEKW, yytext); return FALSE; } +#line 47 "lexer.l" +{ push_kw(TokenKind::TRUEKW, yytext); return TRUE; } YY_BREAK case 14: YY_RULE_SETUP -#line 50 "lexer.l" -{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +#line 48 "lexer.l" +{ push_kw(TokenKind::FALSEKW, yytext); return FALSE; } YY_BREAK case 15: YY_RULE_SETUP -#line 51 "lexer.l" -{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +#line 50 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } YY_BREAK case 16: YY_RULE_SETUP -#line 52 "lexer.l" -{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +#line 51 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } YY_BREAK case 17: YY_RULE_SETUP -#line 53 "lexer.l" -{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +#line 52 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } YY_BREAK case 18: YY_RULE_SETUP -#line 54 "lexer.l" -{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } +#line 53 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } YY_BREAK case 19: -/* rule 19 can match eol */ YY_RULE_SETUP -#line 56 "lexer.l" -{ std::string s(yytext); EmitToken(std::make_unique(yytext, s, yylineno, yycolumn)); yylval.cstr = strdup(s.c_str()); yycolumn += yyleng; return STRING_LITERAL; } +#line 54 "lexer.l" +{ EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } YY_BREAK case 20: +/* rule 20 can match eol */ YY_RULE_SETUP -#line 58 "lexer.l" -{ - if (expectClassName) { expectClassName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } - if (expectMethodName) { expectMethodName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } - if (expectVarName) { expectVarName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } - if (expectMemberName) { expectMemberName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } - if (is_upper(yytext)) { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } - EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; - } +#line 56 "lexer.l" +{ std::string s(yytext); EmitToken(std::make_unique(yytext, s, yylineno, yycolumn)); yylval.cstr = strdup(s.c_str()); yycolumn += yyleng; return STRING_LITERAL; } YY_BREAK case 21: YY_RULE_SETUP -#line 67 "lexer.l" -{ long long v = atoll(yytext); EmitToken(std::make_unique(yytext, v, yylineno, yycolumn)); yylval.ival = v; yycolumn += yyleng; return INT_LITERAL; } +#line 58 "lexer.l" +{ + if (expectClassName) { expectClassName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (expectMethodName) { expectMethodName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (expectVarName) { expectVarName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (expectMemberName) { expectMemberName = 0; EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; } + if (is_upper(yytext)) { EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return TYPE_NAME; } + EmitToken(std::make_unique(yytext, yylineno, yycolumn)); yylval.cstr = strdup(yytext); yycolumn += yyleng; return IDENTIFIER; + } YY_BREAK case 22: YY_RULE_SETUP -#line 69 "lexer.l" -{ push_sym(TokenKind::ASSIGN, yytext); return ASSIGN; } +#line 67 "lexer.l" +{ long long v = atoll(yytext); EmitToken(std::make_unique(yytext, v, yylineno, yycolumn)); yylval.ival = v; yycolumn += yyleng; return INT_LITERAL; } YY_BREAK case 23: YY_RULE_SETUP -#line 70 "lexer.l" -{ push_sym(TokenKind::ARROW, yytext); return ARROW; } +#line 69 "lexer.l" +{ push_sym(TokenKind::ASSIGN, yytext); return ASSIGN; } YY_BREAK case 24: YY_RULE_SETUP -#line 71 "lexer.l" -{ push_sym(TokenKind::EQEQ, yytext); return EQEQ; } +#line 70 "lexer.l" +{ push_sym(TokenKind::ARROW, yytext); return ARROW; } YY_BREAK case 25: YY_RULE_SETUP -#line 72 "lexer.l" -{ push_sym(TokenKind::COLON, yytext); return COLON; } +#line 71 "lexer.l" +{ push_sym(TokenKind::EQEQ, yytext); return EQEQ; } YY_BREAK case 26: YY_RULE_SETUP -#line 73 "lexer.l" -{ push_sym(TokenKind::SEMICOLON, yytext); return SEMICOLON; } +#line 72 "lexer.l" +{ push_sym(TokenKind::COLON, yytext); return COLON; } YY_BREAK case 27: YY_RULE_SETUP -#line 74 "lexer.l" -{ push_sym(TokenKind::COMMA, yytext); return COMMA; } +#line 73 "lexer.l" +{ push_sym(TokenKind::SEMICOLON, yytext); return SEMICOLON; } YY_BREAK case 28: YY_RULE_SETUP -#line 75 "lexer.l" -{ push_sym(TokenKind::LPAREN, yytext); return LPAREN; } +#line 74 "lexer.l" +{ push_sym(TokenKind::COMMA, yytext); return COMMA; } YY_BREAK case 29: YY_RULE_SETUP -#line 76 "lexer.l" -{ push_sym(TokenKind::RPAREN, yytext); return RPAREN; } +#line 75 "lexer.l" +{ push_sym(TokenKind::LPAREN, yytext); return LPAREN; } YY_BREAK case 30: YY_RULE_SETUP -#line 77 "lexer.l" -{ push_sym(TokenKind::LBRACE, yytext); return LBRACE; } +#line 76 "lexer.l" +{ push_sym(TokenKind::RPAREN, yytext); return RPAREN; } YY_BREAK case 31: YY_RULE_SETUP -#line 78 "lexer.l" -{ push_sym(TokenKind::RBRACE, yytext); return RBRACE; } +#line 77 "lexer.l" +{ push_sym(TokenKind::LBRACE, yytext); return LBRACE; } YY_BREAK case 32: YY_RULE_SETUP -#line 79 "lexer.l" -{ push_sym(TokenKind::LBRACKET, yytext); return LBRACKET; } +#line 78 "lexer.l" +{ push_sym(TokenKind::RBRACE, yytext); return RBRACE; } YY_BREAK case 33: YY_RULE_SETUP -#line 80 "lexer.l" -{ push_sym(TokenKind::RBRACKET, yytext); return RBRACKET; } +#line 79 "lexer.l" +{ push_sym(TokenKind::LBRACKET, yytext); return LBRACKET; } YY_BREAK case 34: YY_RULE_SETUP -#line 81 "lexer.l" -{ push_sym(TokenKind::EQUAL, yytext); return EQUAL; } +#line 80 "lexer.l" +{ push_sym(TokenKind::RBRACKET, yytext); return RBRACKET; } YY_BREAK case 35: YY_RULE_SETUP -#line 82 "lexer.l" -{ push_sym(TokenKind::PLUS, yytext); return PLUS; } +#line 81 "lexer.l" +{ push_sym(TokenKind::EQUAL, yytext); return EQUAL; } YY_BREAK case 36: YY_RULE_SETUP -#line 83 "lexer.l" -{ push_sym(TokenKind::MINUS, yytext); return MINUS; } +#line 82 "lexer.l" +{ push_sym(TokenKind::PLUS, yytext); return PLUS; } YY_BREAK case 37: YY_RULE_SETUP -#line 84 "lexer.l" -{ push_sym(TokenKind::STAR, yytext); return STAR; } +#line 83 "lexer.l" +{ push_sym(TokenKind::MINUS, yytext); return MINUS; } YY_BREAK case 38: YY_RULE_SETUP -#line 85 "lexer.l" -{ push_sym(TokenKind::SLASH, yytext); return SLASH; } +#line 84 "lexer.l" +{ push_sym(TokenKind::STAR, yytext); return STAR; } YY_BREAK case 39: YY_RULE_SETUP -#line 86 "lexer.l" -{ push_sym(TokenKind::DOT, yytext); expectMemberName = 1; return DOT; } +#line 85 "lexer.l" +{ push_sym(TokenKind::SLASH, yytext); return SLASH; } YY_BREAK case 40: YY_RULE_SETUP -#line 87 "lexer.l" -{ push_sym(TokenKind::GT, yytext); return GT; } +#line 86 "lexer.l" +{ push_sym(TokenKind::DOT, yytext); expectMemberName = 1; return DOT; } YY_BREAK case 41: YY_RULE_SETUP -#line 88 "lexer.l" -{ push_sym(TokenKind::LT, yytext); return LT; } +#line 87 "lexer.l" +{ push_sym(TokenKind::GT, yytext); return GT; } YY_BREAK case 42: YY_RULE_SETUP -#line 90 "lexer.l" -{ yycolumn += yyleng; } +#line 88 "lexer.l" +{ push_sym(TokenKind::LT, yytext); return LT; } YY_BREAK case 43: YY_RULE_SETUP -#line 91 "lexer.l" -{ yycolumn += yyleng; } +#line 90 "lexer.l" +{ yycolumn += yyleng; } YY_BREAK case 44: -/* rule 44 can match eol */ YY_RULE_SETUP -#line 92 "lexer.l" -{ yycolumn = 1; } +#line 91 "lexer.l" +{ yycolumn += yyleng; } YY_BREAK case 45: +/* rule 45 can match eol */ YY_RULE_SETUP -#line 94 "lexer.l" -{ std::fprintf(stderr, "Unknown char '%s' at %d:%d\n", yytext, yylineno, yycolumn); yycolumn += yyleng; } +#line 92 "lexer.l" +{ yycolumn = 1; } YY_BREAK case 46: YY_RULE_SETUP +#line 94 "lexer.l" +{ std::fprintf(stderr, "Unknown char '%s' at %d:%d\n", yytext, yylineno, yycolumn); yycolumn += yyleng; } + YY_BREAK +case 47: +YY_RULE_SETUP #line 96 "lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1091 "lexer.cpp" +#line 1100 "lexer.cpp" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1384,7 +1393,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 109 ) + if ( yy_current_state >= 112 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -1412,11 +1421,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 109 ) + if ( yy_current_state >= 112 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 108); + yy_is_jam = (yy_current_state == 111); return yy_is_jam ? 0 : yy_current_state; } diff --git a/lexer.l b/lexer.l index 227afe7..7d62480 100644 --- a/lexer.l +++ b/lexer.l @@ -32,11 +32,11 @@ WS [ \t\r]+ %% +"else"[ \t\r\n]+"if" { push_kw(TokenKind::ELSEIF, yytext); return ELSEIF; } "class" { push_kw(TokenKind::CLASS, yytext); expectClassName = 1; return CLASS; } "var" { push_kw(TokenKind::VAR, yytext); expectVarName = 1; return VAR; } "is" { push_kw(TokenKind::IS, yytext); return IS; } "end" { push_kw(TokenKind::END, yytext); return END; } - "method" { push_kw(TokenKind::METHOD, yytext); expectMethodName = 1; return METHOD; } "return" { push_kw(TokenKind::RETURN, yytext); return RETURN; } "if" { push_kw(TokenKind::IF, yytext); return IF; } diff --git a/main.cpp b/main.cpp index 661c5bb..94b00f9 100644 --- a/main.cpp +++ b/main.cpp @@ -15,6 +15,20 @@ int main(int argc, char** argv) { return 1; } + FILE* src = std::fopen(argv[1], "r"); + if (!src) { + std::perror("fopen"); + return 1; + } + + std::cout << "=== SOURCE ===\n"; + int ch; + while ((ch = std::fgetc(src)) != EOF) { + std::cout << static_cast(ch); + } + std::cout << "\n"; + std::fclose(src); + yyin = std::fopen(argv[1], "r"); if (!yyin) { std::perror("fopen"); @@ -37,26 +51,31 @@ int main(int argc, char** argv) { std::cout << "\n=== Semantic Analysis ===\n"; SemanticAnalyzer analyzer; - auto res = analyzer.analyze(g_program); + SemanticResult res = analyzer.analyze(g_program); if (!res.ok) { std::cerr << "Semantic errors found:\n"; - for (auto& e : res.errors) + for (const auto& e : res.errors) { std::cerr << " - " << e << "\n"; + } delete g_program; g_program = nullptr; return 3; - } else { - std::cout << "Semantic analysis completed successfully.\n"; - if (!res.warnings.empty()) { - std::cout << "Warnings:\n"; - for (auto& w : res.warnings) - std::cout << " - " << w << "\n"; + } + + std::cout << "Semantic analysis completed successfully.\n"; + + if (!res.warnings.empty()) { + std::cout << "Warnings:\n"; + for (const auto& w : res.warnings) { + std::cout << " - " << w << "\n"; } - if (!res.optimizations.empty()) { - std::cout << "Optimizations applied:\n"; - for (auto& o : res.optimizations) - std::cout << " * " << o << "\n"; + } + + if (!res.optimizations.empty()) { + std::cout << "Optimizations applied:\n"; + for (const auto& o : res.optimizations) { + std::cout << " * " << o << "\n"; } } diff --git a/mycompiler b/mycompiler index 7a85c1f017a3efbc7e37c06d4e3692d29ff00363..0f44f774bedb07aa0634b0cb9bc197deddd65121 100644 GIT binary patch literal 172664 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

8(=6hKDr!~Ftsf1FGr74YI#h8rB*G| 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%0AMvpX%7p#}CD( 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

~$dw^PDt$4k6`bG*Zi=@Vbz1s_0##C)xjxZ*x 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 R{ef*NJ$;Yed{}P9{{s;`4_W{K literal 106568 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 B0T}=Q diff --git a/parser.cpp b/parser.cpp index 5d3bc18..72197af 100644 --- a/parser.cpp +++ b/parser.cpp @@ -68,20 +68,20 @@ /* First part of user prologue. */ #line 1 "parser.y" - -#include -#include -#include -#include -#include -#include "ast.hpp" -#include "tokens.hpp" - -extern int yylex(void); -extern int yylineno; -void yyerror(const char* s); - -AST::Program* g_program = nullptr; + +#include +#include +#include +#include +#include +#include "ast.hpp" +#include "tokens.hpp" + +extern int yylex(void); +extern int yylineno; +void yyerror(const char* s); + +AST::Program* g_program = nullptr; #line 87 "parser.cpp" @@ -123,67 +123,70 @@ enum yysymbol_kind_t YYSYMBOL_IF = 9, /* IF */ YYSYMBOL_THEN = 10, /* THEN */ YYSYMBOL_ELSE = 11, /* ELSE */ - YYSYMBOL_WHILE = 12, /* WHILE */ - YYSYMBOL_DO = 13, /* DO */ - YYSYMBOL_TRUE = 14, /* TRUE */ - YYSYMBOL_FALSE = 15, /* FALSE */ - YYSYMBOL_COLON = 16, /* COLON */ - YYSYMBOL_SEMICOLON = 17, /* SEMICOLON */ - YYSYMBOL_COMMA = 18, /* COMMA */ - YYSYMBOL_LPAREN = 19, /* LPAREN */ - YYSYMBOL_RPAREN = 20, /* RPAREN */ - YYSYMBOL_LBRACE = 21, /* LBRACE */ - YYSYMBOL_RBRACE = 22, /* RBRACE */ - YYSYMBOL_LBRACKET = 23, /* LBRACKET */ - YYSYMBOL_RBRACKET = 24, /* RBRACKET */ - YYSYMBOL_ASSIGN = 25, /* ASSIGN */ - YYSYMBOL_ARROW = 26, /* ARROW */ - YYSYMBOL_PLUS = 27, /* PLUS */ - YYSYMBOL_MINUS = 28, /* MINUS */ - YYSYMBOL_STAR = 29, /* STAR */ - YYSYMBOL_SLASH = 30, /* SLASH */ - YYSYMBOL_DOT = 31, /* DOT */ - YYSYMBOL_GT = 32, /* GT */ - YYSYMBOL_LT = 33, /* LT */ - YYSYMBOL_EQEQ = 34, /* EQEQ */ - YYSYMBOL_EQUAL = 35, /* EQUAL */ - YYSYMBOL_IDENTIFIER = 36, /* IDENTIFIER */ - YYSYMBOL_TYPE_NAME = 37, /* TYPE_NAME */ - YYSYMBOL_INT_LITERAL = 38, /* INT_LITERAL */ - YYSYMBOL_STRING_LITERAL = 39, /* STRING_LITERAL */ - YYSYMBOL_YYACCEPT = 40, /* $accept */ - YYSYMBOL_program = 41, /* program */ - YYSYMBOL_class_list = 42, /* class_list */ - YYSYMBOL_class_decl = 43, /* class_decl */ - YYSYMBOL_class_body = 44, /* class_body */ - YYSYMBOL_member_list = 45, /* member_list */ - YYSYMBOL_member = 46, /* member */ - YYSYMBOL_type_spec = 47, /* type_spec */ - YYSYMBOL_type_list = 48, /* type_list */ - YYSYMBOL_var_decl = 49, /* var_decl */ - YYSYMBOL_method_decl = 50, /* method_decl */ - YYSYMBOL_opt_params = 51, /* opt_params */ - YYSYMBOL_param_list = 52, /* param_list */ - YYSYMBOL_param = 53, /* param */ - YYSYMBOL_method_body = 54, /* method_body */ - YYSYMBOL_stmt_list = 55, /* stmt_list */ - YYSYMBOL_stmt = 56, /* stmt */ + YYSYMBOL_ELSEIF = 12, /* ELSEIF */ + YYSYMBOL_WHILE = 13, /* WHILE */ + YYSYMBOL_DO = 14, /* DO */ + YYSYMBOL_TRUE = 15, /* TRUE */ + YYSYMBOL_FALSE = 16, /* FALSE */ + YYSYMBOL_COLON = 17, /* COLON */ + YYSYMBOL_SEMICOLON = 18, /* SEMICOLON */ + YYSYMBOL_COMMA = 19, /* COMMA */ + YYSYMBOL_LPAREN = 20, /* LPAREN */ + YYSYMBOL_RPAREN = 21, /* RPAREN */ + YYSYMBOL_LBRACE = 22, /* LBRACE */ + YYSYMBOL_RBRACE = 23, /* RBRACE */ + YYSYMBOL_LBRACKET = 24, /* LBRACKET */ + YYSYMBOL_RBRACKET = 25, /* RBRACKET */ + YYSYMBOL_ASSIGN = 26, /* ASSIGN */ + YYSYMBOL_ARROW = 27, /* ARROW */ + YYSYMBOL_PLUS = 28, /* PLUS */ + YYSYMBOL_MINUS = 29, /* MINUS */ + YYSYMBOL_STAR = 30, /* STAR */ + YYSYMBOL_SLASH = 31, /* SLASH */ + YYSYMBOL_DOT = 32, /* DOT */ + YYSYMBOL_GT = 33, /* GT */ + YYSYMBOL_LT = 34, /* LT */ + YYSYMBOL_EQEQ = 35, /* EQEQ */ + YYSYMBOL_EQUAL = 36, /* EQUAL */ + YYSYMBOL_IDENTIFIER = 37, /* IDENTIFIER */ + YYSYMBOL_TYPE_NAME = 38, /* TYPE_NAME */ + YYSYMBOL_INT_LITERAL = 39, /* INT_LITERAL */ + YYSYMBOL_STRING_LITERAL = 40, /* STRING_LITERAL */ + YYSYMBOL_YYACCEPT = 41, /* $accept */ + YYSYMBOL_program = 42, /* program */ + YYSYMBOL_class_list = 43, /* class_list */ + YYSYMBOL_class_decl = 44, /* class_decl */ + YYSYMBOL_class_body = 45, /* class_body */ + YYSYMBOL_member_list = 46, /* member_list */ + YYSYMBOL_member = 47, /* member */ + YYSYMBOL_type_spec = 48, /* type_spec */ + YYSYMBOL_type_list = 49, /* type_list */ + YYSYMBOL_var_decl = 50, /* var_decl */ + YYSYMBOL_method_decl = 51, /* method_decl */ + YYSYMBOL_opt_params = 52, /* opt_params */ + YYSYMBOL_param_list = 53, /* param_list */ + YYSYMBOL_param = 54, /* param */ + YYSYMBOL_method_body = 55, /* method_body */ + YYSYMBOL_stmt_list = 56, /* stmt_list */ YYSYMBOL_simple_stmt = 57, /* simple_stmt */ - YYSYMBOL_if_stmt = 58, /* if_stmt */ - YYSYMBOL_while_stmt = 59, /* while_stmt */ - YYSYMBOL_expr = 60, /* expr */ - YYSYMBOL_assign_expr = 61, /* assign_expr */ - YYSYMBOL_equality_expr = 62, /* equality_expr */ - YYSYMBOL_relational_expr = 63, /* relational_expr */ - YYSYMBOL_additive_expr = 64, /* additive_expr */ - YYSYMBOL_multiplicative_expr = 65, /* multiplicative_expr */ - YYSYMBOL_unary_expr = 66, /* unary_expr */ - YYSYMBOL_postfix_expr = 67, /* postfix_expr */ - YYSYMBOL_opt_args = 68, /* opt_args */ - YYSYMBOL_arg_list = 69, /* arg_list */ - YYSYMBOL_primary_expr = 70, /* primary_expr */ - YYSYMBOL_type_as_expr = 71, /* type_as_expr */ - YYSYMBOL_lvalue = 72 /* lvalue */ + YYSYMBOL_block_stmt = 58, /* block_stmt */ + YYSYMBOL_if_stmt = 59, /* if_stmt */ + YYSYMBOL_elif_tail = 60, /* elif_tail */ + YYSYMBOL_opt_else = 61, /* opt_else */ + YYSYMBOL_while_stmt = 62, /* while_stmt */ + YYSYMBOL_expr = 63, /* expr */ + YYSYMBOL_assign_expr = 64, /* assign_expr */ + YYSYMBOL_equality_expr = 65, /* equality_expr */ + YYSYMBOL_relational_expr = 66, /* relational_expr */ + YYSYMBOL_additive_expr = 67, /* additive_expr */ + YYSYMBOL_multiplicative_expr = 68, /* multiplicative_expr */ + YYSYMBOL_unary_expr = 69, /* unary_expr */ + YYSYMBOL_postfix_expr = 70, /* postfix_expr */ + YYSYMBOL_opt_args = 71, /* opt_args */ + YYSYMBOL_arg_list = 72, /* arg_list */ + YYSYMBOL_primary_expr = 73, /* primary_expr */ + YYSYMBOL_type_as_expr = 74, /* type_as_expr */ + YYSYMBOL_lvalue = 75 /* lvalue */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; @@ -511,19 +514,19 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 6 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 162 +#define YYLAST 158 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 40 +#define YYNTOKENS 41 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 33 +#define YYNNTS 35 /* YYNRULES -- Number of rules. */ -#define YYNRULES 77 +#define YYNRULES 81 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 142 +#define YYNSTATES 149 /* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 294 +#define YYMAXUTOK 295 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM @@ -566,21 +569,22 @@ static const yytype_int8 yytranslate[] = 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39 + 35, 36, 37, 38, 39, 40 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 78, 78, 83, 84, 88, 97, 98, 102, 103, - 107, 108, 112, 114, 123, 125, 134, 136, 138, 143, - 152, 153, 157, 158, 162, 167, 177, 178, 179, 180, - 181, 182, 186, 187, 188, 192, 193, 194, 195, 196, - 197, 201, 206, 216, 220, 221, 225, 226, 230, 231, - 232, 236, 237, 238, 242, 243, 244, 248, 249, 253, - 255, 257, 259, 264, 265, 269, 270, 274, 275, 276, - 277, 278, 279, 280, 284, 289, 290, 291 + 0, 78, 78, 83, 84, 88, 102, 103, 107, 108, + 112, 113, 117, 119, 129, 131, 141, 143, 145, 150, + 163, 164, 168, 169, 173, 178, 188, 189, 190, 191, + 192, 193, 194, 195, 205, 206, 207, 208, 209, 210, + 214, 224, 231, 235, 242, 243, 247, 257, 261, 262, + 266, 267, 271, 272, 273, 277, 278, 279, 283, 284, + 285, 289, 290, 294, 296, 298, 300, 305, 306, 310, + 311, 315, 316, 317, 318, 319, 320, 321, 325, 330, + 331, 332 }; #endif @@ -597,18 +601,18 @@ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; static const char *const yytname[] = { "\"end of file\"", "error", "\"invalid token\"", "CLASS", "VAR", "IS", - "END", "METHOD", "RETURN", "IF", "THEN", "ELSE", "WHILE", "DO", "TRUE", - "FALSE", "COLON", "SEMICOLON", "COMMA", "LPAREN", "RPAREN", "LBRACE", - "RBRACE", "LBRACKET", "RBRACKET", "ASSIGN", "ARROW", "PLUS", "MINUS", - "STAR", "SLASH", "DOT", "GT", "LT", "EQEQ", "EQUAL", "IDENTIFIER", - "TYPE_NAME", "INT_LITERAL", "STRING_LITERAL", "$accept", "program", - "class_list", "class_decl", "class_body", "member_list", "member", - "type_spec", "type_list", "var_decl", "method_decl", "opt_params", - "param_list", "param", "method_body", "stmt_list", "stmt", "simple_stmt", - "if_stmt", "while_stmt", "expr", "assign_expr", "equality_expr", - "relational_expr", "additive_expr", "multiplicative_expr", "unary_expr", - "postfix_expr", "opt_args", "arg_list", "primary_expr", "type_as_expr", - "lvalue", YY_NULLPTR + "END", "METHOD", "RETURN", "IF", "THEN", "ELSE", "ELSEIF", "WHILE", "DO", + "TRUE", "FALSE", "COLON", "SEMICOLON", "COMMA", "LPAREN", "RPAREN", + "LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "ASSIGN", "ARROW", "PLUS", + "MINUS", "STAR", "SLASH", "DOT", "GT", "LT", "EQEQ", "EQUAL", + "IDENTIFIER", "TYPE_NAME", "INT_LITERAL", "STRING_LITERAL", "$accept", + "program", "class_list", "class_decl", "class_body", "member_list", + "member", "type_spec", "type_list", "var_decl", "method_decl", + "opt_params", "param_list", "param", "method_body", "stmt_list", + "simple_stmt", "block_stmt", "if_stmt", "elif_tail", "opt_else", + "while_stmt", "expr", "assign_expr", "equality_expr", "relational_expr", + "additive_expr", "multiplicative_expr", "unary_expr", "postfix_expr", + "opt_args", "arg_list", "primary_expr", "type_as_expr", "lvalue", YY_NULLPTR }; static const char * @@ -618,12 +622,12 @@ yysymbol_name (yysymbol_kind_t yysymbol) } #endif -#define YYPACT_NINF (-106) +#define YYPACT_NINF (-130) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-76) +#define YYTABLE_NINF (-80) #define yytable_value_is_error(Yyn) \ 0 @@ -632,21 +636,21 @@ yysymbol_name (yysymbol_kind_t yysymbol) STATE-NUM. */ static const yytype_int16 yypact[] = { - 9, -11, 28, 9, -106, 25, -106, -106, 13, 5, - 14, 50, 13, -106, -106, -106, 56, 73, -106, -106, - 32, 44, 62, -14, 84, 91, 94, -106, 32, -106, - 95, 95, 32, 97, 44, -106, -8, -106, -106, 95, - 101, 93, -106, -106, -106, 102, -106, 87, -28, 38, - 61, -106, -5, -106, -106, 48, 105, -106, 32, -106, - 32, -106, 104, -106, -106, -106, 101, 101, 101, 101, - 101, 101, 101, 95, 95, 99, 95, 95, 100, -106, - 115, -106, -106, -28, 38, 38, 61, 61, -106, -106, - -106, 110, 124, 119, -106, 120, -106, -106, 89, -106, - 95, -106, -106, 109, 95, 95, -106, 89, 129, -106, - -106, 53, -106, 131, -106, 138, 132, -106, -106, 95, - 32, 23, -106, -106, -106, -2, 95, 139, -106, -106, - -106, 95, 95, 140, 23, -106, -106, 89, 145, 49, - -106, -106 + 15, -26, 24, 15, -130, 44, -130, -130, 8, 18, + 26, 63, 8, -130, -130, -130, 68, 51, -130, -130, + 50, 62, 57, -10, 91, 89, 108, -130, 50, -130, + 80, 80, 50, 111, 62, -130, -13, -130, -130, 80, + 106, 99, -130, -130, -130, 112, -130, 94, 34, 52, + 67, -130, 41, -130, -130, 40, 113, -130, 50, -130, + 50, -130, 115, -130, -130, -130, 106, 106, 106, 106, + 106, 106, 106, 80, 80, 95, 80, 80, 96, -130, + 107, -130, -130, 34, 52, 52, 67, 67, -130, -130, + -130, 116, 119, 114, -130, 117, -130, -130, 74, -130, + 80, -130, -130, 103, 80, 80, 80, -130, 74, 123, + -130, -130, -130, 60, -130, 130, -130, 138, 135, 132, + -130, -130, -130, 80, 50, 74, 74, -130, -130, -130, + -7, 74, 90, 19, 80, 80, 74, 80, 145, -130, + -130, -130, -130, -130, 142, -130, 74, 90, -130 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -657,36 +661,36 @@ static const yytype_int8 yydefact[] = 0, 0, 0, 2, 4, 0, 1, 3, 7, 0, 0, 0, 6, 9, 10, 11, 0, 0, 5, 8, 0, 21, 12, 0, 0, 0, 20, 23, 0, 16, - 0, 0, 0, 0, 0, 14, 0, 69, 70, 0, - 0, 71, 67, 68, 74, 0, 43, 45, 47, 50, - 53, 56, 58, 62, 72, 0, 0, 24, 0, 22, - 0, 13, 0, 71, 57, 18, 0, 0, 0, 0, - 0, 0, 0, 64, 0, 0, 0, 0, 0, 17, - 0, 15, 73, 46, 48, 49, 51, 52, 54, 55, - 66, 0, 63, 0, 60, 0, 44, 76, 0, 59, - 0, 61, 77, 0, 0, 0, 19, 25, 31, 30, - 40, 0, 65, 0, 35, 0, 28, 27, 29, 0, - 0, 0, 26, 39, 43, 36, 0, 0, 32, 33, - 34, 0, 0, 0, 0, 38, 37, 0, 0, 0, - 41, 42 + 0, 0, 0, 0, 0, 14, 0, 73, 74, 0, + 0, 75, 71, 72, 78, 0, 47, 49, 51, 54, + 57, 60, 62, 66, 76, 0, 0, 24, 0, 22, + 0, 13, 0, 75, 61, 18, 0, 0, 0, 0, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 17, + 0, 15, 77, 50, 52, 53, 55, 56, 58, 59, + 70, 0, 67, 0, 64, 0, 48, 80, 0, 63, + 0, 65, 81, 0, 0, 0, 0, 19, 25, 33, + 31, 32, 39, 0, 69, 0, 34, 0, 0, 29, + 27, 28, 30, 0, 0, 0, 0, 26, 38, 47, + 35, 40, 45, 0, 0, 0, 0, 0, 0, 43, + 46, 37, 36, 44, 0, 41, 0, 45, 42 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -106, -106, -106, 149, -106, -106, 142, -13, -106, -106, - -106, -106, -106, 121, -106, 19, 24, -105, -40, -106, - -30, -71, -106, 96, 15, 36, -32, -106, -106, -106, - -106, -106, -85 + -130, -130, -130, 150, -130, -130, 143, -18, -130, -130, + -130, -130, -130, 120, -130, -93, -86, -129, -71, 9, + -130, -54, -30, -73, -130, 92, 48, 54, -19, -130, + -130, -130, -130, -130, -95 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_uint8 yydefgoto[] = { 0, 2, 3, 4, 11, 12, 13, 44, 36, 14, - 15, 25, 26, 27, 106, 107, 127, 108, 109, 130, - 110, 46, 47, 48, 49, 50, 51, 52, 91, 92, - 53, 54, 55 + 15, 25, 26, 27, 107, 131, 109, 132, 110, 138, + 139, 111, 112, 46, 47, 48, 49, 50, 51, 52, + 91, 92, 53, 54, 55 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -694,78 +698,77 @@ static const yytype_uint8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 45, 56, 116, 29, 67, 68, 96, 23, 64, 62, - 60, 30, 1, 111, 73, 35, 128, 9, 74, 57, - 10, 31, 111, 131, 61, 5, 75, 103, 6, 128, - 8, 104, 105, 132, 116, 126, 111, 37, 38, 88, - 89, 16, 39, 90, 93, 80, 95, 81, 124, 111, - 17, 40, 111, 103, 111, 141, 18, 104, 105, 41, - 22, 42, 43, 37, 38, 69, 70, 117, 39, 22, - 112, 76, 20, 77, 114, 115, 76, 40, 119, 78, - 24, 129, 84, 85, 78, 41, 22, 42, 43, 123, - 71, 72, 21, 103, 129, 28, 133, 104, 105, 117, - 32, 135, 136, 37, 38, 86, 87, 125, 39, 37, - 38, 33, 34, 58, 39, 37, 38, 40, -75, 65, - 39, 66, 79, 40, 82, 41, 22, 42, 43, 40, - 99, 41, 22, 42, 43, 94, 97, 63, 22, 42, - 43, 98, 100, 101, 102, 113, 118, 120, 121, 122, - 134, 140, 7, 137, 19, 59, 139, 0, 138, 0, - 0, 0, 83 + 45, 56, 23, 113, 96, 108, 60, 143, 29, 62, + 35, 5, 9, 113, 57, 10, 30, 147, 1, 134, + 61, 64, 119, 103, 6, 140, 31, 104, 105, 135, + 113, 113, 106, 133, 37, 38, 113, 120, 113, 39, + 80, 113, 81, 90, 93, 119, 95, 119, 40, 8, + 129, 113, 88, 89, 121, 16, 41, 22, 42, 43, + 120, 73, 120, 17, 76, 74, 77, 67, 68, 18, + 114, 21, 78, 75, 116, 117, 118, 121, 103, 121, + 69, 70, 104, 105, 76, 20, 123, 106, 22, 37, + 38, 28, 78, 128, 39, 37, 38, 71, 72, 24, + 39, 136, 137, 40, 141, 142, 130, 144, 32, 40, + 33, 41, 22, 42, 43, 84, 85, 41, 22, 42, + 43, 37, 38, 86, 87, -79, 39, 34, 58, 66, + 65, 79, 94, 97, 98, 40, 82, 99, 100, 101, + 115, 122, 102, 63, 22, 42, 43, 124, 125, 126, + 127, 145, 146, 7, 59, 19, 148, 0, 83 }; static const yytype_int16 yycheck[] = { - 30, 31, 107, 17, 32, 33, 77, 20, 40, 39, - 18, 25, 3, 98, 19, 28, 121, 4, 23, 32, - 7, 35, 107, 25, 32, 36, 31, 4, 0, 134, - 5, 8, 9, 35, 139, 12, 121, 14, 15, 71, - 72, 36, 19, 73, 74, 58, 76, 60, 119, 134, - 36, 28, 137, 4, 139, 6, 6, 8, 9, 36, - 37, 38, 39, 14, 15, 27, 28, 107, 19, 37, - 100, 23, 16, 25, 104, 105, 23, 28, 25, 31, - 36, 121, 67, 68, 31, 36, 37, 38, 39, 119, - 29, 30, 19, 4, 134, 33, 126, 8, 9, 139, - 16, 131, 132, 14, 15, 69, 70, 120, 19, 14, - 15, 20, 18, 16, 19, 14, 15, 28, 25, 17, - 19, 34, 17, 28, 20, 36, 37, 38, 39, 28, - 20, 36, 37, 38, 39, 36, 36, 36, 37, 38, - 39, 26, 18, 24, 24, 36, 17, 16, 10, 17, - 11, 6, 3, 13, 12, 34, 137, -1, 134, -1, - -1, -1, 66 + 30, 31, 20, 98, 77, 98, 19, 136, 18, 39, + 28, 37, 4, 108, 32, 7, 26, 146, 3, 26, + 33, 40, 108, 4, 0, 6, 36, 8, 9, 36, + 125, 126, 13, 126, 15, 16, 131, 108, 133, 20, + 58, 136, 60, 73, 74, 131, 76, 133, 29, 5, + 123, 146, 71, 72, 108, 37, 37, 38, 39, 40, + 131, 20, 133, 37, 24, 24, 26, 33, 34, 6, + 100, 20, 32, 32, 104, 105, 106, 131, 4, 133, + 28, 29, 8, 9, 24, 17, 26, 13, 38, 15, + 16, 34, 32, 123, 20, 15, 16, 30, 31, 37, + 20, 11, 12, 29, 134, 135, 124, 137, 17, 29, + 21, 37, 38, 39, 40, 67, 68, 37, 38, 39, + 40, 15, 16, 69, 70, 26, 20, 19, 17, 35, + 18, 18, 37, 37, 27, 29, 21, 21, 19, 25, + 37, 18, 25, 37, 38, 39, 40, 17, 10, 14, + 18, 6, 10, 3, 34, 12, 147, -1, 66 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { - 0, 3, 41, 42, 43, 36, 0, 43, 5, 4, - 7, 44, 45, 46, 49, 50, 36, 36, 6, 46, - 16, 19, 37, 47, 36, 51, 52, 53, 33, 17, - 25, 35, 16, 20, 18, 47, 48, 14, 15, 19, - 28, 36, 38, 39, 47, 60, 61, 62, 63, 64, - 65, 66, 67, 70, 71, 72, 60, 47, 16, 53, - 18, 32, 60, 36, 66, 17, 34, 32, 33, 27, - 28, 29, 30, 19, 23, 31, 23, 25, 31, 17, - 47, 47, 20, 63, 64, 64, 65, 65, 66, 66, - 60, 68, 69, 60, 36, 60, 61, 36, 26, 20, - 18, 24, 24, 4, 8, 9, 54, 55, 57, 58, - 60, 72, 60, 36, 60, 60, 57, 58, 17, 25, - 16, 10, 17, 60, 61, 47, 12, 56, 57, 58, - 59, 25, 35, 60, 11, 60, 60, 13, 56, 55, - 6, 6 + 0, 3, 42, 43, 44, 37, 0, 44, 5, 4, + 7, 45, 46, 47, 50, 51, 37, 37, 6, 47, + 17, 20, 38, 48, 37, 52, 53, 54, 34, 18, + 26, 36, 17, 21, 19, 48, 49, 15, 16, 20, + 29, 37, 39, 40, 48, 63, 64, 65, 66, 67, + 68, 69, 70, 73, 74, 75, 63, 48, 17, 54, + 19, 33, 63, 37, 69, 18, 35, 33, 34, 28, + 29, 30, 31, 20, 24, 32, 24, 26, 32, 18, + 48, 48, 21, 66, 67, 67, 68, 68, 69, 69, + 63, 71, 72, 63, 37, 63, 64, 37, 27, 21, + 19, 25, 25, 4, 8, 9, 13, 55, 56, 57, + 59, 62, 63, 75, 63, 37, 63, 63, 63, 57, + 59, 62, 18, 26, 17, 10, 14, 18, 63, 64, + 48, 56, 58, 56, 26, 36, 11, 12, 60, 61, + 6, 63, 63, 58, 63, 6, 10, 58, 60 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int8 yyr1[] = { - 0, 40, 41, 42, 42, 43, 44, 44, 45, 45, - 46, 46, 47, 47, 48, 48, 49, 49, 49, 50, - 51, 51, 52, 52, 53, 54, 55, 55, 55, 55, - 55, 55, 56, 56, 56, 57, 57, 57, 57, 57, - 57, 58, 59, 60, 61, 61, 62, 62, 63, 63, - 63, 64, 64, 64, 65, 65, 65, 66, 66, 67, - 67, 67, 67, 68, 68, 69, 69, 70, 70, 70, - 70, 70, 70, 70, 71, 72, 72, 72 + 0, 41, 42, 43, 43, 44, 45, 45, 46, 46, + 47, 47, 48, 48, 49, 49, 50, 50, 50, 51, + 52, 52, 53, 53, 54, 55, 56, 56, 56, 56, + 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, + 58, 59, 60, 60, 61, 61, 62, 63, 64, 64, + 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, + 68, 69, 69, 70, 70, 70, 70, 71, 71, 72, + 72, 73, 73, 73, 73, 73, 73, 73, 74, 75, + 75, 75 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ @@ -774,11 +777,12 @@ static const yytype_int8 yyr2[] = 0, 2, 1, 2, 1, 5, 1, 0, 2, 1, 1, 1, 1, 4, 1, 3, 5, 7, 7, 9, 1, 0, 3, 1, 3, 1, 3, 2, 2, 2, - 1, 1, 1, 1, 1, 2, 4, 6, 6, 3, - 1, 7, 5, 1, 3, 1, 3, 1, 3, 3, - 1, 3, 3, 1, 3, 3, 1, 2, 1, 4, - 3, 4, 1, 1, 0, 3, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 1, 3, 4 + 2, 1, 1, 1, 2, 4, 6, 6, 3, 1, + 1, 6, 5, 1, 2, 0, 5, 1, 3, 1, + 3, 1, 3, 3, 1, 3, 3, 1, 3, 3, + 1, 2, 1, 4, 3, 4, 1, 1, 0, 3, + 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, + 3, 4 }; @@ -1514,487 +1518,533 @@ yyparse (void) case 2: /* program: class_list */ #line 79 "parser.y" { g_program = new AST::Program(); for (auto* c : *(yyvsp[0].classlist)) g_program->classes.push_back(c); delete (yyvsp[0].classlist); } -#line 1518 "parser.cpp" +#line 1522 "parser.cpp" break; case 3: /* class_list: class_list class_decl */ #line 83 "parser.y" { (yyval.classlist) = (yyvsp[-1].classlist); (yyvsp[-1].classlist)->push_back((yyvsp[0].classdecl)); } -#line 1524 "parser.cpp" +#line 1528 "parser.cpp" break; case 4: /* class_list: class_decl */ #line 84 "parser.y" { (yyval.classlist) = new std::vector(); (yyval.classlist)->push_back((yyvsp[0].classdecl)); } -#line 1530 "parser.cpp" +#line 1534 "parser.cpp" break; case 5: /* class_decl: CLASS IDENTIFIER IS class_body END */ #line 89 "parser.y" - { - (yyval.classdecl) = new AST::ClassDecl((yyvsp[-3].cstr)); - for (auto* n : *(yyvsp[-1].memberlist)) { if (auto* v = dynamic_cast(n)) (yyval.classdecl)->fields.push_back(v); else if (auto* m = dynamic_cast(n)) (yyval.classdecl)->methods.push_back(m); else delete n; } - free((yyvsp[-3].cstr)); delete (yyvsp[-1].memberlist); + { + (yyval.classdecl) = new AST::ClassDecl((yyvsp[-3].cstr)); + for (auto* n : *(yyvsp[-1].memberlist)) { + if (auto* v = dynamic_cast(n)) (yyval.classdecl)->fields.push_back(v); + else if (auto* m = dynamic_cast(n)) (yyval.classdecl)->methods.push_back(m); + else delete n; + } + free((yyvsp[-3].cstr)); + delete (yyvsp[-1].memberlist); } -#line 1540 "parser.cpp" +#line 1549 "parser.cpp" break; case 6: /* class_body: member_list */ -#line 97 "parser.y" +#line 102 "parser.y" { (yyval.memberlist) = (yyvsp[0].memberlist); } -#line 1546 "parser.cpp" +#line 1555 "parser.cpp" break; case 7: /* class_body: %empty */ -#line 98 "parser.y" +#line 103 "parser.y" { (yyval.memberlist) = new std::vector(); } -#line 1552 "parser.cpp" +#line 1561 "parser.cpp" break; case 8: /* member_list: member_list member */ -#line 102 "parser.y" +#line 107 "parser.y" { (yyval.memberlist) = (yyvsp[-1].memberlist); (yyvsp[-1].memberlist)->push_back((yyvsp[0].node)); } -#line 1558 "parser.cpp" +#line 1567 "parser.cpp" break; case 9: /* member_list: member */ -#line 103 "parser.y" +#line 108 "parser.y" { (yyval.memberlist) = new std::vector(); (yyval.memberlist)->push_back((yyvsp[0].node)); } -#line 1564 "parser.cpp" +#line 1573 "parser.cpp" break; case 10: /* member: var_decl */ -#line 107 "parser.y" +#line 112 "parser.y" { (yyval.node) = (yyvsp[0].vardecl); } -#line 1570 "parser.cpp" +#line 1579 "parser.cpp" break; case 11: /* member: method_decl */ -#line 108 "parser.y" +#line 113 "parser.y" { (yyval.node) = (yyvsp[0].methoddecl); } -#line 1576 "parser.cpp" +#line 1585 "parser.cpp" break; case 12: /* type_spec: TYPE_NAME */ -#line 113 "parser.y" +#line 118 "parser.y" { (yyval.cstr) = (yyvsp[0].cstr); } -#line 1582 "parser.cpp" +#line 1591 "parser.cpp" break; case 13: /* type_spec: TYPE_NAME LT type_list GT */ -#line 115 "parser.y" - { - std::string s = std::string((yyvsp[-3].cstr)) + "<" + std::string((yyvsp[-1].cstr)) + ">"; - (yyval.cstr) = strdup(s.c_str()); - free((yyvsp[-3].cstr)); free((yyvsp[-1].cstr)); +#line 120 "parser.y" + { + std::string s = std::string((yyvsp[-3].cstr)) + "<" + std::string((yyvsp[-1].cstr)) + ">"; + (yyval.cstr) = strdup(s.c_str()); + free((yyvsp[-3].cstr)); + free((yyvsp[-1].cstr)); } -#line 1592 "parser.cpp" +#line 1602 "parser.cpp" break; case 14: /* type_list: type_spec */ -#line 124 "parser.y" +#line 130 "parser.y" { (yyval.cstr) = (yyvsp[0].cstr); } -#line 1598 "parser.cpp" +#line 1608 "parser.cpp" break; case 15: /* type_list: type_list COMMA type_spec */ -#line 126 "parser.y" - { - std::string s = std::string((yyvsp[-2].cstr)) + "," + std::string((yyvsp[0].cstr)); - (yyval.cstr) = strdup(s.c_str()); - free((yyvsp[-2].cstr)); free((yyvsp[0].cstr)); +#line 132 "parser.y" + { + std::string s = std::string((yyvsp[-2].cstr)) + "," + std::string((yyvsp[0].cstr)); + (yyval.cstr) = strdup(s.c_str()); + free((yyvsp[-2].cstr)); + free((yyvsp[0].cstr)); } -#line 1608 "parser.cpp" +#line 1619 "parser.cpp" break; case 16: /* var_decl: VAR IDENTIFIER COLON type_spec SEMICOLON */ -#line 135 "parser.y" +#line 142 "parser.y" { (yyval.vardecl) = new AST::VarDecl((yyvsp[-3].cstr), (yyvsp[-1].cstr), nullptr); free((yyvsp[-3].cstr)); free((yyvsp[-1].cstr)); } -#line 1614 "parser.cpp" +#line 1625 "parser.cpp" break; case 17: /* var_decl: VAR IDENTIFIER COLON type_spec EQUAL expr SEMICOLON */ -#line 137 "parser.y" +#line 144 "parser.y" { (yyval.vardecl) = new AST::VarDecl((yyvsp[-5].cstr), (yyvsp[-3].cstr), (yyvsp[-1].expr)); free((yyvsp[-5].cstr)); free((yyvsp[-3].cstr)); } -#line 1620 "parser.cpp" +#line 1631 "parser.cpp" break; case 18: /* var_decl: VAR IDENTIFIER COLON type_spec ASSIGN expr SEMICOLON */ -#line 139 "parser.y" +#line 146 "parser.y" { (yyval.vardecl) = new AST::VarDecl((yyvsp[-5].cstr), (yyvsp[-3].cstr), (yyvsp[-1].expr)); free((yyvsp[-5].cstr)); free((yyvsp[-3].cstr)); } -#line 1626 "parser.cpp" +#line 1637 "parser.cpp" break; case 19: /* method_decl: METHOD IDENTIFIER LPAREN opt_params RPAREN COLON type_spec ARROW method_body */ -#line 144 "parser.y" - { - (yyval.methoddecl) = new AST::MethodDecl((yyvsp[-7].cstr), (yyvsp[-2].cstr), (yyvsp[0].stmt)); - if ((yyvsp[-5].paramlist)) { for (auto* p : *(yyvsp[-5].paramlist)) (yyval.methoddecl)->params.push_back(p); delete (yyvsp[-5].paramlist); } - free((yyvsp[-7].cstr)); free((yyvsp[-2].cstr)); +#line 151 "parser.y" + { + (yyval.methoddecl) = new AST::MethodDecl((yyvsp[-7].cstr), (yyvsp[-2].cstr), (yyvsp[0].stmt)); + if ((yyvsp[-5].paramlist)) { + for (auto* p : *(yyvsp[-5].paramlist)) (yyval.methoddecl)->params.push_back(p); + delete (yyvsp[-5].paramlist); + } + free((yyvsp[-7].cstr)); + free((yyvsp[-2].cstr)); } -#line 1636 "parser.cpp" +#line 1651 "parser.cpp" break; case 20: /* opt_params: param_list */ -#line 152 "parser.y" +#line 163 "parser.y" { (yyval.paramlist) = (yyvsp[0].paramlist); } -#line 1642 "parser.cpp" +#line 1657 "parser.cpp" break; case 21: /* opt_params: %empty */ -#line 153 "parser.y" +#line 164 "parser.y" { (yyval.paramlist) = new std::vector(); } -#line 1648 "parser.cpp" +#line 1663 "parser.cpp" break; case 22: /* param_list: param_list COMMA param */ -#line 157 "parser.y" +#line 168 "parser.y" { (yyval.paramlist) = (yyvsp[-2].paramlist); (yyvsp[-2].paramlist)->push_back((yyvsp[0].param)); } -#line 1654 "parser.cpp" +#line 1669 "parser.cpp" break; case 23: /* param_list: param */ -#line 158 "parser.y" +#line 169 "parser.y" { (yyval.paramlist) = new std::vector(); (yyval.paramlist)->push_back((yyvsp[0].param)); } -#line 1660 "parser.cpp" +#line 1675 "parser.cpp" break; case 24: /* param: IDENTIFIER COLON type_spec */ -#line 163 "parser.y" +#line 174 "parser.y" { (yyval.param) = new AST::Param((yyvsp[-2].cstr), (yyvsp[0].cstr)); free((yyvsp[-2].cstr)); free((yyvsp[0].cstr)); } -#line 1666 "parser.cpp" +#line 1681 "parser.cpp" break; case 25: /* method_body: stmt_list */ -#line 168 "parser.y" - { - auto* b = new AST::Block(); - for (auto* s : *(yyvsp[0].stmtlist)) b->stmts.push_back(s); - delete (yyvsp[0].stmtlist); - (yyval.stmt) = b; +#line 179 "parser.y" + { + auto* b = new AST::Block(); + for (auto* s : *(yyvsp[0].stmtlist)) b->stmts.push_back(s); + delete (yyvsp[0].stmtlist); + (yyval.stmt) = b; } -#line 1677 "parser.cpp" +#line 1692 "parser.cpp" break; case 26: /* stmt_list: stmt_list simple_stmt SEMICOLON */ -#line 177 "parser.y" +#line 188 "parser.y" { (yyval.stmtlist) = (yyvsp[-2].stmtlist); (yyvsp[-2].stmtlist)->push_back((yyvsp[-1].stmt)); } -#line 1683 "parser.cpp" +#line 1698 "parser.cpp" break; case 27: /* stmt_list: stmt_list if_stmt */ -#line 178 "parser.y" +#line 189 "parser.y" { (yyval.stmtlist) = (yyvsp[-1].stmtlist); (yyvsp[-1].stmtlist)->push_back((yyvsp[0].stmt)); } -#line 1689 "parser.cpp" +#line 1704 "parser.cpp" break; - case 28: /* stmt_list: stmt_list simple_stmt */ -#line 179 "parser.y" + case 28: /* stmt_list: stmt_list while_stmt */ +#line 190 "parser.y" { (yyval.stmtlist) = (yyvsp[-1].stmtlist); (yyvsp[-1].stmtlist)->push_back((yyvsp[0].stmt)); } -#line 1695 "parser.cpp" +#line 1710 "parser.cpp" break; - case 29: /* stmt_list: simple_stmt SEMICOLON */ -#line 180 "parser.y" - { (yyval.stmtlist) = new std::vector(); (yyval.stmtlist)->push_back((yyvsp[-1].stmt)); } -#line 1701 "parser.cpp" + case 29: /* stmt_list: stmt_list simple_stmt */ +#line 191 "parser.y" + { (yyval.stmtlist) = (yyvsp[-1].stmtlist); (yyvsp[-1].stmtlist)->push_back((yyvsp[0].stmt)); } +#line 1716 "parser.cpp" break; - case 30: /* stmt_list: if_stmt */ -#line 181 "parser.y" - { (yyval.stmtlist) = new std::vector(); (yyval.stmtlist)->push_back((yyvsp[0].stmt)); } -#line 1707 "parser.cpp" + case 30: /* stmt_list: simple_stmt SEMICOLON */ +#line 192 "parser.y" + { (yyval.stmtlist) = new std::vector(); (yyval.stmtlist)->push_back((yyvsp[-1].stmt)); } +#line 1722 "parser.cpp" break; - case 31: /* stmt_list: simple_stmt */ -#line 182 "parser.y" + case 31: /* stmt_list: if_stmt */ +#line 193 "parser.y" { (yyval.stmtlist) = new std::vector(); (yyval.stmtlist)->push_back((yyvsp[0].stmt)); } -#line 1713 "parser.cpp" - break; - - case 32: /* stmt: simple_stmt */ -#line 186 "parser.y" - { (yyval.stmt) = (yyvsp[0].stmt); } -#line 1719 "parser.cpp" +#line 1728 "parser.cpp" break; - case 33: /* stmt: if_stmt */ -#line 187 "parser.y" - { (yyval.stmt) = (yyvsp[0].stmt); } -#line 1725 "parser.cpp" + case 32: /* stmt_list: while_stmt */ +#line 194 "parser.y" + { (yyval.stmtlist) = new std::vector(); (yyval.stmtlist)->push_back((yyvsp[0].stmt)); } +#line 1734 "parser.cpp" break; - case 34: /* stmt: while_stmt */ -#line 188 "parser.y" - { (yyval.stmt) = (yyvsp[0].stmt); } -#line 1731 "parser.cpp" + case 33: /* stmt_list: simple_stmt */ +#line 195 "parser.y" + { (yyval.stmtlist) = new std::vector(); (yyval.stmtlist)->push_back((yyvsp[0].stmt)); } +#line 1740 "parser.cpp" break; - case 35: /* simple_stmt: RETURN expr */ -#line 192 "parser.y" + case 34: /* simple_stmt: RETURN expr */ +#line 205 "parser.y" { (yyval.stmt) = new AST::ReturnStmt((yyvsp[0].expr)); } -#line 1737 "parser.cpp" +#line 1746 "parser.cpp" break; - case 36: /* simple_stmt: VAR IDENTIFIER COLON type_spec */ -#line 193 "parser.y" + case 35: /* simple_stmt: VAR IDENTIFIER COLON type_spec */ +#line 206 "parser.y" { (yyval.stmt) = new AST::VarDeclStmt(new AST::VarDecl((yyvsp[-2].cstr), (yyvsp[0].cstr), nullptr)); free((yyvsp[-2].cstr)); free((yyvsp[0].cstr)); } -#line 1743 "parser.cpp" +#line 1752 "parser.cpp" break; - case 37: /* simple_stmt: VAR IDENTIFIER COLON type_spec EQUAL expr */ -#line 194 "parser.y" + case 36: /* simple_stmt: VAR IDENTIFIER COLON type_spec EQUAL expr */ +#line 207 "parser.y" { (yyval.stmt) = new AST::VarDeclStmt(new AST::VarDecl((yyvsp[-4].cstr), (yyvsp[-2].cstr), (yyvsp[0].expr))); free((yyvsp[-4].cstr)); free((yyvsp[-2].cstr)); } -#line 1749 "parser.cpp" +#line 1758 "parser.cpp" break; - case 38: /* simple_stmt: VAR IDENTIFIER COLON type_spec ASSIGN expr */ -#line 195 "parser.y" + case 37: /* simple_stmt: VAR IDENTIFIER COLON type_spec ASSIGN expr */ +#line 208 "parser.y" { (yyval.stmt) = new AST::VarDeclStmt(new AST::VarDecl((yyvsp[-4].cstr), (yyvsp[-2].cstr), (yyvsp[0].expr))); free((yyvsp[-4].cstr)); free((yyvsp[-2].cstr)); } -#line 1755 "parser.cpp" +#line 1764 "parser.cpp" break; - case 39: /* simple_stmt: lvalue ASSIGN expr */ -#line 196 "parser.y" + case 38: /* simple_stmt: lvalue ASSIGN expr */ +#line 209 "parser.y" { (yyval.stmt) = new AST::ExprStmt(new AST::Binary(AST::BinOp::Assign, (yyvsp[-2].expr), (yyvsp[0].expr))); } -#line 1761 "parser.cpp" +#line 1770 "parser.cpp" break; - case 40: /* simple_stmt: expr */ -#line 197 "parser.y" + case 39: /* simple_stmt: expr */ +#line 210 "parser.y" { (yyval.stmt) = new AST::ExprStmt((yyvsp[0].expr)); } -#line 1767 "parser.cpp" +#line 1776 "parser.cpp" break; - case 41: /* if_stmt: IF expr THEN stmt ELSE stmt END */ -#line 202 "parser.y" - { (yyval.stmt) = new AST::IfStmt((yyvsp[-5].expr), (yyvsp[-3].stmt), (yyvsp[-1].stmt)); } -#line 1773 "parser.cpp" + case 40: /* block_stmt: stmt_list */ +#line 215 "parser.y" + { + auto* b = new AST::Block(); + for (auto* s : *(yyvsp[0].stmtlist)) b->stmts.push_back(s); + delete (yyvsp[0].stmtlist); + (yyval.stmt) = b; + } +#line 1787 "parser.cpp" break; - case 42: /* while_stmt: WHILE expr DO stmt_list END */ -#line 207 "parser.y" - { - auto* b = new AST::Block(); - for (auto* s : *(yyvsp[-1].stmtlist)) b->stmts.push_back(s); - delete (yyvsp[-1].stmtlist); - (yyval.stmt) = new AST::WhileStmt((yyvsp[-3].expr), b); + case 41: /* if_stmt: IF expr THEN block_stmt elif_tail END */ +#line 225 "parser.y" + { + (yyval.stmt) = new AST::IfStmt((yyvsp[-4].expr), (yyvsp[-2].stmt), (yyvsp[-1].stmt)); + } +#line 1795 "parser.cpp" + break; + + case 42: /* elif_tail: ELSEIF expr THEN block_stmt elif_tail */ +#line 232 "parser.y" + { + (yyval.stmt) = new AST::IfStmt((yyvsp[-3].expr), (yyvsp[-1].stmt), (yyvsp[0].stmt)); + } +#line 1803 "parser.cpp" + break; + + case 43: /* elif_tail: opt_else */ +#line 236 "parser.y" + { + (yyval.stmt) = (yyvsp[0].stmt) ? (yyvsp[0].stmt) : static_cast(new AST::Block()); + } +#line 1811 "parser.cpp" + break; + + case 44: /* opt_else: ELSE block_stmt */ +#line 242 "parser.y" + { (yyval.stmt) = (yyvsp[0].stmt); } +#line 1817 "parser.cpp" + break; + + case 45: /* opt_else: %empty */ +#line 243 "parser.y" + { (yyval.stmt) = nullptr; } +#line 1823 "parser.cpp" + break; + + case 46: /* while_stmt: WHILE expr DO stmt_list END */ +#line 248 "parser.y" + { + auto* b = new AST::Block(); + for (auto* s : *(yyvsp[-1].stmtlist)) b->stmts.push_back(s); + delete (yyvsp[-1].stmtlist); + (yyval.stmt) = new AST::WhileStmt((yyvsp[-3].expr), b); } -#line 1784 "parser.cpp" +#line 1834 "parser.cpp" break; - case 43: /* expr: assign_expr */ -#line 216 "parser.y" + case 47: /* expr: assign_expr */ +#line 257 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 1790 "parser.cpp" +#line 1840 "parser.cpp" break; - case 44: /* assign_expr: lvalue ASSIGN assign_expr */ -#line 220 "parser.y" + case 48: /* assign_expr: lvalue ASSIGN assign_expr */ +#line 261 "parser.y" { (yyval.expr) = new AST::Binary(AST::BinOp::Assign, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1796 "parser.cpp" +#line 1846 "parser.cpp" break; - case 45: /* assign_expr: equality_expr */ -#line 221 "parser.y" + case 49: /* assign_expr: equality_expr */ +#line 262 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 1802 "parser.cpp" +#line 1852 "parser.cpp" break; - case 46: /* equality_expr: equality_expr EQEQ relational_expr */ -#line 225 "parser.y" + case 50: /* equality_expr: equality_expr EQEQ relational_expr */ +#line 266 "parser.y" { (yyval.expr) = new AST::Binary(AST::BinOp::Eq, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1808 "parser.cpp" +#line 1858 "parser.cpp" break; - case 47: /* equality_expr: relational_expr */ -#line 226 "parser.y" + case 51: /* equality_expr: relational_expr */ +#line 267 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 1814 "parser.cpp" +#line 1864 "parser.cpp" break; - case 48: /* relational_expr: relational_expr GT additive_expr */ -#line 230 "parser.y" + case 52: /* relational_expr: relational_expr GT additive_expr */ +#line 271 "parser.y" { (yyval.expr) = new AST::Binary(AST::BinOp::Gt, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1820 "parser.cpp" +#line 1870 "parser.cpp" break; - case 49: /* relational_expr: relational_expr LT additive_expr */ -#line 231 "parser.y" + case 53: /* relational_expr: relational_expr LT additive_expr */ +#line 272 "parser.y" { (yyval.expr) = new AST::Binary(AST::BinOp::Lt, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1826 "parser.cpp" +#line 1876 "parser.cpp" break; - case 50: /* relational_expr: additive_expr */ -#line 232 "parser.y" + case 54: /* relational_expr: additive_expr */ +#line 273 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 1832 "parser.cpp" +#line 1882 "parser.cpp" break; - case 51: /* additive_expr: additive_expr PLUS multiplicative_expr */ -#line 236 "parser.y" + case 55: /* additive_expr: additive_expr PLUS multiplicative_expr */ +#line 277 "parser.y" { (yyval.expr) = new AST::Binary(AST::BinOp::Add, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1838 "parser.cpp" +#line 1888 "parser.cpp" break; - case 52: /* additive_expr: additive_expr MINUS multiplicative_expr */ -#line 237 "parser.y" + case 56: /* additive_expr: additive_expr MINUS multiplicative_expr */ +#line 278 "parser.y" { (yyval.expr) = new AST::Binary(AST::BinOp::Sub, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1844 "parser.cpp" +#line 1894 "parser.cpp" break; - case 53: /* additive_expr: multiplicative_expr */ -#line 238 "parser.y" + case 57: /* additive_expr: multiplicative_expr */ +#line 279 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 1850 "parser.cpp" +#line 1900 "parser.cpp" break; - case 54: /* multiplicative_expr: multiplicative_expr STAR unary_expr */ -#line 242 "parser.y" + case 58: /* multiplicative_expr: multiplicative_expr STAR unary_expr */ +#line 283 "parser.y" { (yyval.expr) = new AST::Binary(AST::BinOp::Mul, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1856 "parser.cpp" +#line 1906 "parser.cpp" break; - case 55: /* multiplicative_expr: multiplicative_expr SLASH unary_expr */ -#line 243 "parser.y" + case 59: /* multiplicative_expr: multiplicative_expr SLASH unary_expr */ +#line 284 "parser.y" { (yyval.expr) = new AST::Binary(AST::BinOp::Div, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1862 "parser.cpp" +#line 1912 "parser.cpp" break; - case 56: /* multiplicative_expr: unary_expr */ -#line 244 "parser.y" + case 60: /* multiplicative_expr: unary_expr */ +#line 285 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 1868 "parser.cpp" +#line 1918 "parser.cpp" break; - case 57: /* unary_expr: MINUS unary_expr */ -#line 248 "parser.y" + case 61: /* unary_expr: MINUS unary_expr */ +#line 289 "parser.y" { (yyval.expr) = new AST::Unary(AST::Unary::Op::Neg, (yyvsp[0].expr)); } -#line 1874 "parser.cpp" +#line 1924 "parser.cpp" break; - case 58: /* unary_expr: postfix_expr */ -#line 249 "parser.y" + case 62: /* unary_expr: postfix_expr */ +#line 290 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 1880 "parser.cpp" +#line 1930 "parser.cpp" break; - case 59: /* postfix_expr: postfix_expr LPAREN opt_args RPAREN */ -#line 254 "parser.y" + case 63: /* postfix_expr: postfix_expr LPAREN opt_args RPAREN */ +#line 295 "parser.y" { auto* call = new AST::Call((yyvsp[-3].expr)); for (auto* e : *(yyvsp[-1].exprlist)) call->args.push_back(e); delete (yyvsp[-1].exprlist); (yyval.expr) = call; } -#line 1886 "parser.cpp" +#line 1936 "parser.cpp" break; - case 60: /* postfix_expr: postfix_expr DOT IDENTIFIER */ -#line 256 "parser.y" + case 64: /* postfix_expr: postfix_expr DOT IDENTIFIER */ +#line 297 "parser.y" { (yyval.expr) = new AST::MemberAccess((yyvsp[-2].expr), (yyvsp[0].cstr)); free((yyvsp[0].cstr)); } -#line 1892 "parser.cpp" +#line 1942 "parser.cpp" break; - case 61: /* postfix_expr: postfix_expr LBRACKET expr RBRACKET */ -#line 258 "parser.y" + case 65: /* postfix_expr: postfix_expr LBRACKET expr RBRACKET */ +#line 299 "parser.y" { (yyval.expr) = new AST::Index((yyvsp[-3].expr), (yyvsp[-1].expr)); } -#line 1898 "parser.cpp" +#line 1948 "parser.cpp" break; - case 62: /* postfix_expr: primary_expr */ -#line 260 "parser.y" + case 66: /* postfix_expr: primary_expr */ +#line 301 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 1904 "parser.cpp" +#line 1954 "parser.cpp" break; - case 63: /* opt_args: arg_list */ -#line 264 "parser.y" + case 67: /* opt_args: arg_list */ +#line 305 "parser.y" { (yyval.exprlist) = (yyvsp[0].exprlist); } -#line 1910 "parser.cpp" +#line 1960 "parser.cpp" break; - case 64: /* opt_args: %empty */ -#line 265 "parser.y" + case 68: /* opt_args: %empty */ +#line 306 "parser.y" { (yyval.exprlist) = new std::vector(); } -#line 1916 "parser.cpp" +#line 1966 "parser.cpp" break; - case 65: /* arg_list: arg_list COMMA expr */ -#line 269 "parser.y" + case 69: /* arg_list: arg_list COMMA expr */ +#line 310 "parser.y" { (yyval.exprlist) = (yyvsp[-2].exprlist); (yyvsp[-2].exprlist)->push_back((yyvsp[0].expr)); } -#line 1922 "parser.cpp" +#line 1972 "parser.cpp" break; - case 66: /* arg_list: expr */ -#line 270 "parser.y" + case 70: /* arg_list: expr */ +#line 311 "parser.y" { (yyval.exprlist) = new std::vector(); (yyval.exprlist)->push_back((yyvsp[0].expr)); } -#line 1928 "parser.cpp" +#line 1978 "parser.cpp" break; - case 67: /* primary_expr: INT_LITERAL */ -#line 274 "parser.y" + case 71: /* primary_expr: INT_LITERAL */ +#line 315 "parser.y" { (yyval.expr) = new AST::IntLiteral((yyvsp[0].ival)); } -#line 1934 "parser.cpp" +#line 1984 "parser.cpp" break; - case 68: /* primary_expr: STRING_LITERAL */ -#line 275 "parser.y" + case 72: /* primary_expr: STRING_LITERAL */ +#line 316 "parser.y" { (yyval.expr) = new AST::StringLiteral((yyvsp[0].cstr)); free((yyvsp[0].cstr)); } -#line 1940 "parser.cpp" +#line 1990 "parser.cpp" break; - case 69: /* primary_expr: TRUE */ -#line 276 "parser.y" + case 73: /* primary_expr: TRUE */ +#line 317 "parser.y" { (yyval.expr) = new AST::BoolLiteral(true); } -#line 1946 "parser.cpp" +#line 1996 "parser.cpp" break; - case 70: /* primary_expr: FALSE */ -#line 277 "parser.y" + case 74: /* primary_expr: FALSE */ +#line 318 "parser.y" { (yyval.expr) = new AST::BoolLiteral(false); } -#line 1952 "parser.cpp" +#line 2002 "parser.cpp" break; - case 71: /* primary_expr: IDENTIFIER */ -#line 278 "parser.y" + case 75: /* primary_expr: IDENTIFIER */ +#line 319 "parser.y" { (yyval.expr) = new AST::Identifier((yyvsp[0].cstr)); free((yyvsp[0].cstr)); } -#line 1958 "parser.cpp" +#line 2008 "parser.cpp" break; - case 72: /* primary_expr: type_as_expr */ -#line 279 "parser.y" + case 76: /* primary_expr: type_as_expr */ +#line 320 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 1964 "parser.cpp" +#line 2014 "parser.cpp" break; - case 73: /* primary_expr: LPAREN expr RPAREN */ -#line 280 "parser.y" + case 77: /* primary_expr: LPAREN expr RPAREN */ +#line 321 "parser.y" { (yyval.expr) = (yyvsp[-1].expr); } -#line 1970 "parser.cpp" +#line 2020 "parser.cpp" break; - case 74: /* type_as_expr: type_spec */ -#line 285 "parser.y" + case 78: /* type_as_expr: type_spec */ +#line 326 "parser.y" { (yyval.expr) = new AST::Identifier((yyvsp[0].cstr)); free((yyvsp[0].cstr)); } -#line 1976 "parser.cpp" +#line 2026 "parser.cpp" break; - case 75: /* lvalue: IDENTIFIER */ -#line 289 "parser.y" + case 79: /* lvalue: IDENTIFIER */ +#line 330 "parser.y" { (yyval.expr) = new AST::Identifier((yyvsp[0].cstr)); free((yyvsp[0].cstr)); } -#line 1982 "parser.cpp" +#line 2032 "parser.cpp" break; - case 76: /* lvalue: lvalue DOT IDENTIFIER */ -#line 290 "parser.y" + case 80: /* lvalue: lvalue DOT IDENTIFIER */ +#line 331 "parser.y" { (yyval.expr) = new AST::MemberAccess((yyvsp[-2].expr), (yyvsp[0].cstr)); free((yyvsp[0].cstr)); } -#line 1988 "parser.cpp" +#line 2038 "parser.cpp" break; - case 77: /* lvalue: lvalue LBRACKET expr RBRACKET */ -#line 291 "parser.y" + case 81: /* lvalue: lvalue LBRACKET expr RBRACKET */ +#line 332 "parser.y" { (yyval.expr) = new AST::Index((yyvsp[-3].expr), (yyvsp[-1].expr)); } -#line 1994 "parser.cpp" +#line 2044 "parser.cpp" break; -#line 1998 "parser.cpp" +#line 2048 "parser.cpp" default: break; } @@ -2218,7 +2268,7 @@ yyparse (void) return yyresult; } -#line 294 "parser.y" - - -void yyerror(const char* s) { std::fprintf(stderr, "Parse error at line %d: %s\n", yylineno, s); } +#line 335 "parser.y" + + +void yyerror(const char* s) { std::fprintf(stderr, "Parse error at line %d: %s\n", yylineno, s); } diff --git a/parser.hpp b/parser.hpp index 8d28e61..8d37f6a 100644 --- a/parser.hpp +++ b/parser.hpp @@ -46,11 +46,11 @@ extern int yydebug; #endif /* "%code requires" blocks. */ #line 17 "parser.y" - - #include - namespace AST { - struct Node; struct Program; struct ClassDecl; struct VarDecl; struct Expr; struct Stmt; struct MethodDecl; struct Param; struct Block; - } + + #include + namespace AST { + struct Node; struct Program; struct ClassDecl; struct VarDecl; struct Expr; struct Stmt; struct MethodDecl; struct Param; struct Block; + } #line 56 "parser.hpp" @@ -72,34 +72,35 @@ extern int yydebug; IF = 264, /* IF */ THEN = 265, /* THEN */ ELSE = 266, /* ELSE */ - WHILE = 267, /* WHILE */ - DO = 268, /* DO */ - TRUE = 269, /* TRUE */ - FALSE = 270, /* FALSE */ - COLON = 271, /* COLON */ - SEMICOLON = 272, /* SEMICOLON */ - COMMA = 273, /* COMMA */ - LPAREN = 274, /* LPAREN */ - RPAREN = 275, /* RPAREN */ - LBRACE = 276, /* LBRACE */ - RBRACE = 277, /* RBRACE */ - LBRACKET = 278, /* LBRACKET */ - RBRACKET = 279, /* RBRACKET */ - ASSIGN = 280, /* ASSIGN */ - ARROW = 281, /* ARROW */ - PLUS = 282, /* PLUS */ - MINUS = 283, /* MINUS */ - STAR = 284, /* STAR */ - SLASH = 285, /* SLASH */ - DOT = 286, /* DOT */ - GT = 287, /* GT */ - LT = 288, /* LT */ - EQEQ = 289, /* EQEQ */ - EQUAL = 290, /* EQUAL */ - IDENTIFIER = 291, /* IDENTIFIER */ - TYPE_NAME = 292, /* TYPE_NAME */ - INT_LITERAL = 293, /* INT_LITERAL */ - STRING_LITERAL = 294 /* STRING_LITERAL */ + ELSEIF = 267, /* ELSEIF */ + WHILE = 268, /* WHILE */ + DO = 269, /* DO */ + TRUE = 270, /* TRUE */ + FALSE = 271, /* FALSE */ + COLON = 272, /* COLON */ + SEMICOLON = 273, /* SEMICOLON */ + COMMA = 274, /* COMMA */ + LPAREN = 275, /* LPAREN */ + RPAREN = 276, /* RPAREN */ + LBRACE = 277, /* LBRACE */ + RBRACE = 278, /* RBRACE */ + LBRACKET = 279, /* LBRACKET */ + RBRACKET = 280, /* RBRACKET */ + ASSIGN = 281, /* ASSIGN */ + ARROW = 282, /* ARROW */ + PLUS = 283, /* PLUS */ + MINUS = 284, /* MINUS */ + STAR = 285, /* STAR */ + SLASH = 286, /* SLASH */ + DOT = 287, /* DOT */ + GT = 288, /* GT */ + LT = 289, /* LT */ + EQEQ = 290, /* EQEQ */ + EQUAL = 291, /* EQUAL */ + IDENTIFIER = 292, /* IDENTIFIER */ + TYPE_NAME = 293, /* TYPE_NAME */ + INT_LITERAL = 294, /* INT_LITERAL */ + STRING_LITERAL = 295 /* STRING_LITERAL */ }; typedef enum yytokentype yytoken_kind_t; #endif @@ -109,26 +110,26 @@ extern int yydebug; union YYSTYPE { #line 27 "parser.y" - - long long ival; - char* cstr; - AST::Program* program; - AST::ClassDecl* classdecl; - AST::VarDecl* vardecl; - AST::Expr* expr; - AST::Stmt* stmt; - AST::MethodDecl* methoddecl; - AST::Param* param; - AST::Node* node; - std::vector* classlist; - std::vector* memberlist; - std::vector* varlist; - std::vector* paramlist; - std::vector* stmtlist; - std::vector* exprlist; - std::vector* strlist; - -#line 132 "parser.hpp" + + long long ival; + char* cstr; + AST::Program* program; + AST::ClassDecl* classdecl; + AST::VarDecl* vardecl; + AST::Expr* expr; + AST::Stmt* stmt; + AST::MethodDecl* methoddecl; + AST::Param* param; + AST::Node* node; + std::vector* classlist; + std::vector* memberlist; + std::vector* varlist; + std::vector* paramlist; + std::vector* stmtlist; + std::vector* exprlist; + std::vector* strlist; + +#line 133 "parser.hpp" }; typedef union YYSTYPE YYSTYPE; diff --git a/parser.y b/parser.y index f2dae88..bff846a 100644 --- a/parser.y +++ b/parser.y @@ -45,7 +45,7 @@ AST::Program* g_program = nullptr; } %token CLASS VAR IS END -%token METHOD RETURN IF THEN ELSE +%token METHOD RETURN IF THEN ELSE ELSEIF %token WHILE DO %token TRUE FALSE %token COLON SEMICOLON COMMA @@ -67,8 +67,8 @@ AST::Program* g_program = nullptr; %type opt_params param_list %type param %type type_spec type_list -%type method_body stmt simple_stmt if_stmt while_stmt opt_else -%type stmt_list elseif_list +%type method_body stmt simple_stmt if_stmt while_stmt block_stmt elif_tail opt_else +%type stmt_list %type expr assign_expr equality_expr relational_expr additive_expr multiplicative_expr unary_expr postfix_expr primary_expr lvalue type_as_expr %type arg_list opt_args @@ -187,9 +187,11 @@ method_body stmt_list : stmt_list simple_stmt SEMICOLON { $$ = $1; $1->push_back($2); } | stmt_list if_stmt { $$ = $1; $1->push_back($2); } + | stmt_list while_stmt { $$ = $1; $1->push_back($2); } | stmt_list simple_stmt { $$ = $1; $1->push_back($2); } | simple_stmt SEMICOLON { $$ = new std::vector(); $$->push_back($1); } | if_stmt { $$ = new std::vector(); $$->push_back($1); } + | while_stmt { $$ = new std::vector(); $$->push_back($1); } | simple_stmt { $$ = new std::vector(); $$->push_back($1); } ; @@ -208,48 +210,39 @@ simple_stmt | expr { $$ = new AST::ExprStmt($1); } ; -if_stmt - : IF expr THEN stmt END - { - $$ = new AST::IfStmt($2, $4, new AST::Block()); - } - | IF expr THEN stmt ELSE stmt END - { - $$ = new AST::IfStmt($2, $4, $6); - } - | IF expr THEN stmt elseif_list opt_else END +block_stmt + : stmt_list { - AST::Stmt* tail = $6 ? $6 : static_cast(new AST::Block()); - for (auto it = $5->rbegin(); it != $5->rend(); ++it) { - auto* ifs = dynamic_cast(*it); - if (ifs) { - ifs->elseS = tail; - tail = ifs; - } - } - delete $5; - $$ = new AST::IfStmt($2, $4, tail); + auto* b = new AST::Block(); + for (auto* s : *$1) b->stmts.push_back(s); + delete $1; + $$ = b; } ; -opt_else - : ELSE stmt { $$ = $2; } - | { $$ = nullptr; } +if_stmt + : IF expr THEN block_stmt elif_tail END + { + $$ = new AST::IfStmt($2, $4, $5); + } ; -elseif_list - : elseif_list ELSE IF expr THEN stmt +elif_tail + : ELSEIF expr THEN block_stmt elif_tail { - $$ = $1; - $$->push_back(new AST::IfStmt($4, $6, new AST::Block())); + $$ = new AST::IfStmt($2, $4, $5); } - | ELSE IF expr THEN stmt + | opt_else { - $$ = new std::vector(); - $$->push_back(new AST::IfStmt($3, $5, new AST::Block())); + $$ = $1 ? $1 : static_cast(new AST::Block()); } ; +opt_else + : ELSE block_stmt { $$ = $2; } + | { $$ = nullptr; } + ; + while_stmt : WHILE expr DO stmt_list END { diff --git a/tests/test.o b/tests/test.o new file mode 100644 index 0000000..452c0a8 --- /dev/null +++ b/tests/test.o @@ -0,0 +1,21 @@ +class Types is + var i : Int; + var j : Int; + var s : String; + var b : Bool; +end + +class Main is + var flag : Bool; + method main() : Void => + flag := false; + if flag == false then + output("keywords"); + output(1 + 2 * 3); + output((10 - 5) / 5); + output(true); + output("done") + else + output("never") + end +end diff --git a/tests/test1.o b/tests/test1.o index 3c26240..3c25b0d 100644 --- a/tests/test1.o +++ b/tests/test1.o @@ -1,4 +1,9 @@ -class Point is - var x : Int; - var y : Int; +class Main is + var i : Int; + method main() : Void => + i := 0; + while i < 3 do + output(i); + i := i + 1 + end end diff --git a/tests/test2.o b/tests/test2.o index e906a11..7843c9b 100644 --- a/tests/test2.o +++ b/tests/test2.o @@ -1,4 +1,9 @@ -class Math is - method Add(a : Int, b : Int) : Int => a + b - method Neg(v : Float) : Float => -v +class Main is + var i : Int; + method main() : Void => + if true then + output("true"); + else + output("false"); + end end diff --git a/tests/test3.o b/tests/test3.o index 163be32..7f1d4ad 100644 --- a/tests/test3.o +++ b/tests/test3.o @@ -1,7 +1,14 @@ class Main is - method Run() : Int => - if true then - return 42 + var x : Int; + method main() : Void => + x := 5; + if x < 0 then + output("neg"); + else if x == 0 then + output("zero"); + else if x < 10 then + output("small"); else - return 0 -end \ No newline at end of file + output("big") + end +end diff --git a/tests/test4.o b/tests/test4.o new file mode 100644 index 0000000..66dd971 --- /dev/null +++ b/tests/test4.o @@ -0,0 +1,11 @@ +class Main is + method main() : Int => + if true then + output("then-part"); + return 0; + output("unreachable"); + output("still unreachable") + else + output("else-part") + end +end diff --git a/tests/test5.o b/tests/test5.o new file mode 100644 index 0000000..a8e86bd --- /dev/null +++ b/tests/test5.o @@ -0,0 +1,7 @@ +class Main is + method main() : Int => + output("before"); + return 1; + output("after"); + output("after2") +end diff --git a/tokens.hpp b/tokens.hpp index c673391..5ed661d 100644 --- a/tokens.hpp +++ b/tokens.hpp @@ -7,7 +7,7 @@ enum class TokenKind { CLASS, VAR, IS, END, - METHOD, RETURN, IF, THEN, ELSE, + METHOD, RETURN, IF, THEN, ELSE, ELSEIF, WHILE, DO, TRUEKW, FALSEKW, IDENTIFIER, TYPE_NAME, INT_LITERAL, STRING_LITERAL, @@ -71,6 +71,7 @@ inline const char* TokenKindToString(TokenKind k) { case TokenKind::IF: return "IF"; case TokenKind::THEN: return "THEN"; case TokenKind::ELSE: return "ELSE"; + case TokenKind::ELSEIF: return "ELSEIF"; case TokenKind::WHILE: return "WHILE"; case TokenKind::DO: return "DO"; case TokenKind::TRUEKW: return "TRUE"; From db4436142b97608a7bad077a1bd88eb964cf52c0 Mon Sep 17 00:00:00 2001 From: dorley174 Date: Wed, 19 Nov 2025 21:34:16 +0300 Subject: [PATCH 6/6] added semantic comments while optimize --- mycompiler | Bin 172664 -> 177144 bytes semantic.cpp | 108 +++++++++++++++++++++++---------------------------- semantic.hpp | 3 ++ 3 files changed, 51 insertions(+), 60 deletions(-) diff --git a/mycompiler b/mycompiler index 0f44f774bedb07aa0634b0cb9bc197deddd65121..6a97839fc13d7a847d579e95be378d5047bcaccb 100644 GIT binary patch delta 64883 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 #include -// Helper to get node position (best-effort, using identifiers not storing positions) std::string SemanticAnalyzer::curPos(AST::Node* n) { (void)n; - return ""; // AST nodes currently don't store line/column, so empty + return ""; } SemanticAnalyzer::SemanticAnalyzer() { @@ -16,7 +15,6 @@ SemanticAnalyzer::SemanticAnalyzer() { localsStack.clear(); } -// Build class index void SemanticAnalyzer::indexClasses(AST::Program* p) { for (auto* c : p->classes) { classes[c->name] = c; @@ -26,14 +24,12 @@ void SemanticAnalyzer::indexClasses(AST::Program* p) { SemanticResult SemanticAnalyzer::analyze(AST::Program* p) { result = SemanticResult(); indexClasses(p); - // analyze each class for (auto* c : p->classes) analyzeClass(c); return result; } void SemanticAnalyzer::analyzeClass(AST::ClassDecl* c) { curClass = c; - // fields become available as "locals" inside methods for (auto* m : c->methods) analyzeMethod(m); curClass = nullptr; } @@ -41,21 +37,32 @@ void SemanticAnalyzer::analyzeClass(AST::ClassDecl* c) { void SemanticAnalyzer::analyzeMethod(AST::MethodDecl* m) { curMethod = m; pushScope(); - // declare parameters + declaredLocals.clear(); + usedLocals.clear(); for (auto* p : m->params) { declareLocal(p->name, p->typeName); } - // declare fields (accessible as locals too) for (auto* f : curClass->fields) { declareLocal(f->name, f->typeName); } - // optimize/mutate body before or after checks? We'll do folding first, then checks & other optimizations if (m->body) { - // perform constant folding for expressions inside this method body analyzeBlock(dynamic_cast(m->body)); } else { result.addError("Method " + m->name + " has empty body"); } + for (const auto& name : declaredLocals) { + bool used = false; + for (const auto& u : usedLocals) { + if (u == name) { + used = true; + break; + } + } + if (!used) { + result.warnings.push_back("Variable '" + name + "' is never used in method '" + m->name + "'"); + result.optimizations.push_back("Variable '" + name + "' is unused and can be removed in method '" + m->name + "'"); + } + } popScope(); curMethod = nullptr; } @@ -63,6 +70,7 @@ void SemanticAnalyzer::analyzeMethod(AST::MethodDecl* m) { void SemanticAnalyzer::pushScope() { localsStack.emplace_back(); } + void SemanticAnalyzer::popScope() { if (!localsStack.empty()) localsStack.pop_back(); } @@ -78,12 +86,10 @@ std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { if (auto* sl = dynamic_cast(e)) return std::string("String"); if (auto* bl = dynamic_cast(e)) return std::string("Bool"); if (auto* id = dynamic_cast(e)) { - // lookup locals stack from top for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { auto found = it->find(id->name); if (found != it->end()) return found->second; } - // not found — maybe it's a type-as-expr stored as Identifier node, but in general we warn result.addError("Use of undeclared identifier '" + id->name + "'"); return ""; } @@ -110,9 +116,7 @@ std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { } return "Bool"; case AST::BinOp::Assign: - // lhs should be lvalue: here we take rhs type and compare to declared lhs type if identifier if (auto* lid = dynamic_cast(bin->lhs)) { - // find declared type std::string lhs_type; for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { auto found = it->find(lid->name); @@ -128,7 +132,6 @@ std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { } return lhs_type; } - // assignment to member/index not deeply typed here return rhs; } } @@ -162,11 +165,8 @@ std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { } return ""; } - if (auto* ma = dynamic_cast(e)) { - // try to deduce member type if object has class and field exists (simple) if (auto* objid = dynamic_cast(ma->object)) { - // find name in locals -> type is class name? std::string t; for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { auto found = it->find(objid->name); @@ -176,7 +176,6 @@ std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { result.addError("Unknown object '" + objid->name + "' for member access"); return ""; } - // if t matches a class name, look for field auto cit = classes.find(t); if (cit != classes.end()) { for (auto* f : cit->second->fields) if (f->name == ma->member) return f->typeName; @@ -185,7 +184,6 @@ std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { return ""; } if (auto* idx = dynamic_cast(e)) { - // index expression type inference is complex; skip typeOfExpr(idx->base); typeOfExpr(idx->index); return ""; @@ -195,22 +193,18 @@ std::string SemanticAnalyzer::typeOfExpr(AST::Expr* e) { void SemanticAnalyzer::analyzeBlock(AST::Block* b) { if (!b) return; - // First – recursively fold constants inside expressions and statements for (auto*& s : b->stmts) { - analyzeStmt(s); // analyzeStmt will call analyzeExpr and optimizations + analyzeStmt(s); } - // Remove unreachable code after returns removeUnreachableInBlock(b); } void SemanticAnalyzer::analyzeStmt(AST::Stmt*& s) { if (!s) return; - // IfStmt if (auto* ifs = dynamic_cast(s)) { analyzeExpr(ifs->cond); analyzeStmt(ifs->thenS); analyzeStmt(ifs->elseS); - // after analyzing cond, maybe it's folded to literal; try to simplify simplifyIf(s); return; } @@ -238,11 +232,10 @@ void SemanticAnalyzer::analyzeStmt(AST::Stmt*& s) { return; } if (auto* vds = dynamic_cast(s)) { - // var declaration - register local if (vds->decl) { declareLocal(vds->decl->name, vds->decl->typeName); + declaredLocals.push_back(vds->decl->name); if (vds->decl->init) analyzeExpr(vds->decl->init); - // check init type matches declared type if (vds->decl->init) { auto it = typeOfExpr(vds->decl->init); if (it != "" && it != vds->decl->typeName) { @@ -262,19 +255,14 @@ void SemanticAnalyzer::analyzeStmt(AST::Stmt*& s) { void SemanticAnalyzer::analyzeExpr(AST::Expr*& e) { if (!e) return; - // try constant folding first bool folded = foldConstantsInExpr(e); if (folded) { - // folded expression replaced e; still do type checks on new e } - // then recurse into structure if not literal if (auto* bin = dynamic_cast(e)) { analyzeExpr(bin->lhs); analyzeExpr(bin->rhs); - // assignment: ensure lvalue exists if (bin->op == AST::BinOp::Assign) { if (auto* lid = dynamic_cast(bin->lhs)) { - // must be declared bool found = false; for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { if (it->find(lid->name) != it->end()) { found = true; break; } @@ -288,7 +276,7 @@ void SemanticAnalyzer::analyzeExpr(AST::Expr*& e) { analyzeExpr(un->rhs); return; } - if (auto* call = dynamic_cast(e)) { + if (auto* call = dynamic_cast(e)) { if (auto* id = dynamic_cast(call->callee)) { if (id->name == "output" || id->name == "print") { for (auto*& a : call->args) analyzeExpr(a); @@ -303,7 +291,6 @@ void SemanticAnalyzer::analyzeExpr(AST::Expr*& e) { for (auto*& a : call->args) analyzeExpr(a); return; } - if (auto* ma = dynamic_cast(e)) { analyzeExpr(ma->object); return; @@ -314,44 +301,45 @@ void SemanticAnalyzer::analyzeExpr(AST::Expr*& e) { return; } if (auto* id = dynamic_cast(e)) { - // identifier use check bool found = false; for (auto it = localsStack.rbegin(); it != localsStack.rend(); ++it) { if (it->find(id->name) != it->end()) { found = true; break; } } - if (!found) result.addError("Use of undeclared identifier '" + id->name + "'"); + if (found) { + usedLocals.push_back(id->name); + } else { + result.addError("Use of undeclared identifier '" + id->name + "'"); + } return; } - // literals: nothing to do } bool SemanticAnalyzer::isLiteral(AST::Expr* e) { return dynamic_cast(e) || dynamic_cast(e) || dynamic_cast(e); } -// constant folding implementation bool SemanticAnalyzer::foldConstantsInExpr(AST::Expr*& e) { if (!e) return false; - // recursively fold children first if (auto* bin = dynamic_cast(e)) { bool l = foldConstantsInExpr(bin->lhs); bool r = foldConstantsInExpr(bin->rhs); - // after children folded, try fold this node if (auto* L = dynamic_cast(bin->lhs)) { if (auto* R = dynamic_cast(bin->rhs)) { long long a = L->value; long long b = R->value; if (bin->op == AST::BinOp::Add || bin->op == AST::BinOp::Sub || bin->op == AST::BinOp::Mul || bin->op == AST::BinOp::Div) { - long long res = 0; + long long resv = 0; switch (bin->op) { - case AST::BinOp::Add: res = a + b; break; - case AST::BinOp::Sub: res = a - b; break; - case AST::BinOp::Mul: res = a * b; break; - case AST::BinOp::Div: if (b == 0) { result.addError("Division by zero in constant expression"); return false; } res = a / b; break; + case AST::BinOp::Add: resv = a + b; break; + case AST::BinOp::Sub: resv = a - b; break; + case AST::BinOp::Mul: resv = a * b; break; + case AST::BinOp::Div: + if (b == 0) { result.addError("Division by zero in constant expression"); return false; } + resv = a / b; break; default: break; } delete e; - e = new AST::IntLiteral(res); + e = new AST::IntLiteral(resv); return true; } if (bin->op == AST::BinOp::Gt || bin->op == AST::BinOp::Lt) { @@ -370,7 +358,6 @@ bool SemanticAnalyzer::foldConstantsInExpr(AST::Expr*& e) { } } } - // bool equality folding if (auto* LB = dynamic_cast(bin->lhs)) { if (auto* RB = dynamic_cast(bin->rhs)) { if (bin->op == AST::BinOp::Eq) { @@ -416,31 +403,31 @@ bool SemanticAnalyzer::foldConstantsInExpr(AST::Expr*& e) { void SemanticAnalyzer::simplifyIf(AST::Stmt*& s) { if (!s) return; if (auto* ifs = dynamic_cast(s)) { - // attempt to see if cond is BoolLiteral if (auto* bl = dynamic_cast(ifs->cond)) { if (bl->value) { - // replace s with thenS (which may be a Block or single stmt) + if (ifs->elseS) { + result.optimizations.push_back("Removed else-branch because condition is always true"); + } else { + result.optimizations.push_back("Simplified 'if true' condition"); + } AST::Stmt* newstmt = nullptr; - // if thenS is a Block, keep it if (auto* tb = dynamic_cast(ifs->thenS)) { - // replace by block - // clone pointer ownership: delete whole if-stmt and use thenS pointer newstmt = tb; ifs->thenS = nullptr; ifs->elseS = nullptr; - delete ifs->cond; // cond is BoolLiteral - // replace s + delete ifs->cond; s = newstmt; - // NOTE: caller must not double-delete thenS (we transferred) } else { newstmt = ifs->thenS; ifs->thenS = nullptr; ifs->elseS = nullptr; - delete ifs; // cond already deleted inside destructor? destructor deletes cond and thenS/elseS - we moved pointers so careful + delete ifs; s = newstmt; } } else { - // cond is false -> replace with elseS or empty block + if (ifs->thenS) { + result.optimizations.push_back("Removed then-branch because condition is always false"); + } if (ifs->elseS) { AST::Stmt* newstmt = ifs->elseS; ifs->elseS = nullptr; @@ -448,14 +435,12 @@ void SemanticAnalyzer::simplifyIf(AST::Stmt*& s) { delete ifs; s = newstmt; } else { - // replace with empty block delete ifs; s = new AST::Block(); } } } } else if (auto* blk = dynamic_cast(s)) { - // walk statements and try simplify nested ifs for (auto*& st : blk->stmts) { simplifyIf(st); } @@ -466,15 +451,18 @@ void SemanticAnalyzer::removeUnreachableInBlock(AST::Block* b) { if (!b) return; std::vector newstmts; bool seenReturn = false; + bool removedAny = false; for (auto* s : b->stmts) { if (seenReturn) { - // unreachable: free s delete s; + removedAny = true; continue; } newstmts.push_back(s); if (dynamic_cast(s)) seenReturn = true; - // if we simplified an if into block that contains return at end, this will handle later + } + if (removedAny) { + result.optimizations.push_back("Removed unreachable statements after return"); } b->stmts = std::move(newstmts); } diff --git a/semantic.hpp b/semantic.hpp index 086d797..22cfef0 100644 --- a/semantic.hpp +++ b/semantic.hpp @@ -28,6 +28,9 @@ class SemanticAnalyzer { SemanticResult result; + std::vector declaredLocals; + std::vector usedLocals; + void indexClasses(AST::Program* p); void analyzeClass(AST::ClassDecl* c); void analyzeMethod(AST::MethodDecl* m);