From e8a611a246675a02681c4c03bb16b2bd69665612 Mon Sep 17 00:00:00 2001 From: Lai-YT <381xvmvbib@gmail.com> Date: Fri, 1 Dec 2023 00:44:32 +0800 Subject: [PATCH] Rename precedence to resolve confusion 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`. --- parser.y | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/parser.y b/parser.y index cf919135..85e48864 100644 --- a/parser.y +++ b/parser.y @@ -79,8 +79,9 @@ extern std::unique_ptr 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 @@ -127,7 +128,7 @@ stmt: ';' { $$ = std::make_unique(); } | RETURN expr ';' { $$ = std::make_unique($2); } | expr ';' { $$ = std::make_unique($1); } | block { $$ = $1; } - | IF '(' expr ')' stmt %prec IF { $$ = std::make_unique($3, $5); } + | IF '(' expr ')' stmt %prec IF_WITHOUT_ELSE { $$ = std::make_unique($3, $5); } | IF '(' expr ')' stmt ELSE stmt { $$ = std::make_unique($3, $5, $7); } ;