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