1"""ANTLR3 runtime package"""
2
3# begin[licence]
4#
5# [The "BSD licence"]
6# Copyright (c) 2005-2008 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
34import sys
35import optparse
36
37import antlr3
38
39
40class _Main(object):
41    def __init__(self):
42        self.stdin = sys.stdin
43        self.stdout = sys.stdout
44        self.stderr = sys.stderr
45
46
47    def parseOptions(self, argv):
48        optParser = optparse.OptionParser()
49        optParser.add_option(
50            "--encoding",
51            action="store",
52            type="string",
53            dest="encoding"
54            )
55        optParser.add_option(
56            "--input",
57            action="store",
58            type="string",
59            dest="input"
60            )
61        optParser.add_option(
62            "--interactive", "-i",
63            action="store_true",
64            dest="interactive"
65            )
66        optParser.add_option(
67            "--no-output",
68            action="store_true",
69            dest="no_output"
70            )
71        optParser.add_option(
72            "--profile",
73            action="store_true",
74            dest="profile"
75            )
76        optParser.add_option(
77            "--hotshot",
78            action="store_true",
79            dest="hotshot"
80            )
81        optParser.add_option(
82            "--port",
83            type="int",
84            dest="port",
85            default=None
86            )
87        optParser.add_option(
88            "--debug-socket",
89            action='store_true',
90            dest="debug_socket",
91            default=None
92            )
93
94        self.setupOptions(optParser)
95
96        return optParser.parse_args(argv[1:])
97
98
99    def setupOptions(self, optParser):
100        pass
101
102
103    def execute(self, argv):
104        options, args = self.parseOptions(argv)
105
106        self.setUp(options)
107
108        if options.interactive:
109            while True:
110                try:
111                    input = raw_input(">>> ")
112                except (EOFError, KeyboardInterrupt):
113                    self.stdout.write("\nBye.\n")
114                    break
115
116                inStream = antlr3.ANTLRStringStream(input)
117                self.parseStream(options, inStream)
118
119        else:
120            if options.input is not None:
121                inStream = antlr3.ANTLRStringStream(options.input)
122
123            elif len(args) == 1 and args[0] != '-':
124                inStream = antlr3.ANTLRFileStream(
125                    args[0], encoding=options.encoding
126                    )
127
128            else:
129                inStream = antlr3.ANTLRInputStream(
130                    self.stdin, encoding=options.encoding
131                    )
132
133            if options.profile:
134                try:
135                    import cProfile as profile
136                except ImportError:
137                    import profile
138
139                profile.runctx(
140                    'self.parseStream(options, inStream)',
141                    globals(),
142                    locals(),
143                    'profile.dat'
144                    )
145
146                import pstats
147                stats = pstats.Stats('profile.dat')
148                stats.strip_dirs()
149                stats.sort_stats('time')
150                stats.print_stats(100)
151
152            elif options.hotshot:
153                import hotshot
154
155                profiler = hotshot.Profile('hotshot.dat')
156                profiler.runctx(
157                    'self.parseStream(options, inStream)',
158                    globals(),
159                    locals()
160                    )
161
162            else:
163                self.parseStream(options, inStream)
164
165
166    def setUp(self, options):
167        pass
168
169
170    def parseStream(self, options, inStream):
171        raise NotImplementedError
172
173
174    def write(self, options, text):
175        if not options.no_output:
176            self.stdout.write(text)
177
178
179    def writeln(self, options, text):
180        self.write(options, text + '\n')
181
182
183class LexerMain(_Main):
184    def __init__(self, lexerClass):
185        _Main.__init__(self)
186
187        self.lexerClass = lexerClass
188
189
190    def parseStream(self, options, inStream):
191        lexer = self.lexerClass(inStream)
192        for token in lexer:
193            self.writeln(options, str(token))
194
195
196class ParserMain(_Main):
197    def __init__(self, lexerClassName, parserClass):
198        _Main.__init__(self)
199
200        self.lexerClassName = lexerClassName
201        self.lexerClass = None
202        self.parserClass = parserClass
203
204
205    def setupOptions(self, optParser):
206        optParser.add_option(
207            "--lexer",
208            action="store",
209            type="string",
210            dest="lexerClass",
211            default=self.lexerClassName
212            )
213        optParser.add_option(
214            "--rule",
215            action="store",
216            type="string",
217            dest="parserRule"
218            )
219
220
221    def setUp(self, options):
222        lexerMod = __import__(options.lexerClass)
223        self.lexerClass = getattr(lexerMod, options.lexerClass)
224
225
226    def parseStream(self, options, inStream):
227        kwargs = {}
228        if options.port is not None:
229            kwargs['port'] = options.port
230        if options.debug_socket is not None:
231            kwargs['debug_socket'] = sys.stderr
232
233        lexer = self.lexerClass(inStream)
234        tokenStream = antlr3.CommonTokenStream(lexer)
235        parser = self.parserClass(tokenStream, **kwargs)
236        result = getattr(parser, options.parserRule)()
237        if result is not None:
238            if hasattr(result, 'tree') and result.tree is not None:
239                self.writeln(options, result.tree.toStringTree())
240            else:
241                self.writeln(options, repr(result))
242
243
244class WalkerMain(_Main):
245    def __init__(self, walkerClass):
246        _Main.__init__(self)
247
248        self.lexerClass = None
249        self.parserClass = None
250        self.walkerClass = walkerClass
251
252
253    def setupOptions(self, optParser):
254        optParser.add_option(
255            "--lexer",
256            action="store",
257            type="string",
258            dest="lexerClass",
259            default=None
260            )
261        optParser.add_option(
262            "--parser",
263            action="store",
264            type="string",
265            dest="parserClass",
266            default=None
267            )
268        optParser.add_option(
269            "--parser-rule",
270            action="store",
271            type="string",
272            dest="parserRule",
273            default=None
274            )
275        optParser.add_option(
276            "--rule",
277            action="store",
278            type="string",
279            dest="walkerRule"
280            )
281
282
283    def setUp(self, options):
284        lexerMod = __import__(options.lexerClass)
285        self.lexerClass = getattr(lexerMod, options.lexerClass)
286        parserMod = __import__(options.parserClass)
287        self.parserClass = getattr(parserMod, options.parserClass)
288
289
290    def parseStream(self, options, inStream):
291        lexer = self.lexerClass(inStream)
292        tokenStream = antlr3.CommonTokenStream(lexer)
293        parser = self.parserClass(tokenStream)
294        result = getattr(parser, options.parserRule)()
295        if result is not None:
296            assert hasattr(result, 'tree'), "Parser did not return an AST"
297            nodeStream = antlr3.tree.CommonTreeNodeStream(result.tree)
298            nodeStream.setTokenStream(tokenStream)
299            walker = self.walkerClass(nodeStream)
300            result = getattr(walker, options.walkerRule)()
301            if result is not None:
302                if hasattr(result, 'tree'):
303                    self.writeln(options, result.tree.toStringTree())
304                else:
305                    self.writeln(options, repr(result))
306