Fix: add assignment as right-associative expression
`=` was missing from the Pratt table, causing `a = b;` to fail with "expected `;`, found `=`". Assignment is now BinaryOp::Assign with binding power (2, 2) — lowest precedence, right-associative — so `a = b = c` parses as `a = (b = c)`.
This commit is contained in:
22
GRAMMAR.ebnf
22
GRAMMAR.ebnf
@@ -33,7 +33,23 @@ top_level_def = func_def
|
||||
(* Expressions *)
|
||||
(* ================================================================ *)
|
||||
|
||||
expr = or_expr ;
|
||||
expr = assign_expr ;
|
||||
|
||||
|
||||
(* --- Assignment (lowest-precedence binary operator) --- *)
|
||||
(* *)
|
||||
(* Uses token `=`; right-associative via recursion. *)
|
||||
(* The optional form encodes at-most-one assignment target: chains *)
|
||||
(* like `a = b = c` parse as `a = (b = c)` thanks to right *)
|
||||
(* recursion. *)
|
||||
(* *)
|
||||
(* LL(1): after or_expr, peek at next token. *)
|
||||
(* "=" → consume and recurse into assign_expr *)
|
||||
(* other → return the or_expr as-is *)
|
||||
(* "=" is not in FIRST(stmt), so expr_stmt can still be *)
|
||||
(* distinguished from other statement kinds. *)
|
||||
|
||||
assign_expr = or_expr , [ "=" , assign_expr ] ;
|
||||
|
||||
|
||||
(* --- Logical OR (lowest-precedence binary operator) --- *)
|
||||
@@ -165,7 +181,9 @@ arg_list = [ expr , { "," , expr } ] ;
|
||||
(* if_stmt and while_stmt use expr_ns for their condition. *)
|
||||
(* All other expression positions use the full expr. *)
|
||||
|
||||
expr_ns = or_expr_ns ;
|
||||
expr_ns = assign_expr_ns ;
|
||||
|
||||
assign_expr_ns = or_expr_ns , [ "=" , assign_expr_ns ] ;
|
||||
|
||||
or_expr_ns = and_expr_ns , { "or" , and_expr_ns } ;
|
||||
and_expr_ns = bitor_expr_ns , { "and" , bitor_expr_ns } ;
|
||||
|
||||
Reference in New Issue
Block a user