├── .gitignore ├── CxxLexer.cpp ├── CxxLexer.l ├── CxxLexing.cxx ├── CxxLexing.hxx ├── CxxParser.cpp ├── CxxParser.y ├── CxxParsing.cxx ├── CxxParsing.hxx ├── CxxToken.cpp ├── CxxToken.cxx ├── CxxToken.hxx ├── Makefile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | -------------------------------------------------------------------------------- /CxxLexer.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Title: C++ Grammar Lexer support compilation unit. 3 | // 4 | // File Name: CxxLexer.cpp 5 | // 6 | // Author: E.D.Willink 7 | //END 8 | // 9 | #include 10 | -------------------------------------------------------------------------------- /CxxLexer.l: -------------------------------------------------------------------------------- 1 | /* 2 | * Title: Miniature lexer for C++ parser. 3 | * 4 | * File Name: CxxLexer.l 5 | * 6 | * Author: E.D.Willink 7 | * 8 | * This is a complete lexer for C++, intended for use with CxxParser.y. 9 | * All actions are done by macros, so that there is some chance that customisation 10 | * can be performed within the bounds of the CxxLexing.hxx and CxxLexing.cxx 11 | * include files. 12 | *END 13 | */ 14 | %{ 15 | #include 16 | using namespace std; 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | int yylex(); 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | %} 26 | %a 5000 27 | %e 1500 28 | %n 1000 29 | %o 10000 30 | %p 10000 31 | ws [ \f\v\t] 32 | 33 | digit [0-9] 34 | hex [0-9A-Fa-f] 35 | letter [A-Z_a-z] 36 | simple_escape_sequence (\\\'|\\\"|\\\?|\\\\|\\a|\\b|\\f|\\n|\\r|\\t|\\v) 37 | octal_escape_sequence (\\[0-7]|\\[0-7][0-7]|\\[0-7][0-7][0-7]) 38 | hexadecimal_escape_sequence (\\x{hex}+) 39 | escape_sequence ({simple_escape_sequence}|{octal_escape_sequence}|{hexadecimal_escape_sequence}) 40 | universal_character_name (\\u{hex}{hex}{hex}{hex}|\\U{hex}{hex}{hex}{hex}{hex}{hex}{hex}{hex}) 41 | non_digit ({letter}|{universal_character_name}) 42 | identifier ({non_digit}({non_digit}|{digit})*) 43 | 44 | character_lit (L?\'([^\'\\\n]|\\.)*) 45 | character_literal ({character_lit}\') 46 | 47 | string_lit (L?\"([^\"\\\n]|\\.)*) 48 | string_literal ({string_lit}\") 49 | 50 | pp_number (\.?{digit}({digit}|{non_digit}|[eE][-+]|\.)*) 51 | %% 52 | ^.*\n { LEX_SAVE_LINE(yytext, yyleng); REJECT; } 53 | ^{ws}*"#".* { /* Throw away preprocessor lines - hopefully only #line and equivalent. */ } 54 | 55 | {character_lit}\' { LEX_CHARACTER_TOKEN(yytext, yyleng-1); }; 56 | {character_lit}\\ { ERRMSG("End of line assumed to terminate character with trailing escape."); 57 | LEX_CHARACTER_TOKEN(yytext, yyleng-1); }; 58 | {character_lit} { ERRMSG("End of line assumed to terminate character."); 59 | LEX_CHARACTER_TOKEN(yytext, yyleng); }; 60 | 61 | {string_lit}\" { LEX_STRING_TOKEN(yytext, yyleng-1); }; 62 | {string_lit}\\ { ERRMSG("End of line assumed to terminate string with trailing escape."); 63 | LEX_STRING_TOKEN(yytext, yyleng-1); }; 64 | {string_lit} { ERRMSG("End of line assumed to terminate string."); 65 | LEX_STRING_TOKEN(yytext, yyleng); }; 66 | 67 | "asm" { LEX_STATIC_TOKEN(ASM); } 68 | "auto" { LEX_STATIC_TOKEN(AUTO); } 69 | "bool" { LEX_C_STATIC_TOKEN(BOOL); } 70 | "break" { LEX_STATIC_TOKEN(BREAK); } 71 | "case" { LEX_STATIC_TOKEN(CASE); } 72 | "catch" { LEX_C_STATIC_TOKEN(CATCH); } 73 | "char" { LEX_STATIC_TOKEN(CHAR); } 74 | "class" { LEX_C_STATIC_TOKEN(CLASS); } 75 | "const" { LEX_STATIC_TOKEN(CONST); } 76 | "const_cast" { LEX_C_STATIC_TOKEN(CONST_CAST); } 77 | "continue" { LEX_STATIC_TOKEN(CONTINUE); } 78 | "default" { LEX_STATIC_TOKEN(DEFAULT); } 79 | "delete" { LEX_C_STATIC_TOKEN(DELETE); } 80 | "do" { LEX_STATIC_TOKEN(DO); } 81 | "double" { LEX_STATIC_TOKEN(DOUBLE); } 82 | "dynamic_cast" { LEX_C_STATIC_TOKEN(DYNAMIC_CAST); } 83 | "else" { LEX_STATIC_TOKEN(ELSE); } 84 | "enum" { LEX_STATIC_TOKEN(ENUM); } 85 | "explicit" { LEX_C_STATIC_TOKEN(EXPLICIT); } 86 | "export" { LEX_C_STATIC_TOKEN(EXPORT); } 87 | "extern" { LEX_STATIC_TOKEN(EXTERN); } 88 | "false" { LEX_C_STATIC_TOKEN(FALSE); } 89 | "float" { LEX_STATIC_TOKEN(FLOAT); } 90 | "for" { LEX_STATIC_TOKEN(FOR); } 91 | "friend" { LEX_STATIC_TOKEN(FRIEND); } 92 | "goto" { LEX_STATIC_TOKEN(GOTO); } 93 | "if" { LEX_STATIC_TOKEN(IF); } 94 | "inline" { LEX_C_STATIC_TOKEN(INLINE); } 95 | "int" { LEX_STATIC_TOKEN(INT); } 96 | "long" { LEX_STATIC_TOKEN(LONG); } 97 | "mutable" { LEX_C_STATIC_TOKEN(MUTABLE); } 98 | "namespace" { LEX_C_STATIC_TOKEN(NAMESPACE); } 99 | "new" { LEX_C_STATIC_TOKEN(NEW); } 100 | "operator" { LEX_C_STATIC_TOKEN(OPERATOR); } 101 | "private" { LEX_C_STATIC_TOKEN(PRIVATE); } 102 | "protected" { LEX_C_STATIC_TOKEN(PROTECTED); } 103 | "public" { LEX_C_STATIC_TOKEN(PUBLIC); } 104 | "register" { LEX_STATIC_TOKEN(REGISTER); } 105 | "reinterpret_cast" { LEX_C_STATIC_TOKEN(REINTERPRET_CAST); } 106 | "return" { LEX_STATIC_TOKEN(RETURN); } 107 | "short" { LEX_STATIC_TOKEN(SHORT); } 108 | "signed" { LEX_C_STATIC_TOKEN(SIGNED); } 109 | "sizeof" { LEX_STATIC_TOKEN(SIZEOF); } 110 | "static" { LEX_STATIC_TOKEN(STATIC); } 111 | "static_cast" { LEX_C_STATIC_TOKEN(STATIC_CAST); } 112 | "struct" { LEX_STATIC_TOKEN(STRUCT); } 113 | "switch" { LEX_STATIC_TOKEN(SWITCH); } 114 | "template" { LEX_C_STATIC_TOKEN(TEMPLATE); } 115 | "this" { LEX_C_STATIC_TOKEN(THIS); } 116 | "throw" { LEX_C_STATIC_TOKEN(THROW); } 117 | "true" { LEX_C_STATIC_TOKEN(TRUE); } 118 | "try" { LEX_C_STATIC_TOKEN(TRY); } 119 | "typedef" { LEX_STATIC_TOKEN(TYPEDEF); } 120 | "typeid" { LEX_C_STATIC_TOKEN(TYPEID); } 121 | "typename" { LEX_C_STATIC_TOKEN(TYPENAME); } 122 | "union" { LEX_STATIC_TOKEN(UNION); } 123 | "unsigned" { LEX_STATIC_TOKEN(UNSIGNED); } 124 | "using" { LEX_C_STATIC_TOKEN(USING); } 125 | "virtual" { LEX_STATIC_TOKEN(VIRTUAL); } 126 | "void" { LEX_STATIC_TOKEN(VOID); } 127 | "volatile" { LEX_STATIC_TOKEN(VOLATILE); } 128 | "wchar_t" { LEX_C_STATIC_TOKEN(WCHAR_T); } 129 | "while" { LEX_STATIC_TOKEN(WHILE); } 130 | 131 | "::" { LEX_C_STATIC_TOKEN(SCOPE); } 132 | "..." { LEX_STATIC_TOKEN(ELLIPSIS); } 133 | "<<" { LEX_STATIC_TOKEN(SHL); } 134 | ">>" { LEX_STATIC_TOKEN(SHR); } 135 | "==" { LEX_STATIC_TOKEN(EQ); } 136 | "!=" { LEX_STATIC_TOKEN(NE); } 137 | "<=" { LEX_STATIC_TOKEN(LE); } 138 | ">=" { LEX_STATIC_TOKEN(GE); } 139 | "&&" { LEX_STATIC_TOKEN(LOG_AND); } 140 | "||" { LEX_STATIC_TOKEN(LOG_OR); } 141 | "++" { LEX_STATIC_TOKEN(INC); } 142 | "--" { LEX_STATIC_TOKEN(DEC); } 143 | "->*" { LEX_STATIC_TOKEN(ARROW_STAR); } 144 | "->" { LEX_STATIC_TOKEN(ARROW); } 145 | ".*" { LEX_STATIC_TOKEN(DOT_STAR); } 146 | "+=" { LEX_STATIC_TOKEN(ASS_ADD); } 147 | "-=" { LEX_STATIC_TOKEN(ASS_SUB); } 148 | "*=" { LEX_STATIC_TOKEN(ASS_MUL); } 149 | "/=" { LEX_STATIC_TOKEN(ASS_DIV); } 150 | "%=" { LEX_STATIC_TOKEN(ASS_MOD); } 151 | "^=" { LEX_STATIC_TOKEN(ASS_XOR); } 152 | "&=" { LEX_STATIC_TOKEN(ASS_AND); } 153 | "|=" { LEX_STATIC_TOKEN(ASS_OR); } 154 | ">>=" { LEX_STATIC_TOKEN(ASS_SHR); } 155 | "<<=" { LEX_STATIC_TOKEN(ASS_SHL); } 156 | 157 | {pp_number} { LEX_NUMBER_TOKEN(yytext, yyleng); } 158 | 159 | {identifier} { LEX_IDENTIFIER_TOKEN(yytext, yyleng); } 160 | 161 | {escape_sequence} | 162 | {universal_character_name} { LEX_ESCAPED_TOKEN(yytext, yyleng); } 163 | 164 | \n | 165 | {ws}+ { /* Throw away whitespace */ } 166 | . { LEX_ASCII_TOKEN(yytext[0]); } 167 | 168 | %% 169 | #include 170 | -------------------------------------------------------------------------------- /CxxLexing.cxx: -------------------------------------------------------------------------------- 1 | #ifdef FLEX_PP_CLASS 2 | FLEX_PP_CLASS theLexer; 3 | #define LEX_DOT theLexer . 4 | #else 5 | #define LEX_DOT 6 | #endif 7 | 8 | #include "CxxToken.hxx" 9 | 10 | #include "CxxLexing.hxx" 11 | #include "CxxParser.tab.h" 12 | #include 13 | #include 14 | using namespace std; 15 | bool c_keywords = false; 16 | bool echo_line_numbers = false; 17 | bool echo_line_text = false; 18 | size_t line_number = 0; 19 | 20 | #ifdef NEEDS_YYWRAP 21 | int yywrap() { return 1; } 22 | #endif 23 | extern int yylex (void); 24 | CxxToken *yylex_token() 25 | { 26 | if (!LEX_DOT yylex()) 27 | return 0; 28 | return yyToken; 29 | } 30 | 31 | // 32 | // Configure the lexer to reflect successful parsing of a character value, assigning it to yylval. 33 | // 34 | // The source someText[aLength] should correspond to the parsed text including any L or ' prefix 35 | // but excluding any ' suffix. In this way the return can indicate whether a wide character has 36 | // been detected and the routine can accommodate a variety of erroneous terminations. 37 | // 38 | CxxToken *make_character(const char *someText, size_t aLength) 39 | { 40 | bool isWide = false; 41 | if (someText && aLength) 42 | { 43 | if (*someText == 'L') 44 | { 45 | isWide = true; 46 | someText++; 47 | aLength--; 48 | } 49 | if (!aLength || (*someText != '\'')) 50 | ERRMSG("BUG - bad start of character literal."); 51 | if (aLength) 52 | { 53 | someText++; 54 | aLength--; 55 | } 56 | } 57 | if (isWide) 58 | return make_wide_character(someText, aLength); 59 | else 60 | return make_narrow_character(someText, aLength); 61 | } 62 | 63 | CxxToken *make_identifier(const char *someText, size_t aLength) 64 | { 65 | return new CxxNaffToken(PARSE_TOKEN(Identifier), someText, aLength); 66 | } 67 | 68 | // 69 | // Buffer the incoming line, before any characters are analysed. 70 | // 71 | void make_line(const char *yyText, size_t yyLeng) 72 | { 73 | if (echo_line_text) 74 | cout << tokenMarkDepth << ": " << line_number << ": " << yyText << flush; 75 | else if (echo_line_numbers) 76 | cout << line_number << endl; 77 | line_number++ ; 78 | } 79 | 80 | CxxToken *make_literal_character(const char *someText, size_t aLength) 81 | { 82 | return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength); 83 | } 84 | 85 | CxxToken *make_narrow_character(const char *someText, size_t aLength) 86 | { 87 | return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength); 88 | } 89 | 90 | CxxToken *make_narrow_string(const char *someText, size_t aLength) 91 | { 92 | return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength); 93 | } 94 | 95 | CxxToken *make_number(const char *someText, size_t aLength) 96 | { 97 | return new CxxNaffToken(PARSE_TOKEN(IntegerLiteral), someText, aLength); 98 | } 99 | 100 | // 101 | // Configure the lexer to reflect successful parsing of a categorised string. 102 | // 103 | // The source someText[aLength] should correspond to the parsed text including any 104 | // L or " prefix but excluding any " suffix. In this way the return can indicate whether a wide 105 | // character has been detected and the routine can accommodate a variety of erroneous terminations. 106 | // 107 | CxxToken *make_string(const char *someText, size_t aLength) 108 | { 109 | bool isWide = false; 110 | if (someText && aLength) 111 | { 112 | if (*someText == 'L') 113 | { 114 | isWide = true; 115 | someText++; 116 | aLength--; 117 | } 118 | if (!aLength || (*someText != '"')) 119 | ERRMSG("BUG - bad start of string literal."); 120 | if (aLength) 121 | { 122 | someText++; 123 | aLength--; 124 | } 125 | } 126 | if (isWide) 127 | return make_wide_string(someText, aLength); 128 | else 129 | return make_narrow_string(someText, aLength); 130 | } 131 | 132 | // 133 | // Return the appropriate 1 of 256 flyweight tokens for the ASCII characters. 134 | // 135 | CxxToken *make_token(size_t tokenValue) 136 | { 137 | static CxxToken *asciiTokens[256]; 138 | if (tokenValue >= (sizeof(asciiTokens)/sizeof(asciiTokens[0]))) 139 | { 140 | ERRMSG("Cannot make_token for " << tokenValue); 141 | return 0; 142 | } 143 | CxxToken **p = &asciiTokens[tokenValue]; 144 | CxxToken *theToken = *p; 145 | if (!theToken) 146 | *p = theToken = new CxxToken(tokenValue); 147 | return theToken; 148 | } 149 | 150 | CxxToken *make_wide_character(const char *someText, size_t aLength) 151 | { 152 | return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength); 153 | } 154 | 155 | CxxToken *make_wide_string(const char *someText, size_t aLength) 156 | { 157 | return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength); 158 | } 159 | 160 | -------------------------------------------------------------------------------- /CxxLexing.hxx: -------------------------------------------------------------------------------- 1 | #ifndef CXX_LEXING_HXX 2 | #define CXX_LEXING_HXX 3 | 4 | #include 5 | 6 | #include 7 | 8 | CxxToken *yyToken; 9 | CxxToken *make_character(const char *someText, size_t aLength); 10 | CxxToken *make_string(const char *someText, size_t aLength); 11 | CxxToken *make_identifier(const char *someText, size_t aLength); 12 | void make_line(const char *yyText, size_t yyLeng); 13 | CxxToken *make_literal_character(const char *someText, size_t aLength); 14 | CxxToken *make_narrow_character(const char *someText, size_t aLength); 15 | CxxToken *make_narrow_string(const char *someText, size_t aLength); 16 | CxxToken *make_number(const char *someText, size_t aLength); 17 | CxxToken *make_token(size_t aCxxToken); 18 | CxxToken *make_wide_character(const char *someText, size_t aLength); 19 | CxxToken *make_wide_string(const char *someText, size_t aLength); 20 | 21 | #define LEX_SAVE_LINE(yyText, yyLeng) make_line(yyText, yyLeng); 22 | #define LEX_ASCII_TOKEN(a) yyToken = make_token(a); return true; 23 | #define LEX_STATIC_TOKEN(a) static CxxToken theToken(PARSE_TOKEN(a)); yyToken = &theToken; return true; 24 | #define LEX_C_STATIC_TOKEN(a) \ 25 | if (c_keywords) { LEX_IDENTIFIER_TOKEN(yytext, yyleng) } \ 26 | else { LEX_STATIC_TOKEN(a) } return true; 27 | #define LEX_ESCAPED_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(CharacterLiteral) 28 | // yyToken = make_literal_character(yytext, yyleng); return true; 29 | #define LEX_CHARACTER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(CharacterLiteral) 30 | // yyToken = make_character(yyText, yyLeng); return true; 31 | #define LEX_STRING_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(StringLiteral) 32 | // yyToken = make_string(yyText, yyLeng); return true; 33 | #define LEX_IDENTIFIER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(Identifier) 34 | // yyToken = make_identifier(yyText, yyLeng); return true; 35 | #define LEX_NUMBER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(IntegerLiteral) 36 | // yyToken = make_number(yyText, yyLeng); return true; 37 | #endif -------------------------------------------------------------------------------- /CxxParser.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Title: C++ Grammar Parser support compilation unit. 3 | // 4 | // File Name: CxxParser.cpp 5 | // 6 | // Author: E.D.Willink 7 | //END 8 | // 9 | #include 10 | 11 | -------------------------------------------------------------------------------- /CxxParser.y: -------------------------------------------------------------------------------- 1 | /* This is a yacc-able parser for the entire ISO C++ grammar with no unresolved conflicts. */ 2 | /* The parse is SYNTACTICALLY consistent and requires no template or type name assistance. 3 | * The grammar in the C++ standard notes that its grammar is a superset of the true 4 | * grammar requiring semantic constraints to resolve ambiguities. This grammar is a really big 5 | * superset unifying expressions and declarations, eliminating the type/non-type distinction, 6 | * and iterating to find a consistent solution to the template/arith,metoic < ambiguity. 7 | * As a result the grammar is much simpler, but requires the missing semantic constraints to be 8 | * performed in a subsequent semantic pass, which is of course where they belong. This grammar will 9 | * support conversion of C++ tokens into an Abstract Syntax Tree. A lot of further work is required to 10 | * make that tree useful. 11 | * 12 | * The principles behind this grammar are described in my thesis on Meta-Compilation for C++, which 13 | * may be found via http://www.computing.surrey.ac.uk/research/dsrg/fog/FogThesis.html. 14 | * 15 | * Author: E.D.Willink Ed.Willink@rrl.co.uk 16 | * Date: 19-Jun-2001 17 | */ 18 | /*StartTester*/ 19 | %{ 20 | #include 21 | using namespace std; 22 | %} 23 | /*EndTester*/ 24 | /* 25 | * The lexer (and/or a preprocessor) is expected to identify the following 26 | * 27 | * Punctuation: 28 | */ 29 | %type '+' '-' '*' '/' '%' '^' '&' '|' '~' '!' '<' '>' '=' ':' '[' ']' '{' '}' '(' ')' 30 | %type '?' '.' '\'' '\"' '\\' '@' '$' ';' ',' 31 | /* 32 | * Punctuation sequences 33 | */ 34 | %term ARROW ARROW_STAR DEC EQ GE INC LE LOG_AND LOG_OR NE SHL SHR 35 | %term ASS_ADD ASS_AND ASS_DIV ASS_MOD ASS_MUL ASS_OR ASS_SHL ASS_SHR ASS_SUB ASS_XOR 36 | %term DOT_STAR ELLIPSIS SCOPE 37 | /* 38 | * Reserved words 39 | */ 40 | %term PRIVATE PROTECTED PUBLIC 41 | %term BOOL CHAR DOUBLE FLOAT INT LONG SHORT SIGNED UNSIGNED VOID WCHAR_T 42 | %term CLASS ENUM NAMESPACE STRUCT TYPENAME UNION 43 | %term CONST VOLATILE 44 | %term AUTO EXPLICIT EXPORT EXTERN FRIEND INLINE MUTABLE REGISTER STATIC TEMPLATE TYPEDEF USING VIRTUAL 45 | %term ASM BREAK CASE CATCH CONST_CAST CONTINUE DEFAULT DELETE DO DYNAMIC_CAST 46 | %term ELSE FALSE FOR GOTO IF NEW OPERATOR REINTERPRET_CAST RETURN 47 | %term SIZEOF STATIC_CAST SWITCH THIS THROW TRUE TRY TYPEID WHILE 48 | /* 49 | * Parametric values. 50 | */ 51 | %term CharacterLiteral 52 | %term FloatingLiteral 53 | %term Identifier 54 | %term IntegerLiteral 55 | %term NumberLiteral 56 | %term StringLiteral 57 | /* 58 | * The lexer need not treat '0' as distinct from IntegerLiteral in the hope that pure-specifier can 59 | * be distinguished, It isn't. Semantic rescue from = constant-expression is necessary. 60 | * 61 | * The lexer is not required to distinguish template or type names, although a slight simplification to the 62 | * grammar and elaboration of the action rules could make good use of template name information. 63 | * 64 | * In return for not needing to use semantic information, the lexer must support back-tracking, which 65 | * is easily achieved by a simple linear buffer, a reference implementation of which may be found in the 66 | * accompanying CxxParsing.cxx. Back-tracking is used to support: 67 | * 68 | * Binary search for a consistent parse of the template/arithmetic ambiguity. 69 | * start_search() initialises the search 70 | * advance_search() iterates the search 71 | * end_search() cleans up after a search 72 | * template_test() maintains context during a search 73 | * 74 | * Lookahead to resolve the inheritance/anonymous bit-field similarity 75 | * mark() saves the starting context 76 | * unmark() pops it 77 | * rewind_colon() restores the context and forces the missing : 78 | * 79 | * Lookahead to resolve type 1 function parameter ambiguities 80 | * mark_type1() potentially marks the starting position 81 | * mark() marks the pre { position 82 | * remark() rewinds to the starting position 83 | * unmark() pops the starting position 84 | * 85 | * Note that lookaheads may nest. 86 | */ 87 | 88 | /* 89 | * The parsing philosophy is unusual. The major ambiguities are resolved by creating a unified superset 90 | * grammar rather than non-overlapping subgrammars. Thus the grammar for parameter-declaration covers an 91 | * assignment-expression. Minor ambiguities whose resolution by supersetting would create more 92 | * ambiguities are resolved the normal way with partitioned subgrammars. 93 | * This eliminates the traditional expression/declaration and constructor/parenthesised declarator 94 | * ambiguities at the syntactic level. A subsequent semantic level has to sort the problems out. 95 | * The generality introduces four bogus ambiguities and defers the cast ambiguity for resolution 96 | * once semantic information is available. 97 | * 98 | * The C++ grammar comprises 561 rules and uses 897 states in yacc, with 0 unresolved conflicts. 99 | * 23 conflicts from 10 ambiguities are resolved by 8 %prec's, so that yacc and bison report 0 conflicts. 100 | * 101 | * The ambiguities are: 102 | * 1) dangling else resolved to inner-most if 103 | * 1 conflict in 1 state on else 104 | * 2) < as start-template or less-than 105 | * 1 conflict in 1 states on < 106 | * 3) a :: b :: c resolved to favour a::b::c rather than a::b ::c or a ::b::c 107 | * 1 conflicts in 1 state for :: 108 | * 4) pointer operators maximised at end of conversion id/new in preference to binary operators 109 | * 2 conflicts in 4 states on * and & 110 | * 5a) (a)@b resolved to favour binary a@b rather than cast unary (a)(@b) 111 | * 5b) (a)(b) resolved to favour cast rather than call 112 | * 8 conflicts in 1 state for the 8 prefix operators: 6 unaries and ( and [. 113 | * 6) enum name { resolved to enum-specifier rather than function 114 | * 1 conflict in 1 state on { 115 | * 7) class name { resolved to class-specifier rather than function 116 | * 1 conflict in 1 state on { 117 | * 8) extern "C" resolved to linkage-specification rather than declaration 118 | * 1 conflict in 1 state on StringLiteral 119 | * 9) class X : forced to go through base-clause look-ahead 120 | * 1 conflict in 1 state on : 121 | * 10) id : forced to label_statement rather than constructor_head 122 | * 0 conflicts - but causes a double state for 2) 123 | * of which 124 | * 1 is a fundamental C conflict - always correctly resolved 125 | * can be removed - see the Java spec 126 | * 2, 3, 4 are fundamental C++ conflicts 127 | * 2 always consistently resolved by iteration 128 | * 3 always correctly resolved 129 | * 4 always correctly resolved 130 | * 5 is a result of not using type information - deferred for semantic repair 131 | * 6,7 are caused by parsing over-generous superset - always correctly resolved 132 | * 8 is caused by parsing over-generous superset - always correctly resolved 133 | * can be removed at the expense of 7 rules and 5 states. 134 | * 9 is a look-ahead trick - always correctly resolved 135 | * could be removed by marking one token sooner 136 | * 10 is caused by parsing over-generous superset - always correctly resolved 137 | * 138 | * The hard problem of distinguishing 139 | * class A { class B : C, D, E { -- A::B privately inherits C, D and E 140 | * class A { class B : C, D, E ; -- C is width of anon bit-field 141 | * is resolved by using a lookahead that assumes inheritance and rewinds for the bit-field. 142 | * 143 | * The potential shift-reduce conflict on > is resolved by flattening part of the expression grammar 144 | * to know when the next > is template end or arithmetic >. 145 | * 146 | * The grammar is SYNTACTICALLY context-free with respect to type. No semantic assistance is required 147 | * during syntactic analysis. However the cast ambiguity is deferred and must be recovered 148 | * after syntactic analysis of a statement has completed. 149 | * 150 | * The grammar is SYNTACTICALLY context-free with respect to template-names. This is achieved by 151 | * organising a binary search over all possible template/arithmetic ambiguities with respect to 152 | * the enclosing statement. This is potentially exponentially inefficient but well-behaved in practice. 153 | * Approximately 1% of statements trigger a search and approximately 1% of those are misparsed, 154 | * requiring the semantic analysis to check and correct once template information is available. 155 | * 1.5 parse attempts are required on average per ambiguous statement. 156 | * 157 | * The grammar supports type I function declarations at severe impediment to efficiency. A lookahead 158 | * has to be performed after almost every non-statement close parenthesis. A one-line plus corollary 159 | * change to postfix_expression is commented and strongly recommended to make this grammar as 160 | * efficient as the rather large number of reduction levels permits. 161 | * 162 | * Error recovery occurs mostly at the statement/declaration level. Recovery also occurs at 163 | * the list-element level where this poses no hazard to statement/declaration level recovery. 164 | * Note that since error propagation interacts with the lookaheads for template iteration or 165 | * type 1 function arguments, introduction of finer grained error recovery may repair a false 166 | * parse and so cause a misparse. 167 | * 168 | * The following syntactic analysis errors occur, but are correctable semantically: 169 | * (cast)unary-op expr is parsed as (parenthesised)binary-op expr 170 | * The semantic test should look for a binary/call with a (type) as its left child. 171 | * (parenthesised)(arguments) is parsed as (cast)(parenthesised) 172 | * The semantic test should look for a cast with a non-type as its left child. 173 | * template < and arithmetic < may be cross-parsed (unless semnatic help is provided) 174 | * approximately 0.01% are misparsed, and must be sorted out - not easy. 175 | * 176 | * The syntactic analysis defers the following ambiguities for semantic resolution: 177 | * declaration/expression is parsed as a unified concept 178 | * Use type and context to complete the parse. 179 | * ~class-name is parsed as unary~ name 180 | * The semantic test should look for ~ with a type as its child. 181 | * delete[] expr is parsed as delete []expr 182 | * The semantic test should look for delete with a [] cast of its child. 183 | * operator new/delete[] are parsed as array of operator new/delete 184 | * The semantic test should look for array of operator new/delete 185 | * or activate the two extra commented rules in operator 186 | * template of an explicit_instantiation is buried deep in the tree 187 | * dig it out 188 | * pure-specifier and constant-initializer are covered by assignment-expression 189 | * just another of the deferred declaration/expression ambiguities 190 | * sizeof and typeid don't distinguish type/value syntaxes 191 | * probably makes life polymorphically easier 192 | */ 193 | /* Action code is supplied by a large number of YACC_xxx macros that can be redefined 194 | * by rewriting the include file rather than the grammar. The number of macros is 195 | * slightly reduced by using the following protocols 196 | * 197 | * YACC_LIST(0,0) create empty list (may safely return 0). 198 | * YACC_LIST(0,E) create new list with content E (may return 0 if above returned non-0). 199 | * YACC_LIST(L,E) add E to L 200 | * YACC_LIST(L,0) error propagation, adding nothing to L. 201 | */ 202 | %type bang 203 | %type colon_mark mark mark_type1 204 | %type nest 205 | 206 | %type access_specifier 207 | %type base_specifier 208 | %type base_specifier_list 209 | %type built_in_type_id built_in_type_specifier 210 | %type <_class> class_specifier_head 211 | %type class_key 212 | %type condition condition.opt 213 | %type cv_qualifier cv_qualifier_seq.opt 214 | %type decl_specifier_affix decl_specifier_prefix decl_specifier_suffix function_specifier storage_class_specifier 215 | %type accessibility_specifier asm_definition block_declaration declaration explicit_specialization 216 | %type looped_declaration looping_declaration namespace_alias_definition 217 | %type specialised_block_declaration specialised_declaration template_declaration using_directive 218 | %type compound_declaration declaration_seq.opt 219 | %type nested_ptr_operator ptr_operator 220 | %type delete_expression 221 | %type enumerator_definition 222 | %type enumerator_clause enumerator_list enumerator_list_head 223 | %type exception_declaration 224 | %type exception_specification 225 | %type abstract_declarator.opt abstract_expression abstract_parameter_declaration abstract_pointer_declaration 226 | %type additive_expression and_expression assignment_expression 227 | %type bit_field_declaration bit_field_init_declaration bit_field_width boolean_literal 228 | %type cast_expression conditional_expression constant_expression conversion_type_id ctor_definition 229 | %type direct_abstract_declarator direct_abstract_declarator.opt direct_new_declarator 230 | %type equality_expression exclusive_or_expression expression expression.opt 231 | %type for_init_statement func_definition function_definition 232 | %type inclusive_or_expression init_declaration literal logical_and_expression logical_or_expression 233 | %type multiplicative_expression new_declarator new_type_id 234 | %type pm_expression postfix_expression primary_expression ptr_operator_seq ptr_operator_seq.opt 235 | %type relational_expression shift_expression simple_declaration special_parameter_declaration 236 | %type templated_throw_expression throw_expression templated_abstract_declaration templated_and_expression 237 | %type templated_assignment_expression templated_conditional_expression templated_equality_expression 238 | %type templated_exclusive_or_expression templated_expression templated_inclusive_or_expression templated_logical_and_expression 239 | %type templated_logical_or_expression templated_relational_expression type_id unary_expression 240 | %type constructor_head expression_list expression_list.opt init_declarations 241 | %type new_initializer.opt templated_expression_list type_id_list 242 | %type function_block function_body function_try_block try_block 243 | %type handler 244 | %type handler_seq 245 | %type braced_initializer initializer_clause looped_initializer_clause looping_initializer_clause 246 | %type initializer_list 247 | %type global_scope 248 | %type assignment_operator 249 | %type start_search start_search1 250 | %type mem_initializer 251 | %type ctor_initializer ctor_initializer.opt mem_initializer_list mem_initializer_list_head 252 | %type class_specifier conversion_function_id declarator_id destructor_id 253 | %type elaborated_class_specifier elaborated_enum_specifier elaborated_type_specifier elaborate_type_specifier 254 | %type enum_specifier enumerator id identifier_word id_scope identifier linkage_specification 255 | %type namespace_definition nested_id nested_pseudo_destructor_id nested_special_function_id 256 | %type mem_initializer_id operator operator_function_id pseudo_destructor_id scoped_id scoped_pseudo_destructor_id scoped_special_function_id 257 | %type simple_type_specifier special_function_id suffix_built_in_decl_specifier suffix_named_decl_specifier.bi 258 | %type suffix_built_in_decl_specifier.raw suffix_decl_specified_ids suffix_named_decl_specifiers 259 | %type suffix_named_decl_specifiers.sf suffix_decl_specified_scope suffix_named_decl_specifier 260 | %type template_id type_specifier 261 | %type new_expression 262 | %type parameter_declaration templated_parameter_declaration 263 | %type parameters_clause parameter_declaration_clause parameter_declaration_list 264 | %type parenthesis_clause 265 | %type star_ptr_operator 266 | %type simple_type_parameter 267 | %type compound_statement control_statement declaration_statement iteration_statement jump_statement 268 | %type labeled_statement looped_statement looping_statement selection_statement statement 269 | %type statement_seq.opt 270 | %type string 271 | %type template_argument 272 | %type template_argument_list 273 | %type template_parameter 274 | %type template_parameter_clause template_parameter_list 275 | %type templated_type_parameter 276 | %type type1_parameters 277 | %type util 278 | 279 | /* 280 | * C++ productions replaced by more generalised FOG productions 281 | */ 282 | %type looped_member_declaration looping_member_declaration member_declaration using_declaration 283 | %type member_specification.opt 284 | %type member_init_declaration simple_member_declaration 285 | %type member_init_declarations 286 | 287 | 288 | %nonassoc SHIFT_THERE 289 | %nonassoc SCOPE ELSE INC DEC '+' '-' '*' '&' '[' '{' '<' ':' StringLiteral 290 | %nonassoc REDUCE_HERE_MOSTLY 291 | %nonassoc '(' 292 | /*%nonassoc REDUCE_HERE */ 293 | 294 | %start translation_unit 295 | %% 296 | 297 | /* 298 | * The %prec resolves a conflict in identifier_word : which is forced to be a shift of a label for 299 | * a labeled-statement rather than a reduction for the name of a bit-field or generalised constructor. 300 | * This is pretty dubious syntactically but correct for all semantic possibilities. 301 | * The shift is only activated when the ambiguity exists at the start of a statement. In this context 302 | * a bit-field declaration or constructor definition are not allowed. 303 | */ 304 | identifier_word: Identifier { $$ = $1; } 305 | identifier: identifier_word %prec SHIFT_THERE 306 | /* 307 | * The %prec resolves the $014.2-3 ambiguity: 308 | * Identifier '<' is forced to go through the is-it-a-template-name test 309 | * All names absorb TEMPLATE with the name, so that no template_test is performed for them. 310 | * This requires all potential declarations within an expression to perpetuate this policy 311 | * and thereby guarantee the ultimate coverage of explicit_instantiation. 312 | */ 313 | id: identifier %prec SHIFT_THERE /* Force < through test */ { $$ = YACC_NAME($1); } 314 | | identifier template_test '+' template_argument_list '>' { $$ = YACC_TEMPLATE_NAME($1, $4); } 315 | | identifier template_test '+' '>' { $$ = $1; ERRMSG("Empty template-argument-list"); } 316 | | identifier template_test '-' /* requeued < follows */ { $$ = YACC_NAME($1); } 317 | | template_id 318 | template_test: '<' /* Queue '+' or '-' < as follow on */ { template_test(); } 319 | global_scope: SCOPE { $$ = IS_DEFAULT; } 320 | | TEMPLATE global_scope { $$ = IS_TEMPLATE; } 321 | id_scope: id SCOPE { $$ = YACC_NESTED_SCOPE($1); } 322 | /* 323 | * A :: B :: C; is ambiguous How much is type and how much name ? 324 | * The %prec maximises the (type) length which is the $07.1-2 semantic constraint. 325 | */ 326 | nested_id: id %prec SHIFT_THERE /* Maximise length */ 327 | | id_scope nested_id { $$ = YACC_NESTED_ID($1, $2); } 328 | scoped_id: nested_id 329 | | global_scope nested_id { $$ = YACC_GLOBAL_ID($1, $2); } 330 | 331 | /* 332 | * destructor_id has to be held back to avoid a conflict with a one's complement as per $05.3.1-9, 333 | * It gets put back only when scoped or in a declarator_id, which is only used as an explicit member name. 334 | * Declarations of an unscoped destructor are always parsed as a one's complement. 335 | */ 336 | destructor_id: '~' id { $$ = YACC_DESTRUCTOR_ID($2); } 337 | | TEMPLATE destructor_id { $$ = YACC_SET_TEMPLATE_ID($2); } 338 | special_function_id: conversion_function_id 339 | | operator_function_id 340 | | TEMPLATE special_function_id { $$ = YACC_SET_TEMPLATE_ID($2); } 341 | nested_special_function_id: special_function_id 342 | | id_scope destructor_id { $$ = YACC_NESTED_ID($1, $2); } 343 | | id_scope nested_special_function_id { $$ = YACC_NESTED_ID($1, $2); } 344 | scoped_special_function_id: nested_special_function_id 345 | | global_scope nested_special_function_id { $$ = YACC_GLOBAL_ID($1, $2); } 346 | 347 | /* declarator-id is all names in all scopes, except reserved words */ 348 | declarator_id: scoped_id 349 | | scoped_special_function_id 350 | | destructor_id 351 | 352 | /* The standard defines pseudo-destructors in terms of type-name, which is class/enum/typedef, of which 353 | * class-name is covered by a normal destructor. pseudo-destructors are supposed to support ~int() in 354 | * templates, so the grammar here covers built-in names. Other names are covered by the lack of 355 | * identifier/type discrimination. 356 | */ 357 | built_in_type_id: built_in_type_specifier 358 | | built_in_type_id built_in_type_specifier { $$ = YACC_BUILT_IN_IDS($1, $2); } 359 | pseudo_destructor_id: built_in_type_id SCOPE '~' built_in_type_id { $$ = YACC_PSEUDO_DESTRUCTOR_ID($1, $4); } 360 | | '~' built_in_type_id { $$ = YACC_PSEUDO_DESTRUCTOR_ID(0, $2); } 361 | | TEMPLATE pseudo_destructor_id { $$ = YACC_SET_TEMPLATE_ID($2); } 362 | nested_pseudo_destructor_id: pseudo_destructor_id 363 | | id_scope nested_pseudo_destructor_id { $$ = YACC_NESTED_ID($1, $2); } 364 | scoped_pseudo_destructor_id: nested_pseudo_destructor_id 365 | | global_scope scoped_pseudo_destructor_id { $$ = YACC_GLOBAL_ID($1, $2); } 366 | 367 | /*--------------------------------------------------------------------------------------------------- 368 | * A.2 Lexical conventions 369 | *---------------------------------------------------------------------------------------------------*/ 370 | /* 371 | * String concatenation is a phase 6, not phase 7 activity so does not really belong in the grammar. 372 | * However it may be convenient to have it here to make this grammar fully functional. 373 | * Unfortunately it introduces a conflict with the generalised parsing of extern "C" which 374 | * is correctly resolved to maximise the string length as the token source should do anyway. 375 | */ 376 | string: StringLiteral { $$ = $1; } 377 | /*string: StringLiteral %prec SHIFT_THERE { $$ = YACC_STRINGS($1, 0); } */ 378 | /* | StringLiteral string -- Perverse order avoids conflicts -- { $$ = YACC_STRINGS($1, $2); } */ 379 | literal: IntegerLiteral { $$ = YACC_INTEGER_LITERAL_EXPRESSION($1); } 380 | | CharacterLiteral { $$ = YACC_CHARACTER_LITERAL_EXPRESSION($1); } 381 | | FloatingLiteral { $$ = YACC_FLOATING_LITERAL_EXPRESSION($1); } 382 | | string { $$ = YACC_STRING_LITERAL_EXPRESSION($1); } 383 | | boolean_literal 384 | boolean_literal: FALSE { $$ = YACC_FALSE_EXPRESSION(); } 385 | | TRUE { $$ = YACC_TRUE_EXPRESSION(); } 386 | 387 | /*--------------------------------------------------------------------------------------------------- 388 | * A.3 Basic concepts 389 | *---------------------------------------------------------------------------------------------------*/ 390 | translation_unit: declaration_seq.opt { YACC_RESULT($1); } 391 | 392 | /*--------------------------------------------------------------------------------------------------- 393 | * A.4 Expressions 394 | *--------------------------------------------------------------------------------------------------- 395 | * primary_expression covers an arbitrary sequence of all names with the exception of an unscoped destructor, 396 | * which is parsed as its unary expression which is the correct disambiguation (when ambiguous). 397 | * This eliminates the traditional A(B) meaning A B ambiguity, since we never have to tack an A onto 398 | * the front of something that might start with (. The name length got maximised ab initio. The downside 399 | * is that semantic interpretation must split the names up again. 400 | * 401 | * Unification of the declaration and expression syntax means that unary and binary pointer declarator operators: 402 | * int * * name 403 | * are parsed as binary and unary arithmetic operators (int) * (*name). Since type information is not used 404 | * ambiguities resulting from a cast 405 | * (cast)*(value) 406 | * are resolved to favour the binary rather than the cast unary to ease AST clean-up. 407 | * The cast-call ambiguity must be resolved to the cast to ensure that (a)(b)c can be parsed. 408 | * 409 | * The problem of the functional cast ambiguity 410 | * name(arg) 411 | * as call or declaration is avoided by maximising the name within the parsing kernel. So 412 | * primary_id_expression picks up 413 | * extern long int const var = 5; 414 | * as an assignment to the syntax parsed as "extern long int const var". The presence of two names is 415 | * parsed so that "extern long into const" is distinguished from "var" considerably simplifying subsequent 416 | * semantic resolution. 417 | * 418 | * The generalised name is a concatenation of potential type-names (scoped identifiers or built-in sequences) 419 | * plus optionally one of the special names such as an operator-function-id, conversion-function-id or 420 | * destructor as the final name. 421 | */ 422 | primary_expression: literal 423 | | THIS { $$ = YACC_THIS_EXPRESSION(); } 424 | | suffix_decl_specified_ids { $$ = $1; } 425 | /* | SCOPE identifier -- covered by suffix_decl_specified_ids */ 426 | /* | SCOPE operator_function_id -- covered by suffix_decl_specified_ids */ 427 | /* | SCOPE qualified_id -- covered by suffix_decl_specified_ids */ 428 | | abstract_expression %prec REDUCE_HERE_MOSTLY /* Prefer binary to unary ops, cast to call */ 429 | /* | id_expression -- covered by suffix_decl_specified_ids */ 430 | 431 | /* 432 | * Abstract-expression covers the () and [] of abstract-declarators. 433 | */ 434 | abstract_expression: parenthesis_clause { $$ = YACC_ABSTRACT_FUNCTION_EXPRESSION($1); } 435 | | '[' expression.opt ']' { $$ = YACC_ABSTRACT_ARRAY_EXPRESSION($2); } 436 | | TEMPLATE parenthesis_clause { $$ = YACC_SET_TEMPLATE_EXPRESSION(YACC_ABSTRACT_FUNCTION_EXPRESSION($2)); } 437 | 438 | /* Type I function parameters are ambiguous with respect to the generalised name, so we have to do a lookahead following 439 | * any function-like parentheses. This unfortunately hits normal code, so kill the -- lines and add the ++ lines for efficiency. 440 | * Supporting Type I code under the superset causes perhaps 25% of lookahead parsing. Sometimes complete class definitions 441 | * get traversed since they are valid generalised type I parameters! 442 | */ 443 | type1_parameters: /*----*/ parameter_declaration_list ';' { $$ = YACC_TYPE1_PARAMETERS(0, $1); } 444 | | /*----*/ type1_parameters parameter_declaration_list ';' { $$ = YACC_TYPE1_PARAMETERS($1, $2); } 445 | mark_type1: /* empty */ { $$ = mark_type1(); } 446 | postfix_expression: primary_expression 447 | /* | /++++++/ postfix_expression parenthesis_clause { $$ = YACC_CALL_EXPRESSION($1, $2); } */ 448 | | /*----*/ postfix_expression parenthesis_clause mark_type1 '-' { $$ = YACC_CALL_EXPRESSION($1, $2); } 449 | | /*----*/ postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark '{' error 450 | /*----*/ { yyerrok; remark_type1($6); unmark(); unmark($5); $$ = YACC_TYPE1_EXPRESSION($1, $2, $5); } 451 | | /*----*/ postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark error 452 | /*----*/ { yyerrok; remark_type1($3); unmark(); unmark(); $$ = YACC_CALL_EXPRESSION($1, $2); } 453 | | /*----*/ postfix_expression parenthesis_clause mark_type1 '+' error 454 | /*----*/ { yyerrok; remark_type1($3); unmark(); $$ = YACC_CALL_EXPRESSION($1, $2); } 455 | | postfix_expression '[' expression.opt ']' { $$ = YACC_ARRAY_EXPRESSION($1, $3); } 456 | /* | destructor_id '[' expression.opt ']' -- not semantically valid */ 457 | /* | destructor_id parenthesis_clause -- omitted to resolve known ambiguity */ 458 | /* | simple_type_specifier '(' expression_list.opt ')' -- simple_type_specifier is a primary_expression */ 459 | | postfix_expression '.' declarator_id { $$ = YACC_DOT_EXPRESSION($1, $3); } 460 | /* | postfix_expression '.' TEMPLATE declarator_id -- TEMPLATE absorbed into declarator_id. */ 461 | | postfix_expression '.' scoped_pseudo_destructor_id { $$ = YACC_DOT_EXPRESSION($1, $3); } 462 | | postfix_expression ARROW declarator_id { $$ = YACC_ARROW_EXPRESSION($1, $3); } 463 | /* | postfix_expression ARROW TEMPLATE declarator_id -- TEMPLATE absorbed into declarator_id. */ 464 | | postfix_expression ARROW scoped_pseudo_destructor_id { $$ = YACC_ARROW_EXPRESSION($1, $3); } 465 | | postfix_expression INC { $$ = YACC_POST_INCREMENT_EXPRESSION($1); } 466 | | postfix_expression DEC { $$ = YACC_POST_DECREMENT_EXPRESSION($1); } 467 | | DYNAMIC_CAST '<' type_id '>' '(' expression ')' { $$ = YACC_DYNAMIC_CAST_EXPRESSION($3, $6); } 468 | | STATIC_CAST '<' type_id '>' '(' expression ')' { $$ = YACC_STATIC_CAST_EXPRESSION($3, $6); } 469 | | REINTERPRET_CAST '<' type_id '>' '(' expression ')' { $$ = YACC_REINTERPRET_CAST_EXPRESSION($3, $6); } 470 | | CONST_CAST '<' type_id '>' '(' expression ')' { $$ = YACC_CONST_CAST_EXPRESSION($3, $6); } 471 | | TYPEID parameters_clause { $$ = YACC_TYPEID_EXPRESSION($2); } 472 | /* | TYPEID '(' expression ')' -- covered by parameters_clause */ 473 | /* | TYPEID '(' type_id ')' -- covered by parameters_clause */ 474 | expression_list.opt: /* empty */ { $$ = YACC_EXPRESSIONS(0, 0); } 475 | | expression_list 476 | expression_list: assignment_expression { $$ = YACC_EXPRESSIONS(0, $1); } 477 | | expression_list ',' assignment_expression { $$ = YACC_EXPRESSIONS($1, $3); } 478 | 479 | unary_expression: postfix_expression 480 | | INC cast_expression { $$ = YACC_PRE_INCREMENT_EXPRESSION($2); } 481 | | DEC cast_expression { $$ = YACC_PRE_DECREMENT_EXPRESSION($2); } 482 | | ptr_operator cast_expression { $$ = YACC_POINTER_EXPRESSION($1, $2); } 483 | /* | '*' cast_expression -- covered by ptr_operator */ 484 | /* | '&' cast_expression -- covered by ptr_operator */ 485 | /* | decl_specifier_seq '*' cast_expression -- covered by binary operator */ 486 | /* | decl_specifier_seq '&' cast_expression -- covered by binary operator */ 487 | | suffix_decl_specified_scope star_ptr_operator cast_expression /* covers e.g int ::type::* const t = 4 */ 488 | { $$ = YACC_SCOPED_POINTER_EXPRESSION($1, $2, $3); } 489 | | '+' cast_expression { $$ = YACC_PLUS_EXPRESSION($2); } 490 | | '-' cast_expression { $$ = YACC_MINUS_EXPRESSION($2); } 491 | | '!' cast_expression { $$ = YACC_NOT_EXPRESSION($2); } 492 | | '~' cast_expression { $$ = YACC_COMPLEMENT_EXPRESSION($2); } 493 | | SIZEOF unary_expression { $$ = YACC_SIZEOF_EXPRESSION($2); } 494 | /* | SIZEOF '(' type_id ')' -- covered by unary_expression */ 495 | | new_expression { $$ = $1; } 496 | | global_scope new_expression { $$ = YACC_GLOBAL_EXPRESSION($1, $2); } 497 | | delete_expression { $$ = $1; } 498 | | global_scope delete_expression { $$ = YACC_GLOBAL_EXPRESSION($1, $2); } 499 | /* | DELETE '[' ']' cast_expression -- covered by DELETE cast_expression since cast_expression covers ... */ 500 | /* | SCOPE DELETE '[' ']' cast_expression // ... abstract_expression cast_expression and so [] cast_expression */ 501 | 502 | delete_expression: DELETE cast_expression /* also covers DELETE[] cast_expression */ 503 | { $$ = YACC_DELETE_EXPRESSION($2); } 504 | new_expression: NEW new_type_id new_initializer.opt { $$ = YACC_NEW_TYPE_ID_EXPRESSION(0, $2, $3); } 505 | | NEW parameters_clause new_type_id new_initializer.opt { $$ = YACC_NEW_TYPE_ID_EXPRESSION($2, $3, $4); } 506 | | NEW parameters_clause { $$ = YACC_NEW_EXPRESSION($2, 0, 0); } 507 | /* | NEW '(' type-id ')' -- covered by parameters_clause */ 508 | | NEW parameters_clause parameters_clause new_initializer.opt { $$ = YACC_NEW_EXPRESSION($2, $3, $4); } 509 | /* | NEW '(' type-id ')' new_initializer -- covered by parameters_clause parameters_clause */ 510 | /* | NEW parameters_clause '(' type-id ')' -- covered by parameters_clause parameters_clause */ 511 | /* ptr_operator_seq.opt production reused to save a %prec */ 512 | new_type_id: type_specifier ptr_operator_seq.opt { $$ = YACC_TYPED_EXPRESSION($1, $2); } 513 | | type_specifier new_declarator { $$ = YACC_TYPED_EXPRESSION($1, $2); } 514 | | type_specifier new_type_id { $$ = YACC_TYPED_EXPRESSION($1, $2); } 515 | new_declarator: ptr_operator new_declarator { $$ = YACC_POINTER_EXPRESSION($1, $2); } 516 | | direct_new_declarator 517 | direct_new_declarator: '[' expression ']' { $$ = YACC_ABSTRACT_ARRAY_EXPRESSION($2); } 518 | | direct_new_declarator '[' constant_expression ']' { $$ = YACC_ARRAY_EXPRESSION($1, $3); } 519 | new_initializer.opt: /* empty */ { $$ = YACC_EXPRESSIONS(0, 0); } 520 | | '(' expression_list.opt ')' { $$ = $2; } 521 | 522 | /* cast-expression is generalised to support a [] as well as a () prefix. This covers the omission of DELETE[] which when 523 | * followed by a parenthesised expression was ambiguous. It also covers the gcc indexed array initialisation for free. 524 | */ 525 | cast_expression: unary_expression 526 | | abstract_expression cast_expression { $$ = YACC_CAST_EXPRESSION($1, $2); } 527 | /* | '(' type_id ')' cast_expression -- covered by abstract_expression */ 528 | 529 | pm_expression: cast_expression 530 | | pm_expression DOT_STAR cast_expression { $$ = YACC_DOT_STAR_EXPRESSION($1, $3); } 531 | | pm_expression ARROW_STAR cast_expression { $$ = YACC_ARROW_STAR_EXPRESSION($1, $3); } 532 | multiplicative_expression: pm_expression 533 | | multiplicative_expression star_ptr_operator pm_expression { $$ = YACC_MULTIPLY_EXPRESSION($1, $2, $3); } 534 | | multiplicative_expression '/' pm_expression { $$ = YACC_DIVIDE_EXPRESSION($1, $3); } 535 | | multiplicative_expression '%' pm_expression { $$ = YACC_MODULUS_EXPRESSION($1, $3); } 536 | additive_expression: multiplicative_expression 537 | | additive_expression '+' multiplicative_expression { $$ = YACC_ADD_EXPRESSION($1, $3); } 538 | | additive_expression '-' multiplicative_expression { $$ = YACC_SUBTRACT_EXPRESSION($1, $3); } 539 | shift_expression: additive_expression 540 | | shift_expression SHL additive_expression { $$ = YACC_SHIFT_LEFT_EXPRESSION($1, $3); } 541 | | shift_expression SHR additive_expression { $$ = YACC_SHIFT_RIGHT_EXPRESSION($1, $3); } 542 | relational_expression: shift_expression 543 | | relational_expression '<' shift_expression { $$ = YACC_LESS_THAN_EXPRESSION($1, $3); } 544 | | relational_expression '>' shift_expression { $$ = YACC_GREATER_THAN_EXPRESSION($1, $3); } 545 | | relational_expression LE shift_expression { $$ = YACC_LESS_EQUAL_EXPRESSION($1, $3); } 546 | | relational_expression GE shift_expression { $$ = YACC_GREATER_EQUAL_EXPRESSION($1, $3); } 547 | equality_expression: relational_expression 548 | | equality_expression EQ relational_expression { $$ = YACC_EQUAL_EXPRESSION($1, $3); } 549 | | equality_expression NE relational_expression { $$ = YACC_NOT_EQUAL_EXPRESSION($1, $3); } 550 | and_expression: equality_expression 551 | | and_expression '&' equality_expression { $$ = YACC_AND_EXPRESSION($1, $3); } 552 | exclusive_or_expression: and_expression 553 | | exclusive_or_expression '^' and_expression { $$ = YACC_EXCLUSIVE_OR_EXPRESSION($1, $3); } 554 | inclusive_or_expression: exclusive_or_expression 555 | | inclusive_or_expression '|' exclusive_or_expression { $$ = YACC_INCLUSIVE_OR_EXPRESSION($1, $3); } 556 | logical_and_expression: inclusive_or_expression 557 | | logical_and_expression LOG_AND inclusive_or_expression { $$ = YACC_LOGICAL_AND_EXPRESSION($1, $3); } 558 | logical_or_expression: logical_and_expression 559 | | logical_or_expression LOG_OR logical_and_expression { $$ = YACC_LOGICAL_OR_EXPRESSION($1, $3); } 560 | conditional_expression: logical_or_expression 561 | | logical_or_expression '?' expression ':' assignment_expression 562 | { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); } 563 | 564 | /* assignment-expression is generalised to cover the simple assignment of a braced initializer in order to contribute to the 565 | * coverage of parameter-declaration and init-declaration. 566 | */ 567 | assignment_expression: conditional_expression 568 | | logical_or_expression assignment_operator assignment_expression { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); } 569 | | logical_or_expression '=' braced_initializer { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); } 570 | | throw_expression 571 | assignment_operator: '=' | ASS_ADD | ASS_AND | ASS_DIV | ASS_MOD | ASS_MUL | ASS_OR | ASS_SHL | ASS_SHR | ASS_SUB | ASS_XOR 572 | 573 | /* expression is widely used and usually single-element, so the reductions are arranged so that a 574 | * single-element expression is returned as is. Multi-element expressions are parsed as a list that 575 | * may then behave polymorphically as an element or be compacted to an element. */ 576 | expression.opt: /* empty */ { $$ = YACC_EXPRESSION(0); } 577 | | expression 578 | expression: assignment_expression 579 | | expression_list ',' assignment_expression { $$ = YACC_EXPRESSION(YACC_EXPRESSIONS($1, $3)); } 580 | constant_expression: conditional_expression 581 | 582 | /* The grammar is repeated for when the parser stack knows that the next > must end a template. 583 | */ 584 | templated_relational_expression: shift_expression 585 | | templated_relational_expression '<' shift_expression { $$ = YACC_LESS_THAN_EXPRESSION($1, $3); } 586 | | templated_relational_expression LE shift_expression { $$ = YACC_LESS_EQUAL_EXPRESSION($1, $3); } 587 | | templated_relational_expression GE shift_expression { $$ = YACC_GREATER_EQUAL_EXPRESSION($1, $3); } 588 | templated_equality_expression: templated_relational_expression 589 | | templated_equality_expression EQ templated_relational_expression { $$ = YACC_EQUAL_EXPRESSION($1, $3); } 590 | | templated_equality_expression NE templated_relational_expression { $$ = YACC_NOT_EQUAL_EXPRESSION($1, $3); } 591 | templated_and_expression: templated_equality_expression 592 | | templated_and_expression '&' templated_equality_expression { $$ = YACC_AND_EXPRESSION($1, $3); } 593 | templated_exclusive_or_expression: templated_and_expression 594 | | templated_exclusive_or_expression '^' templated_and_expression 595 | { $$ = YACC_EXCLUSIVE_OR_EXPRESSION($1, $3); } 596 | templated_inclusive_or_expression: templated_exclusive_or_expression 597 | | templated_inclusive_or_expression '|' templated_exclusive_or_expression 598 | { $$ = YACC_INCLUSIVE_OR_EXPRESSION($1, $3); } 599 | templated_logical_and_expression: templated_inclusive_or_expression 600 | | templated_logical_and_expression LOG_AND templated_inclusive_or_expression 601 | { $$ = YACC_LOGICAL_AND_EXPRESSION($1, $3); } 602 | templated_logical_or_expression: templated_logical_and_expression 603 | | templated_logical_or_expression LOG_OR templated_logical_and_expression 604 | { $$ = YACC_LOGICAL_OR_EXPRESSION($1, $3); } 605 | templated_conditional_expression: templated_logical_or_expression 606 | | templated_logical_or_expression '?' templated_expression ':' templated_assignment_expression 607 | { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); } 608 | templated_assignment_expression: templated_conditional_expression 609 | | templated_logical_or_expression assignment_operator templated_assignment_expression 610 | { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); } 611 | | templated_throw_expression 612 | templated_expression: templated_assignment_expression 613 | | templated_expression_list ',' templated_assignment_expression 614 | { $$ = YACC_EXPRESSION(YACC_EXPRESSIONS($1, $3)); } 615 | templated_expression_list: templated_assignment_expression { $$ = YACC_EXPRESSIONS(0, $1); } 616 | | templated_expression_list ',' templated_assignment_expression { $$ = YACC_EXPRESSIONS($1, $3); } 617 | 618 | /*--------------------------------------------------------------------------------------------------- 619 | * A.5 Statements 620 | *--------------------------------------------------------------------------------------------------- 621 | * Parsing statements is easy once simple_declaration has been generalised to cover expression_statement. 622 | */ 623 | looping_statement: start_search looped_statement { $$ = YACC_LINED_STATEMENT($2, $1); end_search($$); } 624 | looped_statement: statement 625 | | advance_search '+' looped_statement { $$ = $3; } 626 | | advance_search '-' { $$ = 0; } 627 | statement: control_statement 628 | /* | expression_statement -- covered by declaration_statement */ 629 | | compound_statement 630 | | declaration_statement 631 | | try_block { $$ = YACC_TRY_BLOCK_STATEMENT($1); } 632 | control_statement: labeled_statement 633 | | selection_statement 634 | | iteration_statement 635 | | jump_statement 636 | labeled_statement: identifier_word ':' looping_statement { $$ = YACC_LABEL_STATEMENT($1, $3); } 637 | | CASE constant_expression ':' looping_statement { $$ = YACC_CASE_STATEMENT($2, $4); } 638 | | DEFAULT ':' looping_statement { $$ = YACC_DEFAULT_STATEMENT($3); } 639 | /*expression_statement: expression.opt ';' -- covered by declaration_statement */ 640 | compound_statement: '{' statement_seq.opt '}' { $$ = YACC_COMPOUND_STATEMENT($2); } 641 | | '{' statement_seq.opt looping_statement '#' bang error '}' { $$ = $2; YACC_UNBANG($5, "Bad statement-seq."); } 642 | statement_seq.opt: /* empty */ { $$ = YACC_STATEMENTS(0, 0); } 643 | | statement_seq.opt looping_statement { $$ = YACC_STATEMENTS($1, YACC_COMPILE_STATEMENT($2)); } 644 | | statement_seq.opt looping_statement '#' bang error ';' { $$ = $1; YACC_UNBANG($4, "Bad statement."); } 645 | /* 646 | * The dangling else conflict is resolved to the innermost if. 647 | */ 648 | selection_statement: IF '(' condition ')' looping_statement %prec SHIFT_THERE { $$ = YACC_IF_STATEMENT($3, $5, 0); } 649 | | IF '(' condition ')' looping_statement ELSE looping_statement { $$ = YACC_IF_STATEMENT($3, $5, $7); } 650 | | SWITCH '(' condition ')' looping_statement { $$ = YACC_SWITCH_STATEMENT($3, $5); } 651 | condition.opt: /* empty */ { $$ = YACC_CONDITION(0); } 652 | | condition 653 | condition: parameter_declaration_list { $$ = YACC_CONDITION($1); } 654 | /* | expression -- covered by parameter_declaration_list */ 655 | /* | type_specifier_seq declarator '=' assignment_expression -- covered by parameter_declaration_list */ 656 | iteration_statement: WHILE '(' condition ')' looping_statement { $$ = YACC_WHILE_STATEMENT($3, $5); } 657 | | DO looping_statement WHILE '(' expression ')' ';' { $$ = YACC_DO_WHILE_STATEMENT($2, $5); } 658 | | FOR '(' for_init_statement condition.opt ';' expression.opt ')' looping_statement 659 | { $$ = YACC_FOR_STATEMENT($3, $4, $6, $8); } 660 | for_init_statement: simple_declaration 661 | /* | expression_statement -- covered by simple_declaration */ 662 | jump_statement: BREAK ';' { $$ = YACC_BREAK_STATEMENT(); } 663 | | CONTINUE ';' { $$ = YACC_CONTINUE_STATEMENT(); } 664 | | RETURN expression.opt ';' { $$ = YACC_RETURN_STATEMENT($2); } 665 | | GOTO identifier ';' { $$ = YACC_GOTO_STATEMENT($2); } 666 | declaration_statement: block_declaration { $$ = YACC_DECLARATION_STATEMENT($1); } 667 | 668 | /*--------------------------------------------------------------------------------------------------- 669 | * A.6 Declarations 670 | *---------------------------------------------------------------------------------------------------*/ 671 | compound_declaration: '{' nest declaration_seq.opt '}' { $$ = $3; unnest($2); } 672 | | '{' nest declaration_seq.opt util looping_declaration '#' bang error '}' 673 | { $$ = $3; unnest($2); YACC_UNBANG($7, "Bad declaration-seq."); } 674 | declaration_seq.opt: /* empty */ { $$ = YACC_DECLARATIONS(0, 0); } 675 | | declaration_seq.opt util looping_declaration { $$ = YACC_DECLARATIONS($1, YACC_COMPILE_DECLARATION($2, $3)); } 676 | | declaration_seq.opt util looping_declaration '#' bang error ';' { $$ = $1; YACC_UNBANG($5, "Bad declaration."); } 677 | looping_declaration: start_search1 looped_declaration { $$ = YACC_LINED_DECLARATION($2, $1); end_search($$); } 678 | looped_declaration: declaration 679 | | advance_search '+' looped_declaration { $$ = $3; } 680 | | advance_search '-' { $$ = 0; } 681 | declaration: block_declaration 682 | | function_definition { $$ = YACC_SIMPLE_DECLARATION($1); } 683 | | template_declaration 684 | /* | explicit_instantiation -- covered by relevant declarations */ 685 | | explicit_specialization 686 | | specialised_declaration 687 | specialised_declaration: linkage_specification { $$ = YACC_LINKAGE_SPECIFICATION($1); } 688 | | namespace_definition { $$ = YACC_NAMESPACE_DECLARATION($1); } 689 | | TEMPLATE specialised_declaration { $$ = YACC_SET_TEMPLATE_DECLARATION($2); } 690 | block_declaration: simple_declaration { $$ = YACC_SIMPLE_DECLARATION($1); } 691 | | specialised_block_declaration 692 | specialised_block_declaration: asm_definition 693 | | namespace_alias_definition 694 | | using_declaration 695 | | using_directive 696 | | TEMPLATE specialised_block_declaration { $$ = YACC_SET_TEMPLATE_DECLARATION($2); } 697 | simple_declaration: ';' { $$ = YACC_EXPRESSION(0); } 698 | | init_declaration ';' 699 | | init_declarations ';' { $$ = $1; } 700 | | decl_specifier_prefix simple_declaration { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); } 701 | 702 | /* A decl-specifier following a ptr_operator provokes a shift-reduce conflict for 703 | * * const name 704 | * which is resolved in favour of the pointer, and implemented by providing versions 705 | * of decl-specifier guaranteed not to start with a cv_qualifier. 706 | * 707 | * decl-specifiers are implemented type-centrically. That is the semantic constraint 708 | * that there must be a type is exploited to impose structure, but actually eliminate 709 | * very little syntax. built-in types are multi-name and so need a different policy. 710 | * 711 | * non-type decl-specifiers are bound to the left-most type in a decl-specifier-seq, 712 | * by parsing from the right and attaching suffixes to the right-hand type. Finally 713 | * residual prefixes attach to the left. 714 | */ 715 | suffix_built_in_decl_specifier.raw: built_in_type_specifier { $$ = $1; } 716 | | suffix_built_in_decl_specifier.raw built_in_type_specifier { $$ = YACC_BUILT_IN_NAME($1, $2); } 717 | | suffix_built_in_decl_specifier.raw decl_specifier_suffix { $$ = YACC_DECL_SPECIFIER_NAME($1, $2); } 718 | suffix_built_in_decl_specifier: suffix_built_in_decl_specifier.raw { $$ = $1; } 719 | | TEMPLATE suffix_built_in_decl_specifier { $$ = YACC_SET_TEMPLATE_NAME($2); } 720 | suffix_named_decl_specifier: scoped_id { $$ = $1; } 721 | | elaborate_type_specifier { $$ = $1; } 722 | | suffix_named_decl_specifier decl_specifier_suffix { $$ = YACC_DECL_SPECIFIER_NAME($1, $2); } 723 | suffix_named_decl_specifier.bi: suffix_named_decl_specifier { $$ = YACC_NAME_EXPRESSION($1); } 724 | | suffix_named_decl_specifier suffix_built_in_decl_specifier.raw { $$ = YACC_TYPED_NAME($1, $2); } 725 | suffix_named_decl_specifiers: suffix_named_decl_specifier.bi 726 | | suffix_named_decl_specifiers suffix_named_decl_specifier.bi { $$ = YACC_TYPED_NAME($1, $2); } 727 | suffix_named_decl_specifiers.sf: scoped_special_function_id /* operators etc */ { $$ = YACC_NAME_EXPRESSION($1); } 728 | | suffix_named_decl_specifiers 729 | | suffix_named_decl_specifiers scoped_special_function_id { $$ = YACC_TYPED_NAME($1, $2); } 730 | suffix_decl_specified_ids: suffix_built_in_decl_specifier 731 | | suffix_built_in_decl_specifier suffix_named_decl_specifiers.sf { $$ = YACC_TYPED_NAME($1, $2); } 732 | | suffix_named_decl_specifiers.sf 733 | suffix_decl_specified_scope: suffix_named_decl_specifiers SCOPE 734 | | suffix_built_in_decl_specifier suffix_named_decl_specifiers SCOPE { $$ = YACC_TYPED_NAME($1, $2); } 735 | | suffix_built_in_decl_specifier SCOPE { $$ = YACC_NAME_EXPRESSION($1); } 736 | 737 | decl_specifier_affix: storage_class_specifier 738 | | function_specifier 739 | | FRIEND 740 | | TYPEDEF 741 | | cv_qualifier { $$ = $1; } 742 | 743 | decl_specifier_suffix: decl_specifier_affix 744 | 745 | decl_specifier_prefix: decl_specifier_affix 746 | | TEMPLATE decl_specifier_prefix { $$ = YACC_SET_TEMPLATE_DECL_SPECIFIER($2); } 747 | 748 | storage_class_specifier: REGISTER | STATIC | MUTABLE 749 | | EXTERN %prec SHIFT_THERE /* Prefer linkage specification */ 750 | | AUTO 751 | 752 | function_specifier: EXPLICIT 753 | | INLINE 754 | | VIRTUAL 755 | 756 | type_specifier: simple_type_specifier 757 | | elaborate_type_specifier 758 | | cv_qualifier { $$ = YACC_CV_DECL_SPECIFIER($1); } 759 | 760 | elaborate_type_specifier: class_specifier 761 | | enum_specifier 762 | | elaborated_type_specifier 763 | | TEMPLATE elaborate_type_specifier { $$ = YACC_SET_TEMPLATE_ID($2); } 764 | simple_type_specifier: scoped_id 765 | | built_in_type_specifier { $$ = YACC_BUILT_IN_ID_ID($1); } 766 | built_in_type_specifier: CHAR | WCHAR_T | BOOL | SHORT | INT | LONG | SIGNED | UNSIGNED | FLOAT | DOUBLE | VOID 767 | 768 | /* 769 | * The over-general use of declaration_expression to cover decl-specifier-seq.opt declarator in a function-definition means that 770 | * class X {}; 771 | * could be a function-definition or a class-specifier. 772 | * enum X {}; 773 | * could be a function-definition or an enum-specifier. 774 | * The function-definition is not syntactically valid so resolving the false conflict in favour of the 775 | * elaborated_type_specifier is correct. 776 | */ 777 | elaborated_type_specifier: elaborated_class_specifier 778 | | elaborated_enum_specifier 779 | | TYPENAME scoped_id { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); } 780 | 781 | elaborated_enum_specifier: ENUM scoped_id %prec SHIFT_THERE { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); } 782 | enum_specifier: ENUM scoped_id enumerator_clause { $$ = YACC_ENUM_SPECIFIER_ID($2, $3); } 783 | | ENUM enumerator_clause { $$ = YACC_ENUM_SPECIFIER_ID(0, $2); } 784 | enumerator_clause: '{' enumerator_list_ecarb { $$ = YACC_ENUMERATORS(0, 0); } 785 | | '{' enumerator_list enumerator_list_ecarb { $$ = $2; } 786 | | '{' enumerator_list ',' enumerator_definition_ecarb { $$ = $2; } 787 | enumerator_list_ecarb: '}' { } 788 | | bang error '}' { YACC_UNBANG($1, "Bad enumerator-list."); } 789 | enumerator_definition_ecarb: '}' { } 790 | | bang error '}' { YACC_UNBANG($1, "Bad enumerator-definition."); } 791 | enumerator_definition_filler: /* empty */ 792 | | bang error ',' { YACC_UNBANG($1, "Bad enumerator-definition."); } 793 | enumerator_list_head: enumerator_definition_filler { $$ = YACC_ENUMERATORS(0, 0); } 794 | | enumerator_list ',' enumerator_definition_filler 795 | enumerator_list: enumerator_list_head enumerator_definition { $$ = YACC_ENUMERATORS($1, $2); } 796 | enumerator_definition: enumerator { $$ = YACC_ENUMERATOR($1, 0); } 797 | | enumerator '=' constant_expression { $$ = YACC_ENUMERATOR($1, $3); } 798 | enumerator: identifier 799 | 800 | namespace_definition: NAMESPACE scoped_id compound_declaration { $$ = YACC_NAMESPACE_DEFINITION($2, $3); } 801 | | NAMESPACE compound_declaration { $$ = YACC_NAMESPACE_DEFINITION(0, $2); } 802 | namespace_alias_definition: NAMESPACE scoped_id '=' scoped_id ';' { $$ = YACC_NAMESPACE_ALIAS_DEFINITION($2, $4); } 803 | 804 | using_declaration: USING declarator_id ';' { $$ = YACC_USING_DECLARATION(false, $2); } 805 | | USING TYPENAME declarator_id ';' { $$ = YACC_USING_DECLARATION(true, $3); } 806 | 807 | using_directive: USING NAMESPACE scoped_id ';' { $$ = YACC_USING_DIRECTIVE($3); } 808 | asm_definition: ASM '(' string ')' ';' { $$ = YACC_ASM_DEFINITION($3); } 809 | linkage_specification: EXTERN string looping_declaration { $$ = YACC_LINKAGE_SPECIFIER($2, $3); } 810 | | EXTERN string compound_declaration { $$ = YACC_LINKAGE_SPECIFIER($2, $3); } 811 | 812 | /*--------------------------------------------------------------------------------------------------- 813 | * A.7 Declarators 814 | *---------------------------------------------------------------------------------------------------*/ 815 | /*init-declarator is named init_declaration to reflect the embedded decl-specifier-seq.opt*/ 816 | init_declarations: assignment_expression ',' init_declaration { $$ = YACC_EXPRESSIONS(YACC_EXPRESSIONS(0, $1), $3); } 817 | | init_declarations ',' init_declaration { $$ = YACC_EXPRESSIONS($1, $3); } 818 | init_declaration: assignment_expression 819 | /* | assignment_expression '=' initializer_clause -- covered by assignment_expression */ 820 | /* | assignment_expression '(' expression_list ')' -- covered by another set of call arguments */ 821 | 822 | /*declarator: -- covered by assignment_expression */ 823 | /*direct_declarator: -- covered by postfix_expression */ 824 | 825 | star_ptr_operator: '*' { $$ = YACC_POINTER_DECLARATOR(); } 826 | | star_ptr_operator cv_qualifier { $$ = YACC_CV_DECLARATOR($1, $2); } 827 | nested_ptr_operator: star_ptr_operator { $$ = $1; } 828 | | id_scope nested_ptr_operator { $$ = YACC_NESTED_DECLARATOR($1, $2); } 829 | ptr_operator: '&' { $$ = YACC_REFERENCE_DECLARATOR(); } 830 | | nested_ptr_operator { $$ = $1; } 831 | | global_scope nested_ptr_operator { $$ = YACC_GLOBAL_DECLARATOR($1, $2); } 832 | ptr_operator_seq: ptr_operator { $$ = YACC_POINTER_EXPRESSION($1, YACC_EPSILON()); } 833 | | ptr_operator ptr_operator_seq { $$ = YACC_POINTER_EXPRESSION($1, $2); } 834 | /* Independently coded to localise the shift-reduce conflict: sharing just needs another %prec */ 835 | ptr_operator_seq.opt: /* empty */ %prec SHIFT_THERE /* Maximise type length */ { $$ = YACC_EXPRESSION(0); } 836 | | ptr_operator ptr_operator_seq.opt { $$ = YACC_POINTER_EXPRESSION($1, $2); } 837 | 838 | cv_qualifier_seq.opt: /* empty */ { $$ = YACC_CV_QUALIFIERS(0, 0); } 839 | | cv_qualifier_seq.opt cv_qualifier { $$ = YACC_CV_QUALIFIERS($1, $2); } 840 | cv_qualifier: CONST | VOLATILE /* | CvQualifier */ 841 | 842 | /*type_id -- also covered by parameter declaration */ 843 | type_id: type_specifier abstract_declarator.opt { $$ = YACC_TYPED_EXPRESSION($1, $2); } 844 | | type_specifier type_id { $$ = YACC_TYPED_EXPRESSION($1, $2); } 845 | 846 | /*abstract_declarator: -- also covered by parameter declaration */ 847 | abstract_declarator.opt: /* empty */ { $$ = YACC_EPSILON(); } 848 | | ptr_operator abstract_declarator.opt { $$ = YACC_POINTER_EXPRESSION($1, $2); } 849 | | direct_abstract_declarator 850 | direct_abstract_declarator.opt: /* empty */ { $$ = YACC_EPSILON(); } 851 | | direct_abstract_declarator 852 | direct_abstract_declarator: direct_abstract_declarator.opt parenthesis_clause { $$ = YACC_CALL_EXPRESSION($1, $2); } 853 | | direct_abstract_declarator.opt '[' ']' { $$ = YACC_ARRAY_EXPRESSION($1, 0); } 854 | | direct_abstract_declarator.opt '[' constant_expression ']' { $$ = YACC_ARRAY_EXPRESSION($1, $3); } 855 | /* | '(' abstract_declarator ')' -- covered by parenthesis_clause */ 856 | 857 | parenthesis_clause: parameters_clause cv_qualifier_seq.opt { $$ = YACC_PARENTHESISED($1, $2, 0); } 858 | | parameters_clause cv_qualifier_seq.opt exception_specification { $$ = YACC_PARENTHESISED($1, $2, $3); } 859 | parameters_clause: '(' parameter_declaration_clause ')' { $$ = $2; } 860 | /* parameter_declaration_clause also covers init_declaration, type_id, declarator and abstract_declarator. */ 861 | parameter_declaration_clause: /* empty */ { $$ = YACC_PARAMETERS(0, 0); } 862 | | parameter_declaration_list 863 | | parameter_declaration_list ELLIPSIS { $$ = YACC_PARAMETERS($1, YACC_ELLIPSIS_EXPRESSION()); } 864 | parameter_declaration_list: parameter_declaration { $$ = YACC_PARAMETERS(0, $1); } 865 | | parameter_declaration_list ',' parameter_declaration { $$ = YACC_PARAMETERS($1, $3); } 866 | 867 | /* A typed abstract qualifier such as 868 | * Class * ... 869 | * looks like a multiply, so pointers are parsed as their binary operation equivalents that 870 | * ultimately terminate with a degenerate right hand term. 871 | */ 872 | abstract_pointer_declaration: ptr_operator_seq 873 | | multiplicative_expression star_ptr_operator ptr_operator_seq.opt { $$ = YACC_MULTIPLY_EXPRESSION($1, $2, $3); } 874 | abstract_parameter_declaration: abstract_pointer_declaration 875 | | and_expression '&' { $$ = YACC_AND_EXPRESSION($1, YACC_EPSILON()); } 876 | | and_expression '&' abstract_pointer_declaration { $$ = YACC_AND_EXPRESSION($1, $3); } 877 | special_parameter_declaration: abstract_parameter_declaration 878 | | abstract_parameter_declaration '=' assignment_expression { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); } 879 | | ELLIPSIS { $$ = YACC_ELLIPSIS_EXPRESSION(); } 880 | parameter_declaration: assignment_expression { $$ = YACC_EXPRESSION_PARAMETER($1); } 881 | | special_parameter_declaration { $$ = YACC_EXPRESSION_PARAMETER($1); } 882 | | decl_specifier_prefix parameter_declaration { $$ = YACC_DECL_SPECIFIER_PARAMETER($2, $1); } 883 | 884 | /* The grammar is repeated for use within template <> 885 | */ 886 | templated_parameter_declaration: templated_assignment_expression { $$ = YACC_EXPRESSION_PARAMETER($1); } 887 | | templated_abstract_declaration { $$ = YACC_EXPRESSION_PARAMETER($1); } 888 | | templated_abstract_declaration '=' templated_assignment_expression 889 | { $$ = YACC_EXPRESSION_PARAMETER(YACC_ASSIGNMENT_EXPRESSION($1, $2, $3)); } 890 | | decl_specifier_prefix templated_parameter_declaration { $$ = YACC_DECL_SPECIFIER_PARAMETER($2, $1); } 891 | templated_abstract_declaration: abstract_pointer_declaration 892 | | templated_and_expression '&' { $$ = YACC_AND_EXPRESSION($1, 0); } 893 | | templated_and_expression '&' abstract_pointer_declaration { $$ = YACC_AND_EXPRESSION($1, $3); } 894 | 895 | /* function_definition includes constructor, destructor, implicit int definitions too. 896 | * A local destructor is successfully parsed as a function-declaration but the ~ was treated as a unary operator. 897 | * constructor_head is the prefix ambiguity between a constructor and a member-init-list starting with a bit-field. 898 | */ 899 | function_definition: ctor_definition 900 | | func_definition 901 | func_definition: assignment_expression function_try_block { $$ = YACC_FUNCTION_DEFINITION($1, $2); } 902 | | assignment_expression function_body { $$ = YACC_FUNCTION_DEFINITION($1, $2); } 903 | | decl_specifier_prefix func_definition { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); } 904 | ctor_definition: constructor_head function_try_block { $$ = YACC_CTOR_DEFINITION($1, $2); } 905 | | constructor_head function_body { $$ = YACC_CTOR_DEFINITION($1, $2); } 906 | | decl_specifier_prefix ctor_definition { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); } 907 | constructor_head: bit_field_init_declaration { $$ = YACC_EXPRESSIONS(0, $1); } 908 | | constructor_head ',' assignment_expression { $$ = YACC_EXPRESSIONS($1, $3); } 909 | function_try_block: TRY function_block handler_seq { $$ = YACC_TRY_FUNCTION_BLOCK($2, $3); } 910 | function_block: ctor_initializer.opt function_body { $$ = YACC_CTOR_FUNCTION_BLOCK($2, $1); } 911 | function_body: compound_statement { $$ = YACC_FUNCTION_BLOCK($1); } 912 | 913 | /* An = initializer looks like an extended assignment_expression. 914 | * An () initializer looks like a function call. 915 | * initializer is therefore flattened into its generalised customers. 916 | *initializer: '=' initializer_clause -- flattened into caller 917 | * | '(' expression_list ')' -- flattened into caller */ 918 | initializer_clause: assignment_expression { $$ = YACC_INITIALIZER_EXPRESSION_CLAUSE($1); } 919 | | braced_initializer 920 | braced_initializer: '{' initializer_list '}' { $$ = YACC_INITIALIZER_LIST_CLAUSE($2); } 921 | | '{' initializer_list ',' '}' { $$ = YACC_INITIALIZER_LIST_CLAUSE($2); } 922 | | '{' '}' { $$ = YACC_INITIALIZER_LIST_CLAUSE(0); } 923 | | '{' looping_initializer_clause '#' bang error '}' { $$ = 0; YACC_UNBANG($4, "Bad initializer_clause."); } 924 | | '{' initializer_list ',' looping_initializer_clause '#' bang error '}' 925 | { $$ = $2; YACC_UNBANG($6, "Bad initializer_clause."); } 926 | initializer_list: looping_initializer_clause { $$ = YACC_INITIALIZER_CLAUSES(0, $1); } 927 | | initializer_list ',' looping_initializer_clause { $$ = YACC_INITIALIZER_CLAUSES($1, $3); } 928 | looping_initializer_clause: start_search looped_initializer_clause { $$ = $2; end_search($$); } 929 | looped_initializer_clause: initializer_clause 930 | | advance_search '+' looped_initializer_clause { $$ = $3; } 931 | | advance_search '-' { $$ = 0; } 932 | 933 | /*--------------------------------------------------------------------------------------------------- 934 | * A.8 Classes 935 | *--------------------------------------------------------------------------------------------------- 936 | * 937 | * An anonymous bit-field declaration may look very like inheritance: 938 | * class A : B = 3; 939 | * class A : B ; 940 | * The two usages are too distant to try to create and enforce a common prefix so we have to resort to 941 | * a parser hack by backtracking. Inheritance is much the most likely so we mark the input stream context 942 | * and try to parse a base-clause. If we successfully reach a { the base-clause is ok and inheritance was 943 | * the correct choice so we unmark and continue. If we fail to find the { an error token causes back-tracking 944 | * to the alternative parse in elaborated_class_specifier which regenerates the : and declares unconditional success. 945 | */ 946 | colon_mark: ':' { $$ = mark(); } 947 | elaborated_class_specifier: class_key scoped_id %prec SHIFT_THERE { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); } 948 | | class_key scoped_id colon_mark error { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); rewind_colon($3, $$); } 949 | class_specifier_head: class_key scoped_id colon_mark base_specifier_list '{' { unmark($4); $$ = YACC_CLASS_SPECIFIER_ID($1, $2, $4); } 950 | | class_key ':' base_specifier_list '{' { $$ = YACC_CLASS_SPECIFIER_ID($1, 0, $3); } 951 | | class_key scoped_id '{' { $$ = YACC_CLASS_SPECIFIER_ID($1, $2, 0); } 952 | | class_key '{' { $$ = YACC_CLASS_SPECIFIER_ID($1, 0, 0); } 953 | class_key: CLASS | STRUCT | UNION 954 | class_specifier: class_specifier_head member_specification.opt '}' { $$ = YACC_CLASS_MEMBERS($1, $2); } 955 | | class_specifier_head member_specification.opt util looping_member_declaration '#' bang error '}' 956 | { $$ = YACC_CLASS_MEMBERS($1, $2); YACC_UNBANG($6, "Bad member_specification.opt."); } 957 | member_specification.opt: /* empty */ { $$ = YACC_MEMBER_DECLARATIONS(0, 0); } 958 | | member_specification.opt util looping_member_declaration { $$ = YACC_MEMBER_DECLARATIONS($1, YACC_COMPILE_DECLARATION($2, $3)); } 959 | | member_specification.opt util looping_member_declaration '#' bang error ';' 960 | { $$ = $1; YACC_UNBANG($5, "Bad member-declaration."); } 961 | looping_member_declaration: start_search looped_member_declaration { $$ = YACC_LINED_DECLARATION($2, $1); end_search($$); } 962 | looped_member_declaration: member_declaration 963 | | advance_search '+' looped_member_declaration { $$ = $3; } 964 | | advance_search '-' { $$ = 0; } 965 | member_declaration: accessibility_specifier 966 | | simple_member_declaration { $$ = YACC_SIMPLE_DECLARATION($1); } 967 | | function_definition { $$ = YACC_SIMPLE_DECLARATION($1); } 968 | /* | function_definition ';' -- trailing ; covered by null declaration */ 969 | /* | qualified_id ';' -- covered by simple_member_declaration */ 970 | | using_declaration 971 | | template_declaration 972 | 973 | /* The generality of constructor names (there need be no parenthesised argument list) means that that 974 | * name : f(g), h(i) 975 | * could be the start of a constructor or the start of an anonymous bit-field. An ambiguity is avoided by 976 | * parsing the ctor-initializer of a function_definition as a bit-field. 977 | */ 978 | simple_member_declaration: ';' { $$ = YACC_EXPRESSION(0); } 979 | | assignment_expression ';' 980 | | constructor_head ';' { $$ = $1; } 981 | | member_init_declarations ';' { $$ = $1; } 982 | | decl_specifier_prefix simple_member_declaration { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); } 983 | member_init_declarations: assignment_expression ',' member_init_declaration { $$ = YACC_EXPRESSIONS(YACC_EXPRESSIONS(0, $1), $3); } 984 | | constructor_head ',' bit_field_init_declaration { $$ = YACC_EXPRESSIONS($1, $3); } 985 | | member_init_declarations ',' member_init_declaration { $$ = YACC_EXPRESSIONS($1, $3); } 986 | member_init_declaration: assignment_expression 987 | /* | assignment_expression '=' initializer_clause -- covered by assignment_expression */ 988 | /* | assignment_expression '(' expression_list ')' -- covered by another set of call arguments */ 989 | | bit_field_init_declaration 990 | accessibility_specifier: access_specifier ':' { $$ = YACC_ACCESSIBILITY_SPECIFIER($1); } 991 | bit_field_declaration: assignment_expression ':' bit_field_width { $$ = YACC_BIT_FIELD_EXPRESSION($1, $3); } 992 | | ':' bit_field_width { $$ = YACC_BIT_FIELD_EXPRESSION(0, $2); } 993 | bit_field_width: logical_or_expression 994 | /* | logical_or_expression '?' expression ':' assignment_expression -- has SR conflict w.r.t later = */ 995 | | logical_or_expression '?' bit_field_width ':' bit_field_width { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); } 996 | bit_field_init_declaration: bit_field_declaration 997 | | bit_field_declaration '=' initializer_clause { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); } 998 | 999 | /*--------------------------------------------------------------------------------------------------- 1000 | * A.9 Derived classes 1001 | *---------------------------------------------------------------------------------------------------*/ 1002 | /*base_clause: ':' base_specifier_list -- flattened */ 1003 | base_specifier_list: base_specifier { $$ = YACC_BASE_SPECIFIERS(0, $1); } 1004 | | base_specifier_list ',' base_specifier { $$ = YACC_BASE_SPECIFIERS($1, $3); } 1005 | base_specifier: scoped_id { $$ = YACC_BASE_SPECIFIER($1); } 1006 | | access_specifier base_specifier { $$ = YACC_ACCESS_BASE_SPECIFIER($2, $1); } 1007 | | VIRTUAL base_specifier { $$ = YACC_VIRTUAL_BASE_SPECIFIER($2); } 1008 | access_specifier: PRIVATE | PROTECTED | PUBLIC 1009 | 1010 | /*--------------------------------------------------------------------------------------------------- 1011 | * A.10 Special member functions 1012 | *---------------------------------------------------------------------------------------------------*/ 1013 | conversion_function_id: OPERATOR conversion_type_id { $$ = YACC_CONVERSION_FUNCTION_ID($2); } 1014 | conversion_type_id: type_specifier ptr_operator_seq.opt { $$ = YACC_TYPED_EXPRESSION($1, $2); } 1015 | | type_specifier conversion_type_id { $$ = YACC_TYPED_EXPRESSION($1, $2); } 1016 | /* 1017 | * Ctor-initialisers can look like a bit field declaration, given the generalisation of names: 1018 | * Class(Type) : m1(1), m2(2) {} 1019 | * NonClass(bit_field) : int(2), second_variable, ... 1020 | * The grammar below is used within a function_try_block or function_definition. 1021 | * See simple_member_declaration for use in normal member function_definition. 1022 | */ 1023 | ctor_initializer.opt: /* empty */ { $$ = YACC_MEM_INITIALIZERS(0, 0); } 1024 | | ctor_initializer 1025 | ctor_initializer: ':' mem_initializer_list { $$ = $2; } 1026 | | ':' mem_initializer_list bang error { $$ = $2; YACC_UNBANG($3, "Bad ctor-initializer."); } 1027 | mem_initializer_list: mem_initializer { $$ = YACC_MEM_INITIALIZERS(0, $1); } 1028 | | mem_initializer_list_head mem_initializer { $$ = YACC_MEM_INITIALIZERS($1, $2); } 1029 | mem_initializer_list_head: mem_initializer_list ',' 1030 | | mem_initializer_list bang error ',' { YACC_UNBANG($2, "Bad mem-initializer."); } 1031 | mem_initializer: mem_initializer_id '(' expression_list.opt ')' { $$ = YACC_MEM_INITIALIZER($1, $3); } 1032 | mem_initializer_id: scoped_id 1033 | 1034 | /*--------------------------------------------------------------------------------------------------- 1035 | * A.11 Overloading 1036 | *---------------------------------------------------------------------------------------------------*/ 1037 | operator_function_id: OPERATOR operator { $$ = YACC_OPERATOR_FUNCTION_ID($2); } 1038 | /* 1039 | * It is not clear from the ANSI standard whether spaces are permitted in delete[]. If not then it can 1040 | * be recognised and returned as DELETE_ARRAY by the lexer. Assuming spaces are permitted there is an 1041 | * ambiguity created by the over generalised nature of expressions. operator new is a valid delarator-id 1042 | * which we may have an undimensioned array of. Semantic rubbish, but syntactically valid. Since the 1043 | * array form is covered by the declarator consideration we can exclude the operator here. The need 1044 | * for a semantic rescue can be eliminated at the expense of a couple of shift-reduce conflicts by 1045 | * removing the comments on the next four lines. 1046 | */ 1047 | operator: /*++++*/ NEW { $$ = YACC_OPERATOR_NEW_ID(); } 1048 | | /*++++*/ DELETE { $$ = YACC_OPERATOR_DELETE_ID(); } 1049 | /* | / ---- / NEW %prec SHIFT_THERE { $$ = YACC_OPERATOR_NEW_ID(); } 1050 | /* | / ---- / DELETE %prec SHIFT_THERE { $$ = YACC_OPERATOR_DELETE_ID(); } 1051 | /* | / ---- / NEW '[' ']' -- Covered by array of OPERATOR NEW */ 1052 | /* | / ---- / DELETE '[' ']' -- Covered by array of OPERATOR DELETE */ 1053 | | '+' { $$ = YACC_OPERATOR_ADD_ID(); } 1054 | | '-' { $$ = YACC_OPERATOR_SUB_ID(); } 1055 | | '*' { $$ = YACC_OPERATOR_MUL_ID(); } 1056 | | '/' { $$ = YACC_OPERATOR_DIV_ID(); } 1057 | | '%' { $$ = YACC_OPERATOR_MOD_ID(); } 1058 | | '^' { $$ = YACC_OPERATOR_XOR_ID(); } 1059 | | '&' { $$ = YACC_OPERATOR_BIT_AND_ID(); } 1060 | | '|' { $$ = YACC_OPERATOR_BIT_OR_ID(); } 1061 | | '~' { $$ = YACC_OPERATOR_BIT_NOT_ID(); } 1062 | | '!' { $$ = YACC_OPERATOR_LOG_NOT_ID(); } 1063 | | '=' { $$ = YACC_OPERATOR_ASS_ID(); } 1064 | | '<' { $$ = YACC_OPERATOR_LT_ID(); } 1065 | | '>' { $$ = YACC_OPERATOR_GT_ID(); } 1066 | | ASS_ADD { $$ = YACC_OPERATOR_ASS_ADD_ID(); } 1067 | | ASS_SUB { $$ = YACC_OPERATOR_ASS_SUB_ID(); } 1068 | | ASS_MUL { $$ = YACC_OPERATOR_ASS_MUL_ID(); } 1069 | | ASS_DIV { $$ = YACC_OPERATOR_ASS_DIV_ID(); } 1070 | | ASS_MOD { $$ = YACC_OPERATOR_ASS_MOD_ID(); } 1071 | | ASS_XOR { $$ = YACC_OPERATOR_ASS_XOR_ID(); } 1072 | | ASS_AND { $$ = YACC_OPERATOR_ASS_BIT_AND_ID(); } 1073 | | ASS_OR { $$ = YACC_OPERATOR_ASS_BIT_OR_ID(); } 1074 | | SHL { $$ = YACC_OPERATOR_SHL_ID(); } 1075 | | SHR { $$ = YACC_OPERATOR_SHR_ID(); } 1076 | | ASS_SHR { $$ = YACC_OPERATOR_ASS_SHR_ID(); } 1077 | | ASS_SHL { $$ = YACC_OPERATOR_ASS_SHL_ID(); } 1078 | | EQ { $$ = YACC_OPERATOR_EQ_ID(); } 1079 | | NE { $$ = YACC_OPERATOR_NE_ID(); } 1080 | | LE { $$ = YACC_OPERATOR_LE_ID(); } 1081 | | GE { $$ = YACC_OPERATOR_GE_ID(); } 1082 | | LOG_AND { $$ = YACC_OPERATOR_LOG_AND_ID(); } 1083 | | LOG_OR { $$ = YACC_OPERATOR_LOG_OR_ID(); } 1084 | | INC { $$ = YACC_OPERATOR_INC_ID(); } 1085 | | DEC { $$ = YACC_OPERATOR_DEC_ID(); } 1086 | | ',' { $$ = YACC_OPERATOR_COMMA_ID(); } 1087 | | ARROW_STAR { $$ = YACC_OPERATOR_ARROW_STAR_ID(); } 1088 | | ARROW { $$ = YACC_OPERATOR_ARROW_ID(); } 1089 | | '(' ')' { $$ = YACC_OPERATOR_CALL_ID(); } 1090 | | '[' ']' { $$ = YACC_OPERATOR_INDEX_ID(); } 1091 | 1092 | /*--------------------------------------------------------------------------------------------------- 1093 | * A.12 Templates 1094 | *---------------------------------------------------------------------------------------------------*/ 1095 | template_declaration: template_parameter_clause declaration { $$ = YACC_TEMPLATE_DECLARATION($1, $2); } 1096 | | EXPORT template_declaration { $$ = YACC_DECL_SPECIFIER_DECLARATION($2, $1); } 1097 | template_parameter_clause: TEMPLATE '<' template_parameter_list '>' { $$ = $3; } 1098 | template_parameter_list: template_parameter { $$ = YACC_TEMPLATE_PARAMETERS(0, $1); } 1099 | | template_parameter_list ',' template_parameter { $$ = YACC_TEMPLATE_PARAMETERS($1, $3); } 1100 | template_parameter: simple_type_parameter { $$ = YACC_INIT_SIMPLE_TYPE_PARAMETER($1, 0); } 1101 | | simple_type_parameter '=' type_id { $$ = YACC_INIT_SIMPLE_TYPE_PARAMETER($1, $3); } 1102 | | templated_type_parameter { $$ = YACC_INIT_TEMPLATED_PARAMETER($1, 0); } 1103 | | templated_type_parameter '=' identifier { $$ = YACC_INIT_TEMPLATED_PARAMETER($1, $3); } 1104 | | templated_parameter_declaration { $$ = YACC_TEMPLATE_PARAMETER($1); } 1105 | | bang error { $$ = 0; YACC_UNBANG($1, "Bad template-parameter."); } 1106 | simple_type_parameter: CLASS { $$ = YACC_CLASS_TYPE_PARAMETER(0); } 1107 | /* | CLASS identifier -- covered by parameter_declaration */ 1108 | | TYPENAME { $$ = YACC_TYPENAME_TYPE_PARAMETER(0); } 1109 | /* | TYPENAME identifier -- covered by parameter_declaration */ 1110 | templated_type_parameter: template_parameter_clause CLASS { $$ = YACC_TEMPLATED_TYPE_PARAMETER($1, 0); } 1111 | | template_parameter_clause CLASS identifier { $$ = YACC_TEMPLATED_TYPE_PARAMETER($1, $3); } 1112 | template_id: TEMPLATE identifier '<' template_argument_list '>' { $$ = YACC_TEMPLATE_NAME($2, $4); } 1113 | | TEMPLATE template_id { $$ = $2; } 1114 | /* 1115 | * template-argument is evaluated using a templated...expression so that > resolves to end of template. 1116 | */ 1117 | template_argument_list: template_argument { $$ = YACC_TEMPLATE_ARGUMENTS(0, $1); } 1118 | | template_argument_list ',' template_argument { $$ = YACC_TEMPLATE_ARGUMENTS($1, $3); } 1119 | template_argument: templated_parameter_declaration { $$ = YACC_TEMPLATE_ARGUMENT($1); } 1120 | /* | type_id -- covered by templated_parameter_declaration */ 1121 | /* | template_name -- covered by templated_parameter_declaration */ 1122 | /* | error -- must allow template failure to re-search */ 1123 | 1124 | /* 1125 | * Generalised naming makes identifier a valid declaration, so TEMPLATE identifier is too. 1126 | * The TEMPLATE prefix is therefore folded into all names, parenthesis_clause and decl_specifier_prefix. 1127 | */ 1128 | /*explicit_instantiation: TEMPLATE declaration */ 1129 | explicit_specialization: TEMPLATE '<' '>' declaration { $$ = YACC_EXPLICIT_SPECIALIZATION($4); } 1130 | 1131 | /*--------------------------------------------------------------------------------------------------- 1132 | * A.13 Exception Handling 1133 | *---------------------------------------------------------------------------------------------------*/ 1134 | try_block: TRY compound_statement handler_seq { $$ = YACC_TRY_BLOCK($2, $3); } 1135 | /*function_try_block: -- moved near function_block */ 1136 | handler_seq: handler { $$ = YACC_HANDLERS(0, $1); } 1137 | | handler handler_seq { $$ = YACC_HANDLERS($2, $1); } 1138 | handler: CATCH '(' exception_declaration ')' compound_statement { $$ = YACC_HANDLER($3, $5); } 1139 | exception_declaration: parameter_declaration { $$ = YACC_EXCEPTION_DECLARATION($1); } 1140 | /* ELLIPSIS -- covered by parameter_declaration */ 1141 | throw_expression: THROW { $$ = YACC_THROW_EXPRESSION(0); } 1142 | | THROW assignment_expression { $$ = YACC_THROW_EXPRESSION($2); } 1143 | templated_throw_expression: THROW { $$ = YACC_THROW_EXPRESSION(0); } 1144 | | THROW templated_assignment_expression { $$ = YACC_THROW_EXPRESSION($2); } 1145 | exception_specification: THROW '(' ')' { $$ = YACC_EXCEPTION_SPECIFICATION(0); } 1146 | | THROW '(' type_id_list ')' { $$ = YACC_EXCEPTION_SPECIFICATION($3); } 1147 | type_id_list: type_id { $$ = YACC_EXPRESSIONS(0, $1); } 1148 | | type_id_list ',' type_id { $$ = YACC_EXPRESSIONS($1, $3); } 1149 | 1150 | /*--------------------------------------------------------------------------------------------------- 1151 | * Back-tracking and context support 1152 | *---------------------------------------------------------------------------------------------------*/ 1153 | advance_search: error { yyerrok; advance_search(); } /* Rewind and queue '+' or '-' '#' */ 1154 | bang: /* empty */ { $$ = YACC_BANG(); } /* set flag to suppress "parse error" */ 1155 | mark: /* empty */ { $$ = mark(); } /* Push lookahead and input token stream context onto a stack */ 1156 | nest: /* empty */ { $$ = nest(); } /* Push a declaration nesting depth onto the parse stack */ 1157 | start_search: /* empty */ { $$ = YACC_LINE(); start_search(false); } /* Create/reset binary search context */ 1158 | start_search1: /* empty */ { $$ = YACC_LINE(); start_search(true); } /* Create/reset binary search context */ 1159 | util: /* empty */ { $$ = YACC_UTILITY_MODE(); } /* Get current utility mode */ 1160 | /*StartTester*/ 1161 | %% 1162 | 1163 | #include 1164 | /*EndTester*/ 1165 | -------------------------------------------------------------------------------- /CxxParsing.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //#include 4 | //#include "CxxParsing.hxx" 5 | 6 | extern CxxToken *yylex_token(); 7 | extern int yyparse(); 8 | extern int yychar; 9 | #ifdef BISON_PP_CLASS 10 | BISON_PP_CLASS theParser; 11 | #define PARSE_DOT theParser . 12 | #define PARSE_SCOPE BISON_PP_CLASS :: 13 | #else 14 | #define PARSE_DOT 15 | #define PARSE_SCOPE 16 | extern int yydebug; 17 | #ifndef YYEMPTY 18 | #define YYEMPTY -1 19 | #endif 20 | #endif 21 | 22 | class CxxSearchContext 23 | { 24 | friend class ios; // Suppress GNU error message for no public constructors. 25 | CxxSearchContext *_next; 26 | size_t _index; 27 | size_t _depth; 28 | size_t _size; 29 | size_t _mark; 30 | bool _enable_type1; 31 | size_t _line; 32 | size_t _advances; 33 | bool _status[32]; 34 | private: 35 | CxxSearchContext(CxxSearchContext *nextSearch) 36 | : _next(nextSearch), _index(0), _depth(0), _size(sizeof(_status)/sizeof(_status[0])), 37 | _mark(0), _enable_type1(false), _line(0), _advances(0) {} 38 | CxxSearchContext(const CxxSearchContext&); 39 | CxxSearchContext& operator=(const CxxSearchContext&); 40 | bool did_search() const { return _depth > 0 ? true : false; } 41 | void initialise(size_t markIndex, bool enableType1); 42 | CxxSearchContext *queue(CxxSearchContext *& listHead); 43 | void reset(); 44 | public: 45 | bool advance(); 46 | bool enable_type1() const { return _enable_type1; } 47 | bool is_template(); 48 | size_t mark() const { return _mark; } 49 | private: 50 | static CxxSearchContext *_current; 51 | static CxxSearchContext *_free; 52 | public: 53 | static size_t actual_searches; 54 | static size_t advances[16]; 55 | static size_t max_search_depth; 56 | static size_t nested_searches; 57 | static size_t releases; 58 | static size_t search_advances; 59 | static size_t unnested_searches; 60 | public: 61 | static CxxSearchContext *current() { return _current; } 62 | static void release(); 63 | static void start(YACC_MARK_TYPE anIndex, bool enableType1); 64 | }; 65 | 66 | size_t bang_depth = 0; 67 | size_t error_count = 0; 68 | size_t marked_error_count = 0; 69 | bool in_type1 = false; 70 | bool show_marked = false; 71 | using namespace std; 72 | int yydebug = 1; 73 | extern FILE * yyin; 74 | int main(int argc, char *argv[]) 75 | { 76 | for (--argc, ++argv; argc-- > 0; ++argv) 77 | { 78 | char *p = *argv; 79 | if (*p == '-') 80 | { 81 | switch (*(p+1)) 82 | { 83 | case 'c': 84 | c_keywords = true; 85 | break; 86 | case 't': 87 | echo_line_text = true; 88 | break; 89 | case 'm': 90 | show_marked = true; 91 | break; 92 | case 'n': 93 | echo_line_numbers = true; 94 | break; 95 | case 'y': 96 | PARSE_DOT yydebug = true; 97 | break; 98 | } 99 | } 100 | else 101 | { 102 | yyin = fopen(p ,"r"); 103 | } 104 | } 105 | if (PARSE_DOT yyparse() != 0) 106 | ERRMSG("Failed to parse to end of file,"); 107 | cout << "error_count = " << error_count 108 | << "\n marked_error_count = " << marked_error_count 109 | << "\n lines = " << line_number 110 | << "\n unnested_searches = " << CxxSearchContext::unnested_searches 111 | << "\n nested_searches = " << CxxSearchContext::nested_searches 112 | << "\n releases = " << CxxSearchContext::releases 113 | << "\n actual_searches = " << CxxSearchContext::actual_searches 114 | << "\n max_search_depth = " << CxxSearchContext::max_search_depth 115 | << "\n search_advances = " << CxxSearchContext::search_advances << endl; 116 | cout << "\n number of occurences of each advance"; 117 | for (size_t i = 0; i < sizeof(CxxSearchContext::advances)/sizeof(CxxSearchContext::advances[0]); i++) 118 | cout << ' ' << CxxSearchContext::advances[i]; 119 | cout << endl; 120 | return 0; 121 | } 122 | 123 | static CxxToken **tokenBuffer = 0; // Allocated buffer 124 | static YACC_MARK_TYPE tokenReadIndex = 0; // Read index 125 | static size_t tokenSize = 0; // Allocate buffer size 126 | static YACC_MARK_TYPE tokenWriteIndex = 0; // Write index 127 | int tokenMarkDepth = 0; // Write index 128 | static CxxToken *primed_tokens[3] = {0, 0}; // Restarting sequence 129 | static void token_put(CxxToken *aToken); 130 | 131 | CxxSearchContext *CxxSearchContext::_current = 0; 132 | CxxSearchContext *CxxSearchContext::_free = 0; 133 | size_t CxxSearchContext::actual_searches = 0; 134 | size_t CxxSearchContext::advances[16] = { 0 }; 135 | size_t CxxSearchContext::max_search_depth = 0; 136 | size_t CxxSearchContext::nested_searches = 0; 137 | size_t CxxSearchContext::releases = 0; 138 | size_t CxxSearchContext::search_advances; 139 | size_t CxxSearchContext::unnested_searches; 140 | 141 | // 142 | // Implements a binary search counter, performing the increment at the 143 | // _index of othe failed search. 144 | // 145 | bool CxxSearchContext::advance() 146 | { 147 | _advances++; 148 | size_t i = _depth; 149 | if (i <= 0) 150 | return false; 151 | while (--i > _index) 152 | _status[i] = false; 153 | while (true) 154 | { 155 | if (!_status[i]) 156 | { 157 | _status[i] = true; 158 | _index = 0; 159 | return true; 160 | } 161 | if (i <= 0) 162 | return false; 163 | _status[i--] = false; 164 | } 165 | } 166 | 167 | void CxxSearchContext::initialise(size_t markIndex, bool enableType1) 168 | { 169 | _index = 0; 170 | _depth = 0; 171 | _mark = markIndex; 172 | _enable_type1 = enableType1; 173 | _line = line_number; 174 | _advances = 0; 175 | } 176 | 177 | bool CxxSearchContext::is_template() 178 | { 179 | if (_index >= _depth) 180 | { 181 | if (_depth >= _size) 182 | { 183 | ERRMSG("Binary search depth exceeded."); 184 | return false; 185 | } 186 | _status[_depth++] = false; 187 | if (_depth > max_search_depth) 188 | max_search_depth = _depth; 189 | } 190 | return _status[_index++] ? false : true; 191 | } 192 | 193 | // 194 | // Put this element onto listHead, returning element under this one. 195 | // 196 | CxxSearchContext *CxxSearchContext::queue(CxxSearchContext *& listHead) 197 | { 198 | CxxSearchContext *oldNext = _next; 199 | _next = listHead; 200 | listHead = this; 201 | return oldNext; 202 | } 203 | 204 | // 205 | // Release the current search buffer. 206 | // 207 | void CxxSearchContext::release() 208 | { 209 | if (_current) 210 | { 211 | releases++; 212 | _current->reset(); 213 | _current = _current->queue(_free); 214 | } 215 | } 216 | 217 | void CxxSearchContext::reset() 218 | { 219 | if (did_search()) 220 | { 221 | _advances++; 222 | actual_searches++; 223 | } 224 | if (_advances >= sizeof(advances)/sizeof(advances[0])) 225 | advances[sizeof(advances)/sizeof(advances[0])-1]++; 226 | else 227 | advances[_advances]++; 228 | } 229 | 230 | void CxxSearchContext::start(YACC_MARK_TYPE anIndex, bool enableType1) 231 | { 232 | if (!_current) 233 | unnested_searches++; 234 | else 235 | nested_searches++; 236 | if (!_free) 237 | _current = new CxxSearchContext(_current); 238 | else 239 | _free = _free->queue(_current); 240 | _current->initialise(anIndex, enableType1); 241 | } 242 | 243 | static CxxToken angleToken('<'); 244 | static CxxToken colonToken(':'); 245 | static CxxToken hashToken('#'); 246 | static CxxToken plusToken('+'); 247 | static CxxToken minusToken('-'); 248 | 249 | void PARSE_SCOPE yyerror(const char *s) 250 | { 251 | if (!bang_depth && (tokenMarkDepth == 0)) 252 | { 253 | cout << s << endl; 254 | increment_error_count(); 255 | } 256 | else 257 | { 258 | if (show_marked) 259 | cout << "Marked " << s << endl; 260 | marked_error_count++; 261 | } 262 | } 263 | 264 | extern YYSTYPE yylval; 265 | // 266 | // Get the next token for the parser, invoking yylex_token to get the next token from the lexer. 267 | // This routine gets renamed to buffered_yylex by a #define when using yacc so that the two purposes 268 | // above are split allowing lookahead buffering and primimimg to occur. 269 | // 270 | int PARSE_SCOPE yylex() 271 | { 272 | CxxToken *aToken = primed_tokens[0]; 273 | if (aToken) 274 | { 275 | primed_tokens[0] = primed_tokens[1]; 276 | primed_tokens[1] = primed_tokens[2]; 277 | primed_tokens[2] = 0; 278 | } 279 | else if (tokenReadIndex < tokenWriteIndex) 280 | aToken = tokenBuffer[tokenReadIndex++]; 281 | else 282 | { 283 | aToken = yylex_token(); 284 | if (!aToken) 285 | return 0; 286 | if (tokenMarkDepth > 0) 287 | token_put(aToken); 288 | else 289 | { 290 | tokenWriteIndex = 0; 291 | tokenReadIndex = 0; 292 | } 293 | } 294 | yylval.token = aToken; 295 | return aToken->value(); 296 | } 297 | 298 | // 299 | // Advance the binary search of template attempts. Rewinds and forces true into the input sequence 300 | // to proceed with the search. Rewinds and forces false to terminate it. Also forces a # that may then 301 | // be used to initiate error propagation. 302 | // 303 | void advance_search() 304 | { 305 | CxxSearchContext::search_advances++; 306 | remark(CxxSearchContext::current()->mark()); 307 | if (CxxSearchContext::current() && CxxSearchContext::current()->advance()) 308 | { 309 | primed_tokens[0] = &plusToken; 310 | primed_tokens[1] = 0; 311 | } 312 | else 313 | { 314 | primed_tokens[0] = &minusToken; 315 | primed_tokens[1] = &hashToken; 316 | } 317 | } 318 | 319 | // 320 | // Complete a search, releasing the search context object and popping a mark off the stack. 321 | // 322 | void end_search(CxxToken *aToken) 323 | { 324 | CxxSearchContext::release(); 325 | unmark(aToken); 326 | } 327 | 328 | // 329 | // Notch up an error and establish a good break point. 330 | // 331 | void increment_error_count() 332 | { 333 | error_count++; 334 | } 335 | 336 | // 337 | // Push a new marked context onto the stack, returning its identity for use by remark(). 338 | // Any parser readahead is incorporated within the marked region. 339 | // 340 | YACC_MARK_TYPE mark() 341 | { 342 | if (primed_tokens[0]) 343 | ERRMSG("Unexpected primed_tokens[0] in mark."); 344 | YACC_MARK_TYPE markIndex = tokenReadIndex; 345 | if (PARSE_DOT yychar != YYEMPTY) 346 | { 347 | // if (primed_tokens[2]) 348 | // token_put(primed_tokens[2]); 349 | // if (primed_tokens[1]) 350 | // token_put(primed_tokens[1]); 351 | // if (primed_tokens[0]) 352 | // token_put(primed_tokens[0]); 353 | // if (!tokenMarkDepth) 354 | if (!tokenReadIndex && !tokenWriteIndex) 355 | { 356 | token_put(PARSE_DOT yylval.token); 357 | tokenReadIndex = 0; 358 | } 359 | else if (!tokenReadIndex) 360 | ERRMSG("Unexpected 0 read index in mark."); 361 | else if (tokenBuffer[--tokenReadIndex] != PARSE_DOT yylval.token) 362 | ERRMSG("Unexpected unget in mark."); 363 | markIndex = tokenReadIndex; 364 | yyclearin; 365 | primed_tokens[0] = 0; 366 | primed_tokens[1] = 0; 367 | } 368 | tokenMarkDepth++; 369 | bang_depth++; 370 | return markIndex; 371 | } 372 | 373 | // 374 | // If it is appropriate to do type I function parameter parsing perform a mark and force a rrue token 375 | // into the input stream. Otherwise just force a false token in. 376 | // 377 | YACC_MARK_TYPE mark_type1() 378 | { 379 | if (!in_type1 && CxxSearchContext::current() && CxxSearchContext::current()->enable_type1()) 380 | { 381 | YACC_MARK_TYPE markIndex = mark(); 382 | primed_tokens[0] = &plusToken; 383 | primed_tokens[1] = 0; 384 | in_type1 = true; 385 | yyclearin; 386 | return markIndex; 387 | } 388 | else 389 | { 390 | primed_tokens[0] = &minusToken; 391 | primed_tokens[1] = PARSE_DOT yychar != YYEMPTY ? PARSE_DOT yylval.token : 0; 392 | yyclearin; 393 | return 0; // Never used. 394 | } 395 | } 396 | 397 | // 398 | // Push a bang context onto the error suppression stack, returning the context for restoration by pop_bang. 399 | // 400 | void pop_bang(YACC_BANG_TYPE bangValue) 401 | { 402 | bang_depth = bangValue; 403 | } 404 | 405 | // 406 | // Push a bang context onto the error suppression stack, returning the context for restoration by pop_bang. 407 | // 408 | YACC_BANG_TYPE push_bang() 409 | { 410 | return bang_depth++; 411 | } 412 | 413 | // 414 | // Reposition the input to restart at the position returned by a mark(). 415 | // 416 | void remark(YACC_MARK_TYPE anIndex) 417 | { 418 | tokenReadIndex = anIndex; 419 | yyclearin; 420 | } 421 | 422 | // 423 | // Reposition the input to restart at the position returned by a mark(). 424 | // 425 | void remark_type1(YACC_MARK_TYPE anIndex) 426 | { 427 | remark(anIndex); 428 | in_type1 = false; 429 | } 430 | 431 | // 432 | // Rewind the input stream back to anIndex and force a : prior to resuming input. 433 | // 434 | void rewind_colon(YACC_MARK_TYPE anIndex, const CxxToken *aToken) 435 | { 436 | remark(anIndex); 437 | unmark(); 438 | primed_tokens[0] = &colonToken; 439 | primed_tokens[1] = PARSE_DOT yylval.token; 440 | } 441 | 442 | // 443 | // Start a new binary search over the template/arithmetic alternative parses of a statement. 444 | // Marks the current position and saves it in a binary search context maintained on a private stack. 445 | // 446 | void start_search(bool enableType1) 447 | { 448 | bool type1Enabled = !CxxSearchContext::current() || CxxSearchContext::current()->enable_type1() ? true : false; 449 | CxxSearchContext::start(mark(), enableType1 && type1Enabled ? true : false); 450 | } 451 | 452 | // 453 | // Determine whether the just parsed < should be interpreted as a template or arithmetic operator. 454 | // The implementation here intersacts with a binary search to traverse all possibilities in 455 | // multiple passes. The search proceeds by branch and bound presuming the template interpretation. 456 | // A true token is forced into the input stream to take the template interpretaion. A false token 457 | // otherwise. 458 | // 459 | // An alternate implementation that keeps track of scopes may interact with semantic knowledge to make 460 | // the correct decision directly. 461 | // 462 | void template_test() 463 | { 464 | if (!CxxSearchContext::current() || CxxSearchContext::current()->is_template()) 465 | { 466 | primed_tokens[0] = &plusToken; 467 | primed_tokens[1] = 0; 468 | } 469 | else 470 | { 471 | primed_tokens[0] = &minusToken; 472 | primed_tokens[1] = &angleToken; 473 | } 474 | } 475 | 476 | void token_put(CxxToken *aToken) 477 | { 478 | if (!tokenBuffer || !tokenSize) 479 | tokenBuffer = new CxxToken *[tokenSize = 256]; 480 | else if (tokenWriteIndex >= tokenSize) 481 | { 482 | CxxToken **oldTokenBuffer = tokenBuffer; 483 | size_t oldTokenSize = tokenSize; 484 | tokenBuffer = new CxxToken *[tokenSize *= 2]; 485 | memcpy(tokenBuffer, oldTokenBuffer, oldTokenSize * sizeof(*oldTokenBuffer)); 486 | delete[] oldTokenBuffer; 487 | } 488 | tokenBuffer[tokenWriteIndex++] = aToken; 489 | tokenReadIndex = tokenWriteIndex; 490 | } 491 | 492 | // 493 | // Pop a marked context off the stack. 494 | // 495 | void unmark(const CxxToken *aToken) 496 | { 497 | if (bang_depth) 498 | bang_depth--; 499 | else 500 | ERRMSG("BUG - should not unmark with 0 bang."); 501 | if (tokenMarkDepth <= 0) 502 | ERRMSG("Unexpected unmark."); 503 | else 504 | tokenMarkDepth--; 505 | } 506 | -------------------------------------------------------------------------------- /CxxParsing.hxx: -------------------------------------------------------------------------------- 1 | #ifndef CXX_PARSING_HXX 2 | #define CXX_PARSING_HXX 3 | 4 | #include 5 | #include 6 | #ifndef _MSC_VER 7 | #include 8 | #else 9 | #include 10 | //#define alloca _alloca 11 | #endif 12 | void advance_search(); 13 | void end_search(CxxToken *aToken); 14 | YACC_MARK_TYPE mark(); 15 | YACC_MARK_TYPE mark_type1(); 16 | size_t nest() { return 0; } 17 | void pop_bang(YACC_BANG_TYPE bangValue); 18 | YACC_BANG_TYPE push_bang(); 19 | void remark(YACC_MARK_TYPE anIndex); 20 | void remark_type1(YACC_MARK_TYPE anIndex); 21 | void rewind_colon(YACC_MARK_TYPE anIndex, const CxxToken *aToken); 22 | void start_search(bool enableType1); 23 | void template_test(); 24 | void unmark(const CxxToken *aToken = 0); 25 | void unnest(size_t aNest) {} 26 | 27 | void classify_argument(); 28 | void classify_function(); 29 | void dollar_kill(); 30 | CxxTokens *get_code(CxxToken *); 31 | CxxTokens *get_expr(); 32 | CxxTokens *get_for_init(); 33 | CxxTokens *get_for_next(); 34 | CxxTokens *get_for_test(); 35 | CxxTokens *get_func(); 36 | CxxTokens *get_raw(CxxToken *); 37 | CxxTokens *get_statement(); 38 | void make(CxxToken *); 39 | void queue(CxxToken *); 40 | int set_replace_formals(int); 41 | 42 | extern CxxToken *_list_token; 43 | 44 | #ifndef BISON_PP_CLASS 45 | void yyerror(const char *s); 46 | #define yylex buffered_yylex 47 | int yylex(); 48 | #endif 49 | 50 | #define YACC_ABSTRACT_ARRAY_EXPRESSION(a) make_abstract_array_expression(a) 51 | #define YACC_ABSTRACT_FUNCTION_EXPRESSION(a) make_abstract_function_expression(a) 52 | #define YACC_ACCESSIBILITY_SPECIFIER(a) make_accessibility_specifier(a) 53 | #define YACC_ACCESS_BASE_SPECIFIER(a,b) make_access_base_specifier(a,b) 54 | #define YACC_ACCESS_SPECIFIER_ID(a) make_access_specifier_id(a) 55 | #define YACC_ADD_EXPRESSION(a,b) make_add_expression(a, b) 56 | #define YACC_AND_EXPRESSION(a,b) make_and_expression(a,b) 57 | #define YACC_ARRAY_EXPRESSION(a,b) make_array_expression(a,b) 58 | #define YACC_ARROW_EXPRESSION(a,b) make_arrow_expression(a,b) 59 | #define YACC_ARROW_STAR_EXPRESSION(a,b) make_arrow_star_expression(a,b) 60 | #define YACC_ASM_DEFINITION(a) make_asm_definition(a) 61 | #define YACC_ASSIGNMENT_EXPRESSION(a,b,c) make_assignment_expression(a,b,c) 62 | #define YACC_BASE_SPECIFIER(a) make_base_specifier(a) 63 | #define YACC_BASE_SPECIFIERS(a,b) make_base_specifiers(a,b) 64 | #define YACC_BIT_FIELD_EXPRESSION(a,b) make_bit_field_expression(a,b) 65 | #define YACC_BREAK_STATEMENT() make_break_statement() 66 | #define YACC_BUILT_IN_ID(a) make_built_in_id(a) 67 | #define YACC_BUILT_IN_ID_ID(a) make_built_in_id_id(a) 68 | #define YACC_BUILT_IN_IDS(a,b) make_built_in_ids(a,b) 69 | #define YACC_BUILT_IN_NAME(a,b) make_built_in_name(a,b) 70 | #define YACC_CALL_EXPRESSION(a,b) make_call_expression(a,b) 71 | #define YACC_CASE_STATEMENT(a,b) make_case_statement(a,b) 72 | #define YACC_CAST_EXPRESSION(a,b) make_cast_expression(a,b) 73 | #define YACC_CHARACTER_LITERAL_EXPRESSION(a) make_character_literal_expression(a) 74 | #define YACC_CLASS_MEMBERS(a,b) make_class_members(a,b) 75 | #define YACC_CLASS_SPECIFIER_ID(a,b,c) make_class_specifier_id(a,b,c) 76 | #define YACC_CLASS_TEMPLATE_PARAMETER(a) make_class_template_parameter(a) 77 | #define YACC_CLASS_TYPE_PARAMETER(a) make_class_type_parameter(a) 78 | #define YACC_COMPILE_DECLARATION(a,b) compile_declaration(a,b) 79 | #define YACC_COMPILE_STATEMENT(a) compile_statement(a) 80 | #define YACC_COMPLEMENT_EXPRESSION(a) make_complement_expression(a) 81 | #define YACC_COMPOUND_STATEMENT(a) make_compound_statement(a) 82 | #define YACC_CONDITION(a) make_condition(a) 83 | #define YACC_CONDITIONAL_EXPRESSION(a,b,c) make_conditional_expression(a,b,c) 84 | #define YACC_CONST_CAST_EXPRESSION(a,b) make_const_cast_expression(a,b) 85 | #define YACC_CONTINUE_STATEMENT() make_continue_statement() 86 | #define YACC_CONVERSION_FUNCTION_ID(a) make_conversion_function_id(a) 87 | #define YACC_CTOR_DEFINITION(a,b) make_ctor_definition(a,b) 88 | #define YACC_CTOR_FUNCTION_BLOCK(a,b) make_ctor_function_block(a,b) 89 | #define YACC_CV_DECLARATOR(a,b) make_cv_declarator(a,b) 90 | #define YACC_CV_DECL_SPECIFIER(a) make_cv_decl_specifier(a) 91 | #define YACC_CV_QUALIFIERS(a,b) make_cv_qualifiers(a,b) 92 | #define YACC_DECLARATIONS(a,b) make_declarations(a,b) 93 | #define YACC_DECLARATION_STATEMENT(a) make_declaration_statement(a) 94 | #define YACC_DECL_SPECIFIER_DECLARATION(a,b) make_decl_specifier_declaration(a,b) 95 | #define YACC_DECL_SPECIFIER_EXPRESSION(a,b) make_decl_specifier_expression(a,b) 96 | #define YACC_DECL_SPECIFIER_NAME(a,b) make_decl_specifier_name(a,b) 97 | #define YACC_DECL_SPECIFIER_PARAMETER(a,b) make_decl_specifier_parameter(a,b) 98 | #define YACC_DECL_SPECIFIERS(a,b) make_decl_specifiers(a,b) 99 | #define YACC_DECL_SPECIFIER_TREE_ARGUMENT(a,b) make_decl_specifier_tree_argument(a,b) 100 | #define YACC_DECL_SPECIFIER_TREE_ARGUMENTS(a,b) make_decl_specifier_tree_arguments(a,b) 101 | #define YACC_DEFAULT_STATEMENT(a) make_default_statement(a) 102 | #define YACC_DELETE_EXPRESSION(a) make_delete_expression(a) 103 | #define YACC_DERIVED_CLAUSE(a,b) make_derived_clause(a,b) 104 | #define YACC_DESTRUCTOR_ID(a) make_destructor_id(a) 105 | #define YACC_DIVIDE_EXPRESSION(a,b) make_divide_expression(a,b) 106 | #define YACC_DOT_EXPRESSION(a,b) make_dot_expression(a,b) 107 | #define YACC_DOT_STAR_EXPRESSION(a,b) make_dot_star_expression(a,b) 108 | #define YACC_DO_WHILE_STATEMENT(a,b) make_do_while_statement(a,b) 109 | #define YACC_DYNAMIC_CAST_EXPRESSION(a,b) make_dynamic_cast_expression(a,b) 110 | #define YACC_ELABORATED_TYPE_SPECIFIER(a,b) make_elaborated_type_specifier(a,b) 111 | #define YACC_ELLIPSIS_EXPRESSION() make_ellipsis_expression() 112 | #define YACC_ENUMERATOR(a,b) make_enumerator(a,b) 113 | #define YACC_ENUMERATORS(a,b) make_enumerators(a,b) 114 | #define YACC_ENUM_SPECIFIER_ID(a,b) make_enum_specifier_id(a,b) 115 | #define YACC_ENUM_TREE_ID(a) make_enum_tree_id(a) 116 | #define YACC_EPSILON() make_epsilon() 117 | #define YACC_EQUAL_EXPRESSION(a,b) make_equal_expression(a,b) 118 | #define YACC_EXCEPTION_DECLARATION(a) make_exception_declaration(a) 119 | #define YACC_EXCEPTION_SPECIFICATION(a) make_exception_specification(a) 120 | #define YACC_EXCLUSIVE_OR_EXPRESSION(a,b) make_exclusive_or_expression(a,b) 121 | #define YACC_EXPLICIT_IMPLEMENTATION_DECLARATION(a) make_explicit_implementation_declaration(a) 122 | #define YACC_EXPLICIT_INTERFACE_DECLARATION(a) make_explicit_interface_declaration(a) 123 | #define YACC_EXPLICIT_SPECIALIZATION(a) make_explicit_specialization(a) 124 | #define YACC_EXPORT_IMPLEMENTATION_DECLARATION(a) make_export_implementation_declaration(a) 125 | #define YACC_EXPORT_INTERFACE_DECLARATION(a) make_export_interface_declaration(a) 126 | #define YACC_EXPORT_NOIMPLEMENTATION_DECLARATION() make_export_noimplementation_declaration() 127 | #define YACC_EXPRESSION(a) make_expression(a) 128 | #define YACC_EXPRESSIONS(a,b) make_expressions(a,b) 129 | #define YACC_EXPRESSION_PARAMETER(a) make_expression_parameter(a) 130 | #define YACC_FALSE_EXPRESSION() make_false_expression() 131 | #define YACC_FILESPACE_DECLARATION(a) make_filespace_declaration(a) 132 | #define YACC_FILESPACE_SPECIFIER(a,b) make_filespace_specifier(a,b) 133 | #define YACC_FILE_ID(a) make_file_id(a) 134 | #define YACC_FILE_ID_IMPLEMENTATION(a) make_file_id_implementation(a) 135 | #define YACC_FILE_ID_INTERFACE(a) make_file_id_interface(a) 136 | #define YACC_FILE_IDS(a,b) make_file_ids(a,b) 137 | #define YACC_FILE_NAME(a) make_file_name(a) 138 | #define YACC_FILE_NAME_GUARD(a,b) make_file_name_guard(a,b) 139 | #define YACC_FILE_NAME_IMPLEMENTATION(a) make_file_name_implementation(a) 140 | #define YACC_FILE_NAME_INTERFACE(a) make_file_name_interface(a) 141 | #define YACC_FILE_NAME_NOGUARD(a) make_file_name_noguard(a) 142 | #define YACC_FILE_NAME_PATH(a,b) make_file_name_path(a,b) 143 | #define YACC_FILE_NAME_PREFIX(a,b) make_file_name_prefix(a,b) 144 | #define YACC_FILE_NAME_SUFFIX(a,b) make_file_name_suffix(a,b) 145 | #define YACC_FILE_NAME_TEMPLATE(a) make_file_name_template(a) 146 | #define YACC_FILE_NAME_UTILITY(a,b) make_file_name_utility(a,b) 147 | #define YACC_FLOATING_LITERAL_EXPRESSION(a) make_floating_literal_expression(a) 148 | #define YACC_FOR_STATEMENT(a,b,c,d) make_for_statement(a,b,c,d) 149 | #define YACC_FUNCTION_BLOCK(a) make_function_block(a) 150 | #define YACC_FUNCTION_DECLARATIONS(a,b) make_function_declarations(a,b) 151 | #define YACC_FUNCTION_DEFINITION(a,b) make_function_definition(a,b) 152 | #define YACC_GLOBAL_DECLARATOR(a,b) make_global_declarator(a,b) 153 | #define YACC_GLOBAL_EXPRESSION(a, b) make_global_expression(a,b) 154 | #define YACC_GLOBAL_ID(a,b) make_global_id(a,b) 155 | #define YACC_GOTO_STATEMENT(a) make_goto_statement(a) 156 | #define YACC_GREATER_EQUAL_EXPRESSION(a,b) make_greater_equal_expression(a,b) 157 | #define YACC_GREATER_THAN_EXPRESSION(a,b) make_greater_than_expression(a,b) 158 | #define YACC_HANDLER(a,b) make_handler(a,b) 159 | #define YACC_HANDLERS(a,b) make_handlers(a,b) 160 | #define YACC_IF_STATEMENT(a,b,c) make_if_statement(a,b,c) 161 | #define YACC_INCLUDE_DECLARATION(a,b) make_include_declaration(a,b) 162 | #define YACC_INCLUSIVE_OR_EXPRESSION(a,b) make_inclusive_or_expression(a,b) 163 | #define YACC_INITIALIZED_PARAMETER(a,b) make_initialized_parameter(a, b) 164 | #define YACC_INITIALIZER_CLAUSES(a,b) make_initializer_clauses(a,b) 165 | #define YACC_INITIALIZER_EXPRESSION_CLAUSE(a) make_initializer_expression_clause(a) 166 | #define YACC_INITIALIZER_LIST_CLAUSE(a) make_initializer_list_clause(a) 167 | #define YACC_INIT_SIMPLE_TYPE_PARAMETER(a,b) make_init_simple_type_parameter(a,b) 168 | #define YACC_INIT_TEMPLATED_PARAMETER(a,b) make_init_templated_parameter(a,b) 169 | #define YACC_INLINE_AS_FRIEND() make_inline_as_friend() 170 | #define YACC_INLINE_IF_SHORT() make_inline_if_short() 171 | #define YACC_INLINE_IN_IMPLEMENTATION() make_inline_in_implementation() 172 | #define YACC_INLINE_IN_INTERFACE() make_inline_in_interface() 173 | #define YACC_INDEX_CAST_EXPRESSION(a,b) make_index_cast_expression(a,b) 174 | #define YACC_INPUT_FILE(a) make_input_file(a) 175 | #define YACC_INTEGER_LITERAL_EXPRESSION(a) make_integer_literal_expression(a) 176 | #define YACC_LABEL_STATEMENT(a,b) make_label_statement(a,b) 177 | #define YACC_LESS_EQUAL_EXPRESSION(a,b) make_less_equal_expression(a,b) 178 | #define YACC_LESS_THAN_EXPRESSION(a,b) make_less_than_expression(a,b) 179 | #define YACC_LINE() make_line() 180 | #define YACC_LINED_DECLARATION(a,b) make_lined_declaration(a,b) 181 | #define YACC_LINED_STATEMENT(a,b) make_lined_statement(a,b) 182 | #define YACC_LINED_TOKEN(a,b) make_lined_token(a,b) 183 | #define YACC_LINKAGE_SPECIFICATION(a) make_linkage_specification(a) 184 | #define YACC_LINKAGE_SPECIFIER(a,b) make_linkage_specifier(a,b) 185 | #define YACC_LOGICAL_AND_EXPRESSION(a,b) make_logical_and_expression(a,b) 186 | #define YACC_LOGICAL_OR_EXPRESSION(a,b) make_logical_or_expression(a,b) 187 | #define YACC_MEMBER_DECLARATIONS(a,b) make_member_declarations(a,b) 188 | #define YACC_MEM_INITIALIZER(a,b) make_mem_initializer(a,b) 189 | #define YACC_MEM_INITIALIZERS(a,b) make_mem_initializers(a,b) 190 | #define YACC_META_ASSIGNMENT_EXPRESSION(a,b,c) make_meta_assignment_expression(a,b,c) 191 | #define YACC_META_BASE_SPECIFIER(a) make_meta_base_specifier(a) 192 | #define YACC_META_BREAK_STATEMENT() make_meta_break_statement() 193 | #define YACC_META_BUILT_IN_TYPE(a) make_meta_built_in_type(a) 194 | #define YACC_META_CASE_STATEMENT(a,b) make_meta_case_statement(a,b) 195 | #define YACC_META_CLASS(a,b,c) make_meta_class(a,b,c) 196 | #define YACC_META_CONTINUE_STATEMENT() make_meta_continue_statement() 197 | #define YACC_META_DEFAULT_STATEMENT(a) make_meta_default_statement(a) 198 | #define YACC_META_DO_WHILE_STATEMENT(a,b,c) make_meta_do_while_statement(a,b,c) 199 | #define YACC_META_FOR_STATEMENT(a,b,c,d,e) make_meta_for_statement(a,b,c,d,e) 200 | #define YACC_META_FUNCTION(a,b,c) make_meta_function(a,b,c) 201 | #define YACC_META_IF_STATEMENT(a,b,c,d) make_meta_if_statement(a,b,c,d) 202 | #define YACC_META_INITIALIZER(a,b) make_meta_initializer(a,b) 203 | #define YACC_META_INITIALIZERS(a,b) make_meta_initializers(a,b) 204 | #define YACC_META_RETURN_STATEMENT(a) make_meta_return_statement(a) 205 | #define YACC_META_STATEMENT(a) make_meta_statement(a) 206 | #define YACC_META_STATEMENT_DECLARATION(a) make_meta_statement_declaration(a) 207 | #define YACC_META_SWITCH_STATEMENT(a,b,c) make_meta_switch_statement(a,b,c) 208 | #define YACC_META_TYPE(a) make_meta_type(a) 209 | #define YACC_META_TYPE_ID(a) make_meta_type_id(a) 210 | #define YACC_META_WHILE_STATEMENT(a,b,c) make_meta_while_statement(a,b,c) 211 | #define YACC_MINUS_EXPRESSION(a) make_minus_expression(a) 212 | #define YACC_MODULUS_EXPRESSION(a,b) make_modulus_expression(a,b) 213 | #define YACC_MULTIPLY_EXPRESSION(a,b,c) make_multiply_expression(a,b,c) 214 | #define YACC_NAME(a) make_name(a) 215 | #define YACC_NAMESPACE_ALIAS_DEFINITION(a,b) make_namespace_alias_definition(a,b) 216 | #define YACC_NAMESPACE_DECLARATION(a) make_namespace_declaration(a) 217 | #define YACC_NAMESPACE_DEFINITION(a,b) make_namespace_definition(a,b) 218 | #define YACC_NAME_EXPRESSION(a) make_name_expression(a) 219 | #define YACC_NESTED_DECLARATOR(a,b) make_nested_declarator(a,b) 220 | #define YACC_NESTED_ID(a,b) make_nested_id(a,b) 221 | #define YACC_NESTED_SCOPE(a) make_nested_scope(a) 222 | #define YACC_NEW_EXPRESSION(a,b,c) make_new_expression(a,b,c) 223 | #define YACC_NEW_TYPE_ID_EXPRESSION(a,b,c) make_new_type_id_expression(a,b,c) 224 | #define YACC_NOT_CONST() make_not_const() 225 | #define YACC_NOT_EQUAL_EXPRESSION(a,b) make_not_equal_expression(a,b) 226 | #define YACC_NOT_EXPRESSION(a) make_not_expression(a) 227 | #define YACC_NOT_INLINE() make_not_inline() 228 | #define YACC_NOT_STATIC() make_not_static() 229 | #define YACC_NOT_VIRTUAL() make_not_virtual() 230 | #define YACC_NOT_VIRTUAL_BASE_SPECIFIER(a) make_not_virtual_base_specifier(a) 231 | #define YACC_NOT_VOLATILE() make_not_volatile() 232 | #define YACC_NUMBER_LITERAL_EXPRESSION(a) make_number_literal_expression(a) 233 | #define YACC_OBJECT_SCOPE_EXPRESSION(a,b) make_object_scope_expression(a,b) 234 | #define YACC_OPERATOR_ADD_ID() make_operator_add_id() 235 | #define YACC_OPERATOR_ARROW_ID() make_operator_arrow_id() 236 | #define YACC_OPERATOR_ARROW_STAR_ID() make_operator_arrow_star_id() 237 | #define YACC_OPERATOR_ASS_ADD_ID() make_operator_ass_add_id() 238 | #define YACC_OPERATOR_ASS_BIT_AND_ID() make_operator_ass_bit_and_id() 239 | #define YACC_OPERATOR_ASS_BIT_OR_ID() make_operator_ass_bit_or_id() 240 | #define YACC_OPERATOR_ASS_DIV_ID() make_operator_ass_div_id() 241 | #define YACC_OPERATOR_ASS_ID() make_operator_ass_id() 242 | #define YACC_OPERATOR_ASS_MOD_ID() make_operator_ass_mod_id() 243 | #define YACC_OPERATOR_ASS_MUL_ID() make_operator_ass_mul_id() 244 | #define YACC_OPERATOR_ASS_SHL_ID() make_operator_ass_shl_id() 245 | #define YACC_OPERATOR_ASS_SHR_ID() make_operator_ass_shr_id() 246 | #define YACC_OPERATOR_ASS_SUB_ID() make_operator_ass_sub_id() 247 | #define YACC_OPERATOR_ASS_XOR_ID() make_operator_ass_xor_id() 248 | #define YACC_OPERATOR_BIT_AND_ID() make_operator_bit_and_id() 249 | #define YACC_OPERATOR_BIT_NOT_ID() make_operator_bit_not_id() 250 | #define YACC_OPERATOR_BIT_OR_ID() make_operator_bit_or_id() 251 | #define YACC_OPERATOR_CALL_ID() make_operator_call_id() 252 | #define YACC_OPERATOR_COMMA_ID() make_operator_comma_id() 253 | #define YACC_OPERATOR_DEC_ID() make_operator_dec_id() 254 | #define YACC_OPERATOR_DELETE_ID() make_operator_delete_id() 255 | #define YACC_OPERATOR_DIV_ID() make_operator_div_id() 256 | #define YACC_OPERATOR_EQ_ID() make_operator_eq_id() 257 | #define YACC_OPERATOR_FUNCTION_ID(a) make_operator_function_id(a) 258 | #define YACC_OPERATOR_GE_ID() make_operator_ge_id() 259 | #define YACC_OPERATOR_GT_ID() make_operator_gt_id() 260 | #define YACC_OPERATOR_INC_ID() make_operator_inc_id() 261 | #define YACC_OPERATOR_INDEX_ID() make_operator_index_id() 262 | #define YACC_OPERATOR_LE_ID() make_operator_le_id() 263 | #define YACC_OPERATOR_LOG_AND_ID() make_operator_log_and_id() 264 | #define YACC_OPERATOR_LOG_NOT_ID() make_operator_log_not_id() 265 | #define YACC_OPERATOR_LOG_OR_ID() make_operator_log_or_id() 266 | #define YACC_OPERATOR_LT_ID() make_operator_lt_id() 267 | #define YACC_OPERATOR_MOD_ID() make_operator_mod_id() 268 | #define YACC_OPERATOR_MUL_ID() make_operator_mul_id() 269 | #define YACC_OPERATOR_NE_ID() make_operator_ne_id() 270 | #define YACC_OPERATOR_NEW_ID() make_operator_new_id() 271 | #define YACC_OPERATOR_SHL_ID() make_operator_shl_id() 272 | #define YACC_OPERATOR_SHR_ID() make_operator_shr_id() 273 | #define YACC_OPERATOR_SUB_ID() make_operator_sub_id() 274 | #define YACC_OPERATOR_XOR_ID() make_operator_xor_id() 275 | #define YACC_PARAMETERS(a,b) make_parameters(a,b) 276 | #define YACC_PARENTHESISED(a,b,c) make_parenthesised(a,b,c) 277 | #define YACC_POINTER_DECLARATOR() make_pointer_declarator() 278 | #define YACC_POINTER_EXPRESSION(a,b) make_pointer_expression(a,b) 279 | #define YACC_PLUS_EXPRESSION(a) make_plus_expression(a) 280 | #define YACC_POSITION(a,b) make_position(a) 281 | #define YACC_POSITION_FUNCTION_BLOCK(a,b) make_position_function_block(a,b) 282 | #define YACC_POST_DECREMENT_EXPRESSION(a) make_post_decrement_expression(a) 283 | #define YACC_POST_INCREMENT_EXPRESSION(a) make_post_increment_expression(a) 284 | #define YACC_PRE_DECREMENT_EXPRESSION(a) make_pre_decrement_expression(a) 285 | #define YACC_PRE_INCREMENT_EXPRESSION(a) make_pre_increment_expression(a) 286 | #define YACC_PSEUDO_DESTRUCTOR_ID(a,b) make_pseudo_destructor_id(a,b) 287 | #define YACC_PURE_VIRTUAL() make_pure_virtual() 288 | #define YACC_READ_ONLY_RESULT(a) make_read_only_result(a) 289 | #define YACC_READ_WRITE_RESULT(a) make_read_write_result(a) 290 | #define YACC_REFERENCE_DECLARATOR() make_reference_declarator() 291 | #define YACC_REINTERPRET_CAST_EXPRESSION(a,b) make_reinterpret_cast_expression(a,b) 292 | #define YACC_RESULT(a) make_result(a) 293 | #define YACC_RETURN_STATEMENT(a) make_return_statement(a) 294 | #define YACC_SCOPED_POINTER_EXPRESSION(a,b,c) make_scoped_pointer_expression(a,b,c) 295 | #define YACC_SCOPED_ID(a,b) make_scoped_id(a,b) 296 | #define YACC_SEGMENT(a,b) make_segment(a) 297 | #define YACC_SEGMENT_FUNCTION_BLOCK(a,b) make_segment_function_block(a,b) 298 | #define YACC_SET_TEMPLATE_DECLARATION(a) make_set_template_declaration(a) 299 | #define YACC_SET_TEMPLATE_DECL_SPECIFIER(a) make_set_template_decl_specifier(a) 300 | #define YACC_SET_TEMPLATE_EXPRESSION(a) make_set_template_expression(a) 301 | #define YACC_SET_TEMPLATE_ID(a) make_set_template_id(a) 302 | #define YACC_SET_TEMPLATE_NAME(a) make_set_template_name(a) 303 | #define YACC_SET_TEMPLATE_SCOPE(a) make_set_template_scope(a) 304 | #define YACC_SHIFT_LEFT_EXPRESSION(a,b) make_shift_left_expression(a,b) 305 | #define YACC_SHIFT_RIGHT_EXPRESSION(a,b) make_shift_right_expression(a,b) 306 | #define YACC_SIMPLE_DECLARATION(a) make_simple_declaration(a) 307 | #define YACC_SIZEOF_EXPRESSION(a) make_sizeof_expression(a) 308 | #define YACC_STATEMENTS(a,b) make_statements(a,b) 309 | #define YACC_STATIC_CAST_EXPRESSION(a,b) make_static_cast_expression(a,b) 310 | #define YACC_STRINGS(a,b) make_strings(a,b) 311 | #define YACC_STRING_LITERAL_EXPRESSION(a) make_string_literal_expression(a) 312 | #define YACC_SUBTRACT_EXPRESSION(a,b) make_subtract_expression(a,b) 313 | #define YACC_SWITCH_STATEMENT(a,b) make_switch_statement(a,b) 314 | #define YACC_SYNTAX_MACRO_DEFINITION(a,b,c,d,e) make_syntax_macro_definition(a,b,c,d,e) 315 | #define YACC_SYNTAX_MACRO_PARAMETER(a,b,c) make_syntax_macro_parameter(a,b,c) 316 | #define YACC_SYNTAX_MACRO_PARAMETERS(a,b) make_syntax_macro_parameters(a,b) 317 | #define YACC_TEMPLATE_ARGUMENT(a) make_template_argument(a) 318 | #define YACC_TEMPLATE_ARGUMENTS(a,b) make_template_arguments(a,b) 319 | #define YACC_TEMPLATED_TEMPLATE_PARAMETER(a,b) make_templated_template_parameter(a,b) 320 | #define YACC_TEMPLATED_TYPE_PARAMETER(a,b) make_templated_type_parameter(a,b) 321 | #define YACC_TEMPLATE_DECLARATION(a,b) make_template_declaration(a,b) 322 | #define YACC_TEMPLATE_NAME(a,b) make_template_name(a,b) 323 | #define YACC_TEMPLATE_PARAMETER(a) make_template_parameter(a) 324 | #define YACC_TEMPLATE_PARAMETERS(a,b) make_template_parameters(a,b) 325 | #define YACC_THIS_EXPRESSION() make_this_expression() 326 | #define YACC_THROW_EXPRESSION(a) make_throw_expression(a) 327 | #define YACC_TOKENS_EXPRESSION(a) make_tokens_expression(a) 328 | #define YACC_TREE_ARGUMENT(a) make_tree_argument(a) 329 | #define YACC_TREE_ARGUMENTS(a,b) make_tree_arguments(a,b) 330 | #define YACC_TREE_ARRAY_EXPRESSION(a,b) make_tree_array_expression(a,b) 331 | #define YACC_TREE_ARROW_EXPRESSION(a,b) make_tree_arrow_expression(a,b) 332 | #define YACC_TREE_ARROW_CALL_EXPRESSION(a,b,c) make_tree_arrow_call_expression(a,b,c) 333 | #define YACC_TREE_CALL_EXPRESSION(a,b) make_tree_call_expression(a,b) 334 | #define YACC_TREE_DOT_EXPRESSION(a,b) make_tree_dot_expression(a,b) 335 | #define YACC_TREE_DOT_CALL_EXPRESSION(a,b,c) make_tree_dot_call_expression(a,b,c) 336 | #define YACC_TREE_EXPRESSION(a) make_tree_expression(a) 337 | #define YACC_TREE_ID(a) make_tree_id(a) 338 | #define YACC_TREE_POINTER_EXPRESSION(a) make_tree_pointer_expression(a) 339 | #define YACC_TRUE_EXPRESSION() make_true_expression() 340 | #define YACC_TRY_BLOCK(a,b) make_try_block(a,b) 341 | #define YACC_TRY_BLOCK_STATEMENT(a) make_try_block_statement(a) 342 | #define YACC_TRY_FUNCTION_BLOCK(a,b) make_try_function_block(a,b) 343 | #define YACC_TYPE1_EXPRESSION(a,b,c) make_type1_expression(a,b,c) 344 | #define YACC_TYPE1_PARAMETERS(a,b) make_type1_parameters(a,b) 345 | #define YACC_TYPED_EXPRESSION(a,b) make_typed_expression(a,b) 346 | #define YACC_TYPED_NAME(a,b) make_typed_name(a,b) 347 | #define YACC_TYPEID_EXPRESSION(a) make_typeid_expression(a) 348 | #define YACC_TYPENAME_TEMPLATE_PARAMETER(a) make_typename_template_parameter(a) 349 | #define YACC_TYPENAME_TYPE_PARAMETER(a) make_typename_type_parameter(a) 350 | #define YACC_TYPE_TEMPLATE_PARAMETER(a,b) make_type_template_parameter(a,b) 351 | #define YACC_USING_DECLARATION(a,b) make_using_declaration(a,b) 352 | #define YACC_USING_DIRECTIVE(a) make_using_directive(a) 353 | #define YACC_USING_FUNCTION_BLOCK(a,b) make_using_function_block(a,b) 354 | #define YACC_USING_IMPLEMENTATION_DECLARATION(a) make_using_implementation_declaration(a) 355 | #define YACC_USING_INTERFACE_DECLARATION(a) make_using_interface_declaration(a) 356 | #define YACC_UTILITY(a) make_utility(0) 357 | #define YACC_UTILITY_MODE() make_utility_mode() 358 | #define YACC_VIRTUAL_BASE_SPECIFIER(a) make_virtual_base_specifier(a) 359 | #define YACC_WHILE_STATEMENT(a,b) make_while_statement(a,b) 360 | 361 | inline CxxDeclaration *compile_declaration(CxxUtility *utilityMode, CxxDeclaration *aDeclaration) { return 0; } 362 | inline CxxStatement *compile_statement(CxxStatement *aDeclaration) { return 0; } 363 | inline void make_result(CxxToken *aResult) {} 364 | 365 | inline CxxExpression *make_abstract_array_expression(CxxExpression *sizeExpr) { return 0; } 366 | inline CxxExpression *make_abstract_function_expression(CxxParenthesised *aparenthesis) { return 0; } 367 | inline CxxBaseSpecifier *make_access_base_specifier(CxxBaseSpecifier *baseSpecifier, CxxAccessSpecifier *accessSpecifier) { return 0; } 368 | inline CxxDeclSpecifierId *make_access_specifier_id(CxxAccessSpecifier *aName) { return 0; } 369 | inline CxxDeclaration *make_accessibility_specifier(CxxAccessSpecifier *accessSpecifier) { return 0; } 370 | inline CxxExpression *make_add_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 371 | inline CxxExpression *make_and_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 372 | inline CxxExpression *make_array_expression(CxxExpression *anExpr, CxxExpression *indexExpr) { return 0; } 373 | inline CxxExpression *make_arrow_expression(CxxExpression *anExpr, CxxName *aName) { return 0; } 374 | inline CxxExpression *make_arrow_star_expression(CxxExpression *anExpr, CxxExpression *memberExpr) { return 0; } 375 | inline CxxDeclaration *make_asm_definition(CxxStrings *aString) { return 0; } 376 | inline CxxExpression *make_assignment_expression(CxxExpression *leftExpr, CxxToken *assOp, CxxExpression *rightExpr) { return 0; } 377 | inline CxxBaseSpecifier *make_base_specifier(CxxName *aName) { return 0; } 378 | inline CxxBaseSpecifiers *make_base_specifiers(CxxBaseSpecifiers *aList, CxxBaseSpecifier *anElement) { return 0; } 379 | inline CxxExpression *make_bit_field_expression(CxxExpression *nameExpr, CxxExpression *sizeExpr) { return 0; } 380 | inline CxxStatement *make_break_statement() { return 0; } 381 | inline CxxName *make_built_in_id(CxxBuiltInId *aName) { return 0; } 382 | inline CxxName *make_built_in_id_id(CxxBuiltInId *aName) { return 0; } 383 | inline CxxBuiltInId *make_built_in_ids(CxxBuiltInId *anExpr, CxxBuiltInId *anElement) { return 0; } 384 | inline CxxName *make_built_in_name(CxxName *aName, CxxBuiltInId *anElement) { return 0; } 385 | inline CxxExpression *make_call_expression(CxxExpression *anExpr, CxxParenthesised *aParenthesis) { return 0; } 386 | inline CxxStatement *make_case_statement(CxxExpression *anExpr, CxxStatement *aStmt) { return 0; } 387 | inline CxxExpression *make_cast_expression(CxxExpression *aCast, CxxExpression *anExpr) { return 0; } 388 | inline CxxExpression *make_character_literal_expression(CxxCharacterLiteral *aLiteral) { return 0; } 389 | inline CxxName *make_class_members(CxxClass *aClass, CxxMemberDeclarations *memberDeclarations) { return 0; } 390 | inline CxxClass *make_class_specifier_id(CxxClassKey *classKey, CxxName *aName, CxxBaseSpecifiers *baseSpecifiers) { return 0; } 391 | inline CxxSimpleTypeParameter *make_class_template_parameter(CxxName *aName) { return 0; } 392 | inline CxxSimpleTypeParameter *make_class_type_parameter(CxxName *aName) { return 0; } 393 | inline CxxStatement *make_compound_statement(CxxStatements *statementList) { return 0; } 394 | inline CxxExpression *make_complement_expression(CxxExpression *anExpr) { return 0; } 395 | inline CxxCondition *make_condition(CxxParameters *aList) { return 0; } 396 | inline CxxExpression *make_conditional_expression(CxxExpression *testExpr, CxxExpression *trueExpr, CxxExpression *falseExpr) { return 0; } 397 | inline CxxExpression *make_const_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; } 398 | inline CxxStatement *make_continue_statement() { return 0; } 399 | inline CxxName *make_conversion_function_id(CxxExpression *typeId) { return 0; } 400 | inline CxxExpression *make_ctor_definition(CxxExpressions *anExpr, CxxFunctionBody *functionBody) { return 0; } 401 | inline CxxFunctionBody *make_ctor_function_block(CxxFunctionBody *functionBody, CxxMemInitializers *ctorList) { return 0; } 402 | inline CxxDeclSpecifierId *make_cv_decl_specifier(CxxCvQualifiers *cvQualifiers) { return 0; } 403 | inline CxxPointerDeclarator *make_cv_declarator(CxxPointerDeclarator *aDeclarator, CxxCvQualifiers *cvQualifiers) { return 0; } 404 | inline CxxCvQualifiers *make_cv_qualifiers(CxxCvQualifiers *aList, CxxCvQualifiers *anElement) { return 0; } 405 | inline CxxDeclaration *make_decl_specifier_declaration(CxxDeclaration *aDeclaration, CxxDeclSpecifierId *declSpecifier) { return 0; } 406 | inline CxxExpression *make_decl_specifier_expression(CxxExpression *anExpr, CxxDeclSpecifierId *declSpecifier) { return 0; } 407 | inline CxxName *make_decl_specifier_name(CxxName *aName, CxxDeclSpecifierId *declSpecifier) { return 0; } 408 | inline CxxParameter *make_decl_specifier_parameter(CxxParameter *aName, CxxDeclSpecifierId *declSpecifier) { return 0; } 409 | inline CxxToken *make_decl_specifier_tree_argument(CxxToken *treeArgument, CxxDeclSpecifierId *aName) { return 0; } 410 | inline CxxTokens *make_decl_specifier_tree_arguments(CxxTokens *treeArguments, CxxDeclSpecifierId *aName) { return 0; } 411 | inline CxxDeclSpecifierId *make_decl_specifiers(CxxDeclSpecifierId *aList, CxxDeclSpecifierId *anElement) { return 0; } 412 | inline CxxDeclarations *make_declarations(CxxDeclarations *aList, CxxDeclaration *anElement) { return 0; } 413 | inline CxxStatement *make_declaration_statement(CxxDeclaration *aDecl) { return 0; } 414 | inline CxxStatement *make_default_statement(CxxStatement *aStmt) { return 0; } 415 | inline CxxExpression *make_delete_expression(CxxExpression *anExpr) { return 0; } 416 | inline CxxDeclaration *make_derived_clause(CxxExpression *derivedPredicate, CxxDeclaration *aDeclaration) { return 0; } 417 | inline CxxName *make_destructor_id(CxxName *aName) { return 0; } 418 | inline CxxExpression *make_divide_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 419 | inline CxxStatement *make_do_while_statement(CxxStatement *aStmt, CxxExpression *testExpr) { return 0; } 420 | inline CxxExpression *make_dot_expression(CxxExpression *anExpr, CxxName *aName) { return 0; } 421 | inline CxxExpression *make_dot_star_expression(CxxExpression *anExpr, CxxExpression *memberExpr) { return 0; } 422 | inline CxxExpression *make_dynamic_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; } 423 | inline CxxName *make_elaborated_type_specifier(CxxClassKey *classKey, CxxName *aName) { return 0; } 424 | inline CxxParameter *make_ellipsis_expression() { return 0; } 425 | inline CxxName *make_enum_specifier_id(CxxName *aName, CxxEnumerators *aList) { return 0; } 426 | inline CxxEnumerator *make_enumerator(CxxName *aName, CxxExpression *anExpr) { return 0; } 427 | inline CxxEnumerators *make_enumerators(CxxEnumerators *aList, CxxEnumerator *anElement) { return 0; } 428 | inline CxxName *make_epsilon() { return 0; } 429 | inline CxxExpression *make_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 430 | inline CxxExceptionDeclaration *make_exception_declaration(CxxParameter *aParameter) { return 0; } 431 | inline CxxExceptionSpecification *make_exception_specification(CxxExpressions *typeIds) { return 0; } 432 | inline CxxExpression *make_exclusive_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 433 | inline CxxDeclaration *make_explicit_implementation_declaration(CxxTokens *someTokens) { return 0; } 434 | inline CxxDeclaration *make_explicit_interface_declaration(CxxTokens *someTokens) { return 0; } 435 | inline CxxDeclaration *make_explicit_specialization(CxxDeclaration *aDeclaration) { return 0; } 436 | inline CxxDeclaration *make_export_implementation_declaration(CxxFileId *fileId) { return 0; } 437 | inline CxxDeclaration *make_export_interface_declaration(CxxFileId *fileId) { return 0; } 438 | inline CxxDeclaration *make_export_noimplementation_declaration() { return 0; } 439 | inline CxxExpression *make_expression(CxxExpressions *aList) { return 0; } 440 | inline CxxParameter *make_expression_parameter(CxxExpression *anExpr) { return 0; } 441 | inline CxxExpressions *make_expressions(CxxExpressions *aList, CxxExpression *anElement) { return 0; } 442 | inline CxxExpression *make_false_expression() { return 0; } 443 | inline CxxFileId *make_file_id(CxxFileName *fileName) { return 0; } 444 | inline CxxFileId *make_file_id_implementation(CxxName *aName) { return 0; } 445 | inline CxxFileId *make_file_id_interface(CxxName *aName) { return 0; } 446 | inline CxxFileIds *make_file_ids(CxxFileIds *aList, CxxFileId *anElement) { return 0; } 447 | inline CxxFileName *make_file_name(CxxStrings *aString) { return 0; } 448 | inline CxxFileName *make_file_name_guard(CxxFileName *fileName, CxxStrings *aString) { return 0; } 449 | inline CxxFileName *make_file_name_implementation(CxxFileName *fileName) { return 0; } 450 | inline CxxFileName *make_file_name_interface(CxxFileName *fileName) { return 0; } 451 | inline CxxFileName *make_file_name_noguard(CxxFileName *fileName) { return 0; } 452 | inline CxxFileName *make_file_name_path(CxxFileName *fileName, CxxStrings *aString) { return 0; } 453 | inline CxxFileName *make_file_name_prefix(CxxFileName *fileName, CxxStrings *aString) { return 0; } 454 | inline CxxFileName *make_file_name_suffix(CxxFileName *fileName, CxxStrings *aString) { return 0; } 455 | inline CxxFileName *make_file_name_template(CxxFileName *fileName) { return 0; } 456 | inline CxxFileName *make_file_name_utility(CxxFileName *fileName, CxxUtility *aUtility) { return 0; } 457 | inline CxxDeclaration *make_filespace_declaration(CxxName *aName) { return 0; } 458 | inline CxxName *make_filespace_specifier(CxxFileName *fileName, CxxDeclarations *aDeclaration) { return 0; } 459 | inline CxxExpression *make_floating_literal_expression(CxxFloatingLiteral *aLiteral) { return 0; } 460 | inline CxxStatement *make_for_statement(CxxExpression *initExpr, CxxCondition *testExpr, CxxExpression *stepExpr, CxxStatement *aStmt) { return 0; } 461 | inline CxxFunctionBody *make_function_block(CxxStatement *aStatement) { return 0; } 462 | inline CxxFunctionDeclarations *make_function_declarations(CxxFunctionDeclarations *aList, CxxDeclaration *anElement) { return 0; } 463 | inline CxxExpression *make_function_definition(CxxExpression *anExpr, CxxFunctionBody *functionBody) { return 0; } 464 | inline CxxDeclarator *make_global_declarator(CxxIsTemplate isTemplate, CxxDeclarator *aDeclarator) { return 0; } 465 | inline CxxExpression *make_global_expression(CxxIsTemplate isTemplate, CxxNewExpression *anExpr) { return 0; } 466 | inline CxxName *make_global_id(CxxIsTemplate isTemplate, CxxName *nestedId) { return 0; } 467 | inline CxxStatement *make_goto_statement(CxxToken *aLabel) { return 0; } 468 | inline CxxExpression *make_greater_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 469 | inline CxxExpression *make_greater_than_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 470 | inline CxxHandler *make_handler(CxxExceptionDeclaration *exceptionDeclaration, CxxStatement *aStatement) { return 0; } 471 | inline CxxHandlers *make_handlers(CxxHandlers *aList, CxxHandler *anElement) { return 0; } 472 | inline CxxStatement *make_if_statement(CxxCondition *testExpr, CxxStatement *trueStmt, CxxStatement *falseStmt) { return 0; } 473 | inline CxxDeclaration *make_include_declaration(CxxStrings *aString, CxxUtility *aUtility) { return 0; } 474 | inline CxxExpression *make_inclusive_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 475 | inline CxxExpression *make_index_cast_expression(CxxExpression *aCast, CxxExpression *anExpr) { return 0; } 476 | inline CxxParameter *make_initialized_parameter(CxxParameter *aParameter, CxxExpression *anExpr) { return 0; } 477 | inline CxxInitializerClauses *make_initializer_clauses(CxxInitializerClauses *aList, CxxInitializerClause *anElement) { return 0; } 478 | inline CxxInitializerClause *make_initializer_expression_clause(CxxExpression *anExpr) { return 0; } 479 | inline CxxInitializerClause *make_initializer_list_clause(CxxInitializerClauses *aList) { return 0; } 480 | inline CxxSimpleTypeParameter *make_init_simple_type_parameter(CxxSimpleTypeParameter *templateParameters, CxxExpression *anExpr) { return 0; } 481 | inline CxxTemplatedTypeParameter *make_init_templated_parameter(CxxTemplatedTypeParameter *typeParameter, CxxName *aName) { return 0; } 482 | inline CxxDeclSpecifierId *make_inline_as_friend() { return 0; } 483 | inline CxxDeclSpecifierId *make_inline_if_short() { return 0; } 484 | inline CxxDeclSpecifierId *make_inline_in_implementation() { return 0; } 485 | inline CxxDeclSpecifierId *make_inline_in_interface() { return 0; } 486 | inline CxxFileId *make_input_file(CxxFileId *fileId) { return 0; } 487 | inline CxxExpression *make_integer_literal_expression(CxxIntegerLiteral *aLiteral) { return 0; } 488 | inline CxxStatement *make_label_statement(CxxToken *aLabel, CxxStatement *aStmt) { return 0; } 489 | inline CxxExpression *make_less_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 490 | inline CxxExpression *make_less_than_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 491 | inline CxxLine *make_line() { return 0; } 492 | inline CxxDeclaration *make_lined_declaration(CxxDeclaration *aDeclaration, CxxLine *aLine) { return 0; } 493 | inline CxxStatement *make_lined_statement(CxxStatement *aStatement, CxxLine *aLine) { return 0; } 494 | inline CxxToken *make_lined_token(CxxToken *aToken, CxxLine *aLine) { return 0; } 495 | inline CxxName *make_linkage_specifier(CxxStrings *aString, CxxDeclaration *aDeclaration) { return 0; } 496 | inline CxxExpression *make_logical_and_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 497 | inline CxxExpression *make_logical_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 498 | inline CxxMemInitializer *make_mem_initializer(CxxName *aName, CxxExpression *anExpr) { return 0; } 499 | inline CxxMemInitializers *make_mem_initializers(CxxMemInitializers *aList, CxxMemInitializer *anElement) { return 0; } 500 | inline CxxMemberDeclarations *make_member_declarations(CxxMemberDeclarations *aList, CxxDeclaration *aDeclaration) { return 0; } 501 | inline CxxExpression *make_meta_assignment_expression(CxxExpression *leftExpr, CxxToken *assOp, CxxToken *rightExpr) { return 0; } 502 | inline CxxBaseSpecifier *make_meta_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; } 503 | inline CxxMetaType *make_meta_built_in_type(CxxBuiltInId *aName) { return 0; } 504 | inline CxxStatement *make_meta_break_statement() { return 0; } 505 | inline CxxStatement *make_meta_case_statement(CxxExpression *anExpr, CxxToken *someTokens) { return 0; } 506 | inline CxxMetaClass *make_meta_class(CxxName *metaClass, CxxBaseSpecifiers *baseSpecifiers, CxxToken *classBody) { return 0; } 507 | inline CxxStatement *make_meta_continue_statement() { return 0; } 508 | inline CxxDeclaration *make_meta_declaration_declaration(CxxDeclaration *metaDeclaration) { return 0; } 509 | inline CxxStatement *make_meta_default_statement(CxxToken *someTokens) { return 0; } 510 | inline CxxStatement *make_meta_do_while_statement(CxxLine *aLine, CxxToken *bodyTokens, CxxToken *testTokens) { return 0; } 511 | inline CxxStatement *make_meta_expression_statement(CxxName *aName, CxxToken *bodyTokens) { return 0; } 512 | inline CxxStatement *make_meta_for_statement(CxxLine *aLine, CxxExpression *initTokens, CxxToken *testTokens, 513 | CxxToken *stepTokens, CxxToken *bodyTokens) { return 0; } 514 | inline CxxExpression *make_meta_function(CxxExpression *anExpr, CxxTokens *aList, CxxToken *aBody) { return 0; } 515 | inline CxxStatement *make_meta_if_statement(CxxLine *aLine, CxxExpression *testTokens, CxxToken *trueTokens, CxxToken *falseTokens) { return 0; } 516 | inline CxxDeclaration *make_linkage_specification(CxxName *aName) { return 0; } 517 | //CxxMetaInitializers *make_meta_initializers(CxxMetaInitializers *aList, CxxToken *anElement) { return 0; } 518 | inline CxxMetaParameter *make_meta_parameter(CxxMetaType *metaType, CxxIsTree isTree, CxxName *aName, CxxToken *anInit) { return 0; } 519 | inline CxxMetaParameters *make_meta_parameters(CxxMetaParameters *aList, CxxMetaParameter *anElement) { return 0; } 520 | inline CxxStatement *make_meta_return_statement(CxxExpression *anExpr) { return 0; } 521 | inline CxxStatement *make_meta_statement(CxxStatement *aStatement) { return 0; } 522 | inline CxxDeclaration *make_meta_statement_declaration(CxxStatement *metaStatement) { return 0; } 523 | inline CxxStatement *make_meta_statement_statement(CxxStatement *metaStatement) { return 0; } 524 | inline CxxStatement *make_meta_switch_statement(CxxLine *aLine, CxxExpression *testTokens, CxxToken *bodyTokens) { return 0; } 525 | inline CxxMetaType *make_meta_type(CxxName *aName) { return 0; } 526 | inline CxxName *make_meta_type_id(CxxMetaType *metaType) { return 0; } 527 | inline CxxStatement *make_meta_while_statement(CxxLine *aLine, CxxToken *testTokens, CxxToken *bodyTokens) { return 0; } 528 | inline CxxExpression *make_minus_expression(CxxExpression *anExpr) { return 0; } 529 | inline CxxExpression *make_modulus_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 530 | inline CxxExpression *make_multiply_expression(CxxExpression *leftExpr, CxxDeclarator *aDeclarator, CxxExpression *rightExpr) { return 0; } 531 | inline CxxName *make_name(CxxName *aName) { return 0; } 532 | inline CxxName *make_name_expression(CxxName *aName) { return 0; } 533 | inline CxxDeclaration *make_namespace_alias_definition(CxxName *aName, CxxName *forId) { return 0; } 534 | inline CxxDeclaration *make_namespace_declaration(CxxName *aName) { return 0; } 535 | inline CxxName *make_namespace_definition(CxxName *aName, CxxDeclarations *aDeclaration) { return 0; } 536 | inline CxxDeclarator *make_nested_declarator(CxxName *aName, CxxDeclarator *aDeclarator) { return 0; } 537 | inline CxxName *make_nested_id(CxxName *nestingId, CxxName *nestedId) { return 0; } 538 | inline CxxName *make_nested_scope(CxxName *nestingId) { return 0; } 539 | inline CxxExpression *make_new_expression(CxxParameters *aPlace, CxxParameters *aType, CxxExpression *anInit) { return 0; } 540 | inline CxxExpression *make_new_type_id_expression(CxxParameters *aPlace, CxxExpression *aType, CxxExpression *anInit) { return 0; } 541 | inline CxxDeclSpecifierId *make_not_const() { return 0; } 542 | inline CxxExpression *make_not_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 543 | inline CxxExpression *make_not_expression(CxxExpression *anExpr) { return 0; } 544 | inline CxxDeclSpecifierId *make_not_inline() { return 0; } 545 | inline CxxDeclSpecifierId *make_not_static() { return 0; } 546 | inline CxxDeclSpecifierId *make_not_virtual() { return 0; } 547 | inline CxxBaseSpecifier *make_not_virtual_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; } 548 | inline CxxDeclSpecifierId *make_not_volatile() { return 0; } 549 | inline CxxExpression *make_number_literal_expression(CxxExpression *anExpr) { return 0; } 550 | inline CxxExpression *make_object_scope_expression(CxxExpression *anExpr, CxxDeclaration *functionDeclarations) { return 0; } 551 | inline CxxName *make_operator_add_id() { return 0; } 552 | inline CxxName *make_operator_arrow_id() { return 0; } 553 | inline CxxName *make_operator_arrow_star_id() { return 0; } 554 | inline CxxName *make_operator_ass_add_id() { return 0; } 555 | inline CxxName *make_operator_ass_bit_and_id() { return 0; } 556 | inline CxxName *make_operator_ass_bit_or_id() { return 0; } 557 | inline CxxName *make_operator_ass_div_id() { return 0; } 558 | inline CxxName *make_operator_ass_id() { return 0; } 559 | inline CxxName *make_operator_ass_mod_id() { return 0; } 560 | inline CxxName *make_operator_ass_mul_id() { return 0; } 561 | inline CxxName *make_operator_ass_shl_id() { return 0; } 562 | inline CxxName *make_operator_ass_shr_id() { return 0; } 563 | inline CxxName *make_operator_ass_sub_id() { return 0; } 564 | inline CxxName *make_operator_ass_xor_id() { return 0; } 565 | inline CxxName *make_operator_bit_and_id() { return 0; } 566 | inline CxxName *make_operator_bit_not_id() { return 0; } 567 | inline CxxName *make_operator_bit_or_id() { return 0; } 568 | inline CxxName *make_operator_call_id() { return 0; } 569 | inline CxxName *make_operator_comma_id() { return 0; } 570 | inline CxxName *make_operator_dec_id() { return 0; } 571 | inline CxxName *make_operator_delete_id() { return 0; } 572 | inline CxxName *make_operator_div_id() { return 0; } 573 | inline CxxName *make_operator_eq_id() { return 0; } 574 | inline CxxName *make_operator_function_id(CxxName *operatorId) { return 0; } 575 | inline CxxName *make_operator_ge_id() { return 0; } 576 | inline CxxName *make_operator_gt_id() { return 0; } 577 | inline CxxName *make_operator_inc_id() { return 0; } 578 | inline CxxName *make_operator_index_id() { return 0; } 579 | inline CxxName *make_operator_le_id() { return 0; } 580 | inline CxxName *make_operator_log_and_id() { return 0; } 581 | inline CxxName *make_operator_log_not_id() { return 0; } 582 | inline CxxName *make_operator_log_or_id() { return 0; } 583 | inline CxxName *make_operator_lt_id() { return 0; } 584 | inline CxxName *make_operator_mod_id() { return 0; } 585 | inline CxxName *make_operator_mul_id() { return 0; } 586 | inline CxxName *make_operator_ne_id() { return 0; } 587 | inline CxxName *make_operator_new_id() { return 0; } 588 | inline CxxName *make_operator_shl_id() { return 0; } 589 | inline CxxName *make_operator_shr_id() { return 0; } 590 | inline CxxName *make_operator_sub_id() { return 0; } 591 | inline CxxName *make_operator_xor_id() { return 0; } 592 | inline CxxParameters *make_parameters(CxxParameters *aList, CxxParameter *anElement) { return 0; } 593 | inline CxxParenthesised *make_parenthesised(CxxParameters *aList, CxxCvQualifiers *cvQualifiers, CxxExceptionSpecification *exceptionSpecification) { return 0; } 594 | inline CxxExpression *make_plus_expression(CxxExpression *anExpr) { return 0; } 595 | inline CxxPointerDeclarator *make_pointer_declarator() { return 0; } 596 | inline CxxExpression *make_pointer_expression(CxxDeclarator *aDeclarator, CxxExpression *anExpr) { return 0; } 597 | inline CxxExpression *make_post_decrement_expression(CxxExpression *anExpr) { return 0; } 598 | inline CxxExpression *make_post_increment_expression(CxxExpression *anExpr) { return 0; } 599 | inline CxxExpression *make_pre_decrement_expression(CxxExpression *anExpr) { return 0; } 600 | inline CxxExpression *make_pre_increment_expression(CxxExpression *anExpr) { return 0; } 601 | inline CxxName *make_pseudo_destructor_id(CxxBuiltInId *aScope, CxxBuiltInId *aName) { return 0; } 602 | inline CxxDeclSpecifierId *make_pure_virtual() { return 0; } 603 | inline CxxDeclarator *make_reference_declarator() { return 0; } 604 | inline CxxExpression *make_reinterpret_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; } 605 | inline CxxStatement *make_return_statement(CxxExpression *anExpr) { return 0; } 606 | inline CxxName *make_scoped_id(CxxName *globalId, CxxName *nestedId) { return 0; } 607 | inline CxxExpression *make_scoped_pointer_expression(CxxExpression *aScope, CxxDeclarator *aDeclarator, CxxExpression *anExpr) { return 0; } 608 | inline CxxSegment *make_segment(CxxSegment *aSegment) { return 0; } 609 | inline CxxFunctionBody *make_segment_function_block(CxxFunctionBody *functionBody, CxxSegment *aSegment) { return 0; } 610 | inline CxxDeclSpecifierId *make_set_template_decl_specifier(CxxDeclSpecifierId *aName) { return 0; } 611 | inline CxxDeclaration *make_set_template_declaration(CxxDeclaration *aDeclaration) { return 0; } 612 | inline CxxExpression *make_set_template_expression(CxxExpression *anExpr) { return 0; } 613 | inline CxxName *make_set_template_id(CxxName *aName) { return 0; } 614 | inline CxxName *make_set_template_name(CxxName *aName) { return 0; } 615 | inline CxxName *make_set_template_scope(CxxName *aName) { return 0; } 616 | inline CxxExpression *make_shift_left_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 617 | inline CxxExpression *make_shift_right_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 618 | inline CxxDeclaration *make_simple_declaration(CxxExpression *anExpr) { return 0; } 619 | inline CxxExpression *make_sizeof_expression(CxxExpression *anExpr) { return 0; } 620 | inline CxxStatements *make_statements(CxxStatements *, CxxStatement *aStmt) { return 0; } 621 | inline CxxExpression *make_static_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; } 622 | inline CxxExpression *make_string_literal_expression(CxxStrings *aString) { return 0; } 623 | inline CxxStrings *make_strings(CxxStringLiteral *anElement, CxxStrings *aList) { return 0; } 624 | inline CxxExpression *make_subtract_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; } 625 | inline CxxStatement *make_switch_statement(CxxCondition *testExpr, CxxStatement *aStmt) { return 0; } 626 | inline CxxExpression *make_syntax_macro_definition(CxxMetaType *metaType, CxxIsTree isTree, CxxName *aName, CxxSyntaxMacroParameters *aList, CxxToken *aBody) { return 0; } 627 | inline CxxSyntaxMacroParameter *make_syntax_macro_parameter(CxxToken *metaType, CxxIsTree isTree, CxxName *aName) { return 0; } 628 | inline CxxSyntaxMacroParameters *make_syntax_macro_parameters(CxxSyntaxMacroParameters *aList, CxxSyntaxMacroParameter *anElement) { return 0; } 629 | inline CxxTemplateArgument *make_template_argument(CxxParameter *aParameter) { return 0; } 630 | inline CxxTemplateArguments *make_template_arguments(CxxTemplateArguments *aList, CxxTemplateArgument *anElement) { return 0; } 631 | inline CxxDeclaration *make_template_declaration(CxxTemplateParameters *aList, CxxDeclaration *aDeclaration) { return 0; } 632 | inline CxxName *make_template_name(CxxName *aName, CxxTemplateArguments *templateArguments) { return 0; } 633 | inline CxxTemplateParameter *make_templated_template_parameter(CxxTemplateParameter *typeParameter, CxxName *aName) { return 0; } 634 | inline CxxTemplateParameter *make_template_parameter(CxxParameter *aParameter) { return 0; } 635 | inline CxxTemplateParameters *make_template_parameters(CxxTemplateParameters *aList, CxxTemplateParameter *anElement) { return 0; } 636 | inline CxxTemplatedTypeParameter *make_templated_type_parameter(CxxTemplateParameters *templateParameters, CxxName *aName) { return 0; } 637 | inline CxxExpression *make_this_expression() { return 0; } 638 | inline CxxExpression *make_throw_expression(CxxExpression *anExpr) { return 0; } 639 | inline CxxExpression *make_tokens_expression(CxxTokens *someTokens) { return 0; } 640 | inline CxxToken *make_tree_argument(CxxToken *aToken) { return 0; } 641 | inline CxxTokens *make_tree_arguments(CxxTokens *aList, CxxToken *anElement) { return 0; } 642 | inline CxxTreeExpression *make_tree_array_expression(CxxTreeExpression *anExpr, CxxExpression *indexExpr) { return 0; } 643 | inline CxxTreeExpression *make_tree_arrow_expression(CxxTreeExpression *anExpr, CxxName *aName) { return 0; } 644 | inline CxxTreeExpression *make_tree_call_expression(CxxTreeExpression *anExpr, CxxTokens *aList) { return 0; } 645 | inline CxxTreeExpression *make_tree_dot_expression(CxxTreeExpression *anExpr, CxxName *aName) { return 0; } 646 | inline CxxTreeExpression *make_tree_expression(CxxName *aName) { return 0; } 647 | inline CxxName *make_tree_id(CxxName *aName) { return 0; } 648 | inline CxxTreeExpression *make_tree_pointer_expression(CxxTreeExpression *anExpr) { return 0; } 649 | inline CxxExpression *make_true_expression() { return 0; } 650 | inline CxxFunctionBody *make_try_block(CxxStatement *aStatement, CxxHandlers *exceptionHandlers) { return 0; } 651 | inline CxxStatement *make_try_block_statement(CxxFunctionBody *tryBlock) { return 0; } 652 | inline CxxFunctionBody *make_try_function_block(CxxFunctionBody *functionBody, CxxHandlers *exceptionHandlers) { return 0; } 653 | inline CxxExpression *make_type1_expression(CxxExpression *functionName, CxxParenthesised *aParenthesis, CxxType1Parameters *type1Parameters) { return 0; } 654 | inline CxxTemplateParameter *make_type_template_parameter(CxxSimpleTypeParameter *typeParameter, CxxExpression *typeId) { return 0; } 655 | inline CxxExpression *make_typed_expression(CxxName *frontName, CxxExpression *backName) { return 0; } 656 | inline CxxName *make_typed_name(CxxName *frontName, CxxName *backName) { return 0; } 657 | inline CxxExpression *make_typeid_expression(CxxExpression *aList) { return 0; } 658 | inline CxxSimpleTypeParameter *make_typename_template_parameter(CxxName *aName) { return 0; } 659 | inline CxxSimpleTypeParameter *make_typename_type_parameter(CxxName *aName) { return 0; } 660 | inline CxxType1Parameters *make_type1_parameters(CxxType1Parameters *aList, CxxParameters *someParameters) { return 0; } 661 | inline CxxDeclaration *make_using_declaration(bool isTypename, CxxName *aName) { return 0; } 662 | inline CxxDeclaration *make_using_directive(CxxName *aName) { return 0; } 663 | inline CxxFunctionBody *make_using_function_block(CxxFunctionBody *functionBody, CxxFileIds *fileIds) { return 0; } 664 | inline CxxDeclaration *make_using_implementation_declaration(CxxFileId *fileId) { return 0; } 665 | inline CxxDeclaration *make_using_interface_declaration(CxxFileId *fileId) { return 0; } 666 | inline CxxUtility *make_utility(CxxUtility *aUtility) { return 0; } 667 | inline CxxUtility *make_utility_mode() { return 0; } 668 | inline CxxBaseSpecifier *make_virtual_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; } 669 | inline CxxStatement *make_while_statement(CxxCondition *testExpr, CxxStatement *aStmt) { return 0; } 670 | #endif -------------------------------------------------------------------------------- /CxxToken.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Title: C++ Grammar Token support compilation unit. 3 | // 4 | // File Name: CxxToken.cpp 5 | // 6 | // Author: E.D.Willink 7 | //END 8 | // 9 | #include 10 | -------------------------------------------------------------------------------- /CxxToken.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //CxxToken::CxxToken() 5 | //: 6 | // _value(0) 7 | //{} 8 | 9 | CxxNaffToken::CxxNaffToken(int tokenValue, const char *yyText, int yyLeng) 10 | : 11 | Super(tokenValue), _text(new char[yyLeng+1]), _leng(yyLeng) 12 | { 13 | memcpy(_text, yyText, yyLeng); 14 | _text[_leng] = 0; 15 | } 16 | 17 | CxxNaffToken::~CxxNaffToken() { delete[] _text; } 18 | -------------------------------------------------------------------------------- /CxxToken.hxx: -------------------------------------------------------------------------------- 1 | #ifndef CXXTOKEN_HXX 2 | #define CXXTOKEN_HXX 3 | 4 | #include 5 | #include 6 | 7 | #define YYSTYPE CxxTokenType 8 | //#define YYSTYPE_IS_DECLARED 1 9 | #define YY_parse_STYPE CxxTokenType 10 | #define YACC_BANG_TYPE size_t 11 | #define YACC_MARK_TYPE size_t 12 | 13 | #define YACC_BANG() push_bang() 14 | #define YACC_UNBANG(bangValue, msg) pop_bang(bangValue); yyerrok; yyclearin; yyerror(msg); 15 | 16 | #define ERRMSG(a) do { std::cout << "ERROR -- " << a << std::endl; increment_error_count(); } while (0) 17 | 18 | #ifdef NEEDS_BOOL 19 | enum bool { false, true }; 20 | #endif 21 | 22 | #ifdef BISON_PP_CLASS 23 | #define PARSE_TOKEN(a) BISON_PP_CLASS::a 24 | #else 25 | #define PARSE_TOKEN(a) a 26 | #endif 27 | 28 | extern size_t line_number; 29 | extern bool c_keywords; 30 | extern bool echo_line_numbers; 31 | extern bool echo_line_text; 32 | extern void increment_error_count(); 33 | extern int tokenMarkDepth; 34 | 35 | class CxxToken 36 | { 37 | int _value; 38 | private: 39 | CxxToken(const CxxToken&); 40 | CxxToken& operator=(const CxxToken&); 41 | public: 42 | CxxToken(int tokenValue = 0) : _value(tokenValue) {} 43 | virtual ~CxxToken() {} 44 | int value() const { return _value; } 45 | }; 46 | 47 | enum CxxIsTemplate { IS_DEFAULT, IS_TEMPLATE }; 48 | enum CxxIsTree { IS_SCALAR, IS_TREE }; 49 | typedef CxxToken CxxTreeArgument; 50 | 51 | class CxxStatement : public CxxToken {}; 52 | typedef CxxStatement CxxDeclaration; 53 | class CxxExpression : public CxxStatement {}; 54 | class CxxName : public CxxExpression {}; 55 | class CxxTokens : public CxxToken {}; 56 | class CxxMetaObject : public CxxExpression {}; 57 | class CxxMetaStatement : public CxxStatement {}; 58 | 59 | class CxxStatements : public CxxStatement {}; 60 | typedef CxxStatements CxxDeclarations; 61 | typedef CxxDeclarations CxxMemberDeclarations; 62 | typedef CxxExpression CxxTreeExpression; 63 | 64 | class CxxKeyword : public CxxName {}; 65 | class CxxDeclSpecifierId : public CxxKeyword {}; 66 | 67 | class CxxAccessSpecifier : public CxxKeyword {}; 68 | class CxxBaseSpecifier : public CxxToken {}; 69 | class CxxBaseSpecifiers : public CxxTokens {}; 70 | class CxxBrace : public CxxToken {}; 71 | class CxxBuiltInId : public CxxName {}; 72 | class CxxCharacterLiteral : public CxxToken {}; 73 | class CxxClass : public CxxToken {}; 74 | class CxxClassKey : public CxxKeyword {}; 75 | class CxxCondition : public CxxExpression {}; 76 | class CxxCvQualifiers : public CxxDeclSpecifierId {}; 77 | class CxxDeclarator : public CxxToken {}; 78 | typedef CxxExpression CxxDeleteExpression; 79 | //class CxxDerived : public CxxToken {}; 80 | //class CxxEnum : public CxxToken {}; 81 | class CxxEnumerator : public CxxToken {}; 82 | class CxxEnumerators : public CxxTokens {}; 83 | class CxxExceptionDeclaration : public CxxToken {}; 84 | class CxxExceptionSpecification : public CxxToken {}; 85 | class CxxExpressions : public CxxExpression {}; 86 | class CxxFileId : public CxxToken {}; 87 | class CxxFileIds : public CxxTokens {}; 88 | class CxxFileName : public CxxToken {}; 89 | class CxxFloatingLiteral : public CxxToken {}; 90 | class CxxFunctionBody : public CxxStatement {}; 91 | class CxxFunctionDeclarations : public CxxDeclarations {}; 92 | class CxxHandler : public CxxToken {}; 93 | class CxxHandlers : public CxxTokens {}; 94 | class CxxIdentifier : public CxxName {}; 95 | //class CxxIds : public CxxTokens {}; 96 | class CxxInitializerClause : public CxxExpression {}; 97 | class CxxInitializerClauses : public CxxInitializerClause {}; 98 | class CxxIntegerLiteral : public CxxToken {}; 99 | class CxxLine : public CxxToken {}; 100 | //class CxxList : public CxxTokens {}; 101 | class CxxMemInitializer : public CxxToken {}; 102 | class CxxMemInitializers : public CxxTokens {}; 103 | class CxxMetaClass : public CxxStatement {}; 104 | class CxxMetaFunction : public CxxMetaObject {}; 105 | class CxxMetaInitializer : public CxxToken {}; 106 | class CxxMetaInitializers : public CxxTokens {}; 107 | class CxxMetaParameter : public CxxToken {}; 108 | class CxxMetaParameters : public CxxTokens {}; 109 | //class CxxMetaPrototype : public CxxToken {}; 110 | //class CxxMetaPrototypes : public CxxTokens {}; 111 | class CxxMetaType : public CxxName {}; 112 | class CxxMetaVariable : public CxxMetaObject {}; 113 | class CxxNamespace : public CxxToken {}; 114 | typedef CxxExpression CxxNewExpression; 115 | class CxxNumberLiteral : public CxxExpression {}; 116 | class CxxParameter : public CxxExpression {}; 117 | class CxxParameters : public CxxExpression {}; 118 | class CxxParenthesised : public CxxToken {}; 119 | class CxxPointerDeclarator : public CxxDeclarator {}; 120 | class CxxPosition : public CxxName {}; 121 | class CxxSegment : public CxxName {}; 122 | class CxxSpacing : public CxxToken {}; 123 | class CxxStrings : public CxxToken {}; 124 | typedef CxxStrings CxxStringLiteral; 125 | class CxxSubspace : public CxxToken {}; 126 | class CxxSyntaxMacroParameter : public CxxToken {}; 127 | class CxxSyntaxMacroParameters : public CxxTokens {}; 128 | class CxxTemplateArgument : public CxxToken {}; 129 | class CxxTemplateArguments : public CxxTokens {}; 130 | class CxxTemplateParameter : public CxxToken {}; 131 | class CxxTemplateParameters : public CxxTokens {}; 132 | class CxxSimpleTypeParameter : public CxxTemplateParameter {}; 133 | class CxxTemplatedTypeParameter : public CxxTemplateParameter {}; 134 | class CxxTokenStatements : public CxxTokens {}; 135 | class CxxTreeArguments : public CxxTokens {}; 136 | class CxxType1Parameters : public CxxTokens {}; 137 | class CxxTypeId : public CxxToken {}; 138 | class CxxTypeIds : public CxxTokens {}; 139 | class CxxUtility : public CxxToken {}; 140 | 141 | #define FOGPARSERVALUE_ENUM(T,N) \ 142 | const T *name2(u_,N); \ 143 | const T& N() const { return *name2(u_,N); } \ 144 | const T* & N() { return name2(u_,N); } 145 | #define FOGPARSERVALUE_POINTER(T,N) T *N; 146 | #define FOGPARSERVALUE_VALUE(T,N) T N; 147 | 148 | union CxxTokenType 149 | { 150 | CxxToken *_token; 151 | 152 | FOGPARSERVALUE_VALUE(bool, _bool) 153 | FOGPARSERVALUE_VALUE(long, _long) 154 | FOGPARSERVALUE_POINTER(CxxBrace, brace) 155 | FOGPARSERVALUE_POINTER(CxxSpacing, spacing) 156 | 157 | FOGPARSERVALUE_POINTER(CxxAccessSpecifier, access_specifier) 158 | FOGPARSERVALUE_POINTER(CxxBaseSpecifier, base_specifier) 159 | FOGPARSERVALUE_POINTER(CxxBaseSpecifiers, base_specifiers) 160 | FOGPARSERVALUE_POINTER(CxxBuiltInId, built_in_id) 161 | FOGPARSERVALUE_POINTER(CxxCharacterLiteral, character_literal) 162 | FOGPARSERVALUE_POINTER(CxxClass, _class) 163 | FOGPARSERVALUE_POINTER(CxxClassKey, class_key) 164 | FOGPARSERVALUE_POINTER(CxxCondition, condition) 165 | FOGPARSERVALUE_POINTER(CxxCvQualifiers, cv_qualifiers) 166 | FOGPARSERVALUE_POINTER(CxxDeclSpecifierId, decl_specifier_id) 167 | FOGPARSERVALUE_POINTER(CxxDeclaration, declaration) 168 | FOGPARSERVALUE_POINTER(CxxDeclarations, declarations) 169 | FOGPARSERVALUE_POINTER(CxxDeclarator, declarator) 170 | FOGPARSERVALUE_POINTER(CxxDeleteExpression, delete_expression) 171 | FOGPARSERVALUE_POINTER(CxxEnumerator, enumerator) 172 | FOGPARSERVALUE_POINTER(CxxEnumerators, enumerators) 173 | FOGPARSERVALUE_POINTER(CxxExceptionDeclaration, exception_declaration) 174 | FOGPARSERVALUE_POINTER(CxxExceptionSpecification, exception_specification) 175 | FOGPARSERVALUE_POINTER(CxxExpression, expression) 176 | FOGPARSERVALUE_POINTER(CxxExpressions, expressions) 177 | FOGPARSERVALUE_POINTER(CxxFileId, file_id) 178 | FOGPARSERVALUE_POINTER(CxxFileIds, file_ids) 179 | FOGPARSERVALUE_POINTER(CxxFileName, file_name) 180 | FOGPARSERVALUE_POINTER(CxxFloatingLiteral, floating_literal) 181 | FOGPARSERVALUE_POINTER(CxxFunctionBody, function_body) 182 | FOGPARSERVALUE_POINTER(CxxHandler, handler) 183 | FOGPARSERVALUE_POINTER(CxxHandlers, handlers) 184 | FOGPARSERVALUE_POINTER(CxxIdentifier, identifier) 185 | FOGPARSERVALUE_POINTER(CxxInitializerClause, initializer_clause) 186 | FOGPARSERVALUE_POINTER(CxxInitializerClauses, initializer_clauses) 187 | FOGPARSERVALUE_POINTER(CxxIntegerLiteral, integer_literal) 188 | FOGPARSERVALUE_POINTER(CxxKeyword, keyword) 189 | FOGPARSERVALUE_POINTER(CxxLine, line) 190 | FOGPARSERVALUE_POINTER(CxxMemInitializer, mem_initializer) 191 | FOGPARSERVALUE_POINTER(CxxMemInitializers, mem_initializers) 192 | FOGPARSERVALUE_POINTER(CxxMemberDeclarations, member_declarations) 193 | FOGPARSERVALUE_POINTER(CxxMetaClass, meta_class) 194 | FOGPARSERVALUE_POINTER(CxxMetaFunction, meta_function) 195 | FOGPARSERVALUE_POINTER(CxxMetaInitializer, meta_initializer) 196 | FOGPARSERVALUE_POINTER(CxxMetaInitializers, meta_initializers) 197 | FOGPARSERVALUE_POINTER(CxxMetaObject, meta_object) 198 | FOGPARSERVALUE_POINTER(CxxMetaStatement, meta_statement) 199 | FOGPARSERVALUE_POINTER(CxxMetaType, meta_type) 200 | FOGPARSERVALUE_POINTER(CxxMetaVariable, meta_variable) 201 | FOGPARSERVALUE_POINTER(CxxName, name) 202 | FOGPARSERVALUE_POINTER(CxxNewExpression, new_expression) 203 | FOGPARSERVALUE_POINTER(CxxNumberLiteral, number_literal) 204 | FOGPARSERVALUE_POINTER(CxxParameter, parameter) 205 | FOGPARSERVALUE_POINTER(CxxParameters, parameters) 206 | FOGPARSERVALUE_POINTER(CxxParenthesised, parenthesised) 207 | FOGPARSERVALUE_POINTER(CxxPointerDeclarator, pointer_declarator) 208 | FOGPARSERVALUE_POINTER(CxxPosition, position) 209 | FOGPARSERVALUE_POINTER(CxxSegment, segment) 210 | FOGPARSERVALUE_POINTER(CxxSimpleTypeParameter, simple_type_parameter) 211 | FOGPARSERVALUE_POINTER(CxxStatement, statement) 212 | FOGPARSERVALUE_POINTER(CxxStatements, statements) 213 | FOGPARSERVALUE_POINTER(CxxStringLiteral, string_literal) 214 | FOGPARSERVALUE_POINTER(CxxStrings, strings) 215 | FOGPARSERVALUE_POINTER(CxxSubspace, subspace) 216 | FOGPARSERVALUE_POINTER(CxxSyntaxMacroParameter, syntax_macro_parameter) 217 | FOGPARSERVALUE_POINTER(CxxSyntaxMacroParameters, syntax_macro_parameters) 218 | FOGPARSERVALUE_POINTER(CxxTemplateArgument, template_argument) 219 | FOGPARSERVALUE_POINTER(CxxTemplateArguments, template_arguments) 220 | FOGPARSERVALUE_POINTER(CxxTemplateParameter, template_parameter) 221 | FOGPARSERVALUE_POINTER(CxxTemplateParameters, template_parameters) 222 | FOGPARSERVALUE_POINTER(CxxTemplatedTypeParameter, templated_type_parameter) 223 | FOGPARSERVALUE_POINTER(CxxToken, token) 224 | FOGPARSERVALUE_POINTER(CxxTokenStatements, token_statements) 225 | FOGPARSERVALUE_POINTER(CxxTokens, tokens) 226 | FOGPARSERVALUE_POINTER(CxxTreeArgument, tree_argument) 227 | FOGPARSERVALUE_POINTER(CxxTreeArguments, tree_arguments) 228 | FOGPARSERVALUE_POINTER(CxxTreeExpression, tree_expression) 229 | FOGPARSERVALUE_POINTER(CxxType1Parameters, type1_parameters) 230 | FOGPARSERVALUE_POINTER(CxxUtility, utility) 231 | 232 | FOGPARSERVALUE_VALUE(int, bang) 233 | FOGPARSERVALUE_VALUE(CxxIsTemplate, is_template) 234 | FOGPARSERVALUE_VALUE(YACC_MARK_TYPE, mark) 235 | FOGPARSERVALUE_VALUE(size_t, nest) 236 | #if 0 237 | CxxAccessSpecifier *access_specifier; 238 | CxxBaseSpecifier *base_specifier; 239 | CxxBaseSpecifiers *base_specifiers; 240 | CxxBuiltInId *built_in_id; 241 | CxxCharacterLiteral *character_literal; 242 | CxxClass *_class; 243 | CxxClassKey *class_key; 244 | CxxCondition *condition; 245 | CxxCvQualifiers *cv_qualifiers; 246 | CxxDeclaration *declaration; 247 | CxxDeclarations *declarations; 248 | CxxDeclarator *declarator; 249 | CxxDeclSpecifierId *decl_specifier_id; 250 | // CxxDerived *derived; 251 | // CxxEnum *_enum; 252 | CxxEnumerator *enumerator; 253 | CxxEnumerators *enumerators; 254 | CxxExceptionDeclaration *exception_declaration; 255 | CxxExceptionSpecification *exception_specification; 256 | CxxExpression *expression; 257 | CxxExpressions *expressions; 258 | CxxFileId *file_id; 259 | CxxFileIds *file_ids; 260 | CxxFileName *file_name; 261 | CxxFloatingLiteral *floating_literal; 262 | CxxFunctionBody *function_body; 263 | CxxFunctionDeclarations *function_declarations; 264 | CxxHandler *handler; 265 | CxxHandlers *handlers; 266 | CxxIdentifier *identifier; 267 | // CxxIds *ids; 268 | CxxInitializerClause *initializer_clause; 269 | CxxInitializerClauses *initializer_clauses; 270 | CxxIntegerLiteral *integer_literal; 271 | CxxKeyword *keyword; 272 | CxxLine *line; 273 | // CxxList *list; 274 | CxxMemInitializer *mem_initializer; 275 | CxxMemInitializers *mem_initializers; 276 | CxxMemberDeclarations *member_declarations; 277 | CxxMetaClass *meta_class; 278 | // CxxMetaFunction *meta_function; 279 | // CxxMetaInitializer *meta_initializer; 280 | // CxxMetaInitializers *meta_initializers; 281 | // CxxMetaObject *meta_object; 282 | CxxMetaParameter *meta_parameter; 283 | CxxMetaParameters *meta_parameters; 284 | // CxxMetaPrototype *meta_prototype; 285 | // CxxMetaPrototypes *meta_prototypes; 286 | // CxxMetaStatement *meta_statement; 287 | CxxMetaType *meta_type; 288 | // CxxMetaVariable *meta_variable; 289 | CxxName *name; 290 | // CxxNamespace *_namespace; 291 | CxxNumberLiteral *number_literal; 292 | CxxParameter *parameter; 293 | CxxParameters *parameters; 294 | CxxParenthesised *parenthesised; 295 | CxxPointerDeclarator *pointer_declarator; 296 | CxxSegment *segment; 297 | CxxSimpleTypeParameter *simple_type_parameter; 298 | CxxStatement *statement; 299 | CxxStatements *statements; 300 | CxxStringLiteral *string_literal; 301 | CxxStrings *strings; 302 | CxxSyntaxMacroParameter *syntax_macro_parameter; 303 | CxxSyntaxMacroParameters *syntax_macro_parameters; 304 | CxxTemplateArgument *template_argument; 305 | CxxTemplateArguments *template_arguments; 306 | CxxTemplateParameter *template_parameter; 307 | CxxTemplateParameters *template_parameters; 308 | CxxTemplatedTypeParameter *templated_type_parameter; 309 | CxxToken *token; 310 | CxxTokens *tokens; 311 | // CxxTreeArgument *tree_argument; 312 | // CxxTreeArguments *tree_arguments; 313 | // CxxTreeExpression *tree_expression; 314 | CxxType1Parameters *type1_parameters; 315 | // CxxTypeId *type_id; 316 | // CxxTypeIds *type_ids; 317 | CxxUtility *utility; 318 | YACC_BANG_TYPE bang; 319 | YACC_MARK_TYPE mark; 320 | size_t nest; 321 | #endif 322 | }; 323 | 324 | class CxxNaffToken : public CxxToken 325 | { 326 | typedef CxxToken Super; 327 | char *_text; 328 | int _leng; 329 | private: 330 | CxxNaffToken(const CxxNaffToken&); 331 | CxxNaffToken& operator=(const CxxNaffToken&); 332 | public: 333 | CxxNaffToken(int tokenValue, const char *yyText, int yyLeng); 334 | virtual ~CxxNaffToken(); 335 | }; 336 | 337 | #endif 338 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | FILES= CxxLexer.cpp CxxParser.cpp CxxToken.cpp 3 | INCLUDE = $(PWD) 4 | 5 | CppParser : CxxLexer.l CxxLexer.cpp CxxLexing.cxx CxxLexing.hxx CxxParser.y CxxToken.cpp CxxToken.cxx CxxToken.hxx 6 | bison -d -v CxxParser.y 7 | flex -o CxxLexer.lex.c CxxLexer.l 8 | g++ -I$(INCLUDE) $(FILES) -ly -lfl -o cppparser 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | cxxparser 2 | ========= 3 | 4 | A C++ parser for Lex and YACC (flex and bison). 5 | 6 | This is a yacc-able parser for the entire ISO C++ grammer with no unresolved conflicts.This project is forked from Willink's work. Please check Willink's Fog here. 7 | http://www.computing.surrey.ac.uk/research/dsrg/fog/ 8 | 9 | The reseaon I fork this project is I can't compile Fog on my OpenSuse. this version looks fine for me. 10 | 11 | ============================== 12 | Usage: 13 | 1. checkout source code; 14 | 2. "make" and you will get a cppparser 15 | 3. cppparser -c -t -y file.cpp 16 | --------------------------------------------------------------------------------