http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/impl/CPPParser/CPP_parser.g ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/impl/CPPParser/CPP_parser.g b/contrib/pdxautoserializer/src/impl/CPPParser/CPP_parser.g new file mode 100755 index 0000000..a3ee7e8 --- /dev/null +++ b/contrib/pdxautoserializer/src/impl/CPPParser/CPP_parser.g @@ -0,0 +1,2646 @@ +/* + * PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g) + * + * Authors: Sumana Srinivasan, NeXT Inc.; [email protected] + * Terence Parr, Parr Research Corporation; [email protected] + * Russell Quong, Purdue University; [email protected] + * + * VERSION 1.2 + * + * 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 [email protected]. + * + * NeXT Computer Inc. + * 900 Chesapeake Dr. + * Redwood City, CA 94555 + * 12/02/1994 + * + * Restructured for public consumption by Terence Parr late February, 1995. + * + * DISCLAIMER: we make no guarantees that this grammar works, makes sense, + * or can be used to do anything useful. + */ +/* 2001-2002 + * Version 1.0 + * This C++ grammar file has been converted from PCCTS to run under + * ANTLR to generate lexer and parser in C++ code by + * Jianguo Zuo and David Wigg at + * The Centre for Systems and Software Engineering + * London South Bank University + * London, UK. + * + */ +/* 2003 + * Version 2.0 was published by David Wigg in September 2003 + */ +/* 2004 + * Version 3.0 July 2004 + * This is version 3.0 of the C++ grammar definition for ANTLR to + * generate lexer and parser in C++ code updated by + * David Wigg at + * The Centre for Systems and Software Engineering + * London South Bank University + * London, UK. + */ +/* 2005 + * Version 3.1 November 2005 + * Updated by David Wigg at London South Bank University + * + * [email protected] + * [email protected] + * + * See MyReadMe.txt for further information + * + * This file is best viewed in courier font with tabs set to 4 spaces + */ + +header +{ + // File generated from CPP_parser.g + // Version 3.1 November 2005 + // This file is best viewed in courier font with tabs set to 4 spaces + // + // The statements in this block appear in both CPPLexer.hpp and CPPParser.hpp +#include <stdio.h> +#include <string.h> +#include "antlr/CharScanner.hpp" +#include "CPPDictionary.hpp" + + // Defined in main.cpp + extern void process_line_directive(const char *, const char *); + + // Declared in main.cpp + extern int deferredLineCount; +} + +options +{ + language = "Cpp"; +} + +{ + // File generated from CPP_parser.g + // Version 3.1 November 2005 + // This file is best viewed in courier font with tabs set to 4 spaces + // + // The statements in this block appear only in CPPParser.cpp and not in CPPLexer.cpp + + // These constants used in the previous version (3.0 July 2004) have now been replaced by the following, + //ID_VAR_NAME is now CPPSymbol::otVariable + //ID_FUN_NAME is now CPPSymbol::otFunction + //ID_INPUT_PARAMETER is now not used + //ID_CLASS_DEF is now CPPSymbol::otClass + //ID_SYSTEM_FUNCTION is now not used + //ID_CONST_DECL is now not used + //ID_TYPEDEF_VAR is now CPPSymbol::otTypedef + + int statementTrace = 2; // Used to control selected (level) tracing (see support.cpp) + // 1 Shows which external and member statements selected + // 2 Shows above plus all declarations/definitions + // 3 reserved for future use + // 4 and above available for user + + void CPPParser::init() + { + antlrTrace(false); // This is a dynamic trace facility for use with -traceParser etc. + // It requires modification in LLkParser.cpp and LLkParser.hpp + // otherwise it should be commented out (see MyReadMe.txt) + // true shows antlr trace (or can be set and reset during parsing) + // false stops showing antlr trace + // Provided the parser is always generated with -traceParser this + // facility allows trace output to be turned on or off by changing + // the setting here from false to true or vice versa and then + // recompiling and linking CPPParser only thus avoiding the need + // to use antlr.Tool to re-generate the lexer and parser again + // with (or without) -traceParser. + // Antlr trace can also be turned on and off dynamically using + // antlrTrace_on or antlrTrace_off statements inserted into the + // source code being parsed (See below). + + // Creates a dictionary to hold symbols with 4001 buckets, 200 scopes and 800,000 characters + // These can be changed to suit the size of program(s) being parsed + symbols = new CPPDictionary(4001, 200, 800000); + + // Set template parameter scope - Not used at present + templateParameterScope = symbols->getCurrentScopeIndex(); // Set template parameter scope to 0 + + symbols->saveScope(); // Advance currentScope from 0 to 1 + // Set "external" scope for all types + externalScope = symbols->getCurrentScopeIndex(); // Set "external" scope to 1 for types + + // Declare predefined scope "std" in external scope + CPPSymbol *a = new CPPSymbol("std", CPPSymbol::otTypedef); + symbols->define("std", a); + + symbols->saveScope(); // Advance currentScope from 1 to 2 (and higher) for all other symbols + // treated as locals + + // Global flags to allow for nested declarations + _td = false; // For typedef + _fd = false; // For friend + _sc = scInvalid; // For StorageClass + _tq = tqInvalid; // For TypeQualifier + _ts = tsInvalid; // For TypeSpecifier + _fs = fsInvalid; // For FunctionSpecifier + + functionDefinition = 0; + qualifierPrefix[0] = '\0'; + enclosingClass = (char *) ""; + assign_stmt_RHS_found = 0; + in_parameter_list = false; + K_and_R = false; // used to distinguish old K & R parameter definitions + in_return = false; + is_address = false; + is_pointer = false; + } + +} // End of CPPParser.cpp block + +class CPPParser extends Parser; + +options +{ + k = 2; + exportVocab = STDC; + buildAST =false; + codeGenMakeSwitchThreshold = 2; + codeGenBitsetTestThreshold = 3; +} + +{ + public: +#define CPPParser_MaxQualifiedItemSize 500 + + // These codes are not stored with symbol names in CPPSymbol, + // but they are available for development + // Can't bitwise-OR enum elements together, this must be an int + typedef unsigned long TypeSpecifier; // note: must be at least 16 bits + typedef unsigned long TypeQualifier; + +#define tsInvalid 0x0 +#define tsVOID 0x1 +#define tsCHAR 0x2 +#define tsSHORT 0x4 +#define tsINT 0x8 +#define tsLONG 0x10 +#define tsFLOAT 0x20 +#define tsDOUBLE 0x40 +#define tsSIGNED 0x80 +#define tsUNSIGNED 0x100 +#define tsTYPEID 0x200 +#define tsSTRUCT 0x400 +#define tsENUM 0x800 +#define tsUNION 0x1000 +#define tsCLASS 0x2000 +#define tsWCHAR_T 0x4000 +#define tsBOOL 0x8000 + + +#define tqInvalid 0x0 +#define tqCONST 0x1 +#define tqVOLATILE 0x2 +#define tqGFEXCLUDE 0x4 +#define tqGFINCLUDE 0x8 +#define tqGFID 0x10 +#define tqGFUNREAD 0x20 + + enum StorageClass + { + scInvalid=0, scAUTO=1, scREGISTER, + scSTATIC, scEXTERN, scMUTABLE + }; + + enum FunctionSpecifier + { + fsInvalid=0, + fsVIRTUAL, fsINLINE, fsEXPLICIT, fsFRIEND + }; + + // JEL 3/26/96 changed to allow ORing of values + // DW 10/04/05 These codes are stored with the item in CPPSymbol in the dictionary See declaratorID + typedef int QualifiedItem; +#define qiInvalid 0x0 +#define qiType 0x1 // includes enum, class, typedefs, namespace +#define qiDtor 0x2 +#define qiCtor 0x4 +#define qiOperator 0x8 +#define qiPtrMember 0x10 +#define qiVar 0x20 +#define qiFun 0x40 +#define qiNamespace 0x50 + + protected: + // Symbol table management stuff + CPPDictionary *symbols; + int templateParameterScope; + int externalScope; + int anyType; + int anyNonType; + + bool _td; // For typedef + bool _fd; // For friend + StorageClass _sc; // For storage class + TypeQualifier _tq; // For type qualifier + TypeSpecifier _ts; // For type specifier + FunctionSpecifier _fs; // For declaration specifier + + int functionDefinition; // 0 = Function definition not being parsed + // 1 = Parsing function name + // 2 = Parsing function parameter list + // 3 = Parsing function block + + char qualifierPrefix[CPPParser_MaxQualifiedItemSize+1]; + char *enclosingClass; + int assign_stmt_RHS_found; + bool in_parameter_list; + bool K_and_R; // used to distinguish old K & R parameter definitions + bool in_return; + bool is_address; + bool is_pointer; + + // Limit lookahead for qualifiedItemIs() + enum + { + MaxTemplateTokenScan = 200 + }; + + public: + void init(); + + protected: + // Semantic interface in Support.cpp; + // You could subclass and redefine these functions + // so you don't have to mess with the grammar itself. + + // Symbol stuff + virtual int qualifiedItemIsOneOf(QualifiedItem qiFlags, int lookahead_offset=0); + virtual QualifiedItem qualifiedItemIs(int lookahead_offset=0); + virtual int skipTemplateQualifiers(int& kInOut); + virtual int skipNestedParens(int& kInOut); + virtual int scopedItem(int k=1); + virtual int finalQualifier(int k=1); + virtual int isTypeName(const char *s); + virtual int isClassName(const char *s); + virtual void end_of_stmt(); + + // Scoping stuff + virtual void enterNewLocalScope(); + virtual void exitLocalScope(); + virtual void enterExternalScope(); + virtual void exitExternalScope(); + + // namespaceEnd stuff + virtual void exitNamespaceScope(); + + // Aggregate stuff + virtual void classForwardDeclaration(TypeSpecifier, FunctionSpecifier,const char *); + virtual void beginClassDefinition(TypeSpecifier,const char *); + virtual void endClassDefinition(); + virtual void beginEnumDefinition(const char *); + virtual void endEnumDefinition(); + virtual void enumElement(const char *); + + // Declaration and definition stuff + virtual void declarationSpecifier(bool,bool,StorageClass,TypeQualifier,TypeSpecifier,FunctionSpecifier); + virtual void beginDeclaration(); + virtual void endDeclaration(); + virtual void beginConstructorDeclaration(const char *); + virtual void endConstructorDeclaration(); + virtual void beginDestructorDeclaration(const char *); + virtual void endDestructorDeclaration(); + virtual void beginParameterDeclaration(); + virtual void beginFieldDeclaration(); + virtual void beginFunctionDefinition(); + virtual void endFunctionDefinition(); + virtual void functionParameterList(); + virtual void functionEndParameterList(int def); + virtual void beginConstructorDefinition(); + virtual void endConstructorDefinition(); + virtual void beginDestructorDefinition(); + virtual void endDestructorDefinition(); + + // Declarator stuff + virtual void declaratorID(const char *, QualifiedItem); // This stores new symbol with its type. + virtual void declaratorArray(); + virtual void declaratorParameterList(int def); + virtual void declaratorEndParameterList(int def); + + // template stuff + virtual void templateTypeParameter(const char *); + virtual void beginTemplateDeclaration(); + virtual void endTemplateDeclaration(); + virtual void beginTemplateDefinition(); + virtual void endTemplateDefinition(); + virtual void beginTemplateParameterList(); + virtual void endTemplateParameterList(); + + // exception stuff + virtual void exceptionBeginHandler(); + virtual void exceptionEndHandler(); + virtual void panic(const char *); + + // myCode functions ready for overriding in MyCode subclass + // Include application code functions here + virtual void myCode_pre_processing(int, char *[]); + virtual void myCode_post_processing(); + virtual void myCode_end_of_stmt(); + virtual void myCode_function_direct_declarator(const char *); + + // Auto-serializer specific stuff + virtual void gfArraySize(const char* id) { } + virtual void gfArrayElemSize(const char* id) { } +} + +translation_unit + : {enterExternalScope();} + (external_declaration)+ EOF + {exitExternalScope();} + ; + +external_declaration + {char *s; + K_and_R = false; + FunctionSpecifier fs = fsInvalid; // inline,virtual,explicit + } + : + ( + // Template explicit specialisation + ("template" LESSTHAN GREATERTHAN)=> + {if(statementTrace>=1) + printf("%d external_declaration template explicit-specialisation\n",LT(1)->getLine()); + } + "template" LESSTHAN GREATERTHAN external_declaration + | + // All typedefs + ("typedef")=> + ( + ("typedef" class_specifier)=> + {if(statementTrace>=1) + printf("%d external_declaration Typedef class type\n",LT(1)->getLine()); + } + "typedef" class_decl_or_def[fs] {_td = true;} (init_declarator_list)? SEMICOLON {end_of_stmt();} + | + ("typedef" "enum")=> + {if(statementTrace>=1) + printf("%d external_declaration Typedef enum type\n",LT(1)->getLine()); + } + "typedef" enum_specifier {_td = true;} (init_declarator_list)? SEMICOLON {end_of_stmt();} + | + (declaration_specifiers function_declarator[0] SEMICOLON)=> // DW 11/02/05 This may not be possible + {if(statementTrace>=1) + printf("%d external_declaration Typedef function type\n",LT(1)->getLine()); + } + declaration + | + {if(statementTrace>=1) + printf("%d external_declaration Typedef variable type\n",LT(1)->getLine()); + } + declaration + ) + | + // Class template declaration or definition + (template_head (fs = function_specifier)* class_specifier)=> + {if (statementTrace>=1) + printf("%d external_declaration Templated class decl or def\n",LT(1)->getLine()); + } + template_head (fs = function_specifier)* class_decl_or_def[fs] (init_declarator_list)? SEMICOLON {end_of_stmt();} // declaration + | + // Enum definition (don't want to backtrack over this in other alts) + ("enum" (ID)? LCURLY)=> + {if (statementTrace>=1) + printf("%d external_declaration Enum definition\n",LT(1)->getLine()); + } + enum_specifier (init_declarator_list)? SEMICOLON {end_of_stmt();} + | + // Destructor definition (templated or non-templated) + ((template_head)? dtor_head[1] LCURLY)=> + {if (statementTrace>=1) + printf("%d external_declaration Destructor definition\n",LT(1)->getLine()); + } + (template_head)? dtor_head[1] dtor_body + | + // Constructor definition (non-templated) + // JEL 4/3/96 Added predicate that works, once the + // restriction is added that ctor cannot be virtual + // and ctor_declarator uses a more restrictive id + ( (options {warnWhenFollowAmbig = false;}: + ctor_decl_spec)? + {qualifiedItemIsOneOf(qiCtor)}? + )=> + {if (statementTrace>=1) + printf("%d external_declaration Constructor definition\n",LT(1)->getLine()); + } + ctor_definition + | + // User-defined type cast + (("inline")? scope_override conversion_function_decl_or_def)=> + {if (statementTrace>=1) + printf("%d external_declaration Operator function\n",LT(1)->getLine()); + } + ("inline")? s = scope_override conversion_function_decl_or_def + | + // Function declaration + (declaration_specifiers function_declarator[0] SEMICOLON)=> + {if (statementTrace>=1) + printf("%d external_declaration Function declaration\n",LT(1)->getLine()); + } + declaration_specifiers function_declarator[0] SEMICOLON {end_of_stmt();} + | + // Function definition + (declaration_specifiers function_declarator[1] LCURLY)=> + {if (statementTrace>=1) + printf("%d external_declaration Function definition\n",LT(1)->getLine()); + } + function_definition + | + // K & R Function definition + (declaration_specifiers function_declarator[1] declaration)=> + {K_and_R = true; + if (statementTrace>=1) + printf("%d external_declaration K & R function definition\n",LT(1)->getLine()); + } + function_definition + | + // K & R Function definition with int return assumed + (function_declarator[1] declaration)=> + {K_and_R = true; + if (statementTrace>=1) + printf("%d external_declaration K & R function definition without return type\n",LT(1)->getLine()); + } + function_definition + | + // Class declaration or definition + (("friend")? (fs = function_specifier)* class_specifier)=> + {if (statementTrace>=1) + printf("%d external_declaration Class decl or def\n",LT(1)->getLine()); + } + ("friend")? (fs = function_specifier)* class_decl_or_def[fs] (init_declarator_list)? SEMICOLON {end_of_stmt();} + | + // Templated functions and constructors matched here. + {beginTemplateDeclaration();} + template_head + ( + // templated forward class decl, init/decl of static member in template + (declaration_specifiers (init_declarator_list)? SEMICOLON {end_of_stmt();})=> + {if (statementTrace>=1) + printf("%d external_declaration Templated class forward declaration\n",LT(1)->getLine()); + } + declaration_specifiers (init_declarator_list)? SEMICOLON {end_of_stmt();} + | + // Templated function declaration + (declaration_specifiers function_declarator[0] SEMICOLON)=> + {if (statementTrace>=1) + printf("%d external_declaration Templated function declaration\n",LT(1)->getLine()); + } + declaration + | + // Templated function definition + (declaration_specifiers function_declarator[1] LCURLY)=> + {if (statementTrace>=1) + printf("%d external_declaration_10c Templated function definition\n",LT(1)->getLine()); + } + function_definition + | + // Templated constructor definition + // JEL 4/3/96 Added predicate that works once the + // restriction is added that ctor cannot be virtual + ( ctor_decl_spec + {qualifiedItemIsOneOf(qiCtor)}? + )=> + {if (statementTrace>=1) + printf("%d external_declaration Templated constructor definition\n",LT(1)->getLine()); + } + ctor_definition + ) + {endTemplateDeclaration();} + | + // Namespace definition + {if (statementTrace>=1) + printf("%d external_declaration Namespace definition\n",LT(1)->getLine()); + } + "namespace" namespace_definition + | + // Anything else + {if (statementTrace>=1) + printf("%d external_declaration Declaration\n",LT(1)->getLine()); + } + declaration + | + // Semicolon + {if (statementTrace>=1) + printf("%d external_declaration Semicolon\n",LT(1)->getLine()); + } + SEMICOLON {end_of_stmt();} + | + // The next two entries may be used for debugging + // Use this statement in the source code to turn antlr trace on (See note above) + "antlrTrace_on" {antlrTrace(true);} + | + // Use this statement in the source code to turn antlr trace off (See note above) + "antlrTrace_off" {antlrTrace(false);} + ) + ; // end of external_declaration + +//namespace_definition +namespace_definition + : + (ns:ID{declaratorID((ns->getText()).data(),qiNamespace);})? + LCURLY + {enterNewLocalScope();} + (external_declaration)* + {exitNamespaceScope();exitLocalScope();} + RCURLY + ; + +//namespace_alias_definition +namespace_alias_definition + {char *qid;} + : + "namespace" + ns2:ID {declaratorID((ns2->getText()).data(),qiNamespace);} + ASSIGNEQUAL qid = qualified_id SEMICOLON {end_of_stmt();} + ; + +member_declaration + {char *q; + FunctionSpecifier fs = fsInvalid; // inline,virtual,explicit + } + : + ( + // Template explicit specialisation + ("template" LESSTHAN GREATERTHAN)=> + {if(statementTrace>=1) + printf("%d member_declaration Template explicit-specialisation\n",LT(1)->getLine()); + } + "template" LESSTHAN GREATERTHAN member_declaration + | + // All typedefs + ("typedef")=> + ( + ("typedef" class_specifier)=> + {if(statementTrace>=1) + printf("%d member_declaration Typedef class type\n",LT(1)->getLine()); + } + "typedef" class_decl_or_def[fs] {_td = true;}(init_declarator_list)? SEMICOLON {end_of_stmt();} + | + ("typedef" "enum")=> + {if(statementTrace>=1) + printf("%d member_declaration Typedef enum type\n",LT(1)->getLine()); + } + "typedef" enum_specifier {_td = true;} (init_declarator_list)? SEMICOLON {end_of_stmt();} + | + (declaration_specifiers function_declarator[0] SEMICOLON)=> // DW 11/02/05 This may not be possible member declaration + {if(statementTrace>=1) + printf("%d member_declaration Typedef function type\n",LT(1)->getLine()); + } + declaration + | + {if(statementTrace>=1) + printf("%d member_declaration Typedef variable type\n",LT(1)->getLine()); + } + declaration + ) + | + // Templated class declaration or definition + (template_head (fs = function_specifier)* class_specifier)=> + {if (statementTrace>=1) + printf("%d member_declaration Templated class decl or def\n",LT(1)->getLine()); + } + template_head (fs = function_specifier)* class_decl_or_def[fs] (init_declarator_list)? SEMICOLON {end_of_stmt();} // declaration + | + // Enum definition (don't want to backtrack over this in other alts) + ("enum" (ID)? LCURLY)=> + {if (statementTrace>=1) + printf("%d member_declaration Enum definition\n",LT(1)->getLine()); + } + enum_specifier (member_declarator_list)? SEMICOLON {end_of_stmt();} + | + // Constructor declarator + ( ctor_decl_spec + {qualifiedItemIsOneOf(qiCtor)}? + ctor_declarator[0] SEMICOLON + )=> + {if (statementTrace>=1) + printf("%d member_declaration Constructor declarator\n",LT(1)->getLine()); + } + ctor_decl_spec ctor_declarator[0] SEMICOLON {end_of_stmt();} + | + // JEL Predicate to distinguish ctor from function + // This works now that ctor cannot have VIRTUAL + // It unfortunately matches A::A where A is not enclosing + // class -- this will have to be checked semantically + // Constructor definition + ( ctor_decl_spec + {qualifiedItemIsOneOf(qiCtor)}? + ctor_declarator[1] + (COLON // DEFINITION :ctor_initializer + |LCURLY // DEFINITION (compound Statement) ? + ) + )=> + {if (statementTrace>=1) + printf("%d member_declaration Constructor definition\n",LT(1)->getLine()); + } + ctor_definition + | + // No template_head allowed for dtor member + // Backtrack if not a dtor (no TILDE) + // Destructor declaration + (dtor_head[0] SEMICOLON)=> + {if (statementTrace>=1) + printf("%d member_declaration Destructor declaration\n",LT(1)->getLine()); + } + dtor_head[0] SEMICOLON {end_of_stmt();} + | + // No template_head allowed for dtor member + // Backtrack if not a dtor (no TILDE) + // Destructor definition + (dtor_head[1] LCURLY)=> + {if (statementTrace>=1) + printf("%d member_declaration Destructor definition\n",LT(1)->getLine()); + } + dtor_head[1] dtor_body + | + // Function declaration + (declaration_specifiers function_declarator[0] SEMICOLON)=> + {if (statementTrace>=1) + printf("%d member_declaration Function declaration\n",LT(1)->getLine()); + } + declaration_specifiers function_declarator[0] SEMICOLON {end_of_stmt();} + | + // Function definition + (declaration_specifiers function_declarator[1] LCURLY)=> + {beginFieldDeclaration(); + if (statementTrace>=1) + printf("%d member_declaration Function definition\n",LT(1)->getLine()); + } + function_definition + | + // User-defined type cast + (("inline")? conversion_function_decl_or_def)=> + {if (statementTrace>=1) + printf("%d member_declaration Operator function\n",LT(1)->getLine()); + } + ("inline")? conversion_function_decl_or_def + | + // Hack to handle decls like "superclass::member", + // to redefine access to private base class public members + // Qualified identifier + (qualified_id SEMICOLON)=> + {if (statementTrace>=1) + printf("%d member_declaration Qualified ID\n",LT(1)->getLine()); + } + q = qualified_id SEMICOLON {end_of_stmt();} + | + // Member with a type (or just a type def?) + // A::T a(), ::T a, ::B a, void a, E a (where E is the enclosing class) + (declaration_specifiers (init_declarator_list)? SEMICOLON)=> + {beginFieldDeclaration(); + if (statementTrace>=1) + printf("%d member_declaration Declaration\n",LT(1)->getLine()); + } + declaration + | + // Class declaration or definition + (("friend")? (fs = function_specifier)* class_specifier)=> + {if (statementTrace>=1) + printf("%d member_declaration Class decl or def\n",LT(1)->getLine()); + } + ("friend")? (fs = function_specifier)* class_decl_or_def[fs] (init_declarator_list)? SEMICOLON {end_of_stmt();} + | + // Member without a type (I guess it can only be a function declaration or definition) + ((fs = function_specifier)* function_declarator[0] SEMICOLON)=> + {beginFieldDeclaration(); + fprintf(stderr,"%d warning Function declaration found without return type\n",LT(1)->getLine()); + if (statementTrace>=1) + printf("%d member_declaration Function declaration\n",LT(1)->getLine()); + } + (fs = function_specifier)* function_declarator[0] SEMICOLON {end_of_stmt();} + + | + // Member without a type (I guess it can only be a function definition) + { + fprintf(stderr,"%d warning Function definition found without return type\n",LT(1)->getLine()); + if (statementTrace>=1) + printf("%d member_declaration Function definition without return type\n",LT(1)->getLine()); + } + function_declarator[1] compound_statement {endFunctionDefinition();} + | + // Templated functions and constructors matched here. + {beginTemplateDeclaration();} + template_head + ( + // templated forward class decl, init/decl of static member in template + (declaration_specifiers (init_declarator_list)? SEMICOLON)=> + {if (statementTrace>=1) + printf("%d member_declaration Templated forward declaration\n",LT(1)->getLine()); + } + declaration_specifiers (init_declarator_list)? SEMICOLON {end_of_stmt();} + | + // Templated function declaration + (declaration_specifiers function_declarator[0] SEMICOLON)=> + {if (statementTrace>=1) + printf("%d member_declaration Templated function declaration\n",LT(1)->getLine()); + } + declaration + | + // Templated function definition + (declaration_specifiers function_declarator[1] LCURLY)=> + {if (statementTrace>=1) + printf("%d member_declaration Templated function definition\n",LT(1)->getLine()); + } + function_definition + | + // Templated constructor definition + // JEL 4/3/96 Added predicate that works once the + // restriction is added that ctor cannot be virtual + (ctor_decl_spec {qualifiedItemIsOneOf(qiCtor)}? + )=> + {if (statementTrace>=1) + printf("%d member_declaration Templated constructor definition\n",LT(1)->getLine()); + } + ctor_definition + | + // Templated operator function + {if (statementTrace>=1) + printf("%d member_declaration Templated operator function\n",LT(1)->getLine()); + } + conversion_function_decl_or_def + | + // Templated class definition + {if (statementTrace>=1) + printf("%d member_declaration Templated class definition\n",LT(1)->getLine()); + } + class_head declaration_specifiers (init_declarator_list)? SEMICOLON {end_of_stmt();} + ) + {endTemplateDeclaration();} + | + // Access specifier + {if (statementTrace>=1) + printf("%d member_declaration Access specifier\n",LT(1)->getLine()); + } + access_specifier COLON + | + // Semicolon + {if (statementTrace>=1) + printf("%d member_declaration Semicolon\n",LT(1)->getLine()); + } + SEMICOLON {end_of_stmt();} + | + // The next two entries may be used for debugging + // Use this statement in the source code to turn antlr trace on (See note above) + "antlrTrace_on" {antlrTrace(true);} + | + // Use this statement in the source code to turn antlr trace off (See note above) + "antlrTrace_off" {antlrTrace(false);} + ) + ; // end member_declaration + +//function_definition +function_definition + : // don't want next action as an init-action due to (...)=> caller + { + beginFunctionDefinition(); + } + ( // Next line is equivalent to guarded predicate in PCCTS + // (SCOPE | ID)? => <<qualifiedItemIsOneOf(qiType|qiCtor)>>? + {( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(qiType|qiCtor) )}? + declaration_specifiers function_declarator[1] + ( options{warnWhenFollowAmbig = false;}: + (declaration)* // Possible for K & R definition + {in_parameter_list = false;} + )? + compound_statement + | // Next line is equivalent to guarded predicate in PCCTS + // (SCOPE | ID)? => <<qualifiedItemIsOneOf(qiPtrMember)>>? + //{( !(LA(1)==SCOPE||LA(1)==ID) || (qualifiedItemIsOneOf(qiPtrMember)) )}? + function_declarator[1] + ( options{warnWhenFollowAmbig = false;}: + (declaration)* // Possible for K & R definition + {in_parameter_list = false;} + )? + compound_statement + ) + {endFunctionDefinition();} + ; + +//declaration +declaration + : + ("extern" StringLiteral)=> + linkage_specification + | + {beginDeclaration();} + declaration_specifiers (init_declarator_list)? SEMICOLON {end_of_stmt();} + {endDeclaration();} + | + using_statement + ; + +//linkage_specification +linkage_specification + : + "extern" + StringLiteral + (LCURLY (external_declaration)* RCURLY + |declaration + ) + ; + +//class_head +class_head + : // Used only by predicates + ( "struct" + | "union" + | "class" + ) + (ID + (LESSTHAN template_argument_list GREATERTHAN)? + (base_clause)? + )? + LCURLY + ; + +//declaration_specifiers +declaration_specifiers + {// Locals + bool td = false; // For typedef + bool fd = false; // For friend + StorageClass sc = scInvalid; // auto,register,static,extern,mutable + TypeQualifier tq = tqInvalid; // const,volatile // aka cv_qualifier See type_qualifier + TypeSpecifier ts = tsInvalid; // char,int,double, etc., class,struct,union + FunctionSpecifier fs = fsInvalid; // inline,virtual,explicit + } + : + { + // Global flags to allow for nested declarations + _td = false; // For typedef + _fd = false; // For friend + _sc = scInvalid; // For StorageClass // auto,register,static,extern,mutable + _tq = tqInvalid; // For TypeQualifier // aka cv_qualifier See type_qualifier + _ts = tsInvalid; // For TypeSpecifier + _fs = fsInvalid; // For FunctionSpecifier // inline,virtual,explicit + + } + ( (options {warnWhenFollowAmbig = false;} + : "typedef" {td=true;} + | "friend" {fd=true;} + | sc = storage_class_specifier // auto,register,static,extern,mutable + | tq = type_qualifier // const,volatile // aka cv_qualifier See type_qualifier + | ts = class_specifier // Only here for disambiguation + | "enum" // Only here for disambiguation + | fs = function_specifier // inline,virtual,explicit + | ("_stdcall"|"__stdcall") + | "GFEXCLUDE" {tq |= tqGFEXCLUDE; _tq |= tqGFEXCLUDE;} + | "GFINCLUDE" {tq |= tqGFINCLUDE; _tq |= tqGFINCLUDE;} + | "GFID" {tq |= tqGFID; _tq |= tqGFID;} + | "GFUNREAD" {tq |= tqGFUNREAD; _tq |= tqGFUNREAD;} + | "GFARRAYSIZE" LPAREN gfArr:ID RPAREN {gfArraySize(gfArr->getText().data());} + | "GFARRAYSIZES" LPAREN gfArrList:StringLiteral RPAREN {gfArraySize(gfArrList->getText().data());} + | "GFARRAYELEMSIZE" LPAREN gfArrElem:ID RPAREN {gfArrayElemSize(gfArrElem->getText().data());} + )* + ts = type_specifier + ) + {declarationSpecifier(td,fd,sc,tq,ts,fs);} + ; + +//storage_class_specifier +storage_class_specifier returns [CPPParser::StorageClass sc = scInvalid] + : "auto" {sc = scAUTO;} + | "register" {sc = scREGISTER;} + | "static" {sc = scSTATIC;} + | "extern" {sc = scEXTERN;} + | "mutable" {sc = scMUTABLE;} + ; + +//function_specifier +function_specifier returns [CPPParser::FunctionSpecifier fs = fsInvalid] + : ("inline"|"_inline"|"__inline") {fs = fsINLINE;} + | "virtual" {fs = fsVIRTUAL;} + | "explicit" {fs = fsEXPLICIT;} + ; + +//type_specifier +type_specifier returns [CPPParser::TypeSpecifier ts = tsInvalid] + { + TypeQualifier tq = tqInvalid; + } + : + ts = simple_type_specifier + ; + +//simple_type_specifier +simple_type_specifier returns [CPPParser::TypeSpecifier ts = tsInvalid] + {char *s; + ts = tsInvalid; + } + : ( {qualifiedItemIsOneOf(qiType|qiCtor)}? + s = qualified_type + | + "typename" + s = qualified_type + {declaratorID(s,qiType);} // This stores typename name in dictionary + | + ( "char" {ts |= tsCHAR;} + | "wchar_t" {ts |= tsWCHAR_T;} + | "bool" {ts |= tsBOOL;} + | "short" {ts |= tsSHORT;} + | "int" {ts |= tsINT;} + | ("_int8"|"__int8"|"int8_t") {ts |= tsINT;} + | ("_int16"|"__int16"|"int16_t") {ts |= tsINT;} + | ("_int32"|"__int32"|"int32_t") {ts |= tsLONG;} + | ("_int64"|"__int64"|"int64_t") {ts |= tsLONG;} + | ("uint8_t") {ts |= (tsUNSIGNED | tsINT);} + | ("uint16_t") {ts |= (tsUNSIGNED | tsINT);} + | ("uint32_t") {ts |= (tsUNSIGNED | tsLONG);} + | ("uint64_t") {ts |= (tsUNSIGNED | tsLONG);} + | ("_w64"|"__w64") {ts |= tsLONG;} + | "long" {ts |= tsLONG;} + | "signed" {ts |= tsSIGNED;} + | "unsigned" {ts |= tsUNSIGNED;} + | "float" {ts |= tsFLOAT;} + | "double" {ts |= tsDOUBLE;} + | "void" {ts |= tsVOID;} + | ("_declspec"|"__declspec") LPAREN ID RPAREN + )+ + //| + // Possible fix towards allowing us to parse *.cpp files directly + //(qualified_type qualified_id)=> s = qualified_type {ts |= tsTYPEID;} + //{printf("simple_type_specifier third option entered\n");} + ) + ; + +//qualified_type +qualified_type returns [char *q = NULL] + {char *s; static char qitem[CPPParser_MaxQualifiedItemSize+1];} + : + // JEL 3/29/96 removed this predicate and moved it upwards to + // simple_type_specifier. This was done to allow parsing of ~ID to + // be a unary_expression, which was never reached with this + // predicate on + // {qualifiedItemIsOneOf(qiType|qiCtor)}? + + s = scope_override + id:ID + (options {warnWhenFollowAmbig = false;}: + LESSTHAN template_argument_list GREATERTHAN + )? + { + strcpy(qitem, s); + strcat(qitem, (id->getText()).data()); + q = qitem; + } + ; + +//class_specifier +class_specifier returns [CPPParser::TypeSpecifier ts = tsInvalid] + : + ( "class" {ts = tsCLASS;} + | "struct" {ts = tsSTRUCT;} + | "union" {ts = tsUNION;} + ) + ; + +//type_qualifier +type_qualifier returns [CPPParser::TypeQualifier tq = tqInvalid] // aka cv_qualifier + : + ( ("const"|"__const") {tq = tqCONST;} + | ("volatile"|"__volatile__") {tq = tqVOLATILE;} + ) + ; + +//class_prefix +class_prefix + : + (("_declspec"!|"__declspec"!) LPAREN! expression RPAREN!)* + { + } + ; + + +//class_decl_or_def +class_decl_or_def [FunctionSpecifier fs] + {char *saveClass; + char *id; + TypeSpecifier ts = tsInvalid; // Available for use + } + : + ( "class" {ts = tsCLASS;} + | "struct" {ts = tsSTRUCT;} + | "union" {ts = tsUNION;} + ) + class_prefix // for decltypes + ("GFIGNORE" LPAREN expression RPAREN {})* + ( id = qualified_id + (options{generateAmbigWarnings = false;}: + (SEMICOLON)=> + // Empty + {classForwardDeclaration(ts, fs, id);} + | + {saveClass = enclosingClass; + enclosingClass = symbols->strdup(id); + } + (base_clause)? + LCURLY + {beginClassDefinition(ts, id);} // This stores class name in dictionary + (member_declaration)* + {endClassDefinition();} + RCURLY + {enclosingClass = saveClass;} + ) + | + LCURLY + {saveClass = enclosingClass; enclosingClass = (char *) "__anonymous";} + {beginClassDefinition(ts, "anonymous");} // This stores "anonymous" name in dictionary + (member_declaration)* + {endClassDefinition();} + RCURLY + {enclosingClass = saveClass;} + ) + ; + +//base_clause +base_clause + : + COLON base_specifier (COMMA base_specifier)* + ; + +//base_specifier +base_specifier + {char *qt;} + : + ( "virtual" (access_specifier)? qt = qualified_type + | access_specifier ("virtual")? qt = qualified_type + | qt = qualified_type + ) + ; + +//access_specifier +access_specifier + : + ( "public" + | "protected" + | "private" + ) + ; + +//enum_specifier +enum_specifier + {char *id;} + : + "enum" + ( + LCURLY enumerator_list RCURLY + | + id = qualified_id + {beginEnumDefinition(id);} // This stores id name as an enum type in dictionary + (LCURLY enumerator_list RCURLY)? + {endEnumDefinition();} + ) + ; + +//enumerator_list +enumerator_list + : + enumerator (COMMA enumerator)* + ; + +//enumerator +enumerator + : + id:ID (ASSIGNEQUAL constant_expression)? + {enumElement((id->getText()).data());} + ; + +/* This matches a generic qualified identifier ::T::B::foo + * (including OPERATOR). + * It might be a good idea to put T::~dtor in here + * as well, but id_expression in expr.g puts it in manually. + * Maybe not, 'cause many people use this assuming only A::B. + * How about a 'qualified_complex_id'? + */ +//qualified_id +qualified_id returns [char *q = NULL] + { + char *so = NULL; + static char qitem[CPPParser_MaxQualifiedItemSize+1]; + } + : + so = scope_override + {strcpy(qitem, so);} + ( + id:ID + (options{warnWhenFollowAmbig = false;}: + LESSTHAN template_argument_list GREATERTHAN)? + {strcat(qitem,(id->getText()).data());} + | + OPERATOR optor + {strcat(qitem,"operator"); strcat(qitem,"NYI");} + | + "this" // DW 21/07/03 fix to pass test8.i + | + ("true"|"false") // DW 21/07/03 fix to pass test8.i + ) + {q = qitem;} + ; + +//typeID +typeID + : + {isTypeName((LT(1)->getText()).data())}? + ID + ; + +//init_declarator_list +init_declarator_list + : + init_declarator (COMMA init_declarator)* + ; + +//init_declarator +init_declarator + : + declarator + ( + ASSIGNEQUAL + initializer + | + LPAREN expression_list RPAREN + )? + ; + +//initializer +initializer + : + remainder_expression // assignment_expression + | + LCURLY initializer (COMMA (initializer)? )* RCURLY // Allows comma at end of list + ; + +//member_declarator_list +member_declarator_list + : + member_declarator (ASSIGNEQUAL OCTALINT)? // The value must be 0 (pure virt.) + (COMMA member_declarator (ASSIGNEQUAL OCTALINT)? )* + ; + +//member_declarator +member_declarator + : + ((ID)? COLON constant_expression)=>(ID)? COLON constant_expression + | + declarator + ; + +//declarator +declarator + : + (ptr_operator)=> ptr_operator // AMPERSAND or STAR etc. + declarator + | + direct_declarator + ; + +//direct_declarator +direct_declarator + {char *id; + CPPParser::TypeQualifier tq;} + : + (qualified_id LPAREN (RPAREN|declaration_specifiers) )=> // Must be function declaration + id = qualified_id + {if (_td==true) // This statement is a typedef + declaratorID(id,qiType); + else + declaratorID(id,qiFun); + } + LPAREN {declaratorParameterList(0);} + (parameter_list)? + RPAREN {declaratorEndParameterList(0);} + (tq = type_qualifier)* + (exception_specification)? + | + (qualified_id LPAREN qualified_id)=> // Must be class instantiation + id = qualified_id + {declaratorID(id,qiVar);} + LPAREN + expression_list + RPAREN + | + (qualified_id LSQUARE)=> // Must be array declaration + id = qualified_id + {if (_td==true) // This statement is a typedef + declaratorID(id,qiType); // This statement is a typedef + else + declaratorID(id,qiVar); + is_address = false; is_pointer = false; + } + (options {warnWhenFollowAmbig = false;}: + LSQUARE (constant_expression)? RSQUARE)+ + {declaratorArray();} + | + id = qualified_id + {if (_td==true) + declaratorID(id,qiType); // This statement is a typedef + else + declaratorID(id,qiVar); + is_address = false; is_pointer = false; + } + | + // DW 24/05/04 This block probably never entered as dtor selected out earlier + // Note In fact no dictionary entries for ctor or dtor + TILDE dtor:ID {declaratorID((dtor->getText()).data(),qiDtor);} // Note "class" not recorded in CPPSymbol + {fprintf(stderr,"%d warning direct_declarator5 entered unexpectedly with %s\n", + LT(1)->getLine(),(dtor->getText()).data());} + LPAREN {declaratorParameterList(0);} + (parameter_list)? + RPAREN {declaratorEndParameterList(0);} + | + LPAREN declarator RPAREN + (options {warnWhenFollowAmbig = false;}: + declarator_suffix)? // DW 1/9/04 declarator_suffix made optional as failed on line 2956 in metrics.i + ; // According to the grammar a declarator_suffix is not required here + +//declarator_suffix +declarator_suffix // Note: Only used above in direct_declarator + {CPPParser::TypeQualifier tq;} + : + ( + //(options {warnWhenFollowAmbig = false;}: + (LSQUARE (constant_expression)? RSQUARE)+ + {declaratorArray();} + | + {(!((LA(1)==LPAREN)&&(LA(2)==ID))||(qualifiedItemIsOneOf(qiType|qiCtor,1)))}? + LPAREN {declaratorParameterList(0);} + (parameter_list)? + RPAREN {declaratorEndParameterList(0);} + (tq = type_qualifier)* + (exception_specification)? + ) + ; + +//conversion_function_decl_or_def +conversion_function_decl_or_def + {CPPParser::TypeQualifier tq;} + : + OPERATOR declaration_specifiers (STAR | AMPERSAND)? // DW 01/08/03 Use type_specifier here? see syntax + (LESSTHAN template_parameter_list GREATERTHAN)? + LPAREN (parameter_list)? RPAREN + (tq = type_qualifier)* // DW 29/07/05 ? changed to * + (exception_specification)? + ( compound_statement + | SEMICOLON {end_of_stmt();} + ) + ; + + //function_declarator +function_declarator [int definition] + : + (ptr_operator)=> ptr_operator function_declarator[definition] + | + function_direct_declarator[definition] + ; + +//function_direct_declarator +function_direct_declarator [int definition] + {char *q; + CPPParser::TypeQualifier tq;} + : + /* predicate indicate that plain ID is ok here; this counteracts any + * other predicate that gets hoisted (along with this one) that + * indicates that an ID is a type or whatever. E.g., + * another rule testing isTypeName() alone, implies that the + * the ID *MUST* be a type name. Combining isTypeName() and + * this predicate in an OR situation like this one: + * ( declaration_specifiers ... | function_declarator ... ) + * would imply that ID can be a type name OR a plain ID. + */ + ( // fix prompted by (isdigit)() in xlocnum + LPAREN + q = qualified_id + { + declaratorID(q,qiFun); + } + RPAREN + | + q = qualified_id + { + declaratorID(q,qiFun); + } + ) + + { +#ifdef MYCODE + if (definition) + myCode_function_direct_declarator(q); +#endif //MYCODE + } + + LPAREN + { + functionParameterList(); + if (K_and_R == false) + in_parameter_list = true; + } + (parameter_list)? + { + if (K_and_R == false) + in_parameter_list = false; + else + in_parameter_list = true; + } + RPAREN + (options{warnWhenFollowAmbig = false;}: + tq = type_qualifier)* + (ASSIGNEQUAL OCTALINT)? // The value of the octal must be 0 + {functionEndParameterList(definition);} + (exception_specification)? + ; + + +//ctor_definition +ctor_definition + : + ctor_head + ctor_body + {endConstructorDefinition();} + ; + +//ctor_head +ctor_head + : + ctor_decl_spec + ctor_declarator[1] + ; + +//ctor_decl_spec +ctor_decl_spec + : + (("inline"|"_inline"|"__inline")|"explicit")* + ; + +//ctor_declarator +ctor_declarator[int definition] + {char *q;} + : + q = qualified_ctor_id + {declaratorParameterList(definition);} + LPAREN (parameter_list)? RPAREN + {declaratorEndParameterList(definition);} + (exception_specification)? + ; + +// This matches a generic qualified identifier ::T::B::foo +// that is satisfactory for a ctor (no operator, no trailing <>) +qualified_ctor_id returns [char *q = NULL] + { + char *so; + static char qitem[CPPParser_MaxQualifiedItemSize+1]; + } + : + so = scope_override + {strcpy(qitem, so);} + id:ID // DW 24/05/04 Note. Neither Ctor or Dtor recorded in dictionary + {strcat(qitem,(id->getText()).data()); + q = qitem;} + ; + +//ctor_body +ctor_body + : + (ctor_initializer)? + compound_statement + ; + +//ctor_initializer +ctor_initializer + : + COLON superclass_init (COMMA superclass_init)* + ; + +//superclass_init +superclass_init + {char *q;} + : + q = qualified_id LPAREN (expression_list)? RPAREN + ; + +//dtor_head +dtor_head[int definition] + : + dtor_decl_spec + dtor_declarator[definition] + ; + +//dtor_decl_spec +dtor_decl_spec + : + (("inline"|"_inline"|"__inline")|"virtual")* + ; + +//dtor_declarator +dtor_declarator[int definition] + {char *s;} + : + s = scope_override + TILDE ID + {declaratorParameterList(definition);} + LPAREN ("void")? RPAREN + {declaratorEndParameterList(definition);} + (exception_specification)? + ; + +//dtor_body +dtor_body + : + compound_statement + {endDestructorDefinition();} + ; + +//parameter_list +parameter_list + : + parameter_declaration_list (ELLIPSIS)? + ; + +//parameter_declaration_list +parameter_declaration_list + : + (parameter_declaration (COMMA parameter_declaration)* ) + ; + +//parameter_declaration +parameter_declaration + : + {beginParameterDeclaration();} + ( + {!((LA(1)==SCOPE) && (LA(2)==STAR||LA(2)==OPERATOR)) && + (!(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(qiType|qiCtor) )}? + + declaration_specifiers // DW 24/3/98 Mods for K & R + ( + (declarator)=> declarator // if arg name given + | + abstract_declarator // if arg name not given // can be empty + ) + | + (declarator)=> declarator // DW 24/3/98 Mods for K & R + | + ELLIPSIS + ) + (ASSIGNEQUAL + remainder_expression // DW 18/4/01 assignment_expression + )? + ; + +//type_id +type_id + : + declaration_specifiers abstract_declarator + ; + +/* This rule looks a bit weird because (...) can happen in two + * places within the declaration such as "void (*)()" (ptr to + * function returning nothing). However, the () of a function + * can only occur after having seen either a (abstract_declarator) + * and not after a [..] or simple '*'. These are the only two + * valid () func-groups: + * int (*)(); // ptr to func + * int (*[])(); // array of ptr to func + */ +//abstract_declarator +abstract_declarator + : + ptr_operator abstract_declarator + | + (LPAREN (ptr_operator)+ RPAREN)=> LPAREN (ptr_operator)+ RPAREN + (options {warnWhenFollowAmbig = false;}: + abstract_declarator_suffix)? + | + // DW 13/06/05 + (options {warnWhenFollowAmbig = false;}: + abstract_declarator_suffix)? + ; + +//abstract_declarator_suffix +abstract_declarator_suffix + : + (LSQUARE (constant_expression)? RSQUARE)+ + {declaratorArray();} + | + LPAREN + {declaratorParameterList(0);} + (parameter_list)? + RPAREN + {declaratorEndParameterList(0);} + cv_qualifier_seq + (exception_specification)? + ; + +//exception_specification +exception_specification + {char *so;} + : + "throw" + LPAREN + ( (so = scope_override ID (COMMA so = scope_override ID)* )? + | ELLIPSIS + ) + RPAREN + ; + +//template_head +template_head + : + "template" + LESSTHAN template_parameter_list GREATERTHAN + ; + +//template_parameter_list +template_parameter_list + : + {beginTemplateParameterList();} + template_parameter (COMMA template_parameter)* + {endTemplateParameterList();} + ; + +/* Rule requires >2 lookahead tokens. The ambiguity is resolved + * correctly, however. According to the manual "...A template argument + * that can be interpreted either as a parameter-declaration or a + * type-argument (because its identifier is the name of an + * already existing class) is taken as type-argument." + * Therefore, any "class ID" that is seen on the input, should + * match the first alternative here (it should be a type-argument). + */ +//template_parameter +template_parameter + : + (options{generateAmbigWarnings = false;}: + type_parameter + | + parameter_declaration + ) + ; + +//type_parameter +type_parameter + : + ( + ("class"|"typename") + (id:ID + { + templateTypeParameter((id->getText()).data()); + } + (ASSIGNEQUAL assigned_type_name)? + )? + | + template_head "class" + (id2:ID + { + templateTypeParameter((id2->getText()).data()); + } + (ASSIGNEQUAL assigned_type_name)? + )? + ) + ; + +/* This is to allow an assigned type_name in a template parameter + * list to be defined previously in the same parameter list, + * as type setting is ineffective whilst guessing + */ +//assigned_type_name +assigned_type_name + {char* qt; TypeSpecifier ts;} + : + (options{generateAmbigWarnings = false;}: + qt = qualified_type abstract_declarator + | + ts = simple_type_specifier abstract_declarator + ) + ; + +// This rule refers to an instance of a template class or function +//template_id +template_id // aka template_class_name + : + ID LESSTHAN template_argument_list GREATERTHAN + ; + +//template_argument_list +template_argument_list + : + template_argument (COMMA template_argument)* + ; + +/* Here assignment_expression was changed to shift_expression to rule out + * x< 1<2 > which causes ambiguities. As a result, these can be used only + * by enclosing parentheses x<(1<2)>. This is true for x<1+2> ==> bad, + * x<(1+2)> ==> ok. + */ +//template_argument +template_argument + : + // DW 07/04/05 This predicate only used here if next is SCOPE or ID + {( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(qiType|qiCtor) )}? + type_id + | + shift_expression // failed in iosfwd + ; + +/////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// +////////////////////////////// STATEMENTS //////////////////////////// +/////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// + +statement_list + : + (statement)+ + ; + +statement + { + FunctionSpecifier fs = fsInvalid; // inline,virtual,explicit + } + : + ( ("namespace"|"using")=> + block_declaration + | (("typedef")? class_specifier (qualified_id)? LCURLY)=> + member_declaration + | (declaration_specifiers LPAREN ptr_operator qualified_id RPAREN)=> + member_declaration + | (declaration_specifiers (ptr_operator ptr_operator) qualified_id)=> + member_declaration + | (declaration_specifiers ((ptr_operator)=>ptr_operator)? qualified_id)=> + member_declaration + | labeled_statement + | case_statement + | default_statement + | expression SEMICOLON! {end_of_stmt();} + | compound_statement + | selection_statement + | iteration_statement + | jump_statement + | SEMICOLON! {end_of_stmt();} + | try_block + | throw_statement + // The next two entries may be used for debugging + // Use this statement in the source code to turn antlr trace on (See note above) + | "antlrTrace_on" {antlrTrace(true);} + // Use this statement in the source code to turn antlr trace off (See note above) + | "antlrTrace_off" {antlrTrace(false);} + ) + ; + +//block_declaration +block_declaration + : simple_declaration + | asm_definition + | namespace_alias_definition + | using_statement + ; + +//simple_definition +simple_declaration + : + declaration_specifiers (init_declarator_list)? SEMICOLON {end_of_stmt();} + ; + +labeled_statement + : + ID COLON statement + ; + +case_statement + : "case" + constant_expression COLON statement + ; + +default_statement + : + "default" COLON statement + ; + +compound_statement + : + LCURLY + {end_of_stmt(); + enterNewLocalScope(); + } + (statement_list)? + RCURLY + {exitLocalScope();} + ; + +/* NOTE: cannot remove ELSE ambiguity, but it parses correctly. + * The warning is removed with the options statement + */ +selection_statement + : + "if" LPAREN + expression RPAREN + statement + (options {warnWhenFollowAmbig = false;}: + "else" statement)? + | + "switch" LPAREN expression RPAREN statement + ; + +iteration_statement + : + "while" + LPAREN expression RPAREN + statement + | + "do" + statement "while" + LPAREN expression RPAREN + SEMICOLON {end_of_stmt();} + | + "for" LPAREN + ( (declaration)=> declaration + | expression SEMICOLON {end_of_stmt();} + | SEMICOLON {end_of_stmt();} + ) + (expression)? SEMICOLON {end_of_stmt();} + (expression)? + RPAREN statement + ; + +jump_statement + : + ( "goto" ID SEMICOLON {end_of_stmt();} + | "continue" SEMICOLON {end_of_stmt();} + | "break" SEMICOLON {end_of_stmt();} + | // DW 16/05/03 May be problem here if return is followed by a cast expression + "return" {in_return = true;} + ( options{warnWhenFollowAmbig = false;}: + (LPAREN {(qualifiedItemIsOneOf(qiType) )}? ID RPAREN)=> + LPAREN ID RPAREN (expression)? // This is an unsatisfactory fix for problem in xstring re "return (allocator);" + // and in xlocale re return (_E)(_Tolower((unsigned char)_C, &_Ctype)); + //{printf("%d CPP_parser.g jump_statement Return fix used\n",LT(1)->getLine());} + | expression + )? SEMICOLON {in_return = false,end_of_stmt();} + ) + ; + +try_block + : + "try" compound_statement (handler)* + ; + +handler + : + "catch" + {exceptionBeginHandler();} + {declaratorParameterList(1);} + LPAREN exception_declaration RPAREN + {declaratorEndParameterList(1);} + compound_statement + {exceptionEndHandler();} + ; + +exception_declaration + : + parameter_declaration_list + ; + +/* This is an expression of type void according to the ARM, which + * to me means "statement"; it removes some ambiguity to put it in + * as a statement also. + */ +throw_statement + : + "throw" (assignment_expression) ? SEMICOLON { end_of_stmt();} + ; + +using_statement + {char *qid;} + : + "using" + ("namespace" qid = qualified_id // Using-directive + |("typename")? qid = qualified_id // Using-declaration + ) + SEMICOLON {end_of_stmt();} + ; + +asm_definition + : + ("asm"|"_asm"|"__asm"|"__asm__") LPAREN StringLiteral RPAREN SEMICOLON {end_of_stmt();} + ; + +/////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// +////////////////////////////// EXPRESSIONS /////////////////////////// +/////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// + +expression + : + assignment_expression (COMMA assignment_expression)* + ; + +// right-to-left for assignment op +assignment_expression + : + conditional_expression + ( + (ASSIGNEQUAL|TIMESEQUAL|DIVIDEEQUAL|MINUSEQUAL|PLUSEQUAL + |MODEQUAL|SHIFTLEFTEQUAL|SHIFTRIGHTEQUAL|BITWISEANDEQUAL + |BITWISEXOREQUAL|BITWISEOREQUAL + ) + remainder_expression + )? + ; + +remainder_expression + : + ( + (conditional_expression (COMMA|SEMICOLON|RPAREN) )=> + {assign_stmt_RHS_found += 1;} + assignment_expression + { + if (assign_stmt_RHS_found > 0) + assign_stmt_RHS_found -= 1; + else + { + fprintf(stderr,"%d warning Error in assign_stmt_RHS_found = %d\n", + LT(1)->getLine(),assign_stmt_RHS_found); + fprintf(stderr,"Press return to continue\n"); + getchar(); + } + } + | + assignment_expression + ) + ; + +conditional_expression + : + logical_or_expression + (QUESTIONMARK expression COLON conditional_expression)? + ; + +constant_expression + : + conditional_expression + ; + +logical_or_expression + : + logical_and_expression (OR logical_and_expression)* + ; + +logical_and_expression + : + inclusive_or_expression (AND inclusive_or_expression)* + ; + +inclusive_or_expression + : + exclusive_or_expression (BITWISEOR exclusive_or_expression)* + ; + +exclusive_or_expression + : + and_expression (BITWISEXOR and_expression)* + ; + +and_expression + : + equality_expression (AMPERSAND equality_expression)* + ; + +equality_expression + : + relational_expression ( (NOTEQUAL|EQUAL) relational_expression)* + ; + +relational_expression + : + shift_expression + (options {warnWhenFollowAmbig = false;}: + ( LESSTHAN + | GREATERTHAN + | LESSTHANOREQUALTO + | GREATERTHANOREQUALTO + ) + shift_expression + )* + ; + +shift_expression + : + additive_expression ((SHIFTLEFT | SHIFTRIGHT) additive_expression)* + ; + +// See comment for multiplicative_expression regarding #pragma +additive_expression + : + multiplicative_expression + (options{warnWhenFollowAmbig = false;}: + (PLUS | MINUS) multiplicative_expression + )* + ; + +// ANTLR has trouble dealing with the analysis of the confusing unary/binary +// operators such as STAR, AMPERSAND, PLUS, etc... +// With the #pragma (now "(options{warnWhenFollowAmbig = false;}:" etc.) +// we simply tell ANTLR to use the "quick-to-analyze" approximate lookahead +// as full LL(k) lookahead will not resolve the ambiguity anyway. Might +// as well not bother. This has the side-benefit that ANTLR doesn't go +// off to lunch here (take infinite time to read grammar). +multiplicative_expression + : + pm_expression + (options{warnWhenFollowAmbig = false;}: + (STAR|DIVIDE|MOD) pm_expression + )* + ; + +pm_expression + : + cast_expression ( (DOTMBR|POINTERTOMBR) cast_expression)* + ; + +/* The string "( ID" can be either the start of a cast or + * the start of a unary_expression. However, the ID must + * be a type name for it to be a cast. Since ANTLR can only hoist + * semantic predicates that are visible without consuming a token, + * the semantic predicate in rule type_name is not hoisted--hence, the + * rule is reported to be ambiguous. I am manually putting in the + * correctly hoisted predicate. + * + * Ack! Actually "( ID" might be the start of "(T(expr))" which makes + * the first parens just an ordinary expression grouping. The solution + * is to look at what follows the type, T. Note, this could be a + * qualified type. Yucko. I believe that "(T(" can only imply + * function-style type cast in an expression (...) grouping. + * + * We DO NOT handle the following situation correctly at the moment: + * Suppose you have + * struct rusage rusage; + * return (rusage.fp); + * return (rusage*)p; + * Now essentially there is an ambiguity here. If rusage is followed by any + * postix operators then it is an identifier else it is a type name. This + * problem does not occur in C because, unless the tag struct is attached, + * rusage is not a type name. However in C++ that restriction is removed. + * No *real* programmer would do this, but it's in the C++ standard just for + * fun.. + * + * Another fun one (from an LL standpoint): + * + * (A::B::T *)v; // that's a cast of v to type A::B::T + * (A::B::foo); // that's a simple member access + * + * The qualifiedItemIs(1) function scans ahead to what follows the + * final "::" and returns qiType if the item is a type. The offset of + * '1' makes it ignore the initial LPAREN; normally, the offset is 0. + */ + +cast_expression + {TypeQualifier tq; + TypeSpecifier ts;} + : + (LPAREN (type_qualifier)* simple_type_specifier (ptr_operator)* RPAREN unary_expression)=> + LPAREN (tq = type_qualifier)* ts = simple_type_specifier (ptr_operator)* RPAREN unary_expression + | + (LPAREN (type_qualifier)* simple_type_specifier (ptr_operator)* RPAREN)=> + // Believe it or not, you can get more than one cast expression in sequence + LPAREN (tq = type_qualifier)* ts = simple_type_specifier (ptr_operator)* RPAREN cast_expression + | + unary_expression // handles outer (...) of "(T(expr))" + ; + +unary_expression + : + ( + (postfix_expression)=> + postfix_expression + | + PLUSPLUS unary_expression + | + MINUSMINUS unary_expression + | + unary_operator cast_expression + | + ( "sizeof" + | "__alignof__" //Zhaojz 02/02/05 to fix bug 29 (GNU) + ) + ( (unary_expression)=> + unary_expression + | + LPAREN type_id RPAREN + ) + | + (SCOPE)? + (new_expression + |delete_expression + ) + ) + ; + +postfix_expression + { + TypeSpecifier ts; + } + : + ( + options {warnWhenFollowAmbig = false;}: + // Function-style cast must have a leading type + {!(LA(1)==LPAREN)}? + (ts = simple_type_specifier LPAREN RPAREN LPAREN)=> // DW 01/08/03 To cope with problem in xtree (see test10.i) + ts = simple_type_specifier LPAREN RPAREN LPAREN (expression_list)? RPAREN + | + {!(LA(1)==LPAREN)}? + (ts = simple_type_specifier LPAREN)=> + ts = simple_type_specifier LPAREN (expression_list)? RPAREN + | + primary_expression + (options {warnWhenFollowAmbig = false;}: + LSQUARE expression RSQUARE + | + LPAREN (expression_list)? RPAREN + | (DOT|POINTERTO) ("template")? id_expression + | PLUSPLUS + | MINUSMINUS + )* + | + ("dynamic_cast"|"static_cast"|"reinterpret_cast"|"const_cast") + LESSTHAN ("const"|"__const")? ts = type_specifier (ptr_operator)? GREATERTHAN + LPAREN expression RPAREN + | + "typeid" + LPAREN ((type_id)=>type_id|expression) RPAREN + ) + ; + +primary_expression + : id_expression + | constant + | "this" + | LPAREN expression RPAREN + ; + +id_expression + {char *s;} + : + s = scope_override + ( ID + | OPERATOR optor + | TILDE (STAR)? ID // DW 29/07/03 STAR included to allow for *_S = ~*_S; seen in vector + ) + ; + +constant + : OCTALINT + | DECIMALINT + | HEXADECIMALINT + | CharLiteral + | WCharLiteral + | (StringLiteral | WStringLiteral)+ + | FLOATONE + | FLOATTWO + | "true" + | "false" + ; + +unary_operator + : AMPERSAND + | STAR + | PLUS + | MINUS + | TILDE + | NOT + ; + +/* JEL The first ()? is used to resolve "new (expr) (type)" because both + * (expr) and (type) look identical until you've seen the whole thing. + * + * new_initializer appears to be conflicting with function arguments as + * function arguments can follow a primary_expression. [This is a full + * LL(k) versus LALL(k) problem. Enhancing context by duplication of + * some rules might handle this.] + */ +new_expression + : + ( + "new" + ( (LPAREN expression_list RPAREN)=> + LPAREN expression_list RPAREN)? + (new_type_id|LPAREN type_id RPAREN) + (options{warnWhenFollowAmbig = false;}: + (new_initializer)=> new_initializer)? + ) + ; + +new_initializer + : + LPAREN (expression_list)? RPAREN + ; + +new_type_id + : + declaration_specifiers + (options {warnWhenFollowAmbig = false;}: + new_declarator + )? + ; + +new_declarator + : + ptr_operator + (options {warnWhenFollowAmbig = false;}: + new_declarator)? + | + direct_new_declarator + ; + +/* The "[expression]" construct conflicts with the "new []" construct + * (and possibly others). We used approximate lookahead for the "new []" + * construct so that it would not try to compute full LL(2) lookahead. + * Here, we use #pragma approx again because anytime we see a [ followed + * by token that can begin an expression, we always want to loop. + * Approximate lookahead handles this correctly. In fact, approximate + * lookahead is the same as full lookahead when all but the last lookahead + * depth are singleton sets; e.g., {"["} followed by FIRST(expression). + */ +direct_new_declarator + : + (options {warnWhenFollowAmbig = false;}: + LSQUARE expression RSQUARE + )+ + ; + +//ptr_operator +ptr_operator + : + ( AMPERSAND {is_address = true;} + | ("_cdecl"|"__cdecl") + | ("_near"|"__near") + | ("_far"|"__far") + | "__interrupt" + | ("pascal"|"_pascal"|"__pascal") + | ("_stdcall"|"__stdcall") + | ptr_to_member // e.g. STAR + ) + ; + +// Match A::B::* +//ptr_to_member +ptr_to_member // Part of ptr_operator in grammar.txt + {char *s;} + : + s = scope_override STAR {is_pointer = true;} cv_qualifier_seq + ; + +// JEL note: does not use (const|volatile)* to avoid lookahead problems +cv_qualifier_seq + {CPPParser::TypeQualifier tq;} + : + (tq = type_qualifier)* + ; + +//scope_override +// Match the A::B::C:: or nothing +scope_override returns [char *s = NULL] + { + static char sitem[CPPParser_MaxQualifiedItemSize+1]; + sitem[0]='\0'; + } + : + (SCOPE {strcat(sitem,"::");} )? + ( options {warnWhenFollowAmbig = false;}: + {scopedItem()}? + id:ID (LESSTHAN template_argument_list GREATERTHAN)? + SCOPE + ("template")? // DW 04/06/05 See _Alloc::template in testMbanefo.i + { + CPPSymbol *cs = (CPPSymbol *) symbols->lookup((id->getText()).data()); + strcat(sitem,(id->getText()).data()); + strcat(sitem,"::"); + } + )* + {s = sitem;} + ; + +delete_expression + : + "delete" (LSQUARE RSQUARE)? cast_expression + ; + +expression_list + : + assignment_expression (COMMA assignment_expression)* + ; + +optor + : + "new" + (options {warnWhenFollowAmbig = false;}: + LSQUARE RSQUARE | ) // check syntax + | + "delete" + (options {warnWhenFollowAmbig = false;}: + LSQUARE RSQUARE | ) // check syntax + | + LPAREN RPAREN + | + LSQUARE RSQUARE + | + optor_simple_tokclass //OPTOR_SIMPLE_TOKCLASS + ; + +//Zuo 5/11/2001 +// This is the equivalent to "#tokclass OPTOR_SIMPLE_TOKCLASS" in cplusplus.g + +optor_simple_tokclass + : + (PLUS|MINUS|STAR|DIVIDE|MOD|BITWISEXOR|AMPERSAND|BITWISEOR|TILDE|NOT| + SHIFTLEFT|SHIFTRIGHT| + ASSIGNEQUAL|TIMESEQUAL|DIVIDEEQUAL|MODEQUAL|PLUSEQUAL|MINUSEQUAL| + SHIFTLEFTEQUAL|SHIFTRIGHTEQUAL|BITWISEANDEQUAL|BITWISEXOREQUAL|BITWISEOREQUAL| + EQUAL|NOTEQUAL|LESSTHAN|GREATERTHAN|LESSTHANOREQUALTO|GREATERTHANOREQUALTO|OR|AND| + PLUSPLUS|MINUSMINUS|COMMA|POINTERTO|POINTERTOMBR + ) + ; + +class CPPLexer extends Lexer; + +options + { + k = 3; + exportVocab = STDC; + testLiterals = true; + } + +// DW 4/11/02 put in to support manual hoisting +tokens + { + OPERATOR = "operator"; + } + +{ +void deferredNewline() + { + deferredLineCount++; // Declared and initialised in main.cpp + } + +void newline() + { + for (;deferredLineCount>0;deferredLineCount--) + { + CharScanner::newline(); + } + CharScanner::newline(); + } +} + +// Operators: + +ASSIGNEQUAL : '=' ; +COLON : ':' ; +COMMA : ',' ; +QUESTIONMARK : '?' ; +SEMICOLON : ';' ; +POINTERTO : "->" ; + +// DOT & ELLIPSIS are commented out since they are generated as part of +// the Number rule below due to some bizarre lexical ambiguity shme. +// DOT : '.' ; +// ELLIPSIS : "..." ; + +LPAREN : '(' ; +RPAREN : ')' ; +LSQUARE : '[' ; +RSQUARE : ']' ; +LCURLY : '{' ; +RCURLY : '}' ; + +EQUAL : "==" ; +NOTEQUAL : "!=" ; +LESSTHANOREQUALTO : "<=" ; +LESSTHAN : "<" ; +GREATERTHANOREQUALTO : ">=" ; +GREATERTHAN : ">" ; + +DIVIDE : '/' ; +DIVIDEEQUAL : "/=" ; +PLUS : '+' ; +PLUSEQUAL : "+=" ; +PLUSPLUS : "++" ; +MINUS : '-' ; +MINUSEQUAL : "-=" ; +MINUSMINUS : "--" ; +STAR : '*' ; +TIMESEQUAL : "*=" ; +MOD : '%' ; +MODEQUAL : "%=" ; +SHIFTRIGHT : ">>" ; +SHIFTRIGHTEQUAL : ">>=" ; +SHIFTLEFT : "<<" ; +SHIFTLEFTEQUAL : "<<=" ; + +AND : "&&" ; +NOT : '!' ; +OR : "||" ; + +AMPERSAND : '&' ; +BITWISEANDEQUAL : "&=" ; +TILDE : '~' ; +BITWISEOR : '|' ; +BITWISEOREQUAL : "|=" ; +BITWISEXOR : '^' ; +BITWISEXOREQUAL : "^=" ; + +//Zuo: the following tokens are come from cplusplus.g + +POINTERTOMBR : "->*" ; +DOTMBR : ".*" ; + +SCOPE : "::" ; + +Whitespace + : + ( // whitespace ignored + (' ' |'\t' | '\f') + | // handle newlines + ( '\r' '\n' // MS + | '\r' // Mac + | '\n' // Unix + ) { newline(); } + | // handle continuation lines + ( '\\' '\r' '\n' // MS + | '\\' '\r' // Mac + | '\\' '\n' // Unix + ) {printf("CPP_parser.g continuation line detected\n"); + deferredNewline();} + ) + {_ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP;} + ; + +Comment + : + "/*" + ( {LA(2) != '/'}? '*' + | EndOfLine {deferredNewline();} + | ~('*'| '\r' | '\n') + )* + "*/" {_ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP;} + ; + +CPPComment + : + "//" (~('\n' | '\r'))* EndOfLine + {_ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; newline();} + ; + +PREPROC_DIRECTIVE + options{paraphrase = "a preprocessor directive";} + : + ('#' (~('\r' | '\n'))* EndOfLine) + {_ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; newline();} + ; + +protected +LineDirective + : + ("line")? // this would be for if the directive started "#line" + (Space)+ + n:Decimal + (Space)+ + (sl:StringLiteral) + ((Space)+ Decimal)* // To support cpp flags (GNU) + { + process_line_directive((sl->getText()).data(), (n->getText()).data()); // see main() + } + EndOfLine + ; + +protected +Space + : + (' '|'\t'|'\f') + ; + + +protected +Pragma + : + ('#' "pragma" (~('\r' | '\n'))* EndOfLine) + {_ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; newline();} + ; + +protected +Error + : + ('#' "error" (~('\r' | '\n'))* EndOfLine) + {_ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; newline();} + ; + + +// Literals: + +/* + * Note that we do NOT handle tri-graphs nor multi-byte sequences. + */ + +/* + * Note that we can't have empty character constants (even though we + * can have empty strings :-). + */ +CharLiteral + : + '\'' (Escape | ~('\'')) '\'' + ; + +WCharLiteral + : + 'L' CharLiteral + ; + + +/* + * Can't have raw imbedded newlines in string constants. Strict reading of + * the standard gives odd dichotomy between newlines & carriage returns. + * Go figure. + */ +StringLiteral + : + '"' + ( Escape + | + ( "\\\r\n" // MS + | "\\\r" // MAC + | "\\\n" // Unix + ) {deferredNewline();} + | + ~('"'|'\r'|'\n'|'\\') + )* + '"' + ; + +WStringLiteral + : + 'L' StringLiteral + ; + +protected +EndOfLine + : + ( options{generateAmbigWarnings = false;}: + "\r\n" // MS + | '\r' // Mac + | '\n' // Unix + ) + ; + +/* + * Handle the various escape sequences. + * + * Note carefully that these numeric escape *sequences* are *not* of the + * same form as the C language numeric *constants*. + * + * There is no such thing as a binary numeric escape sequence. + * + * Octal escape sequences are either 1, 2, or 3 octal digits exactly. + * + * There is no such thing as a decimal escape sequence. + * + * Hexadecimal escape sequences are begun with a leading \x and continue + * until a non-hexadecimal character is found. + * + * No real handling of tri-graph sequences, yet. + */ + +protected +Escape + : + '\\' + ( options{warnWhenFollowAmbig=false;}: + 'a' + | 'b' + | 'f' + | 'n' + | 'r' + | 't' + | 'v' + | '"' + | '\'' + | '\\' + | '?' + | ('0'..'3') (options{warnWhenFollowAmbig=false;}: Digit (options{warnWhenFollowAmbig=false;}: Digit)? )? + | ('4'..'7') (options{warnWhenFollowAmbig=false;}: Digit)? + | 'x' (options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F')+ + ) + ; + +// Numeric Constants: + +protected +Digit + : + '0'..'9' + ; + +protected +Decimal + : + ('0'..'9')+ + ; + +protected +LongSuffix + : 'l' + | 'L' + ; + +protected +UnsignedSuffix + : 'u' + | 'U' + ; + +protected +FloatSuffix + : 'f' + | 'F' + ; + +protected +Exponent + : + ('e'|'E') ('+'|'-')? (Digit)+ + ; + +protected +Vocabulary + : + '\3'..'\377' + ; + +Number + : + ( (Digit)+ ('.' | 'e' | 'E') )=> + (Digit)+ + ( '.' (Digit)* (Exponent)? {_ttype = FLOATONE;} //Zuo 3/12/01 + | Exponent {_ttype = FLOATTWO;} //Zuo 3/12/01 + ) //{_ttype = DoubleDoubleConst;} + (FloatSuffix //{_ttype = FloatDoubleConst;} + |LongSuffix //{_ttype = LongDoubleConst;} + )? + | + ("...")=> "..." {_ttype = ELLIPSIS;} + | + '.' {_ttype = DOT;} + ( (Digit)+ (Exponent)? {_ttype = FLOATONE;} //Zuo 3/12/01 + //{_ttype = DoubleDoubleConst;} + (FloatSuffix //{_ttype = FloatDoubleConst;} + |LongSuffix //{_ttype = LongDoubleConst;} + )? + )? + | + '0' ('0'..'7')* //{_ttype = IntOctalConst;} + (LongSuffix //{_ttype = LongOctalConst;} + |UnsignedSuffix //{_ttype = UnsignedOctalConst;} + )* {_ttype = OCTALINT;} + | + '1'..'9' (Digit)* //{_ttype = IntIntConst;} + (LongSuffix //{_ttype = LongIntConst;} + |UnsignedSuffix //{_ttype = UnsignedIntConst;} + )* {_ttype = DECIMALINT;} + | + '0' ('x' | 'X') ('a'..'f' | 'A'..'F' | Digit)+ + //{_ttype = IntHexConst;} + (LongSuffix //{_ttype = LongHexConst;} + |UnsignedSuffix //{_ttype = UnsignedHexConst;} + )* {_ttype = HEXADECIMALINT;} + ; + +ID + options {testLiterals = true;} + : + ('a'..'z'|'A'..'Z'|'_') + ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* + ; +
http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/impl/CPPParser/DictEntry.hpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/impl/CPPParser/DictEntry.hpp b/contrib/pdxautoserializer/src/impl/CPPParser/DictEntry.hpp new file mode 100644 index 0000000..16f5594 --- /dev/null +++ b/contrib/pdxautoserializer/src/impl/CPPParser/DictEntry.hpp @@ -0,0 +1,98 @@ +/* + * PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g) + * + * Authors: Sumana Srinivasan, NeXT Inc.; [email protected] + * Terence Parr, Parr Research Corporation; [email protected] + * Russell Quong, Purdue University; [email protected] + * + * 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 [email protected]. + * + * 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-2005 Version 3.1 November 2005 + * Modified by David Wigg at London South Bank University for CPP_parser.g + * + * See MyReadMe.txt for further information + * + * This file is best viewed in courier font with tabs set to 4 spaces + */ + +#ifndef DictEntry_hpp +#define DictEntry_hpp + +class DictEntry { + protected: + const char *key; + int hashCode; + DictEntry *next; // next element in the bucket + DictEntry *scope; // next element in the scope + + public: + int this_scope; // 4/2/96 LL - added to store scope + + DictEntry() { + key = NULL; + hashCode = -1; + next = scope = NULL; + } + DictEntry(const char *k, int h = -1) { + key = k; + hashCode = h; + next = scope = NULL; + } + virtual ~DictEntry() { + key = NULL; + hashCode = -1; + next = scope = NULL; + } + + void setKey(char *k) { key = k; } + + const char *getKey() { return key; } + + void setHashCode(int h) { hashCode = h; } + + int getHashCode() { return hashCode; } + + void setNext(DictEntry *n) { next = n; } + + DictEntry *getNext() { return next; } + + void setScope(DictEntry *s) { scope = s; } + + DictEntry *getNextInScope() { return scope; } +}; + +#endif
