Commit 5bf393d0 authored by Eckhart Arnold's avatar Eckhart Arnold
Browse files

parser.py: disabled caching for variable manipulating parsers (and

containing parsers), because caching does not keep track of the state
of variables.
parent 872abf78
......@@ -194,7 +194,9 @@ def add_parser_guard(parser_func):
if node is not None:
# in case of a recursive call saves the result of the first
# (or left-most) call that matches
# (or left-most) call that matches; but not for variable manipulating parsers,
# because caching would interfere with changes of variable state
if not (grammar.rollback__ and grammar.rollback__[-1][0] <= location):
parser.visited[location] = (node, rest)
grammar.last_node__ = node # store last node for Lookbehind operator
elif location in parser.visited:
......@@ -1089,6 +1091,7 @@ class Capture(UnaryOperator):
stack = self.grammar.variables__.setdefault(self.name, [])
stack.append(str(node))
self.grammar.rollback__.append((len(text), lambda : stack.pop()))
# block caching, because it would prevent recapturing of rolled back captures
return Node(self, node), text_
else:
return None, text
......
......@@ -41,18 +41,39 @@ ARITHMETIC_EBNF = """
# example: "5 + 3 * 4"
"""
ARITHMETIC_EBNF_transformation_table = {
# AST Transformations for the DSL-grammar
"formula": [remove_expendables],
"term, expr": [replace_by_single_child, flatten],
"factor": [remove_expendables, reduce_single_child],
(TOKEN_PTYPE): [remove_expendables, reduce_single_child],
"*": [remove_expendables, replace_by_single_child]
}
ARITHMETIC2_EBNF = """
@ whitespace = linefeed
formula = [ //~ ] expr
expr = ex
ex = expr ("+"|"-") term | term
term = term ("*"|"/") factor | factor
factor = /[0-9]+/~
# example: "5 + 3 * 4"
"""
ARITHMETIC_EBNFTransform = partial(traverse, processing_table=ARITHMETIC_EBNF_transformation_table)
# ARITHMETIC_EBNF_transformation_table = {
# # AST Transformations for the DSL-grammar
# "formula": [remove_expendables],
# "term, expr": [replace_by_single_child, flatten],
# "factor": [remove_expendables, reduce_single_child],
# (TOKEN_PTYPE): [remove_expendables, reduce_single_child],
# "*": [remove_expendables, replace_by_single_child]
# }
#
#
# ARITHMETIC2_EBNF_transformation_table = {
# # AST Transformations for the DSL-grammar
# "formula": [remove_expendables],
# "term, ex": [replace_by_single_child, flatten],
# "factor": [remove_expendables, reduce_single_child],
# (TOKEN_PTYPE): [remove_expendables, reduce_single_child],
# "*": [remove_expendables, replace_by_single_child]
# }
#
#
# ARITHMETIC_EBNFTransform = partial(traverse, processing_table=ARITHMETIC_EBNF_transformation_table)
# ARITHMETIC2_EBNFTransform = partial(traverse, processing_table=ARITHMETIC2_EBNF_transformation_table)
class TestInfiLoopsAndRecursion:
......@@ -69,7 +90,15 @@ class TestInfiLoopsAndRecursion:
# self.minilang_parser1.log_parsing_history("test_LeftRecursion_direct")
def test_indirect_left_recursion(self):
pass
minilang = ARITHMETIC2_EBNF
snippet = "5 + 3 * 4"
parser = parser_factory(minilang)()
assert parser
syntax_tree = parser(snippet)
assert not syntax_tree.collect_errors()
assert snippet == str(syntax_tree)
if is_logging():
syntax_tree.log("test_LeftRecursion_indirect.cst")
def test_inifinite_loops(self):
minilang = """not_forever = { // } \n"""
......@@ -218,6 +247,22 @@ class TestPopRetrieve:
syntax_tree = self.minilang_parser3(proper)
assert not syntax_tree.error_flag, str(syntax_tree.collect_errors())
def test_cache_neutrality(self):
"""Test that packrat-caching does not interfere with
Capture-Retrieve-Stack."""
lang = """
text = opening closing
opening = (unmarked_package | marked_package)
closing = ::variable
unmarked_package = package "."
marked_package = package "*" "."
package = "(" variable ")"
variable = /\w+/~
"""
case = "(secret)*. secret"
gr = parser_factory(lang)()
st = gr(case)
assert not st.error_flag, str(st.collect_errors())
def test_single_line(self):
teststr = "Anfang ```code block `` <- keine Ende-Zeichen ! ``` Ende"
......
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