xref: /aosp_15_r20/external/antlr/runtime/Python3/antlr3/main.py (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
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