Home | History | Annotate | Download | only in antlr3
      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