You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
306 lines
8.8 KiB
306 lines
8.8 KiB
"""ANTLR3 runtime package"""
|
|
|
|
# begin[licence]
|
|
#
|
|
# [The "BSD licence"]
|
|
# Copyright (c) 2005-2008 Terence Parr
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
# 3. The name of the author may not be used to endorse or promote products
|
|
# derived from this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#
|
|
# end[licence]
|
|
|
|
|
|
import sys
|
|
import optparse
|
|
|
|
import antlr3
|
|
|
|
|
|
class _Main(object):
|
|
def __init__(self):
|
|
self.stdin = sys.stdin
|
|
self.stdout = sys.stdout
|
|
self.stderr = sys.stderr
|
|
|
|
|
|
def parseOptions(self, argv):
|
|
optParser = optparse.OptionParser()
|
|
optParser.add_option(
|
|
"--encoding",
|
|
action="store",
|
|
type="string",
|
|
dest="encoding"
|
|
)
|
|
optParser.add_option(
|
|
"--input",
|
|
action="store",
|
|
type="string",
|
|
dest="input"
|
|
)
|
|
optParser.add_option(
|
|
"--interactive", "-i",
|
|
action="store_true",
|
|
dest="interactive"
|
|
)
|
|
optParser.add_option(
|
|
"--no-output",
|
|
action="store_true",
|
|
dest="no_output"
|
|
)
|
|
optParser.add_option(
|
|
"--profile",
|
|
action="store_true",
|
|
dest="profile"
|
|
)
|
|
optParser.add_option(
|
|
"--hotshot",
|
|
action="store_true",
|
|
dest="hotshot"
|
|
)
|
|
optParser.add_option(
|
|
"--port",
|
|
type="int",
|
|
dest="port",
|
|
default=None
|
|
)
|
|
optParser.add_option(
|
|
"--debug-socket",
|
|
action='store_true',
|
|
dest="debug_socket",
|
|
default=None
|
|
)
|
|
|
|
self.setupOptions(optParser)
|
|
|
|
return optParser.parse_args(argv[1:])
|
|
|
|
|
|
def setupOptions(self, optParser):
|
|
pass
|
|
|
|
|
|
def execute(self, argv):
|
|
options, args = self.parseOptions(argv)
|
|
|
|
self.setUp(options)
|
|
|
|
if options.interactive:
|
|
while True:
|
|
try:
|
|
input = raw_input(">>> ")
|
|
except (EOFError, KeyboardInterrupt):
|
|
self.stdout.write("\nBye.\n")
|
|
break
|
|
|
|
inStream = antlr3.ANTLRStringStream(input)
|
|
self.parseStream(options, inStream)
|
|
|
|
else:
|
|
if options.input is not None:
|
|
inStream = antlr3.ANTLRStringStream(options.input)
|
|
|
|
elif len(args) == 1 and args[0] != '-':
|
|
inStream = antlr3.ANTLRFileStream(
|
|
args[0], encoding=options.encoding
|
|
)
|
|
|
|
else:
|
|
inStream = antlr3.ANTLRInputStream(
|
|
self.stdin, encoding=options.encoding
|
|
)
|
|
|
|
if options.profile:
|
|
try:
|
|
import cProfile as profile
|
|
except ImportError:
|
|
import profile
|
|
|
|
profile.runctx(
|
|
'self.parseStream(options, inStream)',
|
|
globals(),
|
|
locals(),
|
|
'profile.dat'
|
|
)
|
|
|
|
import pstats
|
|
stats = pstats.Stats('profile.dat')
|
|
stats.strip_dirs()
|
|
stats.sort_stats('time')
|
|
stats.print_stats(100)
|
|
|
|
elif options.hotshot:
|
|
import hotshot
|
|
|
|
profiler = hotshot.Profile('hotshot.dat')
|
|
profiler.runctx(
|
|
'self.parseStream(options, inStream)',
|
|
globals(),
|
|
locals()
|
|
)
|
|
|
|
else:
|
|
self.parseStream(options, inStream)
|
|
|
|
|
|
def setUp(self, options):
|
|
pass
|
|
|
|
|
|
def parseStream(self, options, inStream):
|
|
raise NotImplementedError
|
|
|
|
|
|
def write(self, options, text):
|
|
if not options.no_output:
|
|
self.stdout.write(text)
|
|
|
|
|
|
def writeln(self, options, text):
|
|
self.write(options, text + '\n')
|
|
|
|
|
|
class LexerMain(_Main):
|
|
def __init__(self, lexerClass):
|
|
_Main.__init__(self)
|
|
|
|
self.lexerClass = lexerClass
|
|
|
|
|
|
def parseStream(self, options, inStream):
|
|
lexer = self.lexerClass(inStream)
|
|
for token in lexer:
|
|
self.writeln(options, str(token))
|
|
|
|
|
|
class ParserMain(_Main):
|
|
def __init__(self, lexerClassName, parserClass):
|
|
_Main.__init__(self)
|
|
|
|
self.lexerClassName = lexerClassName
|
|
self.lexerClass = None
|
|
self.parserClass = parserClass
|
|
|
|
|
|
def setupOptions(self, optParser):
|
|
optParser.add_option(
|
|
"--lexer",
|
|
action="store",
|
|
type="string",
|
|
dest="lexerClass",
|
|
default=self.lexerClassName
|
|
)
|
|
optParser.add_option(
|
|
"--rule",
|
|
action="store",
|
|
type="string",
|
|
dest="parserRule"
|
|
)
|
|
|
|
|
|
def setUp(self, options):
|
|
lexerMod = __import__(options.lexerClass)
|
|
self.lexerClass = getattr(lexerMod, options.lexerClass)
|
|
|
|
|
|
def parseStream(self, options, inStream):
|
|
kwargs = {}
|
|
if options.port is not None:
|
|
kwargs['port'] = options.port
|
|
if options.debug_socket is not None:
|
|
kwargs['debug_socket'] = sys.stderr
|
|
|
|
lexer = self.lexerClass(inStream)
|
|
tokenStream = antlr3.CommonTokenStream(lexer)
|
|
parser = self.parserClass(tokenStream, **kwargs)
|
|
result = getattr(parser, options.parserRule)()
|
|
if result is not None:
|
|
if hasattr(result, 'tree') and result.tree is not None:
|
|
self.writeln(options, result.tree.toStringTree())
|
|
else:
|
|
self.writeln(options, repr(result))
|
|
|
|
|
|
class WalkerMain(_Main):
|
|
def __init__(self, walkerClass):
|
|
_Main.__init__(self)
|
|
|
|
self.lexerClass = None
|
|
self.parserClass = None
|
|
self.walkerClass = walkerClass
|
|
|
|
|
|
def setupOptions(self, optParser):
|
|
optParser.add_option(
|
|
"--lexer",
|
|
action="store",
|
|
type="string",
|
|
dest="lexerClass",
|
|
default=None
|
|
)
|
|
optParser.add_option(
|
|
"--parser",
|
|
action="store",
|
|
type="string",
|
|
dest="parserClass",
|
|
default=None
|
|
)
|
|
optParser.add_option(
|
|
"--parser-rule",
|
|
action="store",
|
|
type="string",
|
|
dest="parserRule",
|
|
default=None
|
|
)
|
|
optParser.add_option(
|
|
"--rule",
|
|
action="store",
|
|
type="string",
|
|
dest="walkerRule"
|
|
)
|
|
|
|
|
|
def setUp(self, options):
|
|
lexerMod = __import__(options.lexerClass)
|
|
self.lexerClass = getattr(lexerMod, options.lexerClass)
|
|
parserMod = __import__(options.parserClass)
|
|
self.parserClass = getattr(parserMod, options.parserClass)
|
|
|
|
|
|
def parseStream(self, options, inStream):
|
|
lexer = self.lexerClass(inStream)
|
|
tokenStream = antlr3.CommonTokenStream(lexer)
|
|
parser = self.parserClass(tokenStream)
|
|
result = getattr(parser, options.parserRule)()
|
|
if result is not None:
|
|
assert hasattr(result, 'tree'), "Parser did not return an AST"
|
|
nodeStream = antlr3.tree.CommonTreeNodeStream(result.tree)
|
|
nodeStream.setTokenStream(tokenStream)
|
|
walker = self.walkerClass(nodeStream)
|
|
result = getattr(walker, options.walkerRule)()
|
|
if result is not None:
|
|
if hasattr(result, 'tree'):
|
|
self.writeln(options, result.tree.toStringTree())
|
|
else:
|
|
self.writeln(options, repr(result))
|