Commit 3af59964 authored by Igor Dejanovic's avatar Igor Dejanovic

Fixed bug in parser model construction

Fixed bug in parser model construction from python grammar description
with direct rule call.
parent 43dd61e4
......@@ -15,6 +15,7 @@ from __future__ import print_function, unicode_literals
import re
import bisect
from arpeggio.utils import isstr
import types
DEFAULT_WS = '\t\n\r '
......@@ -1004,7 +1005,7 @@ class ParserPython(Parser):
def inner_from_python(expression):
retval = None
if callable(expression): # Is this expression a parser rule?
if type(expression) == types.FunctionType: # Is this expression a parser rule?
rule = expression.__name__
if rule in __rule_cache:
c_rule = __rule_cache.get(rule)
......@@ -1024,7 +1025,12 @@ class ParserPython(Parser):
# Register rule cross-ref to support recursion
__rule_cache[rule] = CrossRef(rule)
retval = inner_from_python(expression())
curr_expr = expression
while type(curr_expr) == types.FunctionType:
# If function directly returns another function
# go into until non-function is returned.
curr_expr = curr_expr()
retval = inner_from_python(curr_expr)
retval.rule = rule
retval.root = True
......
'''
Created on Jul 6, 2014
@author: igor
'''
import unittest
from arpeggio import SemanticAction, ParserPython
class Test(unittest.TestCase):
def test_direct_rule_call(self):
'''
Test regression where in direct rule call semantic action is
erroneously attached to both caller and callee.
'''
def grammar(): return rule1, rule2
def rule1(): return "a"
def rule2(): return rule1
call_count = [0]
class DummySemAction(SemanticAction):
def first_pass(self, parser, node, nodes):
call_count[0] += 1
return SemanticAction.first_pass(self, parser, node, nodes)
# Sem action is attached to rule2 only but
# this bug will attach it to rule1 also resulting in
# wrong call count.
rule2.sem = DummySemAction()
parser = ParserPython(grammar)
parse_tree = parser.parse("aa")
parser.getASG()
self.assertEqual(call_count[0], 1,
"Semantic action should be called once!")
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