From 2f66c31729f8b50205035fb2549758eb4a596830 Mon Sep 17 00:00:00 2001 From: Stefano Sanfilippo Date: Tue, 2 Dec 2014 16:22:03 +0100 Subject: [PATCH] Getting rid of explicit stacks with more left-recursive rules. As a result, the grammar should be more readable. --- Monicelli.ypp | 127 ++++++++++++++++++++++---------------------------- Nodes.cpp | 10 ++-- Nodes.hpp | 17 +++++-- 3 files changed, 74 insertions(+), 80 deletions(-) diff --git a/Monicelli.ypp b/Monicelli.ypp index 7e6664a..8840c34 100644 --- a/Monicelli.ypp +++ b/Monicelli.ypp @@ -1,6 +1,6 @@ /* * Monicelli: an esoteric language compiler - * + * * Copyright (C) 2014 Stefano Sanfilippo * * This program is free software: you can redistribute it and/or modify @@ -72,16 +72,6 @@ %nonassoc LOWER_THAN_ELSE %nonassoc BRANCH_ELSE -%code { -#include - -static std::stack stmtStack; -static std::stack argsStack; -static std::stack paramsStack; -static std::stack branchCaseStack; -static std::stack funArgStack; -} - %union { int intval; double floatval; @@ -96,17 +86,21 @@ static std::stack funArgStack; Input* inputval; Abort* abortval; Branch* branchval; + Branch::Body* branchbodyval; VarDeclaration* declval; Assignment* assignval; Loop* loopval; BranchCase *caseval; + BranchCaseList *caselistval; Return* returnval; Expression* expressionval; + ExpressionList* exprlistval; SemiExpression *semiexpval; Id* idval; Number* numericval; Function* funval; FunArg *argval; + FunArgList *arglistval; Main* mainval; } @@ -114,23 +108,26 @@ static std::stack funArgStack; %type FLOAT %type ID %type TYPENAME fun_return - %type statement -%type branch_body +%type statements +%type branch_body %type assert_stmt %type fun_call %type arg_decl +%type args_decl args %type fun_decl %type print_stmt %type input_stmt %type abort_stmt %type branch_stmt %type case_stmt +%type cases %type var_decl %type assign_stmt %type loop_stmt %type return_stmt %type expression maybe_expression simple_expression var_init +%type call_arglist call_args %type semi_expression %type variable %type numeric @@ -155,31 +152,24 @@ fun_decls: fun_decls ; fun_decl: - FUN_DECL fun_return ID { - funArgStack.push(new FunArgList()); - } args FUN_END { - stmtStack.push(new StatementList()); - } - statements { - $$ = new Function(new Id($3), $2, funArgStack.top(), stmtStack.top()); - funArgStack.pop(); - stmtStack.pop(); + FUN_DECL fun_return ID args FUN_END statements { + $$ = new Function(new Id($3), $2, $4, $6); } ; fun_return: /* epsilon */ { $$ = Type::VOID; } | TYPENAME { $$ = $1; } ; args: - /* epsilon */ | PARAMS args_decl + /* epsilon */ { $$ = new FunArgList(); }| PARAMS args_decl { $$ = $2; } ; args_decl: arg_decl { - funArgStack.top()->push_back($1); + $$ = new FunArgList(); + $$->push_back($1); } - | arg_decl { - funArgStack.top()->push_back($1); + | args_decl COMMA arg_decl { + $1->push_back($3); } - COMMA args_decl ; arg_decl: variable pointer TYPENAME { @@ -187,23 +177,20 @@ arg_decl: } ; main: - MAIN { - stmtStack.push(new StatementList()); - } - statements { - $$ = new Main(stmtStack.top()); - stmtStack.pop(); + MAIN statements { + $$ = new Main($2); } ; statements: /* epsilon */ { + $$ = new StatementList(); } - | statement { - if ($1 != nullptr) { - stmtStack.top()->push_back($1); + | statements statement { + if ($2 != nullptr) { + $1->push_back($2); } + $$ = $1; } - statements ; statement: assert_stmt { $$ = $1; } @@ -264,61 +251,59 @@ maybe_expression: expression { $$ = $1; } | /* epsilon */ { $$ = nullptr; } ; loop_stmt: - LOOP_BEGIN { - stmtStack.push(new StatementList()); - } - statements LOOP_CONDITION expression { - $$ = new Loop(stmtStack.top(), $5); - stmtStack.pop(); + LOOP_BEGIN statements LOOP_CONDITION expression { + $$ = new Loop($2, $4); } ; branch_stmt: - BRANCH_CONDITION variable BRANCH_BEGIN { - branchCaseStack.push(new BranchCaseList()); - } - branch_body BRANCH_END { - $$ = new Branch($2, branchCaseStack.top(), $5); - branchCaseStack.pop(); + BRANCH_CONDITION variable BRANCH_BEGIN branch_body BRANCH_END { + $$ = new Branch($2, $4); } ; branch_body: cases %prec LOWER_THAN_ELSE { - $$ = nullptr; + $$ = new Branch::Body($1); } - | cases BRANCH_ELSE COLON { - stmtStack.push(new StatementList()); - } - statements { - $$ = stmtStack.top(); - stmtStack.pop(); + | cases BRANCH_ELSE COLON statements { + $$ = new Branch::Body($1, $4); } ; cases: - case_stmt | case_stmt CASE_END cases + case_stmt { + $$ = new BranchCaseList(); + $$->push_back($1); + } + | cases CASE_END case_stmt { + $1->push_back($3); + $$ = $1; + } ; case_stmt: - semi_expression COLON { - stmtStack.push(new StatementList()); - } statements { - branchCaseStack.top()->push_back(new BranchCase($1, stmtStack.top())); - stmtStack.pop(); + semi_expression COLON statements { + $$ = new BranchCase($1, $3); } ; fun_call: - FUN_CALL { - argsStack.push(new ExpressionList()); - } - ID call_args FUN_END { - $$ = new FunctionCall(new Id($3), argsStack.top()); - argsStack.pop(); + FUN_CALL ID call_args FUN_END { + $$ = new FunctionCall(new Id($2), $3); } ; call_args: - /* epsilon */ | PARAMS call_arglist + /* epsilon */ { + $$ = new ExpressionList(); + } + | PARAMS call_arglist { + $$ = $2; + } ; call_arglist: - expression { argsStack.top()->push_back($1); } - | expression { argsStack.top()->push_back($1); } COMMA call_arglist + expression { + $$ = new ExpressionList(); + $$->push_back($1); + } + | call_arglist COMMA expression { + $$->push_back($3); + } ; abort_stmt: ABORT { diff --git a/Nodes.cpp b/Nodes.cpp index 3a33b50..002b2bd 100644 --- a/Nodes.cpp +++ b/Nodes.cpp @@ -122,9 +122,9 @@ void Branch::emit(std::ostream &stream, int indent) { stream << "if ("; var->emit(stream); - if (cases->size() > 0) { - BranchCase *last = cases->back(); - for (BranchCase *c: *cases) { + if (body->cases->size() > 0) { + BranchCase *last = body->cases->back(); + for (BranchCase *c: *body->cases) { c->emit(stream, indent + 1); if (c != last) { stream << " else if ("; @@ -133,12 +133,12 @@ void Branch::emit(std::ostream &stream, int indent) { } } - if (els == nullptr) { + if (body->els == nullptr) { return; } stream << " else {\n"; - els->emit(stream, indent + 1); + body->els->emit(stream, indent + 1); emitIndent(stream, indent); stream << "}"; } diff --git a/Nodes.hpp b/Nodes.hpp index b7e18c3..546a68e 100644 --- a/Nodes.hpp +++ b/Nodes.hpp @@ -265,14 +265,23 @@ typedef PointerList BranchCaseList; class Branch: public Statement { public: - Branch(Id *v, BranchCaseList *c, StatementList *e): - var(v), cases(c), els(e) {} + struct Body { + public: + Body(BranchCaseList *c, StatementList *e = nullptr): cases(c), els(e) {} + + private: + Pointer cases; + Pointer els; + + friend class Branch; + }; + + Branch(Id *v, Branch::Body *b): var(v), body(b) {} virtual void emit(std::ostream &stream, int indent = 0); private: Pointer var; - Pointer cases; - Pointer els; + Pointer body; };