Skip to content

Commit

Permalink
fix: use Converter for derived rules
Browse files Browse the repository at this point in the history
If rule is a rule returning other rule with semantic action it
generates Converter rule to convert result of the 1st rule semantic
action using semantic action provided to the derived rule
  • Loading branch information
deztructor committed Jun 23, 2012
1 parent e0dc908 commit 956f2f3
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
21 changes: 13 additions & 8 deletions parsed/Generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,14 @@ def __getitem__(self, k):
return mk_rule_range(self, r, self._next_child_name)

def __gt__(self, action):
if self._action == action:
return self
res = self.copy
if action.__name__ == '<lambda>':
action.__name__ = ''.join(['!', self.name])
res._action = action
return res
if isinstance(self, TopRule):
return Converter(self, self.name, action)
if self._action == action:
return self
self._action = action
return self

@property
def action(self):
Expand Down Expand Up @@ -210,7 +211,13 @@ def copy(self):
return self.__class__(self.rule, self.name, self.default_action)

def _prepare_context(self, options):
return self.rule(options)
return self.rule(options)

class Converter(Modifier):

def __init__(self, rule, name, action):
super(Converter, self).__init__(rule, name, action)
self.fn = convert

class Aggregate(Rule):

Expand All @@ -236,8 +243,6 @@ def __init__(self, fn):
def _mk_parser(self, name, generator, action, options):
rule = generator()
rule.name = '.'.join([name, rule.name])
if action is not None:
rule._action = action
parser = rule(options)
return parser

Expand Down
12 changes: 12 additions & 0 deletions parsed/Rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,18 @@ def fn(src):
fn.children = list((test,))
return fn

def convert(name, test, action, options):
@rule(name, options)
def fn(src):
pos, value = test.match(src)
if value != nomatch:
value = action(value)
return (pos, value) if value != nomatch else _nomatch_res
else:
return _nomatch_res
fn.children = list((test,))
return fn

def lookahead(name, test, conv, options):
@rule(name, options)
def fn(src):
Expand Down

0 comments on commit 956f2f3

Please sign in to comment.