Skip to content

Commit e58c0c6

Browse files
committed
Merge pull request #37 from introom/rule_argument
invoking rule with argument
2 parents 30e706e + 5d13432 commit e58c0c6

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

ometa/interp.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ class TrampolinedGrammarInterpreter(object):
2020
An interpreter for OMeta grammars that processes input
2121
incrementally.
2222
"""
23-
def __init__(self, grammar, ruleName, callback=None, globals=None):
23+
def __init__(self, grammar, rule, callback=None, globals=None):
2424
self.grammar = grammar
2525
self.position = 0
2626
self.callback = callback
2727
self.globals = globals or {}
2828
self.rules = decomposeGrammar(grammar)
29-
self.next = self.apply(ruleName, None, ())
29+
self.next = self.setNext(rule)
3030
self._localsStack = []
3131
self.currentResult = None
3232
self.input = InputStream([], 0)
@@ -68,6 +68,12 @@ def end(self):
6868
self.callback(*x)
6969

7070

71+
def setNext(self, rule):
72+
if not isinstance(rule, tuple):
73+
rule = (rule, )
74+
return self.apply(rule[0], None, rule[1:])
75+
76+
7177
## Implementation note: each method, instead of being a function
7278
## returning a value, is a generator that will yield '_feed_me' an
7379
## arbitrary number of times, then finally yield the value of the
@@ -148,10 +154,15 @@ def apply(self, ruleName, codeName, args):
148154
Invoke a rule, optionally with arguments.
149155
"""
150156
argvals = []
151-
for a in args:
152-
for x in self._eval(a):
153-
if x is _feed_me: yield x
154-
argvals.append(x[0])
157+
# we tell whether a rule is a manually set one by the codeName
158+
# if it's None, then we think it's set by setNext
159+
if codeName is None:
160+
argvals = args
161+
else:
162+
for a in args:
163+
for x in self._eval(a):
164+
if x is _feed_me: yield x
165+
argvals.append(x[0])
155166
_locals = {}
156167
self._localsStack.append(_locals)
157168
try:

ometa/test/test_tube.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def setUp(self):
3434
_grammar = r"""
3535
delimiter = '\r\n'
3636
initial = <(~delimiter anything)*>:val delimiter -> receiver.receive(val)
37+
witharg :arg1 :arg2 = <(~delimiter anything)*>:a delimiter -> receiver.receive(arg1+arg2+a)
3738
"""
3839
self.grammar = self._parseGrammar(_grammar)
3940

@@ -75,3 +76,16 @@ def test_bindings(self):
7576
bindings = {'SMALL_INT': 3}
7677
TrampolinedParser(self._parseGrammar(grammar), receiver, bindings).receive('0')
7778
self.assertEqual(receiver.received, [3])
79+
80+
81+
def test_currentRuleWithArgs(self):
82+
"""
83+
TrampolinedParser should be able to invoke curruent rule with args.
84+
"""
85+
receiver = TrampolinedReceiver()
86+
receiver.currentRule = "witharg", "nice ", "day"
87+
trampolinedParser = TrampolinedParser(self.grammar, receiver, {})
88+
buf = b' oh yes\r\n'
89+
for c in iterbytes(buf):
90+
trampolinedParser.receive(c)
91+
self.assertEqual(receiver.received, ["nice day oh yes"])

ometa/tube.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def _setupInterp(self):
2626
'initial'.
2727
"""
2828
self._interp = TrampolinedGrammarInterpreter(
29-
grammar=self.grammar, ruleName=self.receiver.currentRule,
29+
grammar=self.grammar, rule=self.receiver.currentRule,
3030
callback=None, globals=self.bindings)
3131

3232

0 commit comments

Comments
 (0)