| """ANTLR3 runtime package""" |
| |
| # begin[licence] |
| # |
| # [The "BSD licence"] |
| # Copyright (c) 2005-2008 Terence Parr |
| # All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions |
| # are met: |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # 3. The name of the author may not be used to endorse or promote products |
| # derived from this software without specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| # |
| # end[licence] |
| |
| |
| import sys |
| import optparse |
| |
| import antlr3 |
| |
| |
| class _Main(object): |
| def __init__(self): |
| self.stdin = sys.stdin |
| self.stdout = sys.stdout |
| self.stderr = sys.stderr |
| |
| |
| def parseOptions(self, argv): |
| optParser = optparse.OptionParser() |
| optParser.add_option( |
| "--encoding", |
| action="store", |
| type="string", |
| dest="encoding" |
| ) |
| optParser.add_option( |
| "--input", |
| action="store", |
| type="string", |
| dest="input" |
| ) |
| optParser.add_option( |
| "--interactive", "-i", |
| action="store_true", |
| dest="interactive" |
| ) |
| optParser.add_option( |
| "--no-output", |
| action="store_true", |
| dest="no_output" |
| ) |
| optParser.add_option( |
| "--profile", |
| action="store_true", |
| dest="profile" |
| ) |
| optParser.add_option( |
| "--hotshot", |
| action="store_true", |
| dest="hotshot" |
| ) |
| optParser.add_option( |
| "--port", |
| type="int", |
| dest="port", |
| default=None |
| ) |
| optParser.add_option( |
| "--debug-socket", |
| action='store_true', |
| dest="debug_socket", |
| default=None |
| ) |
| |
| self.setupOptions(optParser) |
| |
| return optParser.parse_args(argv[1:]) |
| |
| |
| def setupOptions(self, optParser): |
| pass |
| |
| |
| def execute(self, argv): |
| options, args = self.parseOptions(argv) |
| |
| self.setUp(options) |
| |
| if options.interactive: |
| while True: |
| try: |
| input = raw_input(">>> ") |
| except (EOFError, KeyboardInterrupt): |
| self.stdout.write("\nBye.\n") |
| break |
| |
| inStream = antlr3.ANTLRStringStream(input) |
| self.parseStream(options, inStream) |
| |
| else: |
| if options.input is not None: |
| inStream = antlr3.ANTLRStringStream(options.input) |
| |
| elif len(args) == 1 and args[0] != '-': |
| inStream = antlr3.ANTLRFileStream( |
| args[0], encoding=options.encoding |
| ) |
| |
| else: |
| inStream = antlr3.ANTLRInputStream( |
| self.stdin, encoding=options.encoding |
| ) |
| |
| if options.profile: |
| try: |
| import cProfile as profile |
| except ImportError: |
| import profile |
| |
| profile.runctx( |
| 'self.parseStream(options, inStream)', |
| globals(), |
| locals(), |
| 'profile.dat' |
| ) |
| |
| import pstats |
| stats = pstats.Stats('profile.dat') |
| stats.strip_dirs() |
| stats.sort_stats('time') |
| stats.print_stats(100) |
| |
| elif options.hotshot: |
| import hotshot |
| |
| profiler = hotshot.Profile('hotshot.dat') |
| profiler.runctx( |
| 'self.parseStream(options, inStream)', |
| globals(), |
| locals() |
| ) |
| |
| else: |
| self.parseStream(options, inStream) |
| |
| |
| def setUp(self, options): |
| pass |
| |
| |
| def parseStream(self, options, inStream): |
| raise NotImplementedError |
| |
| |
| def write(self, options, text): |
| if not options.no_output: |
| self.stdout.write(text) |
| |
| |
| def writeln(self, options, text): |
| self.write(options, text + '\n') |
| |
| |
| class LexerMain(_Main): |
| def __init__(self, lexerClass): |
| _Main.__init__(self) |
| |
| self.lexerClass = lexerClass |
| |
| |
| def parseStream(self, options, inStream): |
| lexer = self.lexerClass(inStream) |
| for token in lexer: |
| self.writeln(options, str(token)) |
| |
| |
| class ParserMain(_Main): |
| def __init__(self, lexerClassName, parserClass): |
| _Main.__init__(self) |
| |
| self.lexerClassName = lexerClassName |
| self.lexerClass = None |
| self.parserClass = parserClass |
| |
| |
| def setupOptions(self, optParser): |
| optParser.add_option( |
| "--lexer", |
| action="store", |
| type="string", |
| dest="lexerClass", |
| default=self.lexerClassName |
| ) |
| optParser.add_option( |
| "--rule", |
| action="store", |
| type="string", |
| dest="parserRule" |
| ) |
| |
| |
| def setUp(self, options): |
| lexerMod = __import__(options.lexerClass) |
| self.lexerClass = getattr(lexerMod, options.lexerClass) |
| |
| |
| def parseStream(self, options, inStream): |
| kwargs = {} |
| if options.port is not None: |
| kwargs['port'] = options.port |
| if options.debug_socket is not None: |
| kwargs['debug_socket'] = sys.stderr |
| |
| lexer = self.lexerClass(inStream) |
| tokenStream = antlr3.CommonTokenStream(lexer) |
| parser = self.parserClass(tokenStream, **kwargs) |
| result = getattr(parser, options.parserRule)() |
| if result is not None: |
| if hasattr(result, 'tree') and result.tree is not None: |
| self.writeln(options, result.tree.toStringTree()) |
| else: |
| self.writeln(options, repr(result)) |
| |
| |
| class WalkerMain(_Main): |
| def __init__(self, walkerClass): |
| _Main.__init__(self) |
| |
| self.lexerClass = None |
| self.parserClass = None |
| self.walkerClass = walkerClass |
| |
| |
| def setupOptions(self, optParser): |
| optParser.add_option( |
| "--lexer", |
| action="store", |
| type="string", |
| dest="lexerClass", |
| default=None |
| ) |
| optParser.add_option( |
| "--parser", |
| action="store", |
| type="string", |
| dest="parserClass", |
| default=None |
| ) |
| optParser.add_option( |
| "--parser-rule", |
| action="store", |
| type="string", |
| dest="parserRule", |
| default=None |
| ) |
| optParser.add_option( |
| "--rule", |
| action="store", |
| type="string", |
| dest="walkerRule" |
| ) |
| |
| |
| def setUp(self, options): |
| lexerMod = __import__(options.lexerClass) |
| self.lexerClass = getattr(lexerMod, options.lexerClass) |
| parserMod = __import__(options.parserClass) |
| self.parserClass = getattr(parserMod, options.parserClass) |
| |
| |
| def parseStream(self, options, inStream): |
| lexer = self.lexerClass(inStream) |
| tokenStream = antlr3.CommonTokenStream(lexer) |
| parser = self.parserClass(tokenStream) |
| result = getattr(parser, options.parserRule)() |
| if result is not None: |
| assert hasattr(result, 'tree'), "Parser did not return an AST" |
| nodeStream = antlr3.tree.CommonTreeNodeStream(result.tree) |
| nodeStream.setTokenStream(tokenStream) |
| walker = self.walkerClass(nodeStream) |
| result = getattr(walker, options.walkerRule)() |
| if result is not None: |
| if hasattr(result, 'tree'): |
| self.writeln(options, result.tree.toStringTree()) |
| else: |
| self.writeln(options, repr(result)) |