def __init__(self, lex_optimize=True, lextab='pycparser.lextab', yacc_optimize=True, yacctab='pycparser.yacctab', yacc_debug=False): """ Create a new AbaqusParser. Some arguments for controlling the debug/optimization level of the parser are provided. The defaults are tuned for release/performance mode. The simple rules for using them are: *) When tweaking AbaqusParser/CLexer, set these to False *) When releasing a stable parser, set to True lex_optimize: Set to False when you're modifying the lexer. Otherwise, changes in the lexer won't be used, if some lextab.py file exists. When releasing with a stable lexer, set to True to save the re-generation of the lexer table on each run. lextab: Points to the lex table that's used for optimized mode. Only if you're modifying the lexer and want some tests to avoid re-generating the table, make this point to a local lex table file (that's been earlier generated with lex_optimize=True) yacc_optimize: Set to False when you're modifying the parser. Otherwise, changes in the parser won't be used, if some parsetab.py file exists. When releasing with a stable parser, set to True to save the re-generation of the parser table on each run. yacctab: Points to the yacc table that's used for optimized mode. Only if you're modifying the parser, make this point to a local yacc table file yacc_debug: Generate a parser.out file that explains how yacc built the parsing table from the grammar. """ self.clex = AbaqusLexer(error_func=self._lex_error_func) self.clex.build(optimize=lex_optimize, lextab=lextab) self.tokens = self.clex.tokens self.cparser = ply.yacc.yacc(module=self, start='keyword_list', debug=yacc_debug, optimize=yacc_optimize, tabmodule=yacctab)
def __init__( self, lex_optimize=True, lextab='pycparser.lextab', yacc_optimize=True, yacctab='pycparser.yacctab', yacc_debug=False): """ Create a new AbaqusParser. Some arguments for controlling the debug/optimization level of the parser are provided. The defaults are tuned for release/performance mode. The simple rules for using them are: *) When tweaking AbaqusParser/CLexer, set these to False *) When releasing a stable parser, set to True lex_optimize: Set to False when you're modifying the lexer. Otherwise, changes in the lexer won't be used, if some lextab.py file exists. When releasing with a stable lexer, set to True to save the re-generation of the lexer table on each run. lextab: Points to the lex table that's used for optimized mode. Only if you're modifying the lexer and want some tests to avoid re-generating the table, make this point to a local lex table file (that's been earlier generated with lex_optimize=True) yacc_optimize: Set to False when you're modifying the parser. Otherwise, changes in the parser won't be used, if some parsetab.py file exists. When releasing with a stable parser, set to True to save the re-generation of the parser table on each run. yacctab: Points to the yacc table that's used for optimized mode. Only if you're modifying the parser, make this point to a local yacc table file yacc_debug: Generate a parser.out file that explains how yacc built the parsing table from the grammar. """ self.clex = AbaqusLexer(error_func=self._lex_error_func) self.clex.build( optimize=lex_optimize, lextab=lextab) self.tokens = self.clex.tokens self.cparser = ply.yacc.yacc( module=self, start='keyword_list', debug=yacc_debug, optimize=yacc_optimize, tabmodule=yacctab)
class AbaqusParser(PLYParser): def __init__( self, lex_optimize=True, lextab='pycparser.lextab', yacc_optimize=True, yacctab='pycparser.yacctab', yacc_debug=False): """ Create a new AbaqusParser. Some arguments for controlling the debug/optimization level of the parser are provided. The defaults are tuned for release/performance mode. The simple rules for using them are: *) When tweaking AbaqusParser/CLexer, set these to False *) When releasing a stable parser, set to True lex_optimize: Set to False when you're modifying the lexer. Otherwise, changes in the lexer won't be used, if some lextab.py file exists. When releasing with a stable lexer, set to True to save the re-generation of the lexer table on each run. lextab: Points to the lex table that's used for optimized mode. Only if you're modifying the lexer and want some tests to avoid re-generating the table, make this point to a local lex table file (that's been earlier generated with lex_optimize=True) yacc_optimize: Set to False when you're modifying the parser. Otherwise, changes in the parser won't be used, if some parsetab.py file exists. When releasing with a stable parser, set to True to save the re-generation of the parser table on each run. yacctab: Points to the yacc table that's used for optimized mode. Only if you're modifying the parser, make this point to a local yacc table file yacc_debug: Generate a parser.out file that explains how yacc built the parsing table from the grammar. """ self.clex = AbaqusLexer(error_func=self._lex_error_func) self.clex.build( optimize=lex_optimize, lextab=lextab) self.tokens = self.clex.tokens self.cparser = ply.yacc.yacc( module=self, start='keyword_list', debug=yacc_debug, optimize=yacc_optimize, tabmodule=yacctab) def parse(self, text, filename='', debuglevel=0): """ Parses Abaqus input files and returns an AST. text: A string containing the Abaqus input file filename: Name of the file being parsed (for meaningful error messages) debuglevel: Debug level to yacc """ self.clex.filename = filename self.clex.reset_lineno() return self.cparser.parse(text, lexer=self.clex, debug=debuglevel) ######################-- PRIVATE --###################### def _lex_error_func(self, msg, line, column): self._parse_error(msg, self._coord(line, column)) ## ## Grammar productions ## def p_keyword_list(self, p): ''' keyword_list : keyword_list keyword ''' p[0] = p[1] + [p[2]] def p_keyword(self, p): ''' keyword_list : keyword ''' p[0] = [p[1]] def p_single_keyword(self, p): ''' keyword : KEYWORD | KEYWORD data_lines | KEYWORD COMMA param_list | KEYWORD COMMA param_list data_lines ''' if len(p) == 2: # KEYWORD p[0] = Keyword(p[1]) elif len(p) == 3: # KEYWORD data_list p[0] = Keyword(p[1], data = p[2]) elif len(p) == 4: # KEYWORD COMMA param_list p[0] = Keyword(p[1], params = p[3]) elif len(p) == 5: # KEYWORD COMMA param_list data_list p[0] = Keyword(p[1], params = p[3], data = p[4]) else: # Error? pass def p_param_list(self, p): '''param_list : param_list COMMA param''' p[0] = p[1] + [p[3]] def p_param(self, p): '''param_list : param''' p[0] = [p[1]] def p_single_param(self, p): ''' param : PARAM | PARAM EQUALS PARAM | PARAM EQUALS FLOAT_CONST | PARAM EQUALS INT_CONST_DEC ''' if len(p) == 2: p[0] = Parameter(p[1]) elif len(p) == 4: p[0] = Parameter(p[1], value = p[3]) def p_data_lines_list(self, p): ''' data_lines : data_lines data_line ''' p[0] = list_append(p[1],p[2]) def p_data_lines(self, p): ''' data_lines : data_line ''' p[0] = [p[1]] def p_data_line(self, p): ''' data_line : data_list LASTTOKENONLINE | data_list COMMA LASTTOKENONLINE ''' p[0] = p[1] def p_data_list(self, p): ''' data_list : data_list COMMA data | data_list data ''' if len(p) == 3: p[0] = p[1] + [p[2]] elif len(p) == 4: p[0] = p[1] + [p[3]] def p_data(self, p): ''' data_list : data ''' p[0] = [p[1]] def p_single_data(self, p): ''' data : ID | INT_CONST_DEC | FLOAT_CONST ''' p[0] = p[1] def p_error(self, p): if p: self._parse_error( 'before: %s' % p.value, self._coord(p.lineno)) else: self._parse_error('At end of input', '')
class AbaqusParser(PLYParser): def __init__(self, lex_optimize=True, lextab='pycparser.lextab', yacc_optimize=True, yacctab='pycparser.yacctab', yacc_debug=False): """ Create a new AbaqusParser. Some arguments for controlling the debug/optimization level of the parser are provided. The defaults are tuned for release/performance mode. The simple rules for using them are: *) When tweaking AbaqusParser/CLexer, set these to False *) When releasing a stable parser, set to True lex_optimize: Set to False when you're modifying the lexer. Otherwise, changes in the lexer won't be used, if some lextab.py file exists. When releasing with a stable lexer, set to True to save the re-generation of the lexer table on each run. lextab: Points to the lex table that's used for optimized mode. Only if you're modifying the lexer and want some tests to avoid re-generating the table, make this point to a local lex table file (that's been earlier generated with lex_optimize=True) yacc_optimize: Set to False when you're modifying the parser. Otherwise, changes in the parser won't be used, if some parsetab.py file exists. When releasing with a stable parser, set to True to save the re-generation of the parser table on each run. yacctab: Points to the yacc table that's used for optimized mode. Only if you're modifying the parser, make this point to a local yacc table file yacc_debug: Generate a parser.out file that explains how yacc built the parsing table from the grammar. """ self.clex = AbaqusLexer(error_func=self._lex_error_func) self.clex.build(optimize=lex_optimize, lextab=lextab) self.tokens = self.clex.tokens self.cparser = ply.yacc.yacc(module=self, start='keyword_list', debug=yacc_debug, optimize=yacc_optimize, tabmodule=yacctab) def parse(self, text, filename='', debuglevel=0): """ Parses Abaqus input files and returns an AST. text: A string containing the Abaqus input file filename: Name of the file being parsed (for meaningful error messages) debuglevel: Debug level to yacc """ self.clex.filename = filename self.clex.reset_lineno() return self.cparser.parse(text, lexer=self.clex, debug=debuglevel) ######################-- PRIVATE --###################### def _lex_error_func(self, msg, line, column): self._parse_error(msg, self._coord(line, column)) ## ## Grammar productions ## def p_keyword_list(self, p): ''' keyword_list : keyword_list keyword ''' p[0] = p[1] + [p[2]] def p_keyword(self, p): ''' keyword_list : keyword ''' p[0] = [p[1]] def p_single_keyword(self, p): ''' keyword : KEYWORD | KEYWORD data_lines | KEYWORD COMMA param_list | KEYWORD COMMA param_list data_lines ''' if len(p) == 2: # KEYWORD p[0] = Keyword(p[1]) elif len(p) == 3: # KEYWORD data_list p[0] = Keyword(p[1], data=p[2]) elif len(p) == 4: # KEYWORD COMMA param_list p[0] = Keyword(p[1], params=p[3]) elif len(p) == 5: # KEYWORD COMMA param_list data_list p[0] = Keyword(p[1], params=p[3], data=p[4]) else: # Error? pass def p_param_list(self, p): '''param_list : param_list COMMA param''' p[0] = p[1] + [p[3]] def p_param(self, p): '''param_list : param''' p[0] = [p[1]] def p_single_param(self, p): ''' param : PARAM | PARAM EQUALS PARAM | PARAM EQUALS FLOAT_CONST | PARAM EQUALS INT_CONST_DEC ''' if len(p) == 2: p[0] = Parameter(p[1]) elif len(p) == 4: p[0] = Parameter(p[1], value=p[3]) def p_data_lines_list(self, p): ''' data_lines : data_lines data_line ''' p[0] = list_append(p[1], p[2]) def p_data_lines(self, p): ''' data_lines : data_line ''' p[0] = [p[1]] def p_data_line(self, p): ''' data_line : data_list LASTTOKENONLINE | data_list COMMA LASTTOKENONLINE ''' p[0] = p[1] def p_data_list(self, p): ''' data_list : data_list COMMA data | data_list data ''' if len(p) == 3: p[0] = p[1] + [p[2]] elif len(p) == 4: p[0] = p[1] + [p[3]] def p_data(self, p): ''' data_list : data ''' p[0] = [p[1]] def p_single_data(self, p): ''' data : ID | INT_CONST_DEC | FLOAT_CONST ''' p[0] = p[1] def p_error(self, p): if p: self._parse_error('before: %s' % p.value, self._coord(p.lineno)) else: self._parse_error('At end of input', '')