Skip to content

Commit

Permalink
Fix grammar to be lalr compatible and extend evaluation and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
julia-sprenger committed Oct 9, 2024
1 parent 4892341 commit 8c1b806
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 19 deletions.
6 changes: 4 additions & 2 deletions src/larktools/ebnf_grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
// but without the fancy tree shaping directives explained at
// https://lark-parser.readthedocs.io/en/stable/tree_construction.html
multi_line_block: arith_expr | composed_lines | _NL* multi_line_block _NL*
composed_lines: arith_expr _NL multi_line_block
line: arith_expr
multi_line_block: (line _NL? | _NL )*
arith_expr: sum
sum: product | addition | subtraction
Expand Down
28 changes: 13 additions & 15 deletions src/larktools/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,20 @@ def eval_bracketed_arith_expr(node, env):
assert get_name(child) == "arith_expr"
return eval_arith_expr(child, env)

def eval_composed_lines(node, env):
# the newline break does not appear as child node
# return only the result of the latter evaluation
child1 = get_children(node)[0]
child2 = get_children(node)[1]
assert get_name(child1) == "arith_expr"
eval_arith_expr(child1, env)
assert get_name(child2) == "multi_line_block"
return eval_multi_line_block(child2, env)

def eval_multi_line_block(node, env):
# this can be either an arithmetic expression or
# composed lines
def eval_line(node, env):
# this is the content of a single line of input
child = get_children(node)[0]
child_name = get_name(child)
if child_name == "arith_expr":
return eval_arith_expr(child, env)
elif child_name == "composed_lines":
return eval_composed_lines(child, env)

def eval_multi_line_block(node, env):
# this can be either an arithmetic expression or
# composed lines
children = get_children(node)
for child in children:
child_name = get_name(child)
assert child_name == "line"
res = eval_line(child, env)
return res

7 changes: 5 additions & 2 deletions tests/test_syntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def _parse_and_assert(expression: str, expected: Union[int, float]) -> None:
assert expected == res

def test_multi_line():
_parse_and_assert("5\n8",8)
_parse_and_assert("5\n8", 8)
_parse_and_assert("\n\n\n8", 8)
_parse_and_assert("8\n\n\n", 8)
_parse_and_assert("5+5\n3+4\n1+2", 3)
_parse_and_assert("\n\n5\n\n3\8", 8)
_parse_and_assert("\n\n5\n\n3\n8", 8)

0 comments on commit 8c1b806

Please sign in to comment.