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