xref: /aosp_15_r20/external/antlr/runtime/Python/tests/testbase.py (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robotimport unittest
2*16467b97STreehugger Robotimport imp
3*16467b97STreehugger Robotimport os
4*16467b97STreehugger Robotimport errno
5*16467b97STreehugger Robotimport sys
6*16467b97STreehugger Robotimport glob
7*16467b97STreehugger Robotimport re
8*16467b97STreehugger Robotimport tempfile
9*16467b97STreehugger Robotimport shutil
10*16467b97STreehugger Robotimport inspect
11*16467b97STreehugger Robotimport hashlib
12*16467b97STreehugger Robotfrom distutils.errors import *
13*16467b97STreehugger Robotimport antlr3
14*16467b97STreehugger Robot
15*16467b97STreehugger Robotdef unlink(path):
16*16467b97STreehugger Robot    try:
17*16467b97STreehugger Robot        os.unlink(path)
18*16467b97STreehugger Robot    except OSError, exc:
19*16467b97STreehugger Robot        if exc.errno != errno.ENOENT:
20*16467b97STreehugger Robot            raise
21*16467b97STreehugger Robot
22*16467b97STreehugger Robot
23*16467b97STreehugger Robotclass GrammarCompileError(Exception):
24*16467b97STreehugger Robot  """Grammar failed to compile."""
25*16467b97STreehugger Robot  pass
26*16467b97STreehugger Robot
27*16467b97STreehugger Robot
28*16467b97STreehugger Robot# At least on MacOSX tempdir (/tmp) is a symlink. It's sometimes dereferences,
29*16467b97STreehugger Robot# sometimes not, breaking the inspect.getmodule() function.
30*16467b97STreehugger Robottestbasedir = os.path.join(
31*16467b97STreehugger Robot    os.path.realpath(tempfile.gettempdir()),
32*16467b97STreehugger Robot    'antlr3-test')
33*16467b97STreehugger Robot
34*16467b97STreehugger Robot
35*16467b97STreehugger Robotclass BrokenTest(unittest.TestCase.failureException):
36*16467b97STreehugger Robot    def __repr__(self):
37*16467b97STreehugger Robot        name, reason = self.args
38*16467b97STreehugger Robot        return '%s: %s: %s works now' % (
39*16467b97STreehugger Robot            (self.__class__.__name__, name, reason))
40*16467b97STreehugger Robot
41*16467b97STreehugger Robot
42*16467b97STreehugger Robotdef broken(reason, *exceptions):
43*16467b97STreehugger Robot    '''Indicates a failing (or erroneous) test case fails that should succeed.
44*16467b97STreehugger Robot    If the test fails with an exception, list the exception type in args'''
45*16467b97STreehugger Robot    def wrapper(test_method):
46*16467b97STreehugger Robot        def replacement(*args, **kwargs):
47*16467b97STreehugger Robot            try:
48*16467b97STreehugger Robot                test_method(*args, **kwargs)
49*16467b97STreehugger Robot            except exceptions or unittest.TestCase.failureException:
50*16467b97STreehugger Robot                pass
51*16467b97STreehugger Robot            else:
52*16467b97STreehugger Robot                raise BrokenTest(test_method.__name__, reason)
53*16467b97STreehugger Robot        replacement.__doc__ = test_method.__doc__
54*16467b97STreehugger Robot        replacement.__name__ = 'XXX_' + test_method.__name__
55*16467b97STreehugger Robot        replacement.todo = reason
56*16467b97STreehugger Robot        return replacement
57*16467b97STreehugger Robot    return wrapper
58*16467b97STreehugger Robot
59*16467b97STreehugger Robot
60*16467b97STreehugger RobotdependencyCache = {}
61*16467b97STreehugger RobotcompileErrorCache = {}
62*16467b97STreehugger Robot
63*16467b97STreehugger Robot# setup java CLASSPATH
64*16467b97STreehugger Robotif 'CLASSPATH' not in os.environ:
65*16467b97STreehugger Robot    cp = []
66*16467b97STreehugger Robot
67*16467b97STreehugger Robot    baseDir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
68*16467b97STreehugger Robot    libDir = os.path.join(baseDir, 'lib')
69*16467b97STreehugger Robot
70*16467b97STreehugger Robot    jar = os.path.join(libDir, 'ST-4.0.1.jar')
71*16467b97STreehugger Robot    if not os.path.isfile(jar):
72*16467b97STreehugger Robot        raise DistutilsFileError(
73*16467b97STreehugger Robot            "Missing file '%s'. Grap it from a distribution package."
74*16467b97STreehugger Robot            % jar,
75*16467b97STreehugger Robot            )
76*16467b97STreehugger Robot    cp.append(jar)
77*16467b97STreehugger Robot
78*16467b97STreehugger Robot    jar = os.path.join(libDir, 'antlr-2.7.7.jar')
79*16467b97STreehugger Robot    if not os.path.isfile(jar):
80*16467b97STreehugger Robot        raise DistutilsFileError(
81*16467b97STreehugger Robot            "Missing file '%s'. Grap it from a distribution package."
82*16467b97STreehugger Robot            % jar,
83*16467b97STreehugger Robot            )
84*16467b97STreehugger Robot    cp.append(jar)
85*16467b97STreehugger Robot
86*16467b97STreehugger Robot    jar = os.path.join(libDir, 'junit-4.2.jar')
87*16467b97STreehugger Robot    if not os.path.isfile(jar):
88*16467b97STreehugger Robot        raise DistutilsFileError(
89*16467b97STreehugger Robot            "Missing file '%s'. Grap it from a distribution package."
90*16467b97STreehugger Robot            % jar,
91*16467b97STreehugger Robot            )
92*16467b97STreehugger Robot    cp.append(jar)
93*16467b97STreehugger Robot
94*16467b97STreehugger Robot    cp.append(os.path.join(baseDir, 'runtime', 'Python', 'build'))
95*16467b97STreehugger Robot
96*16467b97STreehugger Robot    classpath = '-cp "' + ':'.join([os.path.abspath(p) for p in cp]) + '"'
97*16467b97STreehugger Robot
98*16467b97STreehugger Robotelse:
99*16467b97STreehugger Robot    classpath = ''
100*16467b97STreehugger Robot
101*16467b97STreehugger Robot
102*16467b97STreehugger Robotclass ANTLRTest(unittest.TestCase):
103*16467b97STreehugger Robot    def __init__(self, *args, **kwargs):
104*16467b97STreehugger Robot        unittest.TestCase.__init__(self, *args, **kwargs)
105*16467b97STreehugger Robot
106*16467b97STreehugger Robot        self.moduleName = os.path.splitext(os.path.basename(sys.modules[self.__module__].__file__))[0]
107*16467b97STreehugger Robot        self.className = self.__class__.__name__
108*16467b97STreehugger Robot        self._baseDir = None
109*16467b97STreehugger Robot
110*16467b97STreehugger Robot        self.lexerModule = None
111*16467b97STreehugger Robot        self.parserModule = None
112*16467b97STreehugger Robot
113*16467b97STreehugger Robot        self.grammarName = None
114*16467b97STreehugger Robot        self.grammarType = None
115*16467b97STreehugger Robot
116*16467b97STreehugger Robot
117*16467b97STreehugger Robot    def assertListEqual(self, a, b):
118*16467b97STreehugger Robot        if a == b:
119*16467b97STreehugger Robot            return
120*16467b97STreehugger Robot
121*16467b97STreehugger Robot        import difflib
122*16467b97STreehugger Robot        a = [str(l) + '\n' for l in a]
123*16467b97STreehugger Robot        b = [str(l) + '\n' for l in b]
124*16467b97STreehugger Robot
125*16467b97STreehugger Robot        raise AssertionError(''.join(difflib.unified_diff(a, b)))
126*16467b97STreehugger Robot
127*16467b97STreehugger Robot
128*16467b97STreehugger Robot    @property
129*16467b97STreehugger Robot    def baseDir(self):
130*16467b97STreehugger Robot        if self._baseDir is None:
131*16467b97STreehugger Robot            testName = 'unknownTest'
132*16467b97STreehugger Robot            for frame in inspect.stack():
133*16467b97STreehugger Robot                code = frame[0].f_code
134*16467b97STreehugger Robot                codeMod = inspect.getmodule(code)
135*16467b97STreehugger Robot                if codeMod is None:
136*16467b97STreehugger Robot                    continue
137*16467b97STreehugger Robot
138*16467b97STreehugger Robot                # skip frames not in requested module
139*16467b97STreehugger Robot                if codeMod is not sys.modules[self.__module__]:
140*16467b97STreehugger Robot                    continue
141*16467b97STreehugger Robot
142*16467b97STreehugger Robot                # skip some unwanted names
143*16467b97STreehugger Robot                if code.co_name in ('nextToken', '<module>'):
144*16467b97STreehugger Robot                    continue
145*16467b97STreehugger Robot
146*16467b97STreehugger Robot                if code.co_name.startswith('test'):
147*16467b97STreehugger Robot                    testName = code.co_name
148*16467b97STreehugger Robot                    break
149*16467b97STreehugger Robot
150*16467b97STreehugger Robot            self._baseDir = os.path.join(
151*16467b97STreehugger Robot                testbasedir,
152*16467b97STreehugger Robot                self.moduleName, self.className, testName)
153*16467b97STreehugger Robot            if not os.path.isdir(self._baseDir):
154*16467b97STreehugger Robot                os.makedirs(self._baseDir)
155*16467b97STreehugger Robot
156*16467b97STreehugger Robot        return self._baseDir
157*16467b97STreehugger Robot
158*16467b97STreehugger Robot
159*16467b97STreehugger Robot    def _invokeantlr(self, dir, file, options, javaOptions=''):
160*16467b97STreehugger Robot        cmd = 'cd %s; java %s %s org.antlr.Tool -o . %s %s 2>&1' % (
161*16467b97STreehugger Robot            dir, javaOptions, classpath, options, file
162*16467b97STreehugger Robot            )
163*16467b97STreehugger Robot        fp = os.popen(cmd)
164*16467b97STreehugger Robot        output = ''
165*16467b97STreehugger Robot        failed = False
166*16467b97STreehugger Robot        for line in fp:
167*16467b97STreehugger Robot            output += line
168*16467b97STreehugger Robot
169*16467b97STreehugger Robot            if line.startswith('error('):
170*16467b97STreehugger Robot                failed = True
171*16467b97STreehugger Robot
172*16467b97STreehugger Robot        rc = fp.close()
173*16467b97STreehugger Robot        if rc is not None:
174*16467b97STreehugger Robot            failed = True
175*16467b97STreehugger Robot
176*16467b97STreehugger Robot        if failed:
177*16467b97STreehugger Robot            raise GrammarCompileError(
178*16467b97STreehugger Robot                "Failed to compile grammar '%s':\n%s\n\n" % (file, cmd)
179*16467b97STreehugger Robot                + output
180*16467b97STreehugger Robot                )
181*16467b97STreehugger Robot
182*16467b97STreehugger Robot
183*16467b97STreehugger Robot    def compileGrammar(self, grammarName=None, options='', javaOptions=''):
184*16467b97STreehugger Robot        if grammarName is None:
185*16467b97STreehugger Robot            grammarName = self.moduleName + '.g'
186*16467b97STreehugger Robot
187*16467b97STreehugger Robot        self._baseDir = os.path.join(
188*16467b97STreehugger Robot            testbasedir,
189*16467b97STreehugger Robot            self.moduleName)
190*16467b97STreehugger Robot        if not os.path.isdir(self._baseDir):
191*16467b97STreehugger Robot            os.makedirs(self._baseDir)
192*16467b97STreehugger Robot
193*16467b97STreehugger Robot        if self.grammarName is None:
194*16467b97STreehugger Robot            self.grammarName = os.path.splitext(grammarName)[0]
195*16467b97STreehugger Robot
196*16467b97STreehugger Robot        grammarPath = os.path.join(os.path.dirname(os.path.abspath(__file__)), grammarName)
197*16467b97STreehugger Robot
198*16467b97STreehugger Robot        # get type and name from first grammar line
199*16467b97STreehugger Robot        grammar = open(grammarPath, 'r').read()
200*16467b97STreehugger Robot        m = re.match(r'\s*((lexer|parser|tree)\s+|)grammar\s+(\S+);', grammar, re.MULTILINE)
201*16467b97STreehugger Robot        assert m is not None, grammar
202*16467b97STreehugger Robot        self.grammarType = m.group(2)
203*16467b97STreehugger Robot        if self.grammarType is None:
204*16467b97STreehugger Robot            self.grammarType = 'combined'
205*16467b97STreehugger Robot
206*16467b97STreehugger Robot        if self.grammarType is None:
207*16467b97STreehugger Robot            assert self.grammarType in ('lexer', 'parser', 'tree', 'combined'), self.grammarType
208*16467b97STreehugger Robot
209*16467b97STreehugger Robot        # don't try to rebuild grammar, if it already failed
210*16467b97STreehugger Robot        if grammarName in compileErrorCache:
211*16467b97STreehugger Robot            return
212*16467b97STreehugger Robot
213*16467b97STreehugger Robot        try:
214*16467b97STreehugger Robot        #     # get dependencies from antlr
215*16467b97STreehugger Robot        #     if grammarName in dependencyCache:
216*16467b97STreehugger Robot        #         dependencies = dependencyCache[grammarName]
217*16467b97STreehugger Robot
218*16467b97STreehugger Robot        #     else:
219*16467b97STreehugger Robot        #         dependencies = []
220*16467b97STreehugger Robot        #         cmd = ('cd %s; java %s %s org.antlr.Tool -o . -depend %s 2>&1'
221*16467b97STreehugger Robot        #                % (self.baseDir, javaOptions, classpath, grammarPath))
222*16467b97STreehugger Robot
223*16467b97STreehugger Robot        #         output = ""
224*16467b97STreehugger Robot        #         failed = False
225*16467b97STreehugger Robot
226*16467b97STreehugger Robot        #         fp = os.popen(cmd)
227*16467b97STreehugger Robot        #         for line in fp:
228*16467b97STreehugger Robot        #             output += line
229*16467b97STreehugger Robot
230*16467b97STreehugger Robot        #             if line.startswith('error('):
231*16467b97STreehugger Robot        #                 failed = True
232*16467b97STreehugger Robot        #             elif ':' in line:
233*16467b97STreehugger Robot        #                 a, b = line.strip().split(':', 1)
234*16467b97STreehugger Robot        #                 dependencies.append(
235*16467b97STreehugger Robot        #                     (os.path.join(self.baseDir, a.strip()),
236*16467b97STreehugger Robot        #                      [os.path.join(self.baseDir, b.strip())])
237*16467b97STreehugger Robot        #                     )
238*16467b97STreehugger Robot
239*16467b97STreehugger Robot        #         rc = fp.close()
240*16467b97STreehugger Robot        #         if rc is not None:
241*16467b97STreehugger Robot        #             failed = True
242*16467b97STreehugger Robot
243*16467b97STreehugger Robot        #         if failed:
244*16467b97STreehugger Robot        #             raise GrammarCompileError(
245*16467b97STreehugger Robot        #                 "antlr -depend failed with code %s on grammar '%s':\n\n"
246*16467b97STreehugger Robot        #                 % (rc, grammarName)
247*16467b97STreehugger Robot        #                 + cmd
248*16467b97STreehugger Robot        #                 + "\n"
249*16467b97STreehugger Robot        #                 + output
250*16467b97STreehugger Robot        #                 )
251*16467b97STreehugger Robot
252*16467b97STreehugger Robot        #         # add dependencies to my .stg files
253*16467b97STreehugger Robot        #         templateDir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'tool', 'src', 'main', 'resources', 'org', 'antlr', 'codegen', 'templates', 'Python'))
254*16467b97STreehugger Robot        #         templates = glob.glob(os.path.join(templateDir, '*.stg'))
255*16467b97STreehugger Robot
256*16467b97STreehugger Robot        #         for dst, src in dependencies:
257*16467b97STreehugger Robot        #             src.extend(templates)
258*16467b97STreehugger Robot
259*16467b97STreehugger Robot        #         dependencyCache[grammarName] = dependencies
260*16467b97STreehugger Robot
261*16467b97STreehugger Robot        #     rebuild = False
262*16467b97STreehugger Robot        #     for dest, sources in dependencies:
263*16467b97STreehugger Robot        #         if not os.path.isfile(dest):
264*16467b97STreehugger Robot        #             rebuild = True
265*16467b97STreehugger Robot        #             break
266*16467b97STreehugger Robot
267*16467b97STreehugger Robot        #         for source in sources:
268*16467b97STreehugger Robot        #             if os.path.getmtime(source) > os.path.getmtime(dest):
269*16467b97STreehugger Robot        #                 rebuild = True
270*16467b97STreehugger Robot        #                 break
271*16467b97STreehugger Robot
272*16467b97STreehugger Robot
273*16467b97STreehugger Robot        #     if rebuild:
274*16467b97STreehugger Robot        #         self._invokeantlr(self.baseDir, grammarPath, options, javaOptions)
275*16467b97STreehugger Robot
276*16467b97STreehugger Robot            self._invokeantlr(self.baseDir, grammarPath, options, javaOptions)
277*16467b97STreehugger Robot
278*16467b97STreehugger Robot        except:
279*16467b97STreehugger Robot            # mark grammar as broken
280*16467b97STreehugger Robot            compileErrorCache[grammarName] = True
281*16467b97STreehugger Robot            raise
282*16467b97STreehugger Robot
283*16467b97STreehugger Robot
284*16467b97STreehugger Robot    def lexerClass(self, base):
285*16467b97STreehugger Robot        """Optionally build a subclass of generated lexer class"""
286*16467b97STreehugger Robot
287*16467b97STreehugger Robot        return base
288*16467b97STreehugger Robot
289*16467b97STreehugger Robot
290*16467b97STreehugger Robot    def parserClass(self, base):
291*16467b97STreehugger Robot        """Optionally build a subclass of generated parser class"""
292*16467b97STreehugger Robot
293*16467b97STreehugger Robot        return base
294*16467b97STreehugger Robot
295*16467b97STreehugger Robot
296*16467b97STreehugger Robot    def walkerClass(self, base):
297*16467b97STreehugger Robot        """Optionally build a subclass of generated walker class"""
298*16467b97STreehugger Robot
299*16467b97STreehugger Robot        return base
300*16467b97STreehugger Robot
301*16467b97STreehugger Robot
302*16467b97STreehugger Robot    def __load_module(self, name):
303*16467b97STreehugger Robot        modFile, modPathname, modDescription \
304*16467b97STreehugger Robot                 = imp.find_module(name, [self.baseDir])
305*16467b97STreehugger Robot
306*16467b97STreehugger Robot        return imp.load_module(
307*16467b97STreehugger Robot            name, modFile, modPathname, modDescription
308*16467b97STreehugger Robot            )
309*16467b97STreehugger Robot
310*16467b97STreehugger Robot
311*16467b97STreehugger Robot    def getLexer(self, *args, **kwargs):
312*16467b97STreehugger Robot        """Build lexer instance. Arguments are passed to lexer.__init__()."""
313*16467b97STreehugger Robot
314*16467b97STreehugger Robot        if self.grammarType == 'lexer':
315*16467b97STreehugger Robot            self.lexerModule = self.__load_module(self.grammarName)
316*16467b97STreehugger Robot            cls = getattr(self.lexerModule, self.grammarName)
317*16467b97STreehugger Robot        else:
318*16467b97STreehugger Robot            self.lexerModule = self.__load_module(self.grammarName + 'Lexer')
319*16467b97STreehugger Robot            cls = getattr(self.lexerModule, self.grammarName + 'Lexer')
320*16467b97STreehugger Robot
321*16467b97STreehugger Robot        cls = self.lexerClass(cls)
322*16467b97STreehugger Robot
323*16467b97STreehugger Robot        lexer = cls(*args, **kwargs)
324*16467b97STreehugger Robot
325*16467b97STreehugger Robot        return lexer
326*16467b97STreehugger Robot
327*16467b97STreehugger Robot
328*16467b97STreehugger Robot    def getParser(self, *args, **kwargs):
329*16467b97STreehugger Robot        """Build parser instance. Arguments are passed to parser.__init__()."""
330*16467b97STreehugger Robot
331*16467b97STreehugger Robot        if self.grammarType == 'parser':
332*16467b97STreehugger Robot            self.lexerModule = self.__load_module(self.grammarName)
333*16467b97STreehugger Robot            cls = getattr(self.lexerModule, self.grammarName)
334*16467b97STreehugger Robot        else:
335*16467b97STreehugger Robot            self.parserModule = self.__load_module(self.grammarName + 'Parser')
336*16467b97STreehugger Robot            cls = getattr(self.parserModule, self.grammarName + 'Parser')
337*16467b97STreehugger Robot        cls = self.parserClass(cls)
338*16467b97STreehugger Robot
339*16467b97STreehugger Robot        parser = cls(*args, **kwargs)
340*16467b97STreehugger Robot
341*16467b97STreehugger Robot        return parser
342*16467b97STreehugger Robot
343*16467b97STreehugger Robot
344*16467b97STreehugger Robot    def getWalker(self, *args, **kwargs):
345*16467b97STreehugger Robot        """Build walker instance. Arguments are passed to walker.__init__()."""
346*16467b97STreehugger Robot
347*16467b97STreehugger Robot        self.walkerModule = self.__load_module(self.grammarName + 'Walker')
348*16467b97STreehugger Robot        cls = getattr(self.walkerModule, self.grammarName + 'Walker')
349*16467b97STreehugger Robot        cls = self.walkerClass(cls)
350*16467b97STreehugger Robot
351*16467b97STreehugger Robot        walker = cls(*args, **kwargs)
352*16467b97STreehugger Robot
353*16467b97STreehugger Robot        return walker
354*16467b97STreehugger Robot
355*16467b97STreehugger Robot
356*16467b97STreehugger Robot    def writeInlineGrammar(self, grammar):
357*16467b97STreehugger Robot        # Create a unique ID for this test and use it as the grammar name,
358*16467b97STreehugger Robot        # to avoid class name reuse. This kinda sucks. Need to find a way so
359*16467b97STreehugger Robot        # tests can use the same grammar name without messing up the namespace.
360*16467b97STreehugger Robot        # Well, first I should figure out what the exact problem is...
361*16467b97STreehugger Robot        id = hashlib.md5(self.baseDir).hexdigest()[-8:]
362*16467b97STreehugger Robot        grammar = grammar.replace('$TP', 'TP' + id)
363*16467b97STreehugger Robot        grammar = grammar.replace('$T', 'T' + id)
364*16467b97STreehugger Robot
365*16467b97STreehugger Robot        # get type and name from first grammar line
366*16467b97STreehugger Robot        m = re.match(r'\s*((lexer|parser|tree)\s+|)grammar\s+(\S+);', grammar, re.MULTILINE)
367*16467b97STreehugger Robot        assert m is not None, grammar
368*16467b97STreehugger Robot        grammarType = m.group(2)
369*16467b97STreehugger Robot        if grammarType is None:
370*16467b97STreehugger Robot            grammarType = 'combined'
371*16467b97STreehugger Robot        grammarName = m.group(3)
372*16467b97STreehugger Robot
373*16467b97STreehugger Robot        assert grammarType in ('lexer', 'parser', 'tree', 'combined'), grammarType
374*16467b97STreehugger Robot
375*16467b97STreehugger Robot        grammarPath = os.path.join(self.baseDir, grammarName + '.g')
376*16467b97STreehugger Robot
377*16467b97STreehugger Robot        # dump temp grammar file
378*16467b97STreehugger Robot        fp = open(grammarPath, 'w')
379*16467b97STreehugger Robot        fp.write(grammar)
380*16467b97STreehugger Robot        fp.close()
381*16467b97STreehugger Robot
382*16467b97STreehugger Robot        return grammarName, grammarPath, grammarType
383*16467b97STreehugger Robot
384*16467b97STreehugger Robot
385*16467b97STreehugger Robot    def writeFile(self, name, contents):
386*16467b97STreehugger Robot        testDir = os.path.dirname(os.path.abspath(__file__))
387*16467b97STreehugger Robot        path = os.path.join(self.baseDir, name)
388*16467b97STreehugger Robot
389*16467b97STreehugger Robot        fp = open(path, 'w')
390*16467b97STreehugger Robot        fp.write(contents)
391*16467b97STreehugger Robot        fp.close()
392*16467b97STreehugger Robot
393*16467b97STreehugger Robot        return path
394*16467b97STreehugger Robot
395*16467b97STreehugger Robot
396*16467b97STreehugger Robot    def compileInlineGrammar(self, grammar, options='', javaOptions='',
397*16467b97STreehugger Robot                             returnModule=False):
398*16467b97STreehugger Robot        # write grammar file
399*16467b97STreehugger Robot        grammarName, grammarPath, grammarType = self.writeInlineGrammar(grammar)
400*16467b97STreehugger Robot
401*16467b97STreehugger Robot        # compile it
402*16467b97STreehugger Robot        self._invokeantlr(
403*16467b97STreehugger Robot            os.path.dirname(grammarPath),
404*16467b97STreehugger Robot            os.path.basename(grammarPath),
405*16467b97STreehugger Robot            options,
406*16467b97STreehugger Robot            javaOptions
407*16467b97STreehugger Robot            )
408*16467b97STreehugger Robot
409*16467b97STreehugger Robot        if grammarType == 'combined':
410*16467b97STreehugger Robot            lexerMod = self.__load_module(grammarName + 'Lexer')
411*16467b97STreehugger Robot            parserMod = self.__load_module(grammarName + 'Parser')
412*16467b97STreehugger Robot            if returnModule:
413*16467b97STreehugger Robot                return lexerMod, parserMod
414*16467b97STreehugger Robot
415*16467b97STreehugger Robot            lexerCls = getattr(lexerMod, grammarName + 'Lexer')
416*16467b97STreehugger Robot            lexerCls = self.lexerClass(lexerCls)
417*16467b97STreehugger Robot            parserCls = getattr(parserMod, grammarName + 'Parser')
418*16467b97STreehugger Robot            parserCls = self.parserClass(parserCls)
419*16467b97STreehugger Robot
420*16467b97STreehugger Robot            return lexerCls, parserCls
421*16467b97STreehugger Robot
422*16467b97STreehugger Robot        if grammarType == 'lexer':
423*16467b97STreehugger Robot            lexerMod = self.__load_module(grammarName)
424*16467b97STreehugger Robot            if returnModule:
425*16467b97STreehugger Robot                return lexerMod
426*16467b97STreehugger Robot
427*16467b97STreehugger Robot            lexerCls = getattr(lexerMod, grammarName)
428*16467b97STreehugger Robot            lexerCls = self.lexerClass(lexerCls)
429*16467b97STreehugger Robot
430*16467b97STreehugger Robot            return lexerCls
431*16467b97STreehugger Robot
432*16467b97STreehugger Robot        if grammarType == 'parser':
433*16467b97STreehugger Robot            parserMod = self.__load_module(grammarName)
434*16467b97STreehugger Robot            if returnModule:
435*16467b97STreehugger Robot                return parserMod
436*16467b97STreehugger Robot
437*16467b97STreehugger Robot            parserCls = getattr(parserMod, grammarName)
438*16467b97STreehugger Robot            parserCls = self.parserClass(parserCls)
439*16467b97STreehugger Robot
440*16467b97STreehugger Robot            return parserCls
441*16467b97STreehugger Robot
442*16467b97STreehugger Robot        if grammarType == 'tree':
443*16467b97STreehugger Robot            walkerMod = self.__load_module(grammarName)
444*16467b97STreehugger Robot            if returnModule:
445*16467b97STreehugger Robot                return walkerMod
446*16467b97STreehugger Robot
447*16467b97STreehugger Robot            walkerCls = getattr(walkerMod, grammarName)
448*16467b97STreehugger Robot            walkerCls = self.walkerClass(walkerCls)
449*16467b97STreehugger Robot
450*16467b97STreehugger Robot            return walkerCls
451