Parse arguments iteratively instead of recursively to support argument lists of arbitrary size.

pull/54/merge
Jussi Pakkanen 10 years ago
parent cdbfed21bc
commit fa2c659825
  1. 44
      mparser.py

@ -131,6 +131,9 @@ class IdNode:
self.value = token.value self.value = token.value
assert(isinstance(self.value, str)) assert(isinstance(self.value, str))
def __str__(self):
return "Id node: '%s' (%d, %d)." % (self.value, self.lineno, self.colno)
class NumberNode: class NumberNode:
def __init__(self, token): def __init__(self, token):
self.lineno = token.lineno self.lineno = token.lineno
@ -145,6 +148,9 @@ class StringNode:
self.value = token.value self.value = token.value
assert(isinstance(self.value, str)) assert(isinstance(self.value, str))
def __str__(self):
return "String node: '%s' (%d, %d)." % (self.value, self.lineno, self.colno)
class ArrayNode: class ArrayNode:
def __init__(self, args): def __init__(self, args):
self.lineno = args.lineno self.lineno = args.lineno
@ -255,16 +261,18 @@ class ArgumentNode():
self.order_error = False self.order_error = False
def prepend(self, statement): def prepend(self, statement):
if self.num_kwargs() > 0:
self.order_error = True
if not isinstance(statement, EmptyNode): if not isinstance(statement, EmptyNode):
self.arguments = [statement] + self.arguments self.arguments = [statement] + self.arguments
def append(self, statement): def append(self, statement):
if self.num_kwargs() > 0:
self.order_error = True
if not isinstance(statement, EmptyNode): if not isinstance(statement, EmptyNode):
self.arguments = self.arguments + [statement] self.arguments = self.arguments + [statement]
def set_kwarg(self, name, value): def set_kwarg(self, name, value):
if self.num_args() > 0:
self.order_error = True
self.kwargs[name] = value self.kwargs[name] = value
def num_args(self): def num_args(self):
@ -427,26 +435,22 @@ class Parser:
def args(self): def args(self):
s = self.statement() s = self.statement()
if isinstance(s, EmptyNode): a = ArgumentNode(s)
ArgumentNode(s)
while not isinstance(s, EmptyNode):
if self.accept('comma'):
rest = self.args()
rest.prepend(s)
return rest
if self.accept('colon'):
if not isinstance(s, IdNode):
raise ParseException('Keyword argument must be a plain identifier.',
s.lineno, s.colno)
value = self.statement()
if self.accept('comma'): if self.accept('comma'):
a = self.args() a.append(s)
elif self.accept('colon'):
if not isinstance(s, IdNode):
raise ParseException('Keyword argument must be a plain identifier.',
s.lineno, s.colno)
a.set_kwarg(s.value, self.statement())
if not self.accept('comma'):
return a
else: else:
a = ArgumentNode(self.current) a.append(s)
a.set_kwarg(s.value, value) return a
return a s = self.statement()
a = ArgumentNode(self.current)
a.append(s)
return a return a
def method_call(self, source_object): def method_call(self, source_object):

Loading…
Cancel
Save