"""Utility to print Python code for a given generator object's element tokens""" import string class _GeneratorFormatter: """Singleton Class to give a generator's element tokens as a source string Call this as: printers.asGenerator( generator ) to get a Python source string that tries to recreate the generator as a set of objectgenerator element token objects (as seen in simpleparsegrammar). """ HEAD = """from simpleparse import generator from simpleparse.objectgenerator import * GENERATOR = generator.Generator () class Parser: '''Mix-in class for simpleparse.parser.Parser which uses this GENERATOR to build tagging tables. You'll likely want to override __init__ to avoid building a new parser from a grammar (or subclass BaseParser instead of Parser) ''' def buildTagger( self, name=None, processor = None ): '''Build the tag-table for parsing the EBNF for this parser''' return GENERATOR.buildParser( name, processor ) """ ITEM = """GENERATOR.addDefinition( %(name)s, %(element)s, ) """ def __call__( self, generator ): temp = [self.HEAD] for name,element in map(None, generator.getNames(), generator.getRootObjects()): name = repr(name) element = self.reprObject(element,1) temp.append( self.ITEM%locals()) return string.join( temp, "") def reprObject( self, obj, depth=0, indent=' ' ): """Return a recognisable version of an objectgenerator element token""" argTemplate = (indent*(depth+1))+"%s = %s," temp = ["""%s("""%(obj.__class__.__name__)] for key,value in obj.__dict__.items(): if key == 'children': childTemplate = (indent*(depth+2)) + '%s,' childTemp = ["["] for child in value: childTemp.append(childTemplate%self.reprObject(child,depth+2)) childTemp.append( (indent*(depth+1))+']' ) temp.append( argTemplate% (key, string.join(childTemp, '\n')) ) else: temp.append( argTemplate%( key, repr(value))) temp.append( (indent*depth)+')') return string.join( temp,'\n') asGenerator = _GeneratorFormatter() asObject = asGenerator.reprObject