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 19, 2020
1 parent eb62f83 commit 20d6146
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 24 deletions.
24 changes: 22 additions & 2 deletions rflx/parser/grammar.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# pylint: disable=too-many-lines
import traceback
from typing import Callable, Dict, List, Tuple
from typing import Callable, Dict, List, Tuple, Union

from pyparsing import (
CaselessKeyword,
Expand Down Expand Up @@ -136,6 +136,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 @@ -297,7 +301,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 @@ -881,6 +887,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 20d6146

Please sign in to comment.