Two pass reference resolving.
To enable referencing of symbols creating during resolving itself,
e.g. multiplicity symbols (+, *, ?).
@@ -497,10 +497,13 @@ class PGFile(object):
self.symbols_by_name['STOP'] = STOP
def resolve_references(self):
+ # Two pass resolving to enable referening symbols created during
+ # resolving (e.g. multiplicity symbols).
+ for pazz in [True, False]:
for production in self.productions:
for idx, ref in enumerate(production.rhs):
if isinstance(ref, Reference):
- production.rhs[idx] = self.resolve(ref)
+ production.rhs[idx] = self.resolve(ref, pazz)
def register_symbol(self, symbol):
self.symbols_by_name[symbol.name] = symbol
@@ -564,7 +567,7 @@ class PGFile(object):
recognizers_file))
symbol.recognizer = recognizers[symbol_name]
- def resolve(self, symbol_ref):
+ def resolve(self, symbol_ref, first_pass=False):
"""Resolves given symbol reference.
For local name search this file, for FQN use imports and delegate to
@@ -572,6 +575,10 @@ class PGFile(object):
On each resolved symbol productions in the root file are updated.
+ If this is first pass do not fail on unexisting reference as there
+ might be new symbols created during resolving (e.g. multiplicity
+ symbols).
+
"""
if isinstance(symbol_ref.separator, Reference):
symbol_ref.separator = self.resolve(symbol_ref.separator)
@@ -591,6 +598,9 @@ class PGFile(object):
else:
symbol = self.symbols_by_name.get(symbol_name)
if not symbol:
+ if first_pass:
+ return symbol_ref
+ else:
raise GrammarError(
location=symbol_ref.location,
message='Unknown symbol "{}"'.format(symbol_name))
