/* * PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g) * * Authors: Sumana Srinivasan, NeXT Inc.; sumana_srinivasan@next.com * Terence Parr, Parr Research Corporation; parrt@parr-research.com * Russell Quong, Purdue University; quong@ecn.purdue.edu * * VERSION 1.1 * * SOFTWARE RIGHTS * * This file is a part of the ANTLR-based C++ grammar and is free * software. We do not reserve any LEGAL rights to its use or * distribution, but you may NOT claim ownership or authorship of this * grammar or support code. An individual or company may otherwise do * whatever they wish with the grammar distributed herewith including the * incorporation of the grammar or the output generated by ANTLR into * commerical software. You may redistribute in source or binary form * without payment of royalties to us as long as this header remains * in all source distributions. * * We encourage users to develop parsers/tools using this grammar. * In return, we ask that credit is given to us for developing this * grammar. By "credit", we mean that if you incorporate our grammar or * the generated code into one of your programs (commercial product, * research project, or otherwise) that you acknowledge this fact in the * documentation, research report, etc.... In addition, you should say nice * things about us at every opportunity. * * As long as these guidelines are kept, we expect to continue enhancing * this grammar. Feel free to send us enhancements, fixes, bug reports, * suggestions, or general words of encouragement at parrt@parr-research.com. * * NeXT Computer Inc. * 900 Chesapeake Dr. * Redwood City, CA 94555 * 12/02/1994 * * Restructured for public consumption by Terence Parr late February, 1995. * * Requires PCCTS 1.32b4 or higher to get past ANTLR. * * DISCLAIMER: we make no guarantees that this grammar works, makes sense, * or can be used to do anything useful. */ /* 1999-2004 Version 3.0 July 2004 * Main program of the C++ parser. * Based on 'main.cpp' supplied with John Lilley's C++ parser and modified * by David Wigg at London South Bank University * * To run in DOS window enter, * * >...\CPP_parser program_name.i (/a or /A) * * The input file must be pre-processed if any types are declared outside the * program in the #include files. Otherwise the parser fails. * Error/warning messages to displayed on the screen. */ #include #include #include #include "CPPLexer.hpp" #include "CPPParser.hpp" #ifdef MYCODE #include "MyCode.hpp" #endif MYCODE ANTLR_USING_NAMESPACE(std) ANTLR_USING_NAMESPACE(antlr) // The following data used by process_line_directive(char*,int) below // I believe this data and function have to be at this level so as to // be available to both CPPLexer and CPPParser (and support.cpp) int this_line = 0; // current line int include_line = 0; // include file's line number int include_last_set = 0; // where included file's line number was last set char currentIncludedFile[128]; // path and name of current included file bool in_user_file = false; // true if we are inside the users's source file int principal_line = 0; // principal file's line number int principal_last_set = 0; // where principal file's line number was last set char principal_file[128]; // path and name of principal file bool in_principal_file = false; // true if we are inside the principal file int main(int argc,char* argv[]) { // Adapt the following if block to the requirements of your application if (argc < 2 || argc > 3) { cerr << "Usage:\n" << argv[0] << " filename.i (/a or /A)" << "\n"; exit(1); } // check for input file FILE *input_file_ptr = fopen(argv[1], "r"); if (input_file_ptr == NULL) { cerr << "Failed to open input file " << argv[1] << "\n"; exit(1); } else // close input file fclose(input_file_ptr); char *f = argv[1]; try { ifstream s(f); if (!s) { cerr << "Input stream could not be opened for " << f << "\n"; exit(1); } // Create a scanner that reads from the input stream CPPLexer lexer(s); lexer.setFilename(f); #ifdef MYCODE // Create subclass of parser for MYCODE code that reads from scanner MyCode myCode(lexer); myCode.setFilename(f); myCode.init(); myCode.myCode_pre_processing(argc, argv); myCode.translation_unit(); myCode.myCode_post_processing(); #else // Create a parser that reads from the scanner CPPParser parser(lexer); parser.setFilename(f); parser.init(); parser.translation_unit(); #endif MYCODE } catch (exception& e) { cerr << "parser exception: " << e.what() << endl; // e.printStackTrace(); // so we can get stack trace } printf("\nParse ended\n"); return 0; } // for processing #line .... lines (see note above) void process_line_directive(const char *includedFile, const char *includedLineNo) { // See global interface variables above // Working variables static int line, result; static bool principal_file_set = false; static int x; // Extract included file line no. result = sscanf(includedLineNo, "%d \n", &line); // remove first " from file path+name by shifting all characters left for(x=1;includedFile[x]!='"';x++) { currentIncludedFile[x-1] = includedFile[x]; } // Check path and name are not too long if(x>128) { // printf("Path and name of included file too long\n"); printf("Increase length of currentIncludedFile and\n"); printf(" principal_file to at least %d characters\n",x); printf("Abandon run\n"); getchar(); } // Replace last " from file name with null currentIncludedFile[x-1] = NULL; if (!principal_file_set) { strcpy (principal_file, currentIncludedFile); principal_file_set = true; } // check for main file name if (strcmp(principal_file, currentIncludedFile) == 0) { in_principal_file = true; principal_line = line; principal_last_set = this_line; strcpy(currentIncludedFile, " "); // delete include file name in_user_file = true; // we are processing users's .C or .CPP file } else // Check that this is a genuine path if(currentIncludedFile[1]==':') { in_principal_file = false; include_line = line; include_last_set = this_line; in_user_file = false; // we are processing a header file } }