Commit 19c9cfd5 authored by Eckhart Arnold's avatar Eckhart Arnold
Browse files

changes semantics of lookbehind-parser

parent 813bebe5
...@@ -231,8 +231,6 @@ def add_parser_guard(parser_func): ...@@ -231,8 +231,6 @@ def add_parser_guard(parser_func):
# in case of left recursion, the first recursive step that # in case of left recursion, the first recursive step that
# matches will store its result in the cache # matches will store its result in the cache
parser.visited[location] = (node, rest) parser.visited[location] = (node, rest)
# store last non-empty node for Lookbehind parser
if len(rest) < location: grammar.last_node__ = node
parser.recursion_counter[location] -= 1 parser.recursion_counter[location] -= 1
...@@ -579,8 +577,6 @@ class Grammar: ...@@ -579,8 +577,6 @@ class Grammar:
self.variables__ = dict() # type: Dict[str, List[str]] self.variables__ = dict() # type: Dict[str, List[str]]
self.rollback__ = [] # type: List[Tuple[int, Callable]] self.rollback__ = [] # type: List[Tuple[int, Callable]]
self.last_rb__loc__ = -1 # type: int self.last_rb__loc__ = -1 # type: int
# previously parsed node, needed by Lookbehind parser
self.last_node__ = Node(ZOMBIE_PARSER, '') # type: Node
# support for call stack tracing # support for call stack tracing
self.call_stack__ = [] # type: List[Parser] self.call_stack__ = [] # type: List[Parser]
# snapshots of call stacks # snapshots of call stacks
...@@ -1319,7 +1315,8 @@ class Lookbehind(FlowOperator): ...@@ -1319,7 +1315,8 @@ class Lookbehind(FlowOperator):
super(Lookbehind, self).__init__(parser, name) super(Lookbehind, self).__init__(parser, name)
def __call__(self, text: str) -> Tuple[Node, str]: def __call__(self, text: str) -> Tuple[Node, str]:
if self.sign(self.condition()): backwards_text = self.grammar.document__[-len(text) - 1::-1]
if self.sign(self.regexp.match(backwards_text)):
return Node(self, ''), text return Node(self, ''), text
else: else:
return None, text return None, text
...@@ -1328,14 +1325,7 @@ class Lookbehind(FlowOperator): ...@@ -1328,14 +1325,7 @@ class Lookbehind(FlowOperator):
return '-&' + self.parser.repr return '-&' + self.parser.repr
def sign(self, bool_value) -> bool: def sign(self, bool_value) -> bool:
return bool_value return bool(bool_value)
def condition(self):
node = self.grammar.last_node__
assert node is not None # can be removed
s = str(node)
assert s or node.parser.name == '__ZOMBIE__', str(node.parser)
return self.regexp.match(s)
class NegativeLookbehind(Lookbehind): class NegativeLookbehind(Lookbehind):
...@@ -1344,7 +1334,7 @@ class NegativeLookbehind(Lookbehind): ...@@ -1344,7 +1334,7 @@ class NegativeLookbehind(Lookbehind):
return '-!' + self.parser.repr return '-!' + self.parser.repr
def sign(self, bool_value) -> bool: def sign(self, bool_value) -> bool:
return not bool_value return not bool(bool_value)
######################################################################## ########################################################################
......
...@@ -323,7 +323,7 @@ class TestFlowControlOperators: ...@@ -323,7 +323,7 @@ class TestFlowControlOperators:
end = /END/ end = /END/
word = /\w+/ word = /\w+/
SUCC_LB = indirection SUCC_LB = indirection
indirection = /(?:.*\n)+\s*$/ indirection = /\s*?\n/
""" """
# result, messages, syntax_tree = compile_source(lang, None, get_ebnf_grammar(), # result, messages, syntax_tree = compile_source(lang, None, get_ebnf_grammar(),
# get_ebnf_transformer(), get_ebnf_compiler('LookbehindTest')) # get_ebnf_transformer(), get_ebnf_compiler('LookbehindTest'))
......
...@@ -110,7 +110,7 @@ class TestFlowControl: ...@@ -110,7 +110,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)+\s*$')) + end doc_end = Lookbehind(RegExp('\\s*?\\n')) + 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
...@@ -126,7 +126,7 @@ class TestFlowControl: ...@@ -126,7 +126,7 @@ class TestFlowControl:
parser_initialization__ = "upon instantiation" parser_initialization__ = "upon instantiation"
ws = RegExp('\\s*') ws = RegExp('\\s*')
end = RegExp('END') end = RegExp('END')
SUCC_LB = RegExp('(?:.*\\n)+\\s*$') SUCC_LB = RegExp('\\s*?\\n')
doc_end = Series(Lookbehind(SUCC_LB), end) doc_end = Series(Lookbehind(SUCC_LB), end)
word = RegExp('\w+') word = RegExp('\w+')
sequence = OneOrMore(Series(NegativeLookahead(end), word, ws)) sequence = OneOrMore(Series(NegativeLookahead(end), word, 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