Commit b555c88f authored by Eckhart Arnold's avatar Eckhart Arnold
Browse files

- Lookbehind-Operator rewritten (now only accepts plain RegExp as Argument!) and tested

parent d84004ae
...@@ -1224,31 +1224,27 @@ class NegativeLookahead(Lookahead): ...@@ -1224,31 +1224,27 @@ class NegativeLookahead(Lookahead):
return not bool_value return not bool_value
def iter_right_branch(node) -> Iterator[Node]: # def iter_right_branch(node) -> Iterator[Node]:
""" # """
Iterates over the right branch of `node` starting with node itself. # Iterates over the right branch of `node` starting with node itself.
Iteration is stopped if either there are no child nodes any more or # Iteration is stopped if either there are no child nodes any more or
if the parser of a node is a Lookahead parser. (Reason is: Since # if the parser of a node is a Lookahead parser. (Reason is: Since
lookahead nodes do not advance the parser, it does not make sense # lookahead nodes do not advance the parser, it does not make sense
to look back to them.) # to look back to them.)
""" # """
while node and not isinstance(node.parser, Lookahead): # the second condition should not be necessary # while node:
yield node # for well-formed EBNF code # yield node # for well-formed EBNF code
node = node.children[-1] if node.children else None # node = node.children[-1] if node.children else None
class Lookbehind(FlowOperator): class Lookbehind(FlowOperator):
"""EXPERIMENTAL AND NEVER TESTED!!!""" """EXPERIMENTAL!!!"""
def __init__(self, parser: Parser, name: str = '') -> None: def __init__(self, parser: Parser, name: str = '') -> None:
assert parser.name or isinstance(parser, RegExp) assert isinstance(parser, RegExp)
super(Lookbehind, self).__init__(parser, name) super(Lookbehind, self).__init__(parser, name)
print("WARNING: Lookbehind Operator is experimental!") print("WARNING: Lookbehind Operator is experimental!")
def __call__(self, text: str) -> Tuple[Node, str]: def __call__(self, text: str) -> Tuple[Node, str]:
node = self.grammar.last_node__
# if isinstance(node.parser, Lookahead):
# return Node(self, '').add_error('Lookbehind right after Lookahead '
# 'does not make sense!'), text
if self.sign(self.condition()): if self.sign(self.condition()):
return Node(self, ''), text return Node(self, ''), text
else: else:
...@@ -1262,13 +1258,7 @@ class Lookbehind(FlowOperator): ...@@ -1262,13 +1258,7 @@ class Lookbehind(FlowOperator):
def condition(self): def condition(self):
node = self.grammar.last_node__ node = self.grammar.last_node__
if node and isinstance(self.parser, RegExp) and self.parser.regexp.match(str(node)): return node and self.parser.regexp.match(str(node))
return True
elif self.parser.name:
for node in iter_right_branch(self.grammar.last_node__):
if node.parser.name == self.parser.name:
return True
return False
class NegativeLookbehind(Lookbehind): class NegativeLookbehind(Lookbehind):
......
...@@ -102,7 +102,7 @@ class TestFlowControl: ...@@ -102,7 +102,7 @@ class TestFlowControl:
def test_lookbehind(self): def test_lookbehind(self):
ws = RegExp('\s*') ws = RegExp('\s*')
end = RegExp("END") end = RegExp("END")
doc_end = Lookbehind(RegExp('.*\n$')) + end doc_end = Lookbehind(RegExp('(?:.*\n)+\s*$')) + end
word = RegExp('\w+') word = RegExp('\w+')
sequence = OneOrMore(NegativeLookahead(end) + word + ws) sequence = OneOrMore(NegativeLookahead(end) + word + ws)
document = ws + sequence + doc_end + ws document = ws + sequence + doc_end + ws
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment