[pypy-svn] r35173 - pypy/dist/pypy/rlib/parsing
cfbolz at codespeak.net
cfbolz at codespeak.net
Thu Nov 30 17:06:34 CET 2006
Author: cfbolz
Date: Thu Nov 30 17:06:33 2006
New Revision: 35173
Modified:
pypy/dist/pypy/rlib/parsing/ebnfparse.py
Log:
nicer way to create the rules for *, ? and +
Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py
==============================================================================
--- pypy/dist/pypy/rlib/parsing/ebnfparse.py (original)
+++ pypy/dist/pypy/rlib/parsing/ebnfparse.py Thu Nov 30 17:06:33 2006
@@ -214,11 +214,14 @@
def add_all_possibilities(self):
all_rules = []
+ other_rules = []
all_changes = []
+ other_changes = []
for rule, changes in zip(self.rules, self.changes):
real_changes = []
real_expansions = []
- for expansion, change in zip(rule.expansions, changes):
+ for index, (expansion, change) in enumerate(
+ zip(rule.expansions, changes)):
maybe_pattern = [symbol in self.maybe_rules
for symbol in expansion]
n = maybe_pattern.count(True)
@@ -229,23 +232,41 @@
assert n != len(expansion), (
"currently an expansion needs at least one"
"symbol that always has to occur")
- maybe_index = {}
- for i, star in enumerate(maybe_pattern):
- if star:
- maybe_index[i] = len(maybe_index)
- for i in range(2 ** n):
- real_expansion = []
- real_change = []
- for j, (symbol, ch) in enumerate(zip(expansion, change)):
- if (j not in maybe_index or
- (i & (2 ** (n - 1) >> maybe_index[j])) == 0):
- real_expansion.append(symbol)
- real_change.append(ch)
- real_expansions.append(real_expansion)
- real_changes.append(real_change)
+ slices = []
+ start = 0
+ for i, (maybe, symbol) in enumerate(
+ zip(maybe_pattern, expansion)):
+ if maybe:
+ slices.append((start, i + 1))
+ start = i + 1
+ rest_slice = (start, i + 1)
+ name = rule.nonterminal
+ for i, (start, stop) in enumerate(slices):
+ nextname = "__%s_rest_%s_%s" % (rule.nonterminal, index, i)
+ if i < len(slices) - 1:
+ new_expansions = [
+ expansion[start: stop] + [nextname],
+ expansion[start: stop - 1] + [nextname]]
+ new_changes = [change[start: stop] + ">",
+ change[start: stop - 1] + ">"]
+ else:
+ rest_expansion = expansion[slice(*rest_slice)]
+ new_expansions = [
+ expansion[start: stop] + rest_expansion,
+ expansion[start: stop - 1] + rest_expansion]
+ rest_change = change[slice(*rest_slice)]
+ new_changes = [change[start: stop] + rest_change,
+ change[start: stop - 1] + rest_change]
+ if i == 0:
+ real_expansions += new_expansions
+ real_changes += new_changes
+ else:
+ other_rules.append(Rule(name, new_expansions))
+ other_changes.append(new_changes)
+ name = nextname
all_rules.append(Rule(rule.nonterminal, real_expansions))
all_changes.append(real_changes)
- return all_rules, all_changes
+ return all_rules + other_rules, all_changes + other_changes
class TransformerMaker(object):
def __init__(self, rules, changes):
@@ -280,6 +301,7 @@
assert isinstance(ToAST, type)
assert ToAST.__name__ == "ToAST"
ToAST.source = code
+ ToAST.changes = self.changes
return ToAST
def emit(self, line):
More information about the Pypy-commit
mailing list