Added ZeroAndMore and OneAndMore to BNF. BNF expressions can now be captured
This commit is contained in:
+26
-47
@@ -26,6 +26,7 @@ def get_context():
|
||||
("'foo'+", OneOrMore(StrMatch("foo"))),
|
||||
("1 | 2 | 3", OrderedChoice(StrMatch("1"), StrMatch("2"), StrMatch("3"))),
|
||||
("1|2|3", OrderedChoice(StrMatch("1"), StrMatch("2"), StrMatch("3"))),
|
||||
("1'|' 2 '|' 3", Sequence(StrMatch("1"), StrMatch("|"), StrMatch("2"), StrMatch("|"), StrMatch("3"))),
|
||||
("1 2 'foo'", Sequence(StrMatch("1"), StrMatch("2"), StrMatch("foo"))),
|
||||
("1 2 | 3 4+", OrderedChoice(
|
||||
Sequence(StrMatch("1"), StrMatch("2")),
|
||||
@@ -39,6 +40,29 @@ def get_context():
|
||||
("(1|*) +", Sequence(OrderedChoice(StrMatch("1"), StrMatch("*")), StrMatch("+"))),
|
||||
("1, :&", Sequence(StrMatch("1"), StrMatch(","), StrMatch(":"), StrMatch("&"))),
|
||||
("(1 )", StrMatch("1")),
|
||||
("foo", ConceptMatch("foo")),
|
||||
("foo*", ZeroOrMore(ConceptMatch("foo"))),
|
||||
("foo 'and' bar+", Sequence(ConceptMatch("foo"), StrMatch("and"), OneOrMore(ConceptMatch("bar")))),
|
||||
("foo | bar?", OrderedChoice(ConceptMatch("foo"), Optional(ConceptMatch("bar")))),
|
||||
("'str' = var", Sequence(StrMatch("str"), StrMatch("="), ConceptMatch("var"))),
|
||||
("'str''='var", Sequence(StrMatch("str"), StrMatch("="), ConceptMatch("var"))),
|
||||
("'str'=var", StrMatch("str", rule_name="var")),
|
||||
("'foo'?=var", Optional(StrMatch("foo"), rule_name="var")),
|
||||
("('foo'?)=var", Optional(StrMatch("foo"), rule_name="var")),
|
||||
("'foo'*=var", ZeroOrMore(StrMatch("foo"), rule_name="var")),
|
||||
("('foo'*)=var", ZeroOrMore(StrMatch("foo"), rule_name="var")),
|
||||
("'foo'+=var", OneOrMore(StrMatch("foo"), rule_name="var")),
|
||||
("('foo'+)=var", OneOrMore(StrMatch("foo"), rule_name="var")),
|
||||
("'foo'=var?", Optional(StrMatch("foo", rule_name="var"))),
|
||||
("('foo'=var)?", Optional(StrMatch("foo", rule_name="var"))),
|
||||
("'foo'=var*", ZeroOrMore(StrMatch("foo", rule_name="var"))),
|
||||
("('foo'=var)*", ZeroOrMore(StrMatch("foo", rule_name="var"))),
|
||||
("'foo'=var+", OneOrMore(StrMatch("foo", rule_name="var"))),
|
||||
("('foo'=var)+", OneOrMore(StrMatch("foo", rule_name="var"))),
|
||||
("(1 | 2 | 3)=var", OrderedChoice(StrMatch("1"), StrMatch("2"), StrMatch("3"), rule_name="var")),
|
||||
("(1 2)=var", Sequence(StrMatch("1"), StrMatch("2"), rule_name="var")),
|
||||
("(1 2)+=var", OneOrMore(Sequence(StrMatch("1"), StrMatch("2")), rule_name="var")),
|
||||
("(1 2)=var+", OneOrMore(Sequence(StrMatch("1"), StrMatch("2"), rule_name="var"))),
|
||||
])
|
||||
def test_i_can_parse_regex(expression, expected):
|
||||
parser = BnfParser()
|
||||
@@ -53,7 +77,8 @@ def test_i_can_parse_regex(expression, expected):
|
||||
@pytest.mark.parametrize("expression, error", [
|
||||
("1 ", UnexpectedEndOfFileError()),
|
||||
("1|", UnexpectedEndOfFileError()),
|
||||
("(1|)", UnexpectedTokenErrorNode("Unexpected token 'TokenKind.EOF'", [TokenKind.RPAR])),
|
||||
("(1|)", UnexpectedTokenErrorNode("Unexpected token 'Token(<EOF>)'", [TokenKind.RPAR])),
|
||||
("1=", UnexpectedTokenErrorNode("Unexpected token 'Token(<EOF>)'", [TokenKind.IDENTIFIER])),
|
||||
])
|
||||
def test_i_can_detect_errors(expression, error):
|
||||
parser = BnfParser()
|
||||
@@ -64,52 +89,6 @@ def test_i_can_detect_errors(expression, error):
|
||||
assert ret_value[0] == error
|
||||
|
||||
|
||||
def test_i_can_parse_regex_with_reference():
|
||||
expression = "foo"
|
||||
parser = BnfParser()
|
||||
res = parser.parse(get_context(), Tokenizer(expression))
|
||||
|
||||
assert res.status
|
||||
assert res.value.value == ConceptMatch("foo")
|
||||
assert res.value.source == expression
|
||||
|
||||
|
||||
def test_i_can_parse_cross_ref_with_modifier():
|
||||
expression = "foo*"
|
||||
parser = BnfParser()
|
||||
res = parser.parse(get_context(), Tokenizer(expression))
|
||||
|
||||
assert res.status
|
||||
assert res.value.value == ZeroOrMore(ConceptMatch("foo"))
|
||||
assert res.value.source == expression
|
||||
|
||||
|
||||
def test_i_can_parse_sequence_with_cross_ref():
|
||||
expression = "foo 'and' bar+"
|
||||
parser = BnfParser()
|
||||
res = parser.parse(get_context(), Tokenizer(expression))
|
||||
|
||||
assert res.status
|
||||
assert res.value.value == Sequence(ConceptMatch("foo"), StrMatch("and"), OneOrMore(ConceptMatch("bar")))
|
||||
assert res.value.source == expression
|
||||
|
||||
|
||||
def test_i_can_parse_choice_with_cross_ref():
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar")
|
||||
context = get_context()
|
||||
context.sheerka.add_in_cache(foo)
|
||||
context.sheerka.add_in_cache(bar)
|
||||
|
||||
expression = "foo | bar?"
|
||||
parser = BnfParser()
|
||||
res = parser.parse(context, Tokenizer(expression))
|
||||
|
||||
assert res.status
|
||||
assert res.value.value == OrderedChoice(ConceptMatch("foo"), Optional(ConceptMatch("bar")))
|
||||
assert res.value.source == expression
|
||||
|
||||
|
||||
def test_i_can_use_the_result_of_regex_parsing_to_parse_a_text():
|
||||
foo = Concept(name="foo")
|
||||
bar = Concept(name="bar")
|
||||
|
||||
Reference in New Issue
Block a user