import os import Parser, Lexer def Generate(parser, bison, lexer, filename): from BisonGen import Common outfile = Common.CreateFile(filename, format='c') write = outfile.write write('#include "Python.h"\n') write('#include "structmember.h"\n') write('\n') write('#define PROJECT_NAME "%s"\n' % parser.project) write('#define PARSER_NAME "%s"\n' % parser.name) write('\n') write('/* modules required for action routines */\n') for (package, module) in parser.imports: write('static PyObject *%s;\n' % module) # write out the state tables Parser.OutputTables(bison, outfile) Lexer.OutputTables(lexer, outfile) # write out the template file, adding the actions as appropriate dirname = os.path.dirname(__file__) template = open(os.path.join(dirname, 'Simple.c')) for line in template.readlines(): if line == '$$parser\n': # Place parser actions here Parser.OutputActions(parser, bison, outfile) elif line == '$$lexer\n': # Place lexer actions here Lexer.OutputActions(parser, lexer, outfile) else: write(line) template.close() # write out the module initialization function module_name = parser.name + 'c' write('DL_EXPORT(void) init%s(void) {\n' % module_name) write(' PyObject *module;\n') write('\n') write(' if (PyType_Ready(&Parser_Type) < 0) return;\n') write('\n') write(' module = Py_InitModule("%s", module_methods);\n' % module_name) write(' if (module == NULL) return;\n') write('\n') write(' Py_INCREF(&Parser_Type);\n') write(' PyModule_AddObject(module, "%s",\n' % parser.name) write(' (PyObject *) &Parser_Type);\n') write(' Py_INCREF(&Parser_Type);\n') write(' PyModule_AddObject(module, "new",\n') write(' (PyObject *) &Parser_Type);\n') write('\n') # process the imports if parser.imports: write(' /* import the modules required for action routines */\n') for (package, module) in parser.imports: if package: import_stmt = IMPORT_FROM else: import_stmt = IMPORT_NAME write(import_stmt % {'package':package, 'module':module}) write('\n') write('}\n') outfile.close() return IMPORT_FROM = """ /* from %(package)s import %(module)s */ %(module)s = import_from("%(package)s", "%(module)s"); if (%(module)s == NULL) return; """ IMPORT_NAME = """ /* import %(module)s */ %(module)s = PyImport_ImportModule("%(module)s"); if (%(module)s == NULL) return; """