Skip to content

Commit

Permalink
Rename precedence to resolve confusion
Browse files Browse the repository at this point in the history
The precedence had the same name as the token, while the former one is
used as a placeholder for the precedence. Therefore, it's better for
them to use different names to avoid possible confusion.
The `%prec IF_WITHOUT_ELSE` simply instructs Bison that the rule `IF
'(' expr ')' stmt` has the same precedence as `IF_WITHOUT_ELSE`.
  • Loading branch information
Lai-YT authored and leewei05 committed Nov 30, 2023
1 parent 063afd2 commit e8a611a
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ extern std::unique_ptr<AstNode> program;
// ↳ 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
// Since the token "ELSE" has a higher precedence than the production rule
// "if without else", Yacc shifts to "ELSE" instead of reducing with the rule.
%precedence IF_WITHOUT_ELSE
%precedence ELSE

%start entry
Expand Down Expand Up @@ -127,7 +128,7 @@ stmt: ';' { $$ = std::make_unique<NullStmtNode>(); }
| RETURN expr ';' { $$ = std::make_unique<ReturnStmtNode>($2); }
| expr ';' { $$ = std::make_unique<ExprStmtNode>($1); }
| block { $$ = $1; }
| IF '(' expr ')' stmt %prec IF { $$ = std::make_unique<IfStmtNode>($3, $5); }
| IF '(' expr ')' stmt %prec IF_WITHOUT_ELSE { $$ = std::make_unique<IfStmtNode>($3, $5); }
| IF '(' expr ')' stmt ELSE stmt { $$ = std::make_unique<IfStmtNode>($3, $5, $7); }
;

Expand Down

0 comments on commit e8a611a

Please sign in to comment.