1*16467b97STreehugger Robot"""ANTLR3 runtime package""" 2*16467b97STreehugger Robot 3*16467b97STreehugger Robot# begin[licence] 4*16467b97STreehugger Robot# 5*16467b97STreehugger Robot# [The "BSD licence"] 6*16467b97STreehugger Robot# Copyright (c) 2005-2012 Terence Parr 7*16467b97STreehugger Robot# All rights reserved. 8*16467b97STreehugger Robot# 9*16467b97STreehugger Robot# Redistribution and use in source and binary forms, with or without 10*16467b97STreehugger Robot# modification, are permitted provided that the following conditions 11*16467b97STreehugger Robot# are met: 12*16467b97STreehugger Robot# 1. Redistributions of source code must retain the above copyright 13*16467b97STreehugger Robot# notice, this list of conditions and the following disclaimer. 14*16467b97STreehugger Robot# 2. Redistributions in binary form must reproduce the above copyright 15*16467b97STreehugger Robot# notice, this list of conditions and the following disclaimer in the 16*16467b97STreehugger Robot# documentation and/or other materials provided with the distribution. 17*16467b97STreehugger Robot# 3. The name of the author may not be used to endorse or promote products 18*16467b97STreehugger Robot# derived from this software without specific prior written permission. 19*16467b97STreehugger Robot# 20*16467b97STreehugger Robot# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21*16467b97STreehugger Robot# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22*16467b97STreehugger Robot# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23*16467b97STreehugger Robot# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24*16467b97STreehugger Robot# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25*16467b97STreehugger Robot# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*16467b97STreehugger Robot# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*16467b97STreehugger Robot# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*16467b97STreehugger Robot# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29*16467b97STreehugger Robot# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*16467b97STreehugger Robot# 31*16467b97STreehugger Robot# end[licence] 32*16467b97STreehugger Robot 33*16467b97STreehugger Robot 34*16467b97STreehugger Robotimport sys 35*16467b97STreehugger Robotimport argparse 36*16467b97STreehugger Robot 37*16467b97STreehugger Robotfrom .streams import ANTLRStringStream, ANTLRFileStream, \ 38*16467b97STreehugger Robot ANTLRInputStream, CommonTokenStream 39*16467b97STreehugger Robotfrom .tree import CommonTreeNodeStream 40*16467b97STreehugger Robot 41*16467b97STreehugger Robot 42*16467b97STreehugger Robotclass _Main(object): 43*16467b97STreehugger Robot def __init__(self): 44*16467b97STreehugger Robot self.stdin = sys.stdin 45*16467b97STreehugger Robot self.stdout = sys.stdout 46*16467b97STreehugger Robot self.stderr = sys.stderr 47*16467b97STreehugger Robot 48*16467b97STreehugger Robot 49*16467b97STreehugger Robot def parseArgs(self, argv): 50*16467b97STreehugger Robot argParser = argparse.ArgumentParser() 51*16467b97STreehugger Robot argParser.add_argument("--input") 52*16467b97STreehugger Robot argParser.add_argument("--interactive", "-i", action="store_true") 53*16467b97STreehugger Robot argParser.add_argument("--no-output", action="store_true") 54*16467b97STreehugger Robot argParser.add_argument("--profile", action="store_true") 55*16467b97STreehugger Robot argParser.add_argument("--hotshot", action="store_true") 56*16467b97STreehugger Robot argParser.add_argument("--port", type=int) 57*16467b97STreehugger Robot argParser.add_argument("--debug-socket", action='store_true') 58*16467b97STreehugger Robot argParser.add_argument("file", nargs='?') 59*16467b97STreehugger Robot 60*16467b97STreehugger Robot self.setupArgs(argParser) 61*16467b97STreehugger Robot 62*16467b97STreehugger Robot return argParser.parse_args(argv[1:]) 63*16467b97STreehugger Robot 64*16467b97STreehugger Robot 65*16467b97STreehugger Robot def setupArgs(self, argParser): 66*16467b97STreehugger Robot pass 67*16467b97STreehugger Robot 68*16467b97STreehugger Robot 69*16467b97STreehugger Robot def execute(self, argv): 70*16467b97STreehugger Robot args = self.parseArgs(argv) 71*16467b97STreehugger Robot 72*16467b97STreehugger Robot self.setUp(args) 73*16467b97STreehugger Robot 74*16467b97STreehugger Robot if args.interactive: 75*16467b97STreehugger Robot while True: 76*16467b97STreehugger Robot try: 77*16467b97STreehugger Robot input_str = input(">>> ") 78*16467b97STreehugger Robot except (EOFError, KeyboardInterrupt): 79*16467b97STreehugger Robot self.stdout.write("\nBye.\n") 80*16467b97STreehugger Robot break 81*16467b97STreehugger Robot 82*16467b97STreehugger Robot inStream = ANTLRStringStream(input_str) 83*16467b97STreehugger Robot self.parseStream(args, inStream) 84*16467b97STreehugger Robot 85*16467b97STreehugger Robot else: 86*16467b97STreehugger Robot if args.input: 87*16467b97STreehugger Robot inStream = ANTLRStringStream(args.input) 88*16467b97STreehugger Robot 89*16467b97STreehugger Robot elif args.file and args.file != '-': 90*16467b97STreehugger Robot inStream = ANTLRFileStream(args.file) 91*16467b97STreehugger Robot 92*16467b97STreehugger Robot else: 93*16467b97STreehugger Robot inStream = ANTLRInputStream(self.stdin) 94*16467b97STreehugger Robot 95*16467b97STreehugger Robot if args.profile: 96*16467b97STreehugger Robot try: 97*16467b97STreehugger Robot import cProfile as profile 98*16467b97STreehugger Robot except ImportError: 99*16467b97STreehugger Robot import profile 100*16467b97STreehugger Robot 101*16467b97STreehugger Robot profile.runctx( 102*16467b97STreehugger Robot 'self.parseStream(args, inStream)', 103*16467b97STreehugger Robot globals(), 104*16467b97STreehugger Robot locals(), 105*16467b97STreehugger Robot 'profile.dat' 106*16467b97STreehugger Robot ) 107*16467b97STreehugger Robot 108*16467b97STreehugger Robot import pstats 109*16467b97STreehugger Robot stats = pstats.Stats('profile.dat') 110*16467b97STreehugger Robot stats.strip_dirs() 111*16467b97STreehugger Robot stats.sort_stats('time') 112*16467b97STreehugger Robot stats.print_stats(100) 113*16467b97STreehugger Robot 114*16467b97STreehugger Robot elif args.hotshot: 115*16467b97STreehugger Robot import hotshot 116*16467b97STreehugger Robot 117*16467b97STreehugger Robot profiler = hotshot.Profile('hotshot.dat') 118*16467b97STreehugger Robot profiler.runctx( 119*16467b97STreehugger Robot 'self.parseStream(args, inStream)', 120*16467b97STreehugger Robot globals(), 121*16467b97STreehugger Robot locals() 122*16467b97STreehugger Robot ) 123*16467b97STreehugger Robot 124*16467b97STreehugger Robot else: 125*16467b97STreehugger Robot self.parseStream(args, inStream) 126*16467b97STreehugger Robot 127*16467b97STreehugger Robot 128*16467b97STreehugger Robot def setUp(self, args): 129*16467b97STreehugger Robot pass 130*16467b97STreehugger Robot 131*16467b97STreehugger Robot 132*16467b97STreehugger Robot def parseStream(self, args, inStream): 133*16467b97STreehugger Robot raise NotImplementedError 134*16467b97STreehugger Robot 135*16467b97STreehugger Robot 136*16467b97STreehugger Robot def write(self, args, text): 137*16467b97STreehugger Robot if not args.no_output: 138*16467b97STreehugger Robot self.stdout.write(text) 139*16467b97STreehugger Robot 140*16467b97STreehugger Robot 141*16467b97STreehugger Robot def writeln(self, args, text): 142*16467b97STreehugger Robot self.write(args, text + '\n') 143*16467b97STreehugger Robot 144*16467b97STreehugger Robot 145*16467b97STreehugger Robotclass LexerMain(_Main): 146*16467b97STreehugger Robot def __init__(self, lexerClass): 147*16467b97STreehugger Robot super().__init__() 148*16467b97STreehugger Robot 149*16467b97STreehugger Robot self.lexerClass = lexerClass 150*16467b97STreehugger Robot 151*16467b97STreehugger Robot 152*16467b97STreehugger Robot def parseStream(self, args, inStream): 153*16467b97STreehugger Robot lexer = self.lexerClass(inStream) 154*16467b97STreehugger Robot for token in lexer: 155*16467b97STreehugger Robot self.writeln(args, str(token)) 156*16467b97STreehugger Robot 157*16467b97STreehugger Robot 158*16467b97STreehugger Robotclass ParserMain(_Main): 159*16467b97STreehugger Robot def __init__(self, lexerClassName, parserClass): 160*16467b97STreehugger Robot super().__init__() 161*16467b97STreehugger Robot 162*16467b97STreehugger Robot self.lexerClassName = lexerClassName 163*16467b97STreehugger Robot self.lexerClass = None 164*16467b97STreehugger Robot self.parserClass = parserClass 165*16467b97STreehugger Robot 166*16467b97STreehugger Robot 167*16467b97STreehugger Robot def setupArgs(self, argParser): 168*16467b97STreehugger Robot argParser.add_argument("--lexer", dest="lexerClass", 169*16467b97STreehugger Robot default=self.lexerClassName) 170*16467b97STreehugger Robot argParser.add_argument("--rule", dest="parserRule") 171*16467b97STreehugger Robot 172*16467b97STreehugger Robot 173*16467b97STreehugger Robot def setUp(self, args): 174*16467b97STreehugger Robot lexerMod = __import__(args.lexerClass) 175*16467b97STreehugger Robot self.lexerClass = getattr(lexerMod, args.lexerClass) 176*16467b97STreehugger Robot 177*16467b97STreehugger Robot 178*16467b97STreehugger Robot def parseStream(self, args, inStream): 179*16467b97STreehugger Robot kwargs = {} 180*16467b97STreehugger Robot if args.port is not None: 181*16467b97STreehugger Robot kwargs['port'] = args.port 182*16467b97STreehugger Robot if args.debug_socket: 183*16467b97STreehugger Robot kwargs['debug_socket'] = sys.stderr 184*16467b97STreehugger Robot 185*16467b97STreehugger Robot lexer = self.lexerClass(inStream) 186*16467b97STreehugger Robot tokenStream = CommonTokenStream(lexer) 187*16467b97STreehugger Robot parser = self.parserClass(tokenStream, **kwargs) 188*16467b97STreehugger Robot result = getattr(parser, args.parserRule)() 189*16467b97STreehugger Robot if result: 190*16467b97STreehugger Robot if hasattr(result, 'tree') and result.tree: 191*16467b97STreehugger Robot self.writeln(args, result.tree.toStringTree()) 192*16467b97STreehugger Robot else: 193*16467b97STreehugger Robot self.writeln(args, repr(result)) 194*16467b97STreehugger Robot 195*16467b97STreehugger Robot 196*16467b97STreehugger Robotclass WalkerMain(_Main): 197*16467b97STreehugger Robot def __init__(self, walkerClass): 198*16467b97STreehugger Robot super().__init__() 199*16467b97STreehugger Robot 200*16467b97STreehugger Robot self.lexerClass = None 201*16467b97STreehugger Robot self.parserClass = None 202*16467b97STreehugger Robot self.walkerClass = walkerClass 203*16467b97STreehugger Robot 204*16467b97STreehugger Robot 205*16467b97STreehugger Robot def setupArgs(self, argParser): 206*16467b97STreehugger Robot argParser.add_argument("--lexer", dest="lexerClass") 207*16467b97STreehugger Robot argParser.add_argument("--parser", dest="parserClass") 208*16467b97STreehugger Robot argParser.add_argument("--parser-rule", dest="parserRule") 209*16467b97STreehugger Robot argParser.add_argument("--rule", dest="walkerRule") 210*16467b97STreehugger Robot 211*16467b97STreehugger Robot 212*16467b97STreehugger Robot def setUp(self, args): 213*16467b97STreehugger Robot lexerMod = __import__(args.lexerClass) 214*16467b97STreehugger Robot self.lexerClass = getattr(lexerMod, args.lexerClass) 215*16467b97STreehugger Robot parserMod = __import__(args.parserClass) 216*16467b97STreehugger Robot self.parserClass = getattr(parserMod, args.parserClass) 217*16467b97STreehugger Robot 218*16467b97STreehugger Robot 219*16467b97STreehugger Robot def parseStream(self, args, inStream): 220*16467b97STreehugger Robot lexer = self.lexerClass(inStream) 221*16467b97STreehugger Robot tokenStream = CommonTokenStream(lexer) 222*16467b97STreehugger Robot parser = self.parserClass(tokenStream) 223*16467b97STreehugger Robot result = getattr(parser, args.parserRule)() 224*16467b97STreehugger Robot if result: 225*16467b97STreehugger Robot assert hasattr(result, 'tree'), "Parser did not return an AST" 226*16467b97STreehugger Robot nodeStream = CommonTreeNodeStream(result.tree) 227*16467b97STreehugger Robot nodeStream.setTokenStream(tokenStream) 228*16467b97STreehugger Robot walker = self.walkerClass(nodeStream) 229*16467b97STreehugger Robot result = getattr(walker, args.walkerRule)() 230*16467b97STreehugger Robot if result: 231*16467b97STreehugger Robot if hasattr(result, 'tree'): 232*16467b97STreehugger Robot self.writeln(args, result.tree.toStringTree()) 233*16467b97STreehugger Robot else: 234*16467b97STreehugger Robot self.writeln(args, repr(result)) 235