Skip to content

Commit

Permalink
Adapt session parser to existing validation code
Browse files Browse the repository at this point in the history
Ref. #291
  • Loading branch information
treiher committed Aug 25, 2020
1 parent 9ae4bcf commit 5d772d6
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 23 deletions.
22 changes: 21 additions & 1 deletion rflx/parser/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ def qualified_identifier() -> Token:


def variable() -> Token:
return delimitedList(unqualified_identifier(), delim=".").setParseAction(parse_variable)


def qualified_variable() -> Token:
return Group(qualified_identifier()).setParseAction(
lambda t: Variable(t[0][0], location=t[0][0].location)
)
Expand Down Expand Up @@ -296,7 +300,9 @@ def expression(restricted: bool = False) -> Token:
base = concatenation | numeric_literal() | string_literal()
if not restricted:
base |= quantified_expression | comprehension | call | conversion | message_aggregate
base |= variable()
base |= variable()
else:
base |= qualified_variable()

expr <<= infixNotation(
base,
Expand Down Expand Up @@ -880,6 +886,20 @@ def parse_identifier(string: str, location: int, tokens: ParseResults) -> ID:
return ID(tokens[0], locn)


@fatalexceptions
def parse_variable(string: str, location: int, tokens: ParseResults) -> Union[Variable, Selected]:
assert 1 <= len(tokens) <= 2
assert tokens[0].location
assert tokens[-1].location

locn = Location(start=tokens[0].location.start, end=tokens[-1].location.end)

if len(tokens) == 2:
return Selected(Variable(tokens[0], location=locn), tokens[1], location=locn)

return Variable(tokens[0], location=locn)


@fatalexceptions
def parse_suffix(string: str, location: int, tokens: ParseResults) -> Attribute:
result = tokens[0][0]
Expand Down
62 changes: 40 additions & 22 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ def test_grammar_expression_numeric_literal(string: str, expected: Expr) -> None
assert actual.location


@pytest.mark.parametrize("string,expected", [("X", Variable("X")), ("X.Y", Variable("X.Y"))])
@pytest.mark.parametrize(
"string,expected", [("X", expr.Variable("X")), ("X.Y", expr.Selected(expr.Variable("X"), "Y"))]
)
def test_grammar_variable(string: str, expected: decl.Declaration) -> None:
actual = grammar.variable().parseString(string, parseAll=True)[0]
assert actual == expected
Expand Down Expand Up @@ -326,15 +328,17 @@ def test_grammar_logical_expression_error(string: str, error: Expr) -> None:
),
(
"[for X in Y => X.A]",
expr.Comprehension("X", expr.Variable("Y"), expr.Variable("X.A"), expr.TRUE),
expr.Comprehension(
"X", expr.Variable("Y"), expr.Selected(expr.Variable("X"), "A"), expr.TRUE,
),
),
(
"[for X in Y => X.A when X.B = Z]",
expr.Comprehension(
"X",
expr.Variable("Y"),
expr.Variable("X.A"),
expr.Equal(expr.Variable("X.B"), expr.Variable("Z")),
expr.Selected(expr.Variable("X"), "A"),
expr.Equal(expr.Selected(expr.Variable("X"), "B"), expr.Variable("Z")),
),
),
(
Expand All @@ -361,7 +365,7 @@ def test_grammar_expression_base(string: str, expected: Expr) -> None:
"string,expected",
[
("X'Valid = True", expr.Equal(expr.Valid(expr.Variable("X")), expr.Variable("True"))),
("X.Y /= Z", expr.NotEqual(expr.Variable("X.Y"), expr.Variable("Z"))),
("X.Y /= Z", expr.NotEqual(expr.Selected(expr.Variable("X"), "Y"), expr.Variable("Z"))),
(
"X = Y and Y /= Z",
expr.And(
Expand Down Expand Up @@ -389,26 +393,34 @@ def test_grammar_expression_base(string: str, expected: Expr) -> None:
expr.Or(
expr.Or(
expr.Equal(expr.Valid(expr.Variable("X")), expr.Variable("False")),
expr.NotEqual(expr.Variable("X.A"), expr.Variable("A")),
expr.NotEqual(expr.Selected(expr.Variable("X"), "A"), expr.Variable("A")),
),
expr.NotEqual(expr.Variable("X.B"), expr.Variable("B")),
expr.NotEqual(expr.Selected(expr.Variable("X"), "B"), expr.Variable("B")),
),
And(
expr.Equal(expr.Variable("X.C"), expr.Number(0)),
expr.NotIn(expr.Variable("X.D"), expr.Variable("X.E")),
expr.Equal(expr.Selected(expr.Variable("X"), "C"), expr.Number(0)),
expr.NotIn(
expr.Selected(expr.Variable("X"), "D"),
expr.Selected(expr.Variable("X"), "E"),
),
),
),
),
(
"for some A in X.B => (A.T = P.E and (G.E not in P.S (A.D).V))",
expr.ForSomeIn(
"A",
expr.Variable("X.B"),
expr.Selected(expr.Variable("X"), "B"),
And(
expr.Equal(expr.Variable("A.T"), expr.Variable("P.E")),
expr.Equal(
expr.Selected(expr.Variable("A"), "T"),
expr.Selected(expr.Variable("P"), "E"),
),
expr.NotIn(
expr.Variable("G.E"),
expr.Selected(expr.Conversion("P.S", expr.Variable("A.D")), "V"),
expr.Selected(
expr.Conversion("P.S", expr.Selected(expr.Variable("A"), "D")), "V",
),
),
),
),
Expand All @@ -420,7 +432,7 @@ def test_grammar_expression_base(string: str, expected: Expr) -> None:
"G.E not in P.S (E.D).V",
expr.NotIn(
expr.Variable("G.E"),
expr.Selected(expr.Conversion("P.S", expr.Variable("E.D")), "V"),
expr.Selected(expr.Conversion("P.S", expr.Selected(expr.Variable("E"), "D")), "V"),
),
),
(
Expand All @@ -429,8 +441,8 @@ def test_grammar_expression_base(string: str, expected: Expr) -> None:
expr.Comprehension(
"E",
expr.Variable("L"),
expr.Variable("E.B"),
expr.Equal(expr.Variable("E.T"), expr.Variable("A")),
expr.Selected(expr.Variable("E"), "B"),
expr.Equal(expr.Selected(expr.Variable("E"), "T"), expr.Variable("A")),
)
),
),
Expand All @@ -442,8 +454,8 @@ def test_grammar_expression_base(string: str, expected: Expr) -> None:
expr.Comprehension(
"E",
expr.Variable("L"),
expr.Variable("E.B"),
expr.Equal(expr.Variable("E.T"), expr.Variable("A")),
expr.Selected(expr.Variable("E"), "B"),
expr.Equal(expr.Selected(expr.Variable("E"), "T"), expr.Variable("A")),
)
),
"D",
Expand All @@ -461,17 +473,20 @@ def test_grammar_expression_base(string: str, expected: Expr) -> None:
expr.Head(
expr.Comprehension(
"E",
expr.Variable("C.A"),
expr.Selected(expr.Variable("C"), "A"),
expr.Variable("E"),
expr.Equal(expr.Variable("E.T"), expr.Variable("P.L")),
expr.Equal(
expr.Selected(expr.Variable("E"), "T"),
expr.Selected(expr.Variable("P"), "L"),
),
)
),
"D",
),
),
"H",
),
expr.Equal(expr.Variable("S.G"), expr.Variable("G")),
expr.Equal(expr.Selected(expr.Variable("S"), "G"), expr.Variable("G")),
),
expr.Variable("False"),
),
Expand Down Expand Up @@ -575,8 +590,11 @@ def test_grammar_variable_declaration(string: str, expected: decl.Declaration) -
@pytest.mark.parametrize(
"string,expected",
[
("A : B renames C", decl.RenamingDeclaration("A", "B", Variable("C"))),
("A : B renames C.D", decl.RenamingDeclaration("A", "B", Variable("C.D"))),
("A : B renames C", decl.RenamingDeclaration("A", "B", expr.Variable("C"))),
(
"A : B renames C.D",
decl.RenamingDeclaration("A", "B", expr.Selected(expr.Variable("C"), "D")),
),
],
)
def test_grammar_renaming_declaration(string: str, expected: decl.Declaration) -> None:
Expand Down

0 comments on commit 5d772d6

Please sign in to comment.