Skip to content

Commit

Permalink
Move block statement to statement
Browse files Browse the repository at this point in the history
  • Loading branch information
leewei05 committed Nov 30, 2023
1 parent c217bf8 commit 939323a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
9 changes: 4 additions & 5 deletions include/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,8 @@ struct NullStmtNode : public StmtNode {
};

struct IfStmtNode : public StmtNode {
IfStmtNode(std::unique_ptr<ExprNode> expr,
std::unique_ptr<BlockStmtNode> then,
std::unique_ptr<BlockStmtNode> or_else = {})
IfStmtNode(std::unique_ptr<ExprNode> expr, std::unique_ptr<StmtNode> then,
std::unique_ptr<StmtNode> or_else = {})
: predicate{std::move(expr)},
then{std::move(then)},
or_else{std::move(or_else)} {}
Expand All @@ -105,8 +104,8 @@ struct IfStmtNode : public StmtNode {
virtual void Accept(ModifyingVisitor&) override;

std::unique_ptr<ExprNode> predicate;
std::unique_ptr<BlockStmtNode> then;
std::unique_ptr<BlockStmtNode> or_else;
std::unique_ptr<StmtNode> then;
std::unique_ptr<StmtNode> or_else;
};

struct ReturnStmtNode : public StmtNode {
Expand Down
28 changes: 22 additions & 6 deletions parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ extern std::unique_ptr<AstNode> program;
%left '+' '-'
%left '*' '/' '%'

// Resolve the ambiguity in the "dangling-else" grammar.
// Example: IF '(' expr ')' IF '(' expr ')' stmt • ELSE stmt
// Yacc has two options to make, either shift or reduce:
// Shift derivation
// stmt
// ↳ 13: IF '(' expr ')' stmt
// ↳ 14: IF '(' expr ')' stmt • ELSE stmt
// Reduce derivation
// stmt
// ↳ 14: IF '(' expr ')' stmt ELSE stmt
// ↳ 13: IF '(' expr ')' stmt •
//
// Our goal is to find the closest IF for ELSE, so we tell Yacc to shift.
// ELSE has a higher precendence than IF due to increasing precedence order.
%precedence IF
%precedence ELSE

%start entry

%%
Expand All @@ -74,15 +91,12 @@ entry: main_func {
}
;

/* TODO: mix declarations and statements in compound statement */
main_func: INT MAIN '(' ')' block {
$$ = $5;
}
;

block: '{' decls stmts '}' {
$$ = std::make_unique<BlockStmtNode>($2, $3);
}
block: '{' decls stmts '}' { $$ = std::make_unique<BlockStmtNode>($2, $3); }
;

decls: decls decl {
Expand All @@ -109,8 +123,10 @@ stmts: stmts stmt {
stmt: ';' { $$ = std::make_unique<NullStmtNode>(); }
| RETURN expr ';' { $$ = std::make_unique<ReturnStmtNode>($2); }
| expr ';' { $$ = std::make_unique<ExprStmtNode>($1); }
| IF '(' expr ')' block { $$ = std::make_unique<IfStmtNode>($3, $5); }
| IF '(' expr ')' block ELSE block { $$ = std::make_unique<IfStmtNode>($3, $5, $7); }
| block { $$ = $1; }
/* Assigns the precedence IF to this rule */
| IF '(' expr ')' stmt %prec IF { $$ = std::make_unique<IfStmtNode>($3, $5); }
| IF '(' expr ')' stmt ELSE stmt { $$ = std::make_unique<IfStmtNode>($3, $5, $7); }
;

expr: ID { $$ = std::make_unique<IdExprNode>($1); }
Expand Down

0 comments on commit 939323a

Please sign in to comment.