--- /dev/null
+//
+// Title: C++ Grammar Lexer support compilation unit.
+//
+// File Name: CxxLexer.cpp
+//
+// Author: E.D.Willink
+//END
+//
+#include <CxxLexer.cxx>
--- /dev/null
+/*
+ * Title: Miniature lexer for C++ parser.
+ *
+ * File Name: CxxLexer.l
+ *
+ * Author: E.D.Willink
+ *
+ * This is a complete lexer for C++, intended for use with CxxParser.y.
+ * All actions are done by macros, so that there is some chance that customisation
+ * can be performed within the bounds of the CxxLexing.hxx and CxxLexing.cxx
+ * include files.
+ *END
+ */
+%{
+#include <CxxLexing.hxx>
+%}
+%a 5000
+%e 1500
+%n 1000
+%o 10000
+%p 10000
+ws [ \f\v\t]
+
+digit [0-9]
+hex [0-9A-Fa-f]
+letter [A-Z_a-z]
+simple_escape_sequence (\\\'|\\\"|\\\?|\\\\|\\a|\\b|\\f|\\n|\\r|\\t|\\v)
+octal_escape_sequence (\\[0-7]|\\[0-7][0-7]|\\[0-7][0-7][0-7])
+hexadecimal_escape_sequence (\\x{hex}+)
+escape_sequence ({simple_escape_sequence}|{octal_escape_sequence}|{hexadecimal_escape_sequence})
+universal_character_name (\\u{hex}{hex}{hex}{hex}|\\U{hex}{hex}{hex}{hex}{hex}{hex}{hex}{hex})
+non_digit ({letter}|{universal_character_name})
+identifier ({non_digit}({non_digit}|{digit})*)
+
+character_lit (L?\'([^\'\\\n]|\\.)*)
+character_literal ({character_lit}\')
+
+string_lit (L?\"([^\"\\\n]|\\.)*)
+string_literal ({string_lit}\")
+
+pp_number (\.?{digit}({digit}|{non_digit}|[eE][-+]|\.)*)
+%%
+^.*\n { LEX_SAVE_LINE(yytext, yyleng); REJECT; }
+^{ws}*"#".* { /* Throw away preprocessor lines - hopefully only #line and equivalent. */ }
+
+{character_lit}\' { LEX_CHARACTER_TOKEN(yytext, yyleng-1); };
+{character_lit}\\ { ERRMSG("End of line assumed to terminate character with trailing escape.");
+ LEX_CHARACTER_TOKEN(yytext, yyleng-1); };
+{character_lit} { ERRMSG("End of line assumed to terminate character.");
+ LEX_CHARACTER_TOKEN(yytext, yyleng); };
+
+{string_lit}\" { LEX_STRING_TOKEN(yytext, yyleng-1); };
+{string_lit}\\ { ERRMSG("End of line assumed to terminate string with trailing escape.");
+ LEX_STRING_TOKEN(yytext, yyleng-1); };
+{string_lit} { ERRMSG("End of line assumed to terminate string.");
+ LEX_STRING_TOKEN(yytext, yyleng); };
+
+"asm" { LEX_STATIC_TOKEN(ASM); }
+"auto" { LEX_STATIC_TOKEN(AUTO); }
+"bool" { LEX_C_STATIC_TOKEN(BOOL); }
+"break" { LEX_STATIC_TOKEN(BREAK); }
+"case" { LEX_STATIC_TOKEN(CASE); }
+"catch" { LEX_C_STATIC_TOKEN(CATCH); }
+"char" { LEX_STATIC_TOKEN(CHAR); }
+"class" { LEX_C_STATIC_TOKEN(CLASS); }
+"const" { LEX_STATIC_TOKEN(CONST); }
+"const_cast" { LEX_C_STATIC_TOKEN(CONST_CAST); }
+"continue" { LEX_STATIC_TOKEN(CONTINUE); }
+"default" { LEX_STATIC_TOKEN(DEFAULT); }
+"delete" { LEX_C_STATIC_TOKEN(DELETE); }
+"do" { LEX_STATIC_TOKEN(DO); }
+"double" { LEX_STATIC_TOKEN(DOUBLE); }
+"dynamic_cast" { LEX_C_STATIC_TOKEN(DYNAMIC_CAST); }
+"else" { LEX_STATIC_TOKEN(ELSE); }
+"enum" { LEX_STATIC_TOKEN(ENUM); }
+"explicit" { LEX_C_STATIC_TOKEN(EXPLICIT); }
+"export" { LEX_C_STATIC_TOKEN(EXPORT); }
+"extern" { LEX_STATIC_TOKEN(EXTERN); }
+"false" { LEX_C_STATIC_TOKEN(FALSE); }
+"float" { LEX_STATIC_TOKEN(FLOAT); }
+"for" { LEX_STATIC_TOKEN(FOR); }
+"friend" { LEX_STATIC_TOKEN(FRIEND); }
+"goto" { LEX_STATIC_TOKEN(GOTO); }
+"if" { LEX_STATIC_TOKEN(IF); }
+"inline" { LEX_C_STATIC_TOKEN(INLINE); }
+"int" { LEX_STATIC_TOKEN(INT); }
+"long" { LEX_STATIC_TOKEN(LONG); }
+"mutable" { LEX_C_STATIC_TOKEN(MUTABLE); }
+"namespace" { LEX_C_STATIC_TOKEN(NAMESPACE); }
+"new" { LEX_C_STATIC_TOKEN(NEW); }
+"operator" { LEX_C_STATIC_TOKEN(OPERATOR); }
+"private" { LEX_C_STATIC_TOKEN(PRIVATE); }
+"protected" { LEX_C_STATIC_TOKEN(PROTECTED); }
+"public" { LEX_C_STATIC_TOKEN(PUBLIC); }
+"register" { LEX_STATIC_TOKEN(REGISTER); }
+"reinterpret_cast" { LEX_C_STATIC_TOKEN(REINTERPRET_CAST); }
+"return" { LEX_STATIC_TOKEN(RETURN); }
+"short" { LEX_STATIC_TOKEN(SHORT); }
+"signed" { LEX_C_STATIC_TOKEN(SIGNED); }
+"sizeof" { LEX_STATIC_TOKEN(SIZEOF); }
+"static" { LEX_STATIC_TOKEN(STATIC); }
+"static_cast" { LEX_C_STATIC_TOKEN(STATIC_CAST); }
+"struct" { LEX_STATIC_TOKEN(STRUCT); }
+"switch" { LEX_STATIC_TOKEN(SWITCH); }
+"template" { LEX_C_STATIC_TOKEN(TEMPLATE); }
+"this" { LEX_C_STATIC_TOKEN(THIS); }
+"throw" { LEX_C_STATIC_TOKEN(THROW); }
+"true" { LEX_C_STATIC_TOKEN(TRUE); }
+"try" { LEX_C_STATIC_TOKEN(TRY); }
+"typedef" { LEX_STATIC_TOKEN(TYPEDEF); }
+"typeid" { LEX_C_STATIC_TOKEN(TYPEID); }
+"typename" { LEX_C_STATIC_TOKEN(TYPENAME); }
+"union" { LEX_STATIC_TOKEN(UNION); }
+"unsigned" { LEX_STATIC_TOKEN(UNSIGNED); }
+"using" { LEX_C_STATIC_TOKEN(USING); }
+"virtual" { LEX_STATIC_TOKEN(VIRTUAL); }
+"void" { LEX_STATIC_TOKEN(VOID); }
+"volatile" { LEX_STATIC_TOKEN(VOLATILE); }
+"wchar_t" { LEX_C_STATIC_TOKEN(WCHAR_T); }
+"while" { LEX_STATIC_TOKEN(WHILE); }
+
+"::" { LEX_C_STATIC_TOKEN(SCOPE); }
+"..." { LEX_STATIC_TOKEN(ELLIPSIS); }
+"<<" { LEX_STATIC_TOKEN(SHL); }
+">>" { LEX_STATIC_TOKEN(SHR); }
+"==" { LEX_STATIC_TOKEN(EQ); }
+"!=" { LEX_STATIC_TOKEN(NE); }
+"<=" { LEX_STATIC_TOKEN(LE); }
+">=" { LEX_STATIC_TOKEN(GE); }
+"&&" { LEX_STATIC_TOKEN(LOG_AND); }
+"||" { LEX_STATIC_TOKEN(LOG_OR); }
+"++" { LEX_STATIC_TOKEN(INC); }
+"--" { LEX_STATIC_TOKEN(DEC); }
+"->*" { LEX_STATIC_TOKEN(ARROW_STAR); }
+"->" { LEX_STATIC_TOKEN(ARROW); }
+".*" { LEX_STATIC_TOKEN(DOT_STAR); }
+"+=" { LEX_STATIC_TOKEN(ASS_ADD); }
+"-=" { LEX_STATIC_TOKEN(ASS_SUB); }
+"*=" { LEX_STATIC_TOKEN(ASS_MUL); }
+"/=" { LEX_STATIC_TOKEN(ASS_DIV); }
+"%=" { LEX_STATIC_TOKEN(ASS_MOD); }
+"^=" { LEX_STATIC_TOKEN(ASS_XOR); }
+"&=" { LEX_STATIC_TOKEN(ASS_AND); }
+"|=" { LEX_STATIC_TOKEN(ASS_OR); }
+">>=" { LEX_STATIC_TOKEN(ASS_SHR); }
+"<<=" { LEX_STATIC_TOKEN(ASS_SHL); }
+
+{pp_number} { LEX_NUMBER_TOKEN(yytext, yyleng); }
+
+{identifier} { LEX_IDENTIFIER_TOKEN(yytext, yyleng); }
+
+{escape_sequence} |
+{universal_character_name} { LEX_ESCAPED_TOKEN(yytext, yyleng); }
+
+\n |
+{ws}+ { /* Throw away whitespace */ }
+. { LEX_ASCII_TOKEN(yytext[0]); }
+
+%%
+#include <CxxLexing.cxx>
--- /dev/null
+#ifdef FLEX_PP_CLASS
+FLEX_PP_CLASS theLexer;
+#define LEX_DOT theLexer .
+#else
+#define LEX_DOT
+#endif
+
+bool c_keywords = false;
+bool echo_line_numbers = false;
+bool echo_line_text = false;
+size_t line_number = 0;
+
+#ifdef NEEDS_YYWRAP
+int yywrap() { return 1; }
+#endif
+
+CxxToken *yylex_token()
+{
+ if (!LEX_DOT yylex())
+ return 0;
+ return yyToken;
+}
+
+//
+// Configure the lexer to reflect successful parsing of a character value, assigning it to yylval.
+//
+// The source someText[aLength] should correspond to the parsed text including any L or ' prefix
+// but excluding any ' suffix. In this way the return can indicate whether a wide character has
+// been detected and the routine can accommodate a variety of erroneous terminations.
+//
+CxxToken *make_character(const char *someText, size_t aLength)
+{
+ bool isWide = false;
+ if (someText && aLength)
+ {
+ if (*someText == 'L')
+ {
+ isWide = true;
+ someText++;
+ aLength--;
+ }
+ if (!aLength || (*someText != '\''))
+ ERRMSG("BUG - bad start of character literal.");
+ if (aLength)
+ {
+ someText++;
+ aLength--;
+ }
+ }
+ if (isWide)
+ return make_wide_character(someText, aLength);
+ else
+ return make_narrow_character(someText, aLength);
+}
+
+CxxToken *make_identifier(const char *someText, size_t aLength)
+{
+ return new CxxNaffToken(PARSE_TOKEN(Identifier), someText, aLength);
+}
+
+//
+// Buffer the incoming line, before any characters are analysed.
+//
+void make_line(const char *yyText, size_t yyLeng)
+{
+ if (echo_line_text)
+ cout << tokenMarkDepth << ": " << line_number << ": " << yyText << flush;
+ else if (echo_line_numbers)
+ cout << line_number << endl;
+ line_number++ ;
+}
+
+CxxToken *make_literal_character(const char *someText, size_t aLength)
+{
+ return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
+}
+
+CxxToken *make_narrow_character(const char *someText, size_t aLength)
+{
+ return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
+}
+
+CxxToken *make_narrow_string(const char *someText, size_t aLength)
+{
+ return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
+}
+
+CxxToken *make_number(const char *someText, size_t aLength)
+{
+ return new CxxNaffToken(PARSE_TOKEN(IntegerLiteral), someText, aLength);
+}
+
+//
+// Configure the lexer to reflect successful parsing of a categorised string.
+//
+// The source someText[aLength] should correspond to the parsed text including any
+// L or " prefix but excluding any " suffix. In this way the return can indicate whether a wide
+// character has been detected and the routine can accommodate a variety of erroneous terminations.
+//
+CxxToken *make_string(const char *someText, size_t aLength)
+{
+ bool isWide = false;
+ if (someText && aLength)
+ {
+ if (*someText == 'L')
+ {
+ isWide = true;
+ someText++;
+ aLength--;
+ }
+ if (!aLength || (*someText != '"'))
+ ERRMSG("BUG - bad start of string literal.");
+ if (aLength)
+ {
+ someText++;
+ aLength--;
+ }
+ }
+ if (isWide)
+ return make_wide_string(someText, aLength);
+ else
+ return make_narrow_string(someText, aLength);
+}
+
+//
+// Return the appropriate 1 of 256 flyweight tokens for the ASCII characters.
+//
+CxxToken *make_token(size_t tokenValue)
+{
+ static CxxToken *asciiTokens[256];
+ if (tokenValue >= (sizeof(asciiTokens)/sizeof(asciiTokens[0])))
+ {
+ ERRMSG("Cannot make_token for " << tokenValue);
+ return 0;
+ }
+ CxxToken **p = &asciiTokens[tokenValue];
+ CxxToken *theToken = *p;
+ if (!theToken)
+ *p = theToken = new CxxToken(tokenValue);
+ return theToken;
+}
+
+CxxToken *make_wide_character(const char *someText, size_t aLength)
+{
+ return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
+}
+
+CxxToken *make_wide_string(const char *someText, size_t aLength)
+{
+ return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
+}
+
--- /dev/null
+#include <CxxToken.hxx>
+
+#include <CxxParser.hxx>
+
+static CxxToken *yyToken;
+static CxxToken *make_character(const char *someText, size_t aLength);
+static CxxToken *make_string(const char *someText, size_t aLength);
+static CxxToken *make_identifier(const char *someText, size_t aLength);
+static void make_line(const char *yyText, size_t yyLeng);
+static CxxToken *make_literal_character(const char *someText, size_t aLength);
+static CxxToken *make_narrow_character(const char *someText, size_t aLength);
+static CxxToken *make_narrow_string(const char *someText, size_t aLength);
+static CxxToken *make_number(const char *someText, size_t aLength);
+static CxxToken *make_token(size_t aCxxToken);
+static CxxToken *make_wide_character(const char *someText, size_t aLength);
+static CxxToken *make_wide_string(const char *someText, size_t aLength);
+
+#define LEX_SAVE_LINE(yyText, yyLeng) make_line(yyText, yyLeng);
+#define LEX_ASCII_TOKEN(a) yyToken = make_token(a); return true;
+#define LEX_STATIC_TOKEN(a) static CxxToken theToken(PARSE_TOKEN(a)); yyToken = &theToken; return true;
+#define LEX_C_STATIC_TOKEN(a) \
+ if (c_keywords) { LEX_IDENTIFIER_TOKEN(yytext, yyleng) } \
+ else { LEX_STATIC_TOKEN(a) } return true;
+#define LEX_ESCAPED_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(CharacterLiteral)
+// yyToken = make_literal_character(yytext, yyleng); return true;
+#define LEX_CHARACTER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(CharacterLiteral)
+// yyToken = make_character(yyText, yyLeng); return true;
+#define LEX_STRING_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(StringLiteral)
+// yyToken = make_string(yyText, yyLeng); return true;
+#define LEX_IDENTIFIER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(Identifier)
+// yyToken = make_identifier(yyText, yyLeng); return true;
+#define LEX_NUMBER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(IntegerLiteral)
+// yyToken = make_number(yyText, yyLeng); return true;
--- /dev/null
+//
+// Title: C++ Grammar Parser support compilation unit.
+//
+// File Name: CxxParser.cpp
+//
+// Author: E.D.Willink
+//END
+//
+#include <CxxParser.cxx>
+
--- /dev/null
+/* This is a yacc-able parser for the entire ISO C++ grammar with no unresolved conflicts. */
+/* The parse is SYNTACTICALLY consistent and requires no template or type name assistance.
+ * The grammar in the C++ standard notes that its grammar is a superset of the true
+ * grammar requiring semantic constraints to resolve ambiguities. This grammar is a really big
+ * superset unifying expressions and declarations, eliminating the type/non-type distinction,
+ * and iterating to find a consistent solution to the template/arith,metoic < ambiguity.
+ * As a result the grammar is much simpler, but requires the missing semantic constraints to be
+ * performed in a subsequent semantic pass, which is of course where they belong. This grammar will
+ * support conversion of C++ tokens into an Abstract Syntax Tree. A lot of further work is required to
+ * make that tree useful.
+ *
+ * The principles behind this grammar are described in my thesis on Meta-Compilation for C++, which
+ * may be found via http://www.computing.surrey.ac.uk/research/dsrg/fog/FogThesis.html.
+ *
+ * Author: E.D.Willink Ed.Willink@rrl.co.uk
+ * Date: 19-Jun-2001
+ */
+/*StartTester*/
+%{
+#include <CxxParsing.hxx>
+%}
+/*EndTester*/
+/*
+ * The lexer (and/or a preprocessor) is expected to identify the following
+ *
+ * Punctuation:
+ */
+%type <keyword> '+' '-' '*' '/' '%' '^' '&' '|' '~' '!' '<' '>' '=' ':' '[' ']' '{' '}' '(' ')'
+%type <keyword> '?' '.' '\'' '\"' '\\' '@' '$' ';' ','
+/*
+ * Punctuation sequences
+ */
+%term <keyword> ARROW ARROW_STAR DEC EQ GE INC LE LOG_AND LOG_OR NE SHL SHR
+%term <keyword> ASS_ADD ASS_AND ASS_DIV ASS_MOD ASS_MUL ASS_OR ASS_SHL ASS_SHR ASS_SUB ASS_XOR
+%term <keyword> DOT_STAR ELLIPSIS SCOPE
+/*
+ * Reserved words
+ */
+%term <access_specifier> PRIVATE PROTECTED PUBLIC
+%term <built_in_id> BOOL CHAR DOUBLE FLOAT INT LONG SHORT SIGNED UNSIGNED VOID WCHAR_T
+%term <class_key> CLASS ENUM NAMESPACE STRUCT TYPENAME UNION
+%term <cv_qualifiers> CONST VOLATILE
+%term <decl_specifier_id> AUTO EXPLICIT EXPORT EXTERN FRIEND INLINE MUTABLE REGISTER STATIC TEMPLATE TYPEDEF USING VIRTUAL
+%term <keyword> ASM BREAK CASE CATCH CONST_CAST CONTINUE DEFAULT DELETE DO DYNAMIC_CAST
+%term <keyword> ELSE FALSE FOR GOTO IF NEW OPERATOR REINTERPRET_CAST RETURN
+%term <keyword> SIZEOF STATIC_CAST SWITCH THIS THROW TRUE TRY TYPEID WHILE
+/*
+ * Parametric values.
+ */
+%term <character_literal> CharacterLiteral
+%term <floating_literal> FloatingLiteral
+%term <identifier> Identifier
+%term <integer_literal> IntegerLiteral
+%term <number_literal> NumberLiteral
+%term <string_literal> StringLiteral
+/*
+ * The lexer need not treat '0' as distinct from IntegerLiteral in the hope that pure-specifier can
+ * be distinguished, It isn't. Semantic rescue from = constant-expression is necessary.
+ *
+ * The lexer is not required to distinguish template or type names, although a slight simplification to the
+ * grammar and elaboration of the action rules could make good use of template name information.
+ *
+ * In return for not needing to use semantic information, the lexer must support back-tracking, which
+ * is easily achieved by a simple linear buffer, a reference implementation of which may be found in the
+ * accompanying CxxParsing.cxx. Back-tracking is used to support:
+ *
+ * Binary search for a consistent parse of the template/arithmetic ambiguity.
+ * start_search() initialises the search
+ * advance_search() iterates the search
+ * end_search() cleans up after a search
+ * template_test() maintains context during a search
+ *
+ * Lookahead to resolve the inheritance/anonymous bit-field similarity
+ * mark() saves the starting context
+ * unmark() pops it
+ * rewind_colon() restores the context and forces the missing :
+ *
+ * Lookahead to resolve type 1 function parameter ambiguities
+ * mark_type1() potentially marks the starting position
+ * mark() marks the pre { position
+ * remark() rewinds to the starting position
+ * unmark() pops the starting position
+ *
+ * Note that lookaheads may nest.
+ */
+
+/*
+ * The parsing philosophy is unusual. The major ambiguities are resolved by creating a unified superset
+ * grammar rather than non-overlapping subgrammars. Thus the grammar for parameter-declaration covers an
+ * assignment-expression. Minor ambiguities whose resolution by supersetting would create more
+ * ambiguities are resolved the normal way with partitioned subgrammars.
+ * This eliminates the traditional expression/declaration and constructor/parenthesised declarator
+ * ambiguities at the syntactic level. A subsequent semantic level has to sort the problems out.
+ * The generality introduces four bogus ambiguities and defers the cast ambiguity for resolution
+ * once semantic information is available.
+ *
+ * The C++ grammar comprises 561 rules and uses 897 states in yacc, with 0 unresolved conflicts.
+ * 23 conflicts from 10 ambiguities are resolved by 8 %prec's, so that yacc and bison report 0 conflicts.
+ *
+ * The ambiguities are:
+ * 1) dangling else resolved to inner-most if
+ * 1 conflict in 1 state on else
+ * 2) < as start-template or less-than
+ * 1 conflict in 1 states on <
+ * 3) a :: b :: c resolved to favour a::b::c rather than a::b ::c or a ::b::c
+ * 1 conflicts in 1 state for ::
+ * 4) pointer operators maximised at end of conversion id/new in preference to binary operators
+ * 2 conflicts in 4 states on * and &
+ * 5a) (a)@b resolved to favour binary a@b rather than cast unary (a)(@b)
+ * 5b) (a)(b) resolved to favour cast rather than call
+ * 8 conflicts in 1 state for the 8 prefix operators: 6 unaries and ( and [.
+ * 6) enum name { resolved to enum-specifier rather than function
+ * 1 conflict in 1 state on {
+ * 7) class name { resolved to class-specifier rather than function
+ * 1 conflict in 1 state on {
+ * 8) extern "C" resolved to linkage-specification rather than declaration
+ * 1 conflict in 1 state on StringLiteral
+ * 9) class X : forced to go through base-clause look-ahead
+ * 1 conflict in 1 state on :
+ * 10) id : forced to label_statement rather than constructor_head
+ * 0 conflicts - but causes a double state for 2)
+ * of which
+ * 1 is a fundamental C conflict - always correctly resolved
+ * can be removed - see the Java spec
+ * 2, 3, 4 are fundamental C++ conflicts
+ * 2 always consistently resolved by iteration
+ * 3 always correctly resolved
+ * 4 always correctly resolved
+ * 5 is a result of not using type information - deferred for semantic repair
+ * 6,7 are caused by parsing over-generous superset - always correctly resolved
+ * 8 is caused by parsing over-generous superset - always correctly resolved
+ * can be removed at the expense of 7 rules and 5 states.
+ * 9 is a look-ahead trick - always correctly resolved
+ * could be removed by marking one token sooner
+ * 10 is caused by parsing over-generous superset - always correctly resolved
+ *
+ * The hard problem of distinguishing
+ * class A { class B : C, D, E { -- A::B privately inherits C, D and E
+ * class A { class B : C, D, E ; -- C is width of anon bit-field
+ * is resolved by using a lookahead that assumes inheritance and rewinds for the bit-field.
+ *
+ * The potential shift-reduce conflict on > is resolved by flattening part of the expression grammar
+ * to know when the next > is template end or arithmetic >.
+ *
+ * The grammar is SYNTACTICALLY context-free with respect to type. No semantic assistance is required
+ * during syntactic analysis. However the cast ambiguity is deferred and must be recovered
+ * after syntactic analysis of a statement has completed.
+ *
+ * The grammar is SYNTACTICALLY context-free with respect to template-names. This is achieved by
+ * organising a binary search over all possible template/arithmetic ambiguities with respect to
+ * the enclosing statement. This is potentially exponentially inefficient but well-behaved in practice.
+ * Approximately 1% of statements trigger a search and approximately 1% of those are misparsed,
+ * requiring the semantic analysis to check and correct once template information is available.
+ * 1.5 parse attempts are required on average per ambiguous statement.
+ *
+ * The grammar supports type I function declarations at severe impediment to efficiency. A lookahead
+ * has to be performed after almost every non-statement close parenthesis. A one-line plus corollary
+ * change to postfix_expression is commented and strongly recommended to make this grammar as
+ * efficient as the rather large number of reduction levels permits.
+ *
+ * Error recovery occurs mostly at the statement/declaration level. Recovery also occurs at
+ * the list-element level where this poses no hazard to statement/declaration level recovery.
+ * Note that since error propagation interacts with the lookaheads for template iteration or
+ * type 1 function arguments, introduction of finer grained error recovery may repair a false
+ * parse and so cause a misparse.
+ *
+ * The following syntactic analysis errors occur, but are correctable semantically:
+ * (cast)unary-op expr is parsed as (parenthesised)binary-op expr
+ * The semantic test should look for a binary/call with a (type) as its left child.
+ * (parenthesised)(arguments) is parsed as (cast)(parenthesised)
+ * The semantic test should look for a cast with a non-type as its left child.
+ * template < and arithmetic < may be cross-parsed (unless semnatic help is provided)
+ * approximately 0.01% are misparsed, and must be sorted out - not easy.
+ *
+ * The syntactic analysis defers the following ambiguities for semantic resolution:
+ * declaration/expression is parsed as a unified concept
+ * Use type and context to complete the parse.
+ * ~class-name is parsed as unary~ name
+ * The semantic test should look for ~ with a type as its child.
+ * delete[] expr is parsed as delete []expr
+ * The semantic test should look for delete with a [] cast of its child.
+ * operator new/delete[] are parsed as array of operator new/delete
+ * The semantic test should look for array of operator new/delete
+ * or activate the two extra commented rules in operator
+ * template of an explicit_instantiation is buried deep in the tree
+ * dig it out
+ * pure-specifier and constant-initializer are covered by assignment-expression
+ * just another of the deferred declaration/expression ambiguities
+ * sizeof and typeid don't distinguish type/value syntaxes
+ * probably makes life polymorphically easier
+ */
+/* Action code is supplied by a large number of YACC_xxx macros that can be redefined
+ * by rewriting the include file rather than the grammar. The number of macros is
+ * slightly reduced by using the following protocols
+ *
+ * YACC_LIST(0,0) create empty list (may safely return 0).
+ * YACC_LIST(0,E) create new list with content E (may return 0 if above returned non-0).
+ * YACC_LIST(L,E) add E to L
+ * YACC_LIST(L,0) error propagation, adding nothing to L.
+ */
+%type <bang> bang
+%type <mark> colon_mark mark mark_type1
+%type <nest> nest
+
+%type <access_specifier> access_specifier
+%type <base_specifier> base_specifier
+%type <base_specifiers> base_specifier_list
+%type <built_in_id> built_in_type_id built_in_type_specifier
+%type <_class> class_specifier_head
+%type <class_key> class_key
+%type <condition> condition condition.opt
+%type <cv_qualifiers> cv_qualifier cv_qualifier_seq.opt
+%type <decl_specifier_id> decl_specifier_affix decl_specifier_prefix decl_specifier_suffix function_specifier storage_class_specifier
+%type <declaration> accessibility_specifier asm_definition block_declaration declaration explicit_specialization
+%type <declaration> looped_declaration looping_declaration namespace_alias_definition
+%type <declaration> specialised_block_declaration specialised_declaration template_declaration using_directive
+%type <declarations> compound_declaration declaration_seq.opt
+%type <declarator> nested_ptr_operator ptr_operator
+%type <delete_expression> delete_expression
+%type <enumerator> enumerator_definition
+%type <enumerators> enumerator_clause enumerator_list enumerator_list_head
+%type <exception_declaration> exception_declaration
+%type <exception_specification> exception_specification
+%type <expression> abstract_declarator.opt abstract_expression abstract_parameter_declaration abstract_pointer_declaration
+%type <expression> additive_expression and_expression assignment_expression
+%type <expression> bit_field_declaration bit_field_init_declaration bit_field_width boolean_literal
+%type <expression> cast_expression conditional_expression constant_expression conversion_type_id ctor_definition
+%type <expression> direct_abstract_declarator direct_abstract_declarator.opt direct_new_declarator
+%type <expression> equality_expression exclusive_or_expression expression expression.opt
+%type <expression> for_init_statement func_definition function_definition
+%type <expression> inclusive_or_expression init_declaration literal logical_and_expression logical_or_expression
+%type <expression> multiplicative_expression new_declarator new_type_id
+%type <expression> pm_expression postfix_expression primary_expression ptr_operator_seq ptr_operator_seq.opt
+%type <expression> relational_expression shift_expression simple_declaration special_parameter_declaration
+%type <expression> templated_throw_expression throw_expression templated_abstract_declaration templated_and_expression
+%type <expression>templated_assignment_expression templated_conditional_expression templated_equality_expression
+%type <expression> templated_exclusive_or_expression templated_expression templated_inclusive_or_expression templated_logical_and_expression
+%type <expression> templated_logical_or_expression templated_relational_expression type_id unary_expression
+%type <expressions> constructor_head expression_list expression_list.opt init_declarations
+%type <expressions> new_initializer.opt templated_expression_list type_id_list
+%type <function_body> function_block function_body function_try_block try_block
+%type <handler> handler
+%type <handlers> handler_seq
+%type <initializer_clause> braced_initializer initializer_clause looped_initializer_clause looping_initializer_clause
+%type <initializer_clauses> initializer_list
+%type <is_template> global_scope
+%type <keyword> assignment_operator
+%type <line> start_search start_search1
+%type <mem_initializer> mem_initializer
+%type <mem_initializers> ctor_initializer ctor_initializer.opt mem_initializer_list mem_initializer_list_head
+%type <name> class_specifier conversion_function_id declarator_id destructor_id
+%type <name> elaborated_class_specifier elaborated_enum_specifier elaborated_type_specifier elaborate_type_specifier
+%type <name> enum_specifier enumerator id identifier_word id_scope identifier linkage_specification
+%type <name> namespace_definition nested_id nested_pseudo_destructor_id nested_special_function_id
+%type <name> mem_initializer_id operator operator_function_id pseudo_destructor_id scoped_id scoped_pseudo_destructor_id scoped_special_function_id
+%type <name> simple_type_specifier special_function_id suffix_built_in_decl_specifier suffix_named_decl_specifier.bi
+%type <name> suffix_built_in_decl_specifier.raw suffix_decl_specified_ids suffix_named_decl_specifiers
+%type <name> suffix_named_decl_specifiers.sf suffix_decl_specified_scope suffix_named_decl_specifier
+%type <name> template_id type_specifier
+%type <new_expression> new_expression
+%type <parameter> parameter_declaration templated_parameter_declaration
+%type <parameters> parameters_clause parameter_declaration_clause parameter_declaration_list
+%type <parenthesised> parenthesis_clause
+%type <pointer_declarator> star_ptr_operator
+%type <simple_type_parameter> simple_type_parameter
+%type <statement> compound_statement control_statement declaration_statement iteration_statement jump_statement
+%type <statement> labeled_statement looped_statement looping_statement selection_statement statement
+%type <statements> statement_seq.opt
+%type <strings> string
+%type <template_argument> template_argument
+%type <template_arguments> template_argument_list
+%type <template_parameter> template_parameter
+%type <template_parameters> template_parameter_clause template_parameter_list
+%type <templated_type_parameter> templated_type_parameter
+%type <type1_parameters> type1_parameters
+%type <utility> util
+
+/*
+ * C++ productions replaced by more generalised FOG productions
+ */
+%type <declaration> looped_member_declaration looping_member_declaration member_declaration using_declaration
+%type <declarations> member_specification.opt
+%type <expression> member_init_declaration simple_member_declaration
+%type <expressions> member_init_declarations
+
+\f
+%nonassoc SHIFT_THERE
+%nonassoc SCOPE ELSE INC DEC '+' '-' '*' '&' '[' '{' '<' ':' StringLiteral
+%nonassoc REDUCE_HERE_MOSTLY
+%nonassoc '('
+/*%nonassoc REDUCE_HERE */
+
+%start translation_unit
+%%
+
+/*
+ * The %prec resolves a conflict in identifier_word : which is forced to be a shift of a label for
+ * a labeled-statement rather than a reduction for the name of a bit-field or generalised constructor.
+ * This is pretty dubious syntactically but correct for all semantic possibilities.
+ * The shift is only activated when the ambiguity exists at the start of a statement. In this context
+ * a bit-field declaration or constructor definition are not allowed.
+ */
+identifier_word: Identifier { $$ = $1; }
+identifier: identifier_word %prec SHIFT_THERE
+/*
+ * The %prec resolves the $014.2-3 ambiguity:
+ * Identifier '<' is forced to go through the is-it-a-template-name test
+ * All names absorb TEMPLATE with the name, so that no template_test is performed for them.
+ * This requires all potential declarations within an expression to perpetuate this policy
+ * and thereby guarantee the ultimate coverage of explicit_instantiation.
+ */
+id: identifier %prec SHIFT_THERE /* Force < through test */ { $$ = YACC_NAME($1); }
+ | identifier template_test '+' template_argument_list '>' { $$ = YACC_TEMPLATE_NAME($1, $4); }
+ | identifier template_test '+' '>' { $$ = $1; ERRMSG("Empty template-argument-list"); }
+ | identifier template_test '-' /* requeued < follows */ { $$ = YACC_NAME($1); }
+ | template_id
+template_test: '<' /* Queue '+' or '-' < as follow on */ { template_test(); }
+global_scope: SCOPE { $$ = IS_DEFAULT; }
+ | TEMPLATE global_scope { $$ = IS_TEMPLATE; }
+id_scope: id SCOPE { $$ = YACC_NESTED_SCOPE($1); }
+/*
+ * A :: B :: C; is ambiguous How much is type and how much name ?
+ * The %prec maximises the (type) length which is the $07.1-2 semantic constraint.
+ */
+nested_id: id %prec SHIFT_THERE /* Maximise length */
+ | id_scope nested_id { $$ = YACC_NESTED_ID($1, $2); }
+scoped_id: nested_id
+ | global_scope nested_id { $$ = YACC_GLOBAL_ID($1, $2); }
+
+/*
+ * destructor_id has to be held back to avoid a conflict with a one's complement as per $05.3.1-9,
+ * It gets put back only when scoped or in a declarator_id, which is only used as an explicit member name.
+ * Declarations of an unscoped destructor are always parsed as a one's complement.
+ */
+destructor_id: '~' id { $$ = YACC_DESTRUCTOR_ID($2); }
+ | TEMPLATE destructor_id { $$ = YACC_SET_TEMPLATE_ID($2); }
+special_function_id: conversion_function_id
+ | operator_function_id
+ | TEMPLATE special_function_id { $$ = YACC_SET_TEMPLATE_ID($2); }
+nested_special_function_id: special_function_id
+ | id_scope destructor_id { $$ = YACC_NESTED_ID($1, $2); }
+ | id_scope nested_special_function_id { $$ = YACC_NESTED_ID($1, $2); }
+scoped_special_function_id: nested_special_function_id
+ | global_scope nested_special_function_id { $$ = YACC_GLOBAL_ID($1, $2); }
+
+/* declarator-id is all names in all scopes, except reserved words */
+declarator_id: scoped_id
+ | scoped_special_function_id
+ | destructor_id
+
+/* The standard defines pseudo-destructors in terms of type-name, which is class/enum/typedef, of which
+ * class-name is covered by a normal destructor. pseudo-destructors are supposed to support ~int() in
+ * templates, so the grammar here covers built-in names. Other names are covered by the lack of
+ * identifier/type discrimination.
+ */
+built_in_type_id: built_in_type_specifier
+ | built_in_type_id built_in_type_specifier { $$ = YACC_BUILT_IN_IDS($1, $2); }
+pseudo_destructor_id: built_in_type_id SCOPE '~' built_in_type_id { $$ = YACC_PSEUDO_DESTRUCTOR_ID($1, $4); }
+ | '~' built_in_type_id { $$ = YACC_PSEUDO_DESTRUCTOR_ID(0, $2); }
+ | TEMPLATE pseudo_destructor_id { $$ = YACC_SET_TEMPLATE_ID($2); }
+nested_pseudo_destructor_id: pseudo_destructor_id
+ | id_scope nested_pseudo_destructor_id { $$ = YACC_NESTED_ID($1, $2); }
+scoped_pseudo_destructor_id: nested_pseudo_destructor_id
+ | global_scope scoped_pseudo_destructor_id { $$ = YACC_GLOBAL_ID($1, $2); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.2 Lexical conventions
+ *---------------------------------------------------------------------------------------------------*/
+/*
+ * String concatenation is a phase 6, not phase 7 activity so does not really belong in the grammar.
+ * However it may be convenient to have it here to make this grammar fully functional.
+ * Unfortunately it introduces a conflict with the generalised parsing of extern "C" which
+ * is correctly resolved to maximise the string length as the token source should do anyway.
+ */
+string: StringLiteral { $$ = $1; }
+/*string: StringLiteral %prec SHIFT_THERE { $$ = YACC_STRINGS($1, 0); } */
+/* | StringLiteral string -- Perverse order avoids conflicts -- { $$ = YACC_STRINGS($1, $2); } */
+literal: IntegerLiteral { $$ = YACC_INTEGER_LITERAL_EXPRESSION($1); }
+ | CharacterLiteral { $$ = YACC_CHARACTER_LITERAL_EXPRESSION($1); }
+ | FloatingLiteral { $$ = YACC_FLOATING_LITERAL_EXPRESSION($1); }
+ | string { $$ = YACC_STRING_LITERAL_EXPRESSION($1); }
+ | boolean_literal
+boolean_literal: FALSE { $$ = YACC_FALSE_EXPRESSION(); }
+ | TRUE { $$ = YACC_TRUE_EXPRESSION(); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.3 Basic concepts
+ *---------------------------------------------------------------------------------------------------*/
+translation_unit: declaration_seq.opt { YACC_RESULT($1); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.4 Expressions
+ *---------------------------------------------------------------------------------------------------
+ * primary_expression covers an arbitrary sequence of all names with the exception of an unscoped destructor,
+ * which is parsed as its unary expression which is the correct disambiguation (when ambiguous).
+ * This eliminates the traditional A(B) meaning A B ambiguity, since we never have to tack an A onto
+ * the front of something that might start with (. The name length got maximised ab initio. The downside
+ * is that semantic interpretation must split the names up again.
+ *
+ * Unification of the declaration and expression syntax means that unary and binary pointer declarator operators:
+ * int * * name
+ * are parsed as binary and unary arithmetic operators (int) * (*name). Since type information is not used
+ * ambiguities resulting from a cast
+ * (cast)*(value)
+ * are resolved to favour the binary rather than the cast unary to ease AST clean-up.
+ * The cast-call ambiguity must be resolved to the cast to ensure that (a)(b)c can be parsed.
+ *
+ * The problem of the functional cast ambiguity
+ * name(arg)
+ * as call or declaration is avoided by maximising the name within the parsing kernel. So
+ * primary_id_expression picks up
+ * extern long int const var = 5;
+ * as an assignment to the syntax parsed as "extern long int const var". The presence of two names is
+ * parsed so that "extern long into const" is distinguished from "var" considerably simplifying subsequent
+ * semantic resolution.
+ *
+ * The generalised name is a concatenation of potential type-names (scoped identifiers or built-in sequences)
+ * plus optionally one of the special names such as an operator-function-id, conversion-function-id or
+ * destructor as the final name.
+ */
+primary_expression: literal
+ | THIS { $$ = YACC_THIS_EXPRESSION(); }
+ | suffix_decl_specified_ids { $$ = $1; }
+/* | SCOPE identifier -- covered by suffix_decl_specified_ids */
+/* | SCOPE operator_function_id -- covered by suffix_decl_specified_ids */
+/* | SCOPE qualified_id -- covered by suffix_decl_specified_ids */
+ | abstract_expression %prec REDUCE_HERE_MOSTLY /* Prefer binary to unary ops, cast to call */
+/* | id_expression -- covered by suffix_decl_specified_ids */
+
+/*
+ * Abstract-expression covers the () and [] of abstract-declarators.
+ */
+abstract_expression: parenthesis_clause { $$ = YACC_ABSTRACT_FUNCTION_EXPRESSION($1); }
+ | '[' expression.opt ']' { $$ = YACC_ABSTRACT_ARRAY_EXPRESSION($2); }
+ | TEMPLATE parenthesis_clause { $$ = YACC_SET_TEMPLATE_EXPRESSION(YACC_ABSTRACT_FUNCTION_EXPRESSION($2)); }
+
+/* Type I function parameters are ambiguous with respect to the generalised name, so we have to do a lookahead following
+ * any function-like parentheses. This unfortunately hits normal code, so kill the -- lines and add the ++ lines for efficiency.
+ * Supporting Type I code under the superset causes perhaps 25% of lookahead parsing. Sometimes complete class definitions
+ * get traversed since they are valid generalised type I parameters!
+ */
+type1_parameters: /*----*/ parameter_declaration_list ';' { $$ = YACC_TYPE1_PARAMETERS(0, $1); }
+ | /*----*/ type1_parameters parameter_declaration_list ';' { $$ = YACC_TYPE1_PARAMETERS($1, $2); }
+mark_type1: /* empty */ { $$ = mark_type1(); }
+postfix_expression: primary_expression
+/* | /++++++/ postfix_expression parenthesis_clause { $$ = YACC_CALL_EXPRESSION($1, $2); } */
+ | /*----*/ postfix_expression parenthesis_clause mark_type1 '-' { $$ = YACC_CALL_EXPRESSION($1, $2); }
+ | /*----*/ postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark '{' error
+ /*----*/ { yyerrok; remark_type1($6); unmark(); unmark($5); $$ = YACC_TYPE1_EXPRESSION($1, $2, $5); }
+ | /*----*/ postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark error
+ /*----*/ { yyerrok; remark_type1($3); unmark(); unmark(); $$ = YACC_CALL_EXPRESSION($1, $2); }
+ | /*----*/ postfix_expression parenthesis_clause mark_type1 '+' error
+ /*----*/ { yyerrok; remark_type1($3); unmark(); $$ = YACC_CALL_EXPRESSION($1, $2); }
+ | postfix_expression '[' expression.opt ']' { $$ = YACC_ARRAY_EXPRESSION($1, $3); }
+/* | destructor_id '[' expression.opt ']' -- not semantically valid */
+/* | destructor_id parenthesis_clause -- omitted to resolve known ambiguity */
+/* | simple_type_specifier '(' expression_list.opt ')' -- simple_type_specifier is a primary_expression */
+ | postfix_expression '.' declarator_id { $$ = YACC_DOT_EXPRESSION($1, $3); }
+/* | postfix_expression '.' TEMPLATE declarator_id -- TEMPLATE absorbed into declarator_id. */
+ | postfix_expression '.' scoped_pseudo_destructor_id { $$ = YACC_DOT_EXPRESSION($1, $3); }
+ | postfix_expression ARROW declarator_id { $$ = YACC_ARROW_EXPRESSION($1, $3); }
+/* | postfix_expression ARROW TEMPLATE declarator_id -- TEMPLATE absorbed into declarator_id. */
+ | postfix_expression ARROW scoped_pseudo_destructor_id { $$ = YACC_ARROW_EXPRESSION($1, $3); }
+ | postfix_expression INC { $$ = YACC_POST_INCREMENT_EXPRESSION($1); }
+ | postfix_expression DEC { $$ = YACC_POST_DECREMENT_EXPRESSION($1); }
+ | DYNAMIC_CAST '<' type_id '>' '(' expression ')' { $$ = YACC_DYNAMIC_CAST_EXPRESSION($3, $6); }
+ | STATIC_CAST '<' type_id '>' '(' expression ')' { $$ = YACC_STATIC_CAST_EXPRESSION($3, $6); }
+ | REINTERPRET_CAST '<' type_id '>' '(' expression ')' { $$ = YACC_REINTERPRET_CAST_EXPRESSION($3, $6); }
+ | CONST_CAST '<' type_id '>' '(' expression ')' { $$ = YACC_CONST_CAST_EXPRESSION($3, $6); }
+ | TYPEID parameters_clause { $$ = YACC_TYPEID_EXPRESSION($2); }
+/* | TYPEID '(' expression ')' -- covered by parameters_clause */
+/* | TYPEID '(' type_id ')' -- covered by parameters_clause */
+expression_list.opt: /* empty */ { $$ = YACC_EXPRESSIONS(0, 0); }
+ | expression_list
+expression_list: assignment_expression { $$ = YACC_EXPRESSIONS(0, $1); }
+ | expression_list ',' assignment_expression { $$ = YACC_EXPRESSIONS($1, $3); }
+
+unary_expression: postfix_expression
+ | INC cast_expression { $$ = YACC_PRE_INCREMENT_EXPRESSION($2); }
+ | DEC cast_expression { $$ = YACC_PRE_DECREMENT_EXPRESSION($2); }
+ | ptr_operator cast_expression { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+/* | '*' cast_expression -- covered by ptr_operator */
+/* | '&' cast_expression -- covered by ptr_operator */
+/* | decl_specifier_seq '*' cast_expression -- covered by binary operator */
+/* | decl_specifier_seq '&' cast_expression -- covered by binary operator */
+ | suffix_decl_specified_scope star_ptr_operator cast_expression /* covers e.g int ::type::* const t = 4 */
+ { $$ = YACC_SCOPED_POINTER_EXPRESSION($1, $2, $3); }
+ | '+' cast_expression { $$ = YACC_PLUS_EXPRESSION($2); }
+ | '-' cast_expression { $$ = YACC_MINUS_EXPRESSION($2); }
+ | '!' cast_expression { $$ = YACC_NOT_EXPRESSION($2); }
+ | '~' cast_expression { $$ = YACC_COMPLEMENT_EXPRESSION($2); }
+ | SIZEOF unary_expression { $$ = YACC_SIZEOF_EXPRESSION($2); }
+/* | SIZEOF '(' type_id ')' -- covered by unary_expression */
+ | new_expression { $$ = $1; }
+ | global_scope new_expression { $$ = YACC_GLOBAL_EXPRESSION($1, $2); }
+ | delete_expression { $$ = $1; }
+ | global_scope delete_expression { $$ = YACC_GLOBAL_EXPRESSION($1, $2); }
+/* | DELETE '[' ']' cast_expression -- covered by DELETE cast_expression since cast_expression covers ... */
+/* | SCOPE DELETE '[' ']' cast_expression // ... abstract_expression cast_expression and so [] cast_expression */
+
+delete_expression: DELETE cast_expression /* also covers DELETE[] cast_expression */
+ { $$ = YACC_DELETE_EXPRESSION($2); }
+new_expression: NEW new_type_id new_initializer.opt { $$ = YACC_NEW_TYPE_ID_EXPRESSION(0, $2, $3); }
+ | NEW parameters_clause new_type_id new_initializer.opt { $$ = YACC_NEW_TYPE_ID_EXPRESSION($2, $3, $4); }
+ | NEW parameters_clause { $$ = YACC_NEW_EXPRESSION($2, 0, 0); }
+/* | NEW '(' type-id ')' -- covered by parameters_clause */
+ | NEW parameters_clause parameters_clause new_initializer.opt { $$ = YACC_NEW_EXPRESSION($2, $3, $4); }
+/* | NEW '(' type-id ')' new_initializer -- covered by parameters_clause parameters_clause */
+/* | NEW parameters_clause '(' type-id ')' -- covered by parameters_clause parameters_clause */
+ /* ptr_operator_seq.opt production reused to save a %prec */
+new_type_id: type_specifier ptr_operator_seq.opt { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+ | type_specifier new_declarator { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+ | type_specifier new_type_id { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+new_declarator: ptr_operator new_declarator { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+ | direct_new_declarator
+direct_new_declarator: '[' expression ']' { $$ = YACC_ABSTRACT_ARRAY_EXPRESSION($2); }
+ | direct_new_declarator '[' constant_expression ']' { $$ = YACC_ARRAY_EXPRESSION($1, $3); }
+new_initializer.opt: /* empty */ { $$ = YACC_EXPRESSIONS(0, 0); }
+ | '(' expression_list.opt ')' { $$ = $2; }
+
+/* cast-expression is generalised to support a [] as well as a () prefix. This covers the omission of DELETE[] which when
+ * followed by a parenthesised expression was ambiguous. It also covers the gcc indexed array initialisation for free.
+ */
+cast_expression: unary_expression
+ | abstract_expression cast_expression { $$ = YACC_CAST_EXPRESSION($1, $2); }
+/* | '(' type_id ')' cast_expression -- covered by abstract_expression */
+
+pm_expression: cast_expression
+ | pm_expression DOT_STAR cast_expression { $$ = YACC_DOT_STAR_EXPRESSION($1, $3); }
+ | pm_expression ARROW_STAR cast_expression { $$ = YACC_ARROW_STAR_EXPRESSION($1, $3); }
+multiplicative_expression: pm_expression
+ | multiplicative_expression star_ptr_operator pm_expression { $$ = YACC_MULTIPLY_EXPRESSION($1, $2, $3); }
+ | multiplicative_expression '/' pm_expression { $$ = YACC_DIVIDE_EXPRESSION($1, $3); }
+ | multiplicative_expression '%' pm_expression { $$ = YACC_MODULUS_EXPRESSION($1, $3); }
+additive_expression: multiplicative_expression
+ | additive_expression '+' multiplicative_expression { $$ = YACC_ADD_EXPRESSION($1, $3); }
+ | additive_expression '-' multiplicative_expression { $$ = YACC_SUBTRACT_EXPRESSION($1, $3); }
+shift_expression: additive_expression
+ | shift_expression SHL additive_expression { $$ = YACC_SHIFT_LEFT_EXPRESSION($1, $3); }
+ | shift_expression SHR additive_expression { $$ = YACC_SHIFT_RIGHT_EXPRESSION($1, $3); }
+relational_expression: shift_expression
+ | relational_expression '<' shift_expression { $$ = YACC_LESS_THAN_EXPRESSION($1, $3); }
+ | relational_expression '>' shift_expression { $$ = YACC_GREATER_THAN_EXPRESSION($1, $3); }
+ | relational_expression LE shift_expression { $$ = YACC_LESS_EQUAL_EXPRESSION($1, $3); }
+ | relational_expression GE shift_expression { $$ = YACC_GREATER_EQUAL_EXPRESSION($1, $3); }
+equality_expression: relational_expression
+ | equality_expression EQ relational_expression { $$ = YACC_EQUAL_EXPRESSION($1, $3); }
+ | equality_expression NE relational_expression { $$ = YACC_NOT_EQUAL_EXPRESSION($1, $3); }
+and_expression: equality_expression
+ | and_expression '&' equality_expression { $$ = YACC_AND_EXPRESSION($1, $3); }
+exclusive_or_expression: and_expression
+ | exclusive_or_expression '^' and_expression { $$ = YACC_EXCLUSIVE_OR_EXPRESSION($1, $3); }
+inclusive_or_expression: exclusive_or_expression
+ | inclusive_or_expression '|' exclusive_or_expression { $$ = YACC_INCLUSIVE_OR_EXPRESSION($1, $3); }
+logical_and_expression: inclusive_or_expression
+ | logical_and_expression LOG_AND inclusive_or_expression { $$ = YACC_LOGICAL_AND_EXPRESSION($1, $3); }
+logical_or_expression: logical_and_expression
+ | logical_or_expression LOG_OR logical_and_expression { $$ = YACC_LOGICAL_OR_EXPRESSION($1, $3); }
+conditional_expression: logical_or_expression
+ | logical_or_expression '?' expression ':' assignment_expression
+ { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); }
+
+/* assignment-expression is generalised to cover the simple assignment of a braced initializer in order to contribute to the
+ * coverage of parameter-declaration and init-declaration.
+ */
+assignment_expression: conditional_expression
+ | logical_or_expression assignment_operator assignment_expression { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+ | logical_or_expression '=' braced_initializer { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+ | throw_expression
+assignment_operator: '=' | ASS_ADD | ASS_AND | ASS_DIV | ASS_MOD | ASS_MUL | ASS_OR | ASS_SHL | ASS_SHR | ASS_SUB | ASS_XOR
+
+/* expression is widely used and usually single-element, so the reductions are arranged so that a
+ * single-element expression is returned as is. Multi-element expressions are parsed as a list that
+ * may then behave polymorphically as an element or be compacted to an element. */
+expression.opt: /* empty */ { $$ = YACC_EXPRESSION(0); }
+ | expression
+expression: assignment_expression
+ | expression_list ',' assignment_expression { $$ = YACC_EXPRESSION(YACC_EXPRESSIONS($1, $3)); }
+constant_expression: conditional_expression
+
+/* The grammar is repeated for when the parser stack knows that the next > must end a template.
+ */
+templated_relational_expression: shift_expression
+ | templated_relational_expression '<' shift_expression { $$ = YACC_LESS_THAN_EXPRESSION($1, $3); }
+ | templated_relational_expression LE shift_expression { $$ = YACC_LESS_EQUAL_EXPRESSION($1, $3); }
+ | templated_relational_expression GE shift_expression { $$ = YACC_GREATER_EQUAL_EXPRESSION($1, $3); }
+templated_equality_expression: templated_relational_expression
+ | templated_equality_expression EQ templated_relational_expression { $$ = YACC_EQUAL_EXPRESSION($1, $3); }
+ | templated_equality_expression NE templated_relational_expression { $$ = YACC_NOT_EQUAL_EXPRESSION($1, $3); }
+templated_and_expression: templated_equality_expression
+ | templated_and_expression '&' templated_equality_expression { $$ = YACC_AND_EXPRESSION($1, $3); }
+templated_exclusive_or_expression: templated_and_expression
+ | templated_exclusive_or_expression '^' templated_and_expression
+ { $$ = YACC_EXCLUSIVE_OR_EXPRESSION($1, $3); }
+templated_inclusive_or_expression: templated_exclusive_or_expression
+ | templated_inclusive_or_expression '|' templated_exclusive_or_expression
+ { $$ = YACC_INCLUSIVE_OR_EXPRESSION($1, $3); }
+templated_logical_and_expression: templated_inclusive_or_expression
+ | templated_logical_and_expression LOG_AND templated_inclusive_or_expression
+ { $$ = YACC_LOGICAL_AND_EXPRESSION($1, $3); }
+templated_logical_or_expression: templated_logical_and_expression
+ | templated_logical_or_expression LOG_OR templated_logical_and_expression
+ { $$ = YACC_LOGICAL_OR_EXPRESSION($1, $3); }
+templated_conditional_expression: templated_logical_or_expression
+ | templated_logical_or_expression '?' templated_expression ':' templated_assignment_expression
+ { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); }
+templated_assignment_expression: templated_conditional_expression
+ | templated_logical_or_expression assignment_operator templated_assignment_expression
+ { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+ | templated_throw_expression
+templated_expression: templated_assignment_expression
+ | templated_expression_list ',' templated_assignment_expression
+ { $$ = YACC_EXPRESSION(YACC_EXPRESSIONS($1, $3)); }
+templated_expression_list: templated_assignment_expression { $$ = YACC_EXPRESSIONS(0, $1); }
+ | templated_expression_list ',' templated_assignment_expression { $$ = YACC_EXPRESSIONS($1, $3); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.5 Statements
+ *---------------------------------------------------------------------------------------------------
+ * Parsing statements is easy once simple_declaration has been generalised to cover expression_statement.
+ */
+looping_statement: start_search looped_statement { $$ = YACC_LINED_STATEMENT($2, $1); end_search($$); }
+looped_statement: statement
+ | advance_search '+' looped_statement { $$ = $3; }
+ | advance_search '-' { $$ = 0; }
+statement: control_statement
+/* | expression_statement -- covered by declaration_statement */
+ | compound_statement
+ | declaration_statement
+ | try_block { $$ = YACC_TRY_BLOCK_STATEMENT($1); }
+control_statement: labeled_statement
+ | selection_statement
+ | iteration_statement
+ | jump_statement
+labeled_statement: identifier_word ':' looping_statement { $$ = YACC_LABEL_STATEMENT($1, $3); }
+ | CASE constant_expression ':' looping_statement { $$ = YACC_CASE_STATEMENT($2, $4); }
+ | DEFAULT ':' looping_statement { $$ = YACC_DEFAULT_STATEMENT($3); }
+/*expression_statement: expression.opt ';' -- covered by declaration_statement */
+compound_statement: '{' statement_seq.opt '}' { $$ = YACC_COMPOUND_STATEMENT($2); }
+ | '{' statement_seq.opt looping_statement '#' bang error '}' { $$ = $2; YACC_UNBANG($5, "Bad statement-seq."); }
+statement_seq.opt: /* empty */ { $$ = YACC_STATEMENTS(0, 0); }
+ | statement_seq.opt looping_statement { $$ = YACC_STATEMENTS($1, YACC_COMPILE_STATEMENT($2)); }
+ | statement_seq.opt looping_statement '#' bang error ';' { $$ = $1; YACC_UNBANG($4, "Bad statement."); }
+/*
+ * The dangling else conflict is resolved to the innermost if.
+ */
+selection_statement: IF '(' condition ')' looping_statement %prec SHIFT_THERE { $$ = YACC_IF_STATEMENT($3, $5, 0); }
+ | IF '(' condition ')' looping_statement ELSE looping_statement { $$ = YACC_IF_STATEMENT($3, $5, $7); }
+ | SWITCH '(' condition ')' looping_statement { $$ = YACC_SWITCH_STATEMENT($3, $5); }
+condition.opt: /* empty */ { $$ = YACC_CONDITION(0); }
+ | condition
+condition: parameter_declaration_list { $$ = YACC_CONDITION($1); }
+/* | expression -- covered by parameter_declaration_list */
+/* | type_specifier_seq declarator '=' assignment_expression -- covered by parameter_declaration_list */
+iteration_statement: WHILE '(' condition ')' looping_statement { $$ = YACC_WHILE_STATEMENT($3, $5); }
+ | DO looping_statement WHILE '(' expression ')' ';' { $$ = YACC_DO_WHILE_STATEMENT($2, $5); }
+ | FOR '(' for_init_statement condition.opt ';' expression.opt ')' looping_statement
+ { $$ = YACC_FOR_STATEMENT($3, $4, $6, $8); }
+for_init_statement: simple_declaration
+/* | expression_statement -- covered by simple_declaration */
+jump_statement: BREAK ';' { $$ = YACC_BREAK_STATEMENT(); }
+ | CONTINUE ';' { $$ = YACC_CONTINUE_STATEMENT(); }
+ | RETURN expression.opt ';' { $$ = YACC_RETURN_STATEMENT($2); }
+ | GOTO identifier ';' { $$ = YACC_GOTO_STATEMENT($2); }
+declaration_statement: block_declaration { $$ = YACC_DECLARATION_STATEMENT($1); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.6 Declarations
+ *---------------------------------------------------------------------------------------------------*/
+compound_declaration: '{' nest declaration_seq.opt '}' { $$ = $3; unnest($2); }
+ | '{' nest declaration_seq.opt util looping_declaration '#' bang error '}'
+ { $$ = $3; unnest($2); YACC_UNBANG($7, "Bad declaration-seq."); }
+declaration_seq.opt: /* empty */ { $$ = YACC_DECLARATIONS(0, 0); }
+ | declaration_seq.opt util looping_declaration { $$ = YACC_DECLARATIONS($1, YACC_COMPILE_DECLARATION($2, $3)); }
+ | declaration_seq.opt util looping_declaration '#' bang error ';' { $$ = $1; YACC_UNBANG($5, "Bad declaration."); }
+looping_declaration: start_search1 looped_declaration { $$ = YACC_LINED_DECLARATION($2, $1); end_search($$); }
+looped_declaration: declaration
+ | advance_search '+' looped_declaration { $$ = $3; }
+ | advance_search '-' { $$ = 0; }
+declaration: block_declaration
+ | function_definition { $$ = YACC_SIMPLE_DECLARATION($1); }
+ | template_declaration
+/* | explicit_instantiation -- covered by relevant declarations */
+ | explicit_specialization
+ | specialised_declaration
+specialised_declaration: linkage_specification { $$ = YACC_LINKAGE_SPECIFICATION($1); }
+ | namespace_definition { $$ = YACC_NAMESPACE_DECLARATION($1); }
+ | TEMPLATE specialised_declaration { $$ = YACC_SET_TEMPLATE_DECLARATION($2); }
+block_declaration: simple_declaration { $$ = YACC_SIMPLE_DECLARATION($1); }
+ | specialised_block_declaration
+specialised_block_declaration: asm_definition
+ | namespace_alias_definition
+ | using_declaration
+ | using_directive
+ | TEMPLATE specialised_block_declaration { $$ = YACC_SET_TEMPLATE_DECLARATION($2); }
+simple_declaration: ';' { $$ = YACC_EXPRESSION(0); }
+ | init_declaration ';'
+ | init_declarations ';' { $$ = $1; }
+ | decl_specifier_prefix simple_declaration { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
+
+/* A decl-specifier following a ptr_operator provokes a shift-reduce conflict for
+ * * const name
+ * which is resolved in favour of the pointer, and implemented by providing versions
+ * of decl-specifier guaranteed not to start with a cv_qualifier.
+ *
+ * decl-specifiers are implemented type-centrically. That is the semantic constraint
+ * that there must be a type is exploited to impose structure, but actually eliminate
+ * very little syntax. built-in types are multi-name and so need a different policy.
+ *
+ * non-type decl-specifiers are bound to the left-most type in a decl-specifier-seq,
+ * by parsing from the right and attaching suffixes to the right-hand type. Finally
+ * residual prefixes attach to the left.
+ */
+suffix_built_in_decl_specifier.raw: built_in_type_specifier { $$ = $1; }
+ | suffix_built_in_decl_specifier.raw built_in_type_specifier { $$ = YACC_BUILT_IN_NAME($1, $2); }
+ | suffix_built_in_decl_specifier.raw decl_specifier_suffix { $$ = YACC_DECL_SPECIFIER_NAME($1, $2); }
+suffix_built_in_decl_specifier: suffix_built_in_decl_specifier.raw { $$ = $1; }
+ | TEMPLATE suffix_built_in_decl_specifier { $$ = YACC_SET_TEMPLATE_NAME($2); }
+suffix_named_decl_specifier: scoped_id { $$ = $1; }
+ | elaborate_type_specifier { $$ = $1; }
+ | suffix_named_decl_specifier decl_specifier_suffix { $$ = YACC_DECL_SPECIFIER_NAME($1, $2); }
+suffix_named_decl_specifier.bi: suffix_named_decl_specifier { $$ = YACC_NAME_EXPRESSION($1); }
+ | suffix_named_decl_specifier suffix_built_in_decl_specifier.raw { $$ = YACC_TYPED_NAME($1, $2); }
+suffix_named_decl_specifiers: suffix_named_decl_specifier.bi
+ | suffix_named_decl_specifiers suffix_named_decl_specifier.bi { $$ = YACC_TYPED_NAME($1, $2); }
+suffix_named_decl_specifiers.sf: scoped_special_function_id /* operators etc */ { $$ = YACC_NAME_EXPRESSION($1); }
+ | suffix_named_decl_specifiers
+ | suffix_named_decl_specifiers scoped_special_function_id { $$ = YACC_TYPED_NAME($1, $2); }
+suffix_decl_specified_ids: suffix_built_in_decl_specifier
+ | suffix_built_in_decl_specifier suffix_named_decl_specifiers.sf { $$ = YACC_TYPED_NAME($1, $2); }
+ | suffix_named_decl_specifiers.sf
+suffix_decl_specified_scope: suffix_named_decl_specifiers SCOPE
+ | suffix_built_in_decl_specifier suffix_named_decl_specifiers SCOPE { $$ = YACC_TYPED_NAME($1, $2); }
+ | suffix_built_in_decl_specifier SCOPE { $$ = YACC_NAME_EXPRESSION($1); }
+
+decl_specifier_affix: storage_class_specifier
+ | function_specifier
+ | FRIEND
+ | TYPEDEF
+ | cv_qualifier { $$ = $1; }
+
+decl_specifier_suffix: decl_specifier_affix
+
+decl_specifier_prefix: decl_specifier_affix
+ | TEMPLATE decl_specifier_prefix { $$ = YACC_SET_TEMPLATE_DECL_SPECIFIER($2); }
+
+storage_class_specifier: REGISTER | STATIC | MUTABLE
+ | EXTERN %prec SHIFT_THERE /* Prefer linkage specification */
+ | AUTO
+
+function_specifier: EXPLICIT
+ | INLINE
+ | VIRTUAL
+
+type_specifier: simple_type_specifier
+ | elaborate_type_specifier
+ | cv_qualifier { $$ = YACC_CV_DECL_SPECIFIER($1); }
+
+elaborate_type_specifier: class_specifier
+ | enum_specifier
+ | elaborated_type_specifier
+ | TEMPLATE elaborate_type_specifier { $$ = YACC_SET_TEMPLATE_ID($2); }
+simple_type_specifier: scoped_id
+ | built_in_type_specifier { $$ = YACC_BUILT_IN_ID_ID($1); }
+built_in_type_specifier: CHAR | WCHAR_T | BOOL | SHORT | INT | LONG | SIGNED | UNSIGNED | FLOAT | DOUBLE | VOID
+
+/*
+ * The over-general use of declaration_expression to cover decl-specifier-seq.opt declarator in a function-definition means that
+ * class X {};
+ * could be a function-definition or a class-specifier.
+ * enum X {};
+ * could be a function-definition or an enum-specifier.
+ * The function-definition is not syntactically valid so resolving the false conflict in favour of the
+ * elaborated_type_specifier is correct.
+ */
+elaborated_type_specifier: elaborated_class_specifier
+ | elaborated_enum_specifier
+ | TYPENAME scoped_id { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); }
+
+elaborated_enum_specifier: ENUM scoped_id %prec SHIFT_THERE { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); }
+enum_specifier: ENUM scoped_id enumerator_clause { $$ = YACC_ENUM_SPECIFIER_ID($2, $3); }
+ | ENUM enumerator_clause { $$ = YACC_ENUM_SPECIFIER_ID(0, $2); }
+enumerator_clause: '{' enumerator_list_ecarb { $$ = YACC_ENUMERATORS(0, 0); }
+ | '{' enumerator_list enumerator_list_ecarb { $$ = $2; }
+ | '{' enumerator_list ',' enumerator_definition_ecarb { $$ = $2; }
+enumerator_list_ecarb: '}' { }
+ | bang error '}' { YACC_UNBANG($1, "Bad enumerator-list."); }
+enumerator_definition_ecarb: '}' { }
+ | bang error '}' { YACC_UNBANG($1, "Bad enumerator-definition."); }
+enumerator_definition_filler: /* empty */
+ | bang error ',' { YACC_UNBANG($1, "Bad enumerator-definition."); }
+enumerator_list_head: enumerator_definition_filler { $$ = YACC_ENUMERATORS(0, 0); }
+ | enumerator_list ',' enumerator_definition_filler
+enumerator_list: enumerator_list_head enumerator_definition { $$ = YACC_ENUMERATORS($1, $2); }
+enumerator_definition: enumerator { $$ = YACC_ENUMERATOR($1, 0); }
+ | enumerator '=' constant_expression { $$ = YACC_ENUMERATOR($1, $3); }
+enumerator: identifier
+
+namespace_definition: NAMESPACE scoped_id compound_declaration { $$ = YACC_NAMESPACE_DEFINITION($2, $3); }
+ | NAMESPACE compound_declaration { $$ = YACC_NAMESPACE_DEFINITION(0, $2); }
+namespace_alias_definition: NAMESPACE scoped_id '=' scoped_id ';' { $$ = YACC_NAMESPACE_ALIAS_DEFINITION($2, $4); }
+
+using_declaration: USING declarator_id ';' { $$ = YACC_USING_DECLARATION(false, $2); }
+ | USING TYPENAME declarator_id ';' { $$ = YACC_USING_DECLARATION(true, $3); }
+
+using_directive: USING NAMESPACE scoped_id ';' { $$ = YACC_USING_DIRECTIVE($3); }
+asm_definition: ASM '(' string ')' ';' { $$ = YACC_ASM_DEFINITION($3); }
+linkage_specification: EXTERN string looping_declaration { $$ = YACC_LINKAGE_SPECIFIER($2, $3); }
+ | EXTERN string compound_declaration { $$ = YACC_LINKAGE_SPECIFIER($2, $3); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.7 Declarators
+ *---------------------------------------------------------------------------------------------------*/
+/*init-declarator is named init_declaration to reflect the embedded decl-specifier-seq.opt*/
+init_declarations: assignment_expression ',' init_declaration { $$ = YACC_EXPRESSIONS(YACC_EXPRESSIONS(0, $1), $3); }
+ | init_declarations ',' init_declaration { $$ = YACC_EXPRESSIONS($1, $3); }
+init_declaration: assignment_expression
+/* | assignment_expression '=' initializer_clause -- covered by assignment_expression */
+/* | assignment_expression '(' expression_list ')' -- covered by another set of call arguments */
+
+/*declarator: -- covered by assignment_expression */
+/*direct_declarator: -- covered by postfix_expression */
+
+star_ptr_operator: '*' { $$ = YACC_POINTER_DECLARATOR(); }
+ | star_ptr_operator cv_qualifier { $$ = YACC_CV_DECLARATOR($1, $2); }
+nested_ptr_operator: star_ptr_operator { $$ = $1; }
+ | id_scope nested_ptr_operator { $$ = YACC_NESTED_DECLARATOR($1, $2); }
+ptr_operator: '&' { $$ = YACC_REFERENCE_DECLARATOR(); }
+ | nested_ptr_operator { $$ = $1; }
+ | global_scope nested_ptr_operator { $$ = YACC_GLOBAL_DECLARATOR($1, $2); }
+ptr_operator_seq: ptr_operator { $$ = YACC_POINTER_EXPRESSION($1, YACC_EPSILON()); }
+ | ptr_operator ptr_operator_seq { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+/* Independently coded to localise the shift-reduce conflict: sharing just needs another %prec */
+ptr_operator_seq.opt: /* empty */ %prec SHIFT_THERE /* Maximise type length */ { $$ = YACC_EXPRESSION(0); }
+ | ptr_operator ptr_operator_seq.opt { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+
+cv_qualifier_seq.opt: /* empty */ { $$ = YACC_CV_QUALIFIERS(0, 0); }
+ | cv_qualifier_seq.opt cv_qualifier { $$ = YACC_CV_QUALIFIERS($1, $2); }
+cv_qualifier: CONST | VOLATILE /* | CvQualifier */
+
+/*type_id -- also covered by parameter declaration */
+type_id: type_specifier abstract_declarator.opt { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+ | type_specifier type_id { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+
+/*abstract_declarator: -- also covered by parameter declaration */
+abstract_declarator.opt: /* empty */ { $$ = YACC_EPSILON(); }
+ | ptr_operator abstract_declarator.opt { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+ | direct_abstract_declarator
+direct_abstract_declarator.opt: /* empty */ { $$ = YACC_EPSILON(); }
+ | direct_abstract_declarator
+direct_abstract_declarator: direct_abstract_declarator.opt parenthesis_clause { $$ = YACC_CALL_EXPRESSION($1, $2); }
+ | direct_abstract_declarator.opt '[' ']' { $$ = YACC_ARRAY_EXPRESSION($1, 0); }
+ | direct_abstract_declarator.opt '[' constant_expression ']' { $$ = YACC_ARRAY_EXPRESSION($1, $3); }
+/* | '(' abstract_declarator ')' -- covered by parenthesis_clause */
+
+parenthesis_clause: parameters_clause cv_qualifier_seq.opt { $$ = YACC_PARENTHESISED($1, $2, 0); }
+ | parameters_clause cv_qualifier_seq.opt exception_specification { $$ = YACC_PARENTHESISED($1, $2, $3); }
+parameters_clause: '(' parameter_declaration_clause ')' { $$ = $2; }
+/* parameter_declaration_clause also covers init_declaration, type_id, declarator and abstract_declarator. */
+parameter_declaration_clause: /* empty */ { $$ = YACC_PARAMETERS(0, 0); }
+ | parameter_declaration_list
+ | parameter_declaration_list ELLIPSIS { $$ = YACC_PARAMETERS($1, YACC_ELLIPSIS_EXPRESSION()); }
+parameter_declaration_list: parameter_declaration { $$ = YACC_PARAMETERS(0, $1); }
+ | parameter_declaration_list ',' parameter_declaration { $$ = YACC_PARAMETERS($1, $3); }
+
+/* A typed abstract qualifier such as
+ * Class * ...
+ * looks like a multiply, so pointers are parsed as their binary operation equivalents that
+ * ultimately terminate with a degenerate right hand term.
+ */
+abstract_pointer_declaration: ptr_operator_seq
+ | multiplicative_expression star_ptr_operator ptr_operator_seq.opt { $$ = YACC_MULTIPLY_EXPRESSION($1, $2, $3); }
+abstract_parameter_declaration: abstract_pointer_declaration
+ | and_expression '&' { $$ = YACC_AND_EXPRESSION($1, YACC_EPSILON()); }
+ | and_expression '&' abstract_pointer_declaration { $$ = YACC_AND_EXPRESSION($1, $3); }
+special_parameter_declaration: abstract_parameter_declaration
+ | abstract_parameter_declaration '=' assignment_expression { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+ | ELLIPSIS { $$ = YACC_ELLIPSIS_EXPRESSION(); }
+parameter_declaration: assignment_expression { $$ = YACC_EXPRESSION_PARAMETER($1); }
+ | special_parameter_declaration { $$ = YACC_EXPRESSION_PARAMETER($1); }
+ | decl_specifier_prefix parameter_declaration { $$ = YACC_DECL_SPECIFIER_PARAMETER($2, $1); }
+
+/* The grammar is repeated for use within template <>
+ */
+templated_parameter_declaration: templated_assignment_expression { $$ = YACC_EXPRESSION_PARAMETER($1); }
+ | templated_abstract_declaration { $$ = YACC_EXPRESSION_PARAMETER($1); }
+ | templated_abstract_declaration '=' templated_assignment_expression
+ { $$ = YACC_EXPRESSION_PARAMETER(YACC_ASSIGNMENT_EXPRESSION($1, $2, $3)); }
+ | decl_specifier_prefix templated_parameter_declaration { $$ = YACC_DECL_SPECIFIER_PARAMETER($2, $1); }
+templated_abstract_declaration: abstract_pointer_declaration
+ | templated_and_expression '&' { $$ = YACC_AND_EXPRESSION($1, 0); }
+ | templated_and_expression '&' abstract_pointer_declaration { $$ = YACC_AND_EXPRESSION($1, $3); }
+
+/* function_definition includes constructor, destructor, implicit int definitions too.
+ * A local destructor is successfully parsed as a function-declaration but the ~ was treated as a unary operator.
+ * constructor_head is the prefix ambiguity between a constructor and a member-init-list starting with a bit-field.
+ */
+function_definition: ctor_definition
+ | func_definition
+func_definition: assignment_expression function_try_block { $$ = YACC_FUNCTION_DEFINITION($1, $2); }
+ | assignment_expression function_body { $$ = YACC_FUNCTION_DEFINITION($1, $2); }
+ | decl_specifier_prefix func_definition { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
+ctor_definition: constructor_head function_try_block { $$ = YACC_CTOR_DEFINITION($1, $2); }
+ | constructor_head function_body { $$ = YACC_CTOR_DEFINITION($1, $2); }
+ | decl_specifier_prefix ctor_definition { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
+constructor_head: bit_field_init_declaration { $$ = YACC_EXPRESSIONS(0, $1); }
+ | constructor_head ',' assignment_expression { $$ = YACC_EXPRESSIONS($1, $3); }
+function_try_block: TRY function_block handler_seq { $$ = YACC_TRY_FUNCTION_BLOCK($2, $3); }
+function_block: ctor_initializer.opt function_body { $$ = YACC_CTOR_FUNCTION_BLOCK($2, $1); }
+function_body: compound_statement { $$ = YACC_FUNCTION_BLOCK($1); }
+
+/* An = initializer looks like an extended assignment_expression.
+ * An () initializer looks like a function call.
+ * initializer is therefore flattened into its generalised customers.
+ *initializer: '=' initializer_clause -- flattened into caller
+ * | '(' expression_list ')' -- flattened into caller */
+initializer_clause: assignment_expression { $$ = YACC_INITIALIZER_EXPRESSION_CLAUSE($1); }
+ | braced_initializer
+braced_initializer: '{' initializer_list '}' { $$ = YACC_INITIALIZER_LIST_CLAUSE($2); }
+ | '{' initializer_list ',' '}' { $$ = YACC_INITIALIZER_LIST_CLAUSE($2); }
+ | '{' '}' { $$ = YACC_INITIALIZER_LIST_CLAUSE(0); }
+ | '{' looping_initializer_clause '#' bang error '}' { $$ = 0; YACC_UNBANG($4, "Bad initializer_clause."); }
+ | '{' initializer_list ',' looping_initializer_clause '#' bang error '}'
+ { $$ = $2; YACC_UNBANG($6, "Bad initializer_clause."); }
+initializer_list: looping_initializer_clause { $$ = YACC_INITIALIZER_CLAUSES(0, $1); }
+ | initializer_list ',' looping_initializer_clause { $$ = YACC_INITIALIZER_CLAUSES($1, $3); }
+looping_initializer_clause: start_search looped_initializer_clause { $$ = $2; end_search($$); }
+looped_initializer_clause: initializer_clause
+ | advance_search '+' looped_initializer_clause { $$ = $3; }
+ | advance_search '-' { $$ = 0; }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.8 Classes
+ *---------------------------------------------------------------------------------------------------
+ *
+ * An anonymous bit-field declaration may look very like inheritance:
+ * class A : B = 3;
+ * class A : B ;
+ * The two usages are too distant to try to create and enforce a common prefix so we have to resort to
+ * a parser hack by backtracking. Inheritance is much the most likely so we mark the input stream context
+ * and try to parse a base-clause. If we successfully reach a { the base-clause is ok and inheritance was
+ * the correct choice so we unmark and continue. If we fail to find the { an error token causes back-tracking
+ * to the alternative parse in elaborated_class_specifier which regenerates the : and declares unconditional success.
+ */
+colon_mark: ':' { $$ = mark(); }
+elaborated_class_specifier: class_key scoped_id %prec SHIFT_THERE { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); }
+ | class_key scoped_id colon_mark error { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); rewind_colon($3, $$); }
+class_specifier_head: class_key scoped_id colon_mark base_specifier_list '{' { unmark($4); $$ = YACC_CLASS_SPECIFIER_ID($1, $2, $4); }
+ | class_key ':' base_specifier_list '{' { $$ = YACC_CLASS_SPECIFIER_ID($1, 0, $3); }
+ | class_key scoped_id '{' { $$ = YACC_CLASS_SPECIFIER_ID($1, $2, 0); }
+ | class_key '{' { $$ = YACC_CLASS_SPECIFIER_ID($1, 0, 0); }
+class_key: CLASS | STRUCT | UNION
+class_specifier: class_specifier_head member_specification.opt '}' { $$ = YACC_CLASS_MEMBERS($1, $2); }
+ | class_specifier_head member_specification.opt util looping_member_declaration '#' bang error '}'
+ { $$ = YACC_CLASS_MEMBERS($1, $2); YACC_UNBANG($6, "Bad member_specification.opt."); }
+member_specification.opt: /* empty */ { $$ = YACC_MEMBER_DECLARATIONS(0, 0); }
+ | member_specification.opt util looping_member_declaration { $$ = YACC_MEMBER_DECLARATIONS($1, YACC_COMPILE_DECLARATION($2, $3)); }
+ | member_specification.opt util looping_member_declaration '#' bang error ';'
+ { $$ = $1; YACC_UNBANG($5, "Bad member-declaration."); }
+looping_member_declaration: start_search looped_member_declaration { $$ = YACC_LINED_DECLARATION($2, $1); end_search($$); }
+looped_member_declaration: member_declaration
+ | advance_search '+' looped_member_declaration { $$ = $3; }
+ | advance_search '-' { $$ = 0; }
+member_declaration: accessibility_specifier
+ | simple_member_declaration { $$ = YACC_SIMPLE_DECLARATION($1); }
+ | function_definition { $$ = YACC_SIMPLE_DECLARATION($1); }
+/* | function_definition ';' -- trailing ; covered by null declaration */
+/* | qualified_id ';' -- covered by simple_member_declaration */
+ | using_declaration
+ | template_declaration
+
+/* The generality of constructor names (there need be no parenthesised argument list) means that that
+ * name : f(g), h(i)
+ * could be the start of a constructor or the start of an anonymous bit-field. An ambiguity is avoided by
+ * parsing the ctor-initializer of a function_definition as a bit-field.
+ */
+simple_member_declaration: ';' { $$ = YACC_EXPRESSION(0); }
+ | assignment_expression ';'
+ | constructor_head ';' { $$ = $1; }
+ | member_init_declarations ';' { $$ = $1; }
+ | decl_specifier_prefix simple_member_declaration { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
+member_init_declarations: assignment_expression ',' member_init_declaration { $$ = YACC_EXPRESSIONS(YACC_EXPRESSIONS(0, $1), $3); }
+ | constructor_head ',' bit_field_init_declaration { $$ = YACC_EXPRESSIONS($1, $3); }
+ | member_init_declarations ',' member_init_declaration { $$ = YACC_EXPRESSIONS($1, $3); }
+member_init_declaration: assignment_expression
+/* | assignment_expression '=' initializer_clause -- covered by assignment_expression */
+/* | assignment_expression '(' expression_list ')' -- covered by another set of call arguments */
+ | bit_field_init_declaration
+accessibility_specifier: access_specifier ':' { $$ = YACC_ACCESSIBILITY_SPECIFIER($1); }
+bit_field_declaration: assignment_expression ':' bit_field_width { $$ = YACC_BIT_FIELD_EXPRESSION($1, $3); }
+ | ':' bit_field_width { $$ = YACC_BIT_FIELD_EXPRESSION(0, $2); }
+bit_field_width: logical_or_expression
+/* | logical_or_expression '?' expression ':' assignment_expression -- has SR conflict w.r.t later = */
+ | logical_or_expression '?' bit_field_width ':' bit_field_width { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); }
+bit_field_init_declaration: bit_field_declaration
+ | bit_field_declaration '=' initializer_clause { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.9 Derived classes
+ *---------------------------------------------------------------------------------------------------*/
+/*base_clause: ':' base_specifier_list -- flattened */
+base_specifier_list: base_specifier { $$ = YACC_BASE_SPECIFIERS(0, $1); }
+ | base_specifier_list ',' base_specifier { $$ = YACC_BASE_SPECIFIERS($1, $3); }
+base_specifier: scoped_id { $$ = YACC_BASE_SPECIFIER($1); }
+ | access_specifier base_specifier { $$ = YACC_ACCESS_BASE_SPECIFIER($2, $1); }
+ | VIRTUAL base_specifier { $$ = YACC_VIRTUAL_BASE_SPECIFIER($2); }
+access_specifier: PRIVATE | PROTECTED | PUBLIC
+
+/*---------------------------------------------------------------------------------------------------
+ * A.10 Special member functions
+ *---------------------------------------------------------------------------------------------------*/
+conversion_function_id: OPERATOR conversion_type_id { $$ = YACC_CONVERSION_FUNCTION_ID($2); }
+conversion_type_id: type_specifier ptr_operator_seq.opt { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+ | type_specifier conversion_type_id { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+/*
+ * Ctor-initialisers can look like a bit field declaration, given the generalisation of names:
+ * Class(Type) : m1(1), m2(2) {}
+ * NonClass(bit_field) : int(2), second_variable, ...
+ * The grammar below is used within a function_try_block or function_definition.
+ * See simple_member_declaration for use in normal member function_definition.
+ */
+ctor_initializer.opt: /* empty */ { $$ = YACC_MEM_INITIALIZERS(0, 0); }
+ | ctor_initializer
+ctor_initializer: ':' mem_initializer_list { $$ = $2; }
+ | ':' mem_initializer_list bang error { $$ = $2; YACC_UNBANG($3, "Bad ctor-initializer."); }
+mem_initializer_list: mem_initializer { $$ = YACC_MEM_INITIALIZERS(0, $1); }
+ | mem_initializer_list_head mem_initializer { $$ = YACC_MEM_INITIALIZERS($1, $2); }
+mem_initializer_list_head: mem_initializer_list ','
+ | mem_initializer_list bang error ',' { YACC_UNBANG($2, "Bad mem-initializer."); }
+mem_initializer: mem_initializer_id '(' expression_list.opt ')' { $$ = YACC_MEM_INITIALIZER($1, $3); }
+mem_initializer_id: scoped_id
+
+/*---------------------------------------------------------------------------------------------------
+ * A.11 Overloading
+ *---------------------------------------------------------------------------------------------------*/
+operator_function_id: OPERATOR operator { $$ = YACC_OPERATOR_FUNCTION_ID($2); }
+/*
+ * It is not clear from the ANSI standard whether spaces are permitted in delete[]. If not then it can
+ * be recognised and returned as DELETE_ARRAY by the lexer. Assuming spaces are permitted there is an
+ * ambiguity created by the over generalised nature of expressions. operator new is a valid delarator-id
+ * which we may have an undimensioned array of. Semantic rubbish, but syntactically valid. Since the
+ * array form is covered by the declarator consideration we can exclude the operator here. The need
+ * for a semantic rescue can be eliminated at the expense of a couple of shift-reduce conflicts by
+ * removing the comments on the next four lines.
+ */
+operator: /*++++*/ NEW { $$ = YACC_OPERATOR_NEW_ID(); }
+ | /*++++*/ DELETE { $$ = YACC_OPERATOR_DELETE_ID(); }
+/* | / ---- / NEW %prec SHIFT_THERE { $$ = YACC_OPERATOR_NEW_ID(); }
+/* | / ---- / DELETE %prec SHIFT_THERE { $$ = YACC_OPERATOR_DELETE_ID(); }
+/* | / ---- / NEW '[' ']' -- Covered by array of OPERATOR NEW */
+/* | / ---- / DELETE '[' ']' -- Covered by array of OPERATOR DELETE */
+ | '+' { $$ = YACC_OPERATOR_ADD_ID(); }
+ | '-' { $$ = YACC_OPERATOR_SUB_ID(); }
+ | '*' { $$ = YACC_OPERATOR_MUL_ID(); }
+ | '/' { $$ = YACC_OPERATOR_DIV_ID(); }
+ | '%' { $$ = YACC_OPERATOR_MOD_ID(); }
+ | '^' { $$ = YACC_OPERATOR_XOR_ID(); }
+ | '&' { $$ = YACC_OPERATOR_BIT_AND_ID(); }
+ | '|' { $$ = YACC_OPERATOR_BIT_OR_ID(); }
+ | '~' { $$ = YACC_OPERATOR_BIT_NOT_ID(); }
+ | '!' { $$ = YACC_OPERATOR_LOG_NOT_ID(); }
+ | '=' { $$ = YACC_OPERATOR_ASS_ID(); }
+ | '<' { $$ = YACC_OPERATOR_LT_ID(); }
+ | '>' { $$ = YACC_OPERATOR_GT_ID(); }
+ | ASS_ADD { $$ = YACC_OPERATOR_ASS_ADD_ID(); }
+ | ASS_SUB { $$ = YACC_OPERATOR_ASS_SUB_ID(); }
+ | ASS_MUL { $$ = YACC_OPERATOR_ASS_MUL_ID(); }
+ | ASS_DIV { $$ = YACC_OPERATOR_ASS_DIV_ID(); }
+ | ASS_MOD { $$ = YACC_OPERATOR_ASS_MOD_ID(); }
+ | ASS_XOR { $$ = YACC_OPERATOR_ASS_XOR_ID(); }
+ | ASS_AND { $$ = YACC_OPERATOR_ASS_BIT_AND_ID(); }
+ | ASS_OR { $$ = YACC_OPERATOR_ASS_BIT_OR_ID(); }
+ | SHL { $$ = YACC_OPERATOR_SHL_ID(); }
+ | SHR { $$ = YACC_OPERATOR_SHR_ID(); }
+ | ASS_SHR { $$ = YACC_OPERATOR_ASS_SHR_ID(); }
+ | ASS_SHL { $$ = YACC_OPERATOR_ASS_SHL_ID(); }
+ | EQ { $$ = YACC_OPERATOR_EQ_ID(); }
+ | NE { $$ = YACC_OPERATOR_NE_ID(); }
+ | LE { $$ = YACC_OPERATOR_LE_ID(); }
+ | GE { $$ = YACC_OPERATOR_GE_ID(); }
+ | LOG_AND { $$ = YACC_OPERATOR_LOG_AND_ID(); }
+ | LOG_OR { $$ = YACC_OPERATOR_LOG_OR_ID(); }
+ | INC { $$ = YACC_OPERATOR_INC_ID(); }
+ | DEC { $$ = YACC_OPERATOR_DEC_ID(); }
+ | ',' { $$ = YACC_OPERATOR_COMMA_ID(); }
+ | ARROW_STAR { $$ = YACC_OPERATOR_ARROW_STAR_ID(); }
+ | ARROW { $$ = YACC_OPERATOR_ARROW_ID(); }
+ | '(' ')' { $$ = YACC_OPERATOR_CALL_ID(); }
+ | '[' ']' { $$ = YACC_OPERATOR_INDEX_ID(); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.12 Templates
+ *---------------------------------------------------------------------------------------------------*/
+template_declaration: template_parameter_clause declaration { $$ = YACC_TEMPLATE_DECLARATION($1, $2); }
+ | EXPORT template_declaration { $$ = YACC_DECL_SPECIFIER_DECLARATION($2, $1); }
+template_parameter_clause: TEMPLATE '<' template_parameter_list '>' { $$ = $3; }
+template_parameter_list: template_parameter { $$ = YACC_TEMPLATE_PARAMETERS(0, $1); }
+ | template_parameter_list ',' template_parameter { $$ = YACC_TEMPLATE_PARAMETERS($1, $3); }
+template_parameter: simple_type_parameter { $$ = YACC_INIT_SIMPLE_TYPE_PARAMETER($1, 0); }
+ | simple_type_parameter '=' type_id { $$ = YACC_INIT_SIMPLE_TYPE_PARAMETER($1, $3); }
+ | templated_type_parameter { $$ = YACC_INIT_TEMPLATED_PARAMETER($1, 0); }
+ | templated_type_parameter '=' identifier { $$ = YACC_INIT_TEMPLATED_PARAMETER($1, $3); }
+ | templated_parameter_declaration { $$ = YACC_TEMPLATE_PARAMETER($1); }
+ | bang error { $$ = 0; YACC_UNBANG($1, "Bad template-parameter."); }
+simple_type_parameter: CLASS { $$ = YACC_CLASS_TYPE_PARAMETER(0); }
+/* | CLASS identifier -- covered by parameter_declaration */
+ | TYPENAME { $$ = YACC_TYPENAME_TYPE_PARAMETER(0); }
+/* | TYPENAME identifier -- covered by parameter_declaration */
+templated_type_parameter: template_parameter_clause CLASS { $$ = YACC_TEMPLATED_TYPE_PARAMETER($1, 0); }
+ | template_parameter_clause CLASS identifier { $$ = YACC_TEMPLATED_TYPE_PARAMETER($1, $3); }
+template_id: TEMPLATE identifier '<' template_argument_list '>' { $$ = YACC_TEMPLATE_NAME($2, $4); }
+ | TEMPLATE template_id { $$ = $2; }
+/*
+ * template-argument is evaluated using a templated...expression so that > resolves to end of template.
+ */
+template_argument_list: template_argument { $$ = YACC_TEMPLATE_ARGUMENTS(0, $1); }
+ | template_argument_list ',' template_argument { $$ = YACC_TEMPLATE_ARGUMENTS($1, $3); }
+template_argument: templated_parameter_declaration { $$ = YACC_TEMPLATE_ARGUMENT($1); }
+/* | type_id -- covered by templated_parameter_declaration */
+/* | template_name -- covered by templated_parameter_declaration */
+/* | error -- must allow template failure to re-search */
+
+/*
+ * Generalised naming makes identifier a valid declaration, so TEMPLATE identifier is too.
+ * The TEMPLATE prefix is therefore folded into all names, parenthesis_clause and decl_specifier_prefix.
+ */
+/*explicit_instantiation: TEMPLATE declaration */
+explicit_specialization: TEMPLATE '<' '>' declaration { $$ = YACC_EXPLICIT_SPECIALIZATION($4); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.13 Exception Handling
+ *---------------------------------------------------------------------------------------------------*/
+try_block: TRY compound_statement handler_seq { $$ = YACC_TRY_BLOCK($2, $3); }
+/*function_try_block: -- moved near function_block */
+handler_seq: handler { $$ = YACC_HANDLERS(0, $1); }
+ | handler handler_seq { $$ = YACC_HANDLERS($2, $1); }
+handler: CATCH '(' exception_declaration ')' compound_statement { $$ = YACC_HANDLER($3, $5); }
+exception_declaration: parameter_declaration { $$ = YACC_EXCEPTION_DECLARATION($1); }
+/* ELLIPSIS -- covered by parameter_declaration */
+throw_expression: THROW { $$ = YACC_THROW_EXPRESSION(0); }
+ | THROW assignment_expression { $$ = YACC_THROW_EXPRESSION($2); }
+templated_throw_expression: THROW { $$ = YACC_THROW_EXPRESSION(0); }
+ | THROW templated_assignment_expression { $$ = YACC_THROW_EXPRESSION($2); }
+exception_specification: THROW '(' ')' { $$ = YACC_EXCEPTION_SPECIFICATION(0); }
+ | THROW '(' type_id_list ')' { $$ = YACC_EXCEPTION_SPECIFICATION($3); }
+type_id_list: type_id { $$ = YACC_EXPRESSIONS(0, $1); }
+ | type_id_list ',' type_id { $$ = YACC_EXPRESSIONS($1, $3); }
+
+/*---------------------------------------------------------------------------------------------------
+ * Back-tracking and context support
+ *---------------------------------------------------------------------------------------------------*/
+advance_search: error { yyerrok; advance_search(); } /* Rewind and queue '+' or '-' '#' */
+bang: /* empty */ { $$ = YACC_BANG(); } /* set flag to suppress "parse error" */
+mark: /* empty */ { $$ = mark(); } /* Push lookahead and input token stream context onto a stack */
+nest: /* empty */ { $$ = nest(); } /* Push a declaration nesting depth onto the parse stack */
+start_search: /* empty */ { $$ = YACC_LINE(); start_search(false); } /* Create/reset binary search context */
+start_search1: /* empty */ { $$ = YACC_LINE(); start_search(true); } /* Create/reset binary search context */
+util: /* empty */ { $$ = YACC_UTILITY_MODE(); } /* Get current utility mode */
+/*StartTester*/
+%%
+#include <CxxParsing.cxx>
+/*EndTester*/
--- /dev/null
+#include <iostream.h>
+#include <memory.h>
+#include <CxxToken.hxx>
+
+extern CxxToken *yylex_token();
+
+#ifdef BISON_PP_CLASS
+BISON_PP_CLASS theParser;
+#define PARSE_DOT theParser .
+#define PARSE_SCOPE BISON_PP_CLASS ::
+#else
+#define PARSE_DOT
+#define PARSE_SCOPE
+extern int yydebug;
+#ifndef YYEMPTY
+#define YYEMPTY -1
+#endif
+#endif
+
+class CxxSearchContext
+{
+ friend class ios; // Suppress GNU error message for no public constructors.
+ CxxSearchContext *_next;
+ size_t _index;
+ size_t _depth;
+ size_t _size;
+ size_t _mark;
+ bool _enable_type1;
+ size_t _line;
+ size_t _advances;
+ bool _status[32];
+private:
+ CxxSearchContext(CxxSearchContext *nextSearch)
+ : _next(nextSearch), _index(0), _depth(0), _size(sizeof(_status)/sizeof(_status[0])),
+ _mark(0), _enable_type1(false), _line(0), _advances(0) {}
+ CxxSearchContext(const CxxSearchContext&);
+ CxxSearchContext& operator=(const CxxSearchContext&);
+ bool did_search() const { return _depth > 0 ? true : false; }
+ void initialise(size_t markIndex, bool enableType1);
+ CxxSearchContext *queue(CxxSearchContext *& listHead);
+ void reset();
+public:
+ bool advance();
+ bool enable_type1() const { return _enable_type1; }
+ bool is_template();
+ size_t mark() const { return _mark; }
+private:
+ static CxxSearchContext *_current;
+ static CxxSearchContext *_free;
+public:
+ static size_t actual_searches;
+ static size_t advances[16];
+ static size_t max_search_depth;
+ static size_t nested_searches;
+ static size_t releases;
+ static size_t search_advances;
+ static size_t unnested_searches;
+public:
+ static CxxSearchContext *current() { return _current; }
+ static void release();
+ static void start(YACC_MARK_TYPE anIndex, bool enableType1);
+};
+
+size_t bang_depth = 0;
+size_t error_count = 0;
+size_t marked_error_count = 0;
+bool in_type1 = false;
+bool show_marked = false;
+
+int main(int argc, char *argv[])
+{
+ for (--argc, ++argv; argc-- > 0; ++argv)
+ {
+ char *p = *argv;
+ if (*p == '-')
+ {
+ switch (*(p+1))
+ {
+ case 'c':
+ c_keywords = true;
+ break;
+ case 't':
+ echo_line_text = true;
+ break;
+ case 'm':
+ show_marked = true;
+ break;
+ case 'n':
+ echo_line_numbers = true;
+ break;
+ case 'y':
+ PARSE_DOT yydebug = true;
+ break;
+ }
+ }
+ }
+ if (PARSE_DOT yyparse() != 0)
+ ERRMSG("Failed to parse to end of file,");
+ cout << "error_count = " << error_count
+ << ", marked_error_count = " << marked_error_count
+ << ", lines = " << line_number
+ << ", unnested_searches = " << CxxSearchContext::unnested_searches
+ << ", nested_searches = " << CxxSearchContext::nested_searches
+ << ", releases = " << CxxSearchContext::releases
+ << ", actual_searches = " << CxxSearchContext::actual_searches
+ << ", max_search_depth = " << CxxSearchContext::max_search_depth
+ << ", search_advances = " << CxxSearchContext::search_advances << endl;
+ cout << "number of occurences of each advance";
+ for (size_t i = 0; i < sizeof(CxxSearchContext::advances)/sizeof(CxxSearchContext::advances[0]); i++)
+ cout << ' ' << CxxSearchContext::advances[i];
+ cout << endl;
+ return 0;
+}
+
+static CxxToken **tokenBuffer = 0; // Allocated buffer
+static YACC_MARK_TYPE tokenReadIndex = 0; // Read index
+static size_t tokenSize = 0; // Allocate buffer size
+static YACC_MARK_TYPE tokenWriteIndex = 0; // Write index
+int tokenMarkDepth = 0; // Write index
+static CxxToken *primed_tokens[3] = {0, 0}; // Restarting sequence
+static void token_put(CxxToken *aToken);
+
+CxxSearchContext *CxxSearchContext::_current = 0;
+CxxSearchContext *CxxSearchContext::_free = 0;
+size_t CxxSearchContext::actual_searches = 0;
+size_t CxxSearchContext::advances[16] = { 0 };
+size_t CxxSearchContext::max_search_depth = 0;
+size_t CxxSearchContext::nested_searches = 0;
+size_t CxxSearchContext::releases = 0;
+size_t CxxSearchContext::search_advances;
+size_t CxxSearchContext::unnested_searches;
+
+//
+// Implements a binary search counter, performing the increment at the
+// _index of othe failed search.
+//
+bool CxxSearchContext::advance()
+{
+ _advances++;
+ size_t i = _depth;
+ if (i <= 0)
+ return false;
+ while (--i > _index)
+ _status[i] = false;
+ while (true)
+ {
+ if (!_status[i])
+ {
+ _status[i] = true;
+ _index = 0;
+ return true;
+ }
+ if (i <= 0)
+ return false;
+ _status[i--] = false;
+ }
+}
+
+void CxxSearchContext::initialise(size_t markIndex, bool enableType1)
+{
+ _index = 0;
+ _depth = 0;
+ _mark = markIndex;
+ _enable_type1 = enableType1;
+ _line = line_number;
+ _advances = 0;
+}
+
+bool CxxSearchContext::is_template()
+{
+ if (_index >= _depth)
+ {
+ if (_depth >= _size)
+ {
+ ERRMSG("Binary search depth exceeded.");
+ return false;
+ }
+ _status[_depth++] = false;
+ if (_depth > max_search_depth)
+ max_search_depth = _depth;
+ }
+ return _status[_index++] ? false : true;
+}
+
+//
+// Put this element onto listHead, returning element under this one.
+//
+CxxSearchContext *CxxSearchContext::queue(CxxSearchContext *& listHead)
+{
+ CxxSearchContext *oldNext = _next;
+ _next = listHead;
+ listHead = this;
+ return oldNext;
+}
+
+//
+// Release the current search buffer.
+//
+void CxxSearchContext::release()
+{
+ if (_current)
+ {
+ releases++;
+ _current->reset();
+ _current = _current->queue(_free);
+ }
+}
+
+void CxxSearchContext::reset()
+{
+ if (did_search())
+ {
+ _advances++;
+ actual_searches++;
+ }
+ if (_advances >= sizeof(advances)/sizeof(advances[0]))
+ advances[sizeof(advances)/sizeof(advances[0])-1]++;
+ else
+ advances[_advances]++;
+}
+
+void CxxSearchContext::start(YACC_MARK_TYPE anIndex, bool enableType1)
+{
+ if (!_current)
+ unnested_searches++;
+ else
+ nested_searches++;
+ if (!_free)
+ _current = new CxxSearchContext(_current);
+ else
+ _free = _free->queue(_current);
+ _current->initialise(anIndex, enableType1);
+}
+
+static CxxToken angleToken('<');
+static CxxToken colonToken(':');
+static CxxToken hashToken('#');
+static CxxToken plusToken('+');
+static CxxToken minusToken('-');
+
+void PARSE_SCOPE yyerror(const char *s)
+{
+ if (!bang_depth && (tokenMarkDepth == 0))
+ {
+ cout << s << endl;
+ increment_error_count();
+ }
+ else
+ {
+ if (show_marked)
+ cout << "Marked " << s << endl;
+ marked_error_count++;
+ }
+}
+
+//
+// Get the next token for the parser, invoking yylex_token to get the next token from the lexer.
+// This routine gets renamed to buffered_yylex by a #define when using yacc so that the two purposes
+// above are split allowing lookahead buffering and primimimg to occur.
+//
+int PARSE_SCOPE yylex()
+{
+ CxxToken *aToken = primed_tokens[0];
+ if (aToken)
+ {
+ primed_tokens[0] = primed_tokens[1];
+ primed_tokens[1] = primed_tokens[2];
+ primed_tokens[2] = 0;
+ }
+ else if (tokenReadIndex < tokenWriteIndex)
+ aToken = tokenBuffer[tokenReadIndex++];
+ else
+ {
+ aToken = yylex_token();
+ if (!aToken)
+ return 0;
+ if (tokenMarkDepth > 0)
+ token_put(aToken);
+ else
+ {
+ tokenWriteIndex = 0;
+ tokenReadIndex = 0;
+ }
+ }
+ yylval.token = aToken;
+ return aToken->value();
+}
+
+//
+// Advance the binary search of template attempts. Rewinds and forces true into the input sequence
+// to proceed with the search. Rewinds and forces false to terminate it. Also forces a # that may then
+// be used to initiate error propagation.
+//
+void advance_search()
+{
+ CxxSearchContext::search_advances++;
+ remark(CxxSearchContext::current()->mark());
+ if (CxxSearchContext::current() && CxxSearchContext::current()->advance())
+ {
+ primed_tokens[0] = &plusToken;
+ primed_tokens[1] = 0;
+ }
+ else
+ {
+ primed_tokens[0] = &minusToken;
+ primed_tokens[1] = &hashToken;
+ }
+}
+
+//
+// Complete a search, releasing the search context object and popping a mark off the stack.
+//
+void end_search(CxxToken *aToken)
+{
+ CxxSearchContext::release();
+ unmark(aToken);
+}
+
+//
+// Notch up an error and establish a good break point.
+//
+void increment_error_count()
+{
+ error_count++;
+}
+
+//
+// Push a new marked context onto the stack, returning its identity for use by remark().
+// Any parser readahead is incorporated within the marked region.
+//
+YACC_MARK_TYPE mark()
+{
+ if (primed_tokens[0])
+ ERRMSG("Unexpected primed_tokens[0] in mark.");
+ YACC_MARK_TYPE markIndex = tokenReadIndex;
+ if (PARSE_DOT yychar != YYEMPTY)
+ {
+// if (primed_tokens[2])
+// token_put(primed_tokens[2]);
+// if (primed_tokens[1])
+// token_put(primed_tokens[1]);
+// if (primed_tokens[0])
+// token_put(primed_tokens[0]);
+// if (!tokenMarkDepth)
+ if (!tokenReadIndex && !tokenWriteIndex)
+ {
+ token_put(PARSE_DOT yylval.token);
+ tokenReadIndex = 0;
+ }
+ else if (!tokenReadIndex)
+ ERRMSG("Unexpected 0 read index in mark.");
+ else if (tokenBuffer[--tokenReadIndex] != PARSE_DOT yylval.token)
+ ERRMSG("Unexpected unget in mark.");
+ markIndex = tokenReadIndex;
+ yyclearin;
+ primed_tokens[0] = 0;
+ primed_tokens[1] = 0;
+ }
+ tokenMarkDepth++;
+ bang_depth++;
+ return markIndex;
+}
+
+//
+// If it is appropriate to do type I function parameter parsing perform a mark and force a rrue token
+// into the input stream. Otherwise just force a false token in.
+//
+YACC_MARK_TYPE mark_type1()
+{
+ if (!in_type1 && CxxSearchContext::current() && CxxSearchContext::current()->enable_type1())
+ {
+ YACC_MARK_TYPE markIndex = mark();
+ primed_tokens[0] = &plusToken;
+ primed_tokens[1] = 0;
+ in_type1 = true;
+ yyclearin;
+ return markIndex;
+ }
+ else
+ {
+ primed_tokens[0] = &minusToken;
+ primed_tokens[1] = PARSE_DOT yychar != YYEMPTY ? PARSE_DOT yylval.token : 0;
+ yyclearin;
+ return 0; // Never used.
+ }
+}
+
+//
+// Push a bang context onto the error suppression stack, returning the context for restoration by pop_bang.
+//
+void pop_bang(YACC_BANG_TYPE bangValue)
+{
+ bang_depth = bangValue;
+}
+
+//
+// Push a bang context onto the error suppression stack, returning the context for restoration by pop_bang.
+//
+YACC_BANG_TYPE push_bang()
+{
+ return bang_depth++;
+}
+
+//
+// Reposition the input to restart at the position returned by a mark().
+//
+void remark(YACC_MARK_TYPE anIndex)
+{
+ tokenReadIndex = anIndex;
+ yyclearin;
+}
+
+//
+// Reposition the input to restart at the position returned by a mark().
+//
+void remark_type1(YACC_MARK_TYPE anIndex)
+{
+ remark(anIndex);
+ in_type1 = false;
+}
+
+//
+// Rewind the input stream back to anIndex and force a : prior to resuming input.
+//
+void rewind_colon(YACC_MARK_TYPE anIndex, const CxxToken *aToken)
+{
+ remark(anIndex);
+ unmark();
+ primed_tokens[0] = &colonToken;
+ primed_tokens[1] = PARSE_DOT yylval.token;
+}
+
+//
+// Start a new binary search over the template/arithmetic alternative parses of a statement.
+// Marks the current position and saves it in a binary search context maintained on a private stack.
+//
+void start_search(bool enableType1)
+{
+ bool type1Enabled = !CxxSearchContext::current() || CxxSearchContext::current()->enable_type1() ? true : false;
+ CxxSearchContext::start(mark(), enableType1 && type1Enabled ? true : false);
+}
+
+//
+// Determine whether the just parsed < should be interpreted as a template or arithmetic operator.
+// The implementation here intersacts with a binary search to traverse all possibilities in
+// multiple passes. The search proceeds by branch and bound presuming the template interpretation.
+// A true token is forced into the input stream to take the template interpretaion. A false token
+// otherwise.
+//
+// An alternate implementation that keeps track of scopes may interact with semantic knowledge to make
+// the correct decision directly.
+//
+void template_test()
+{
+ if (!CxxSearchContext::current() || CxxSearchContext::current()->is_template())
+ {
+ primed_tokens[0] = &plusToken;
+ primed_tokens[1] = 0;
+ }
+ else
+ {
+ primed_tokens[0] = &minusToken;
+ primed_tokens[1] = &angleToken;
+ }
+}
+
+void token_put(CxxToken *aToken)
+{
+ if (!tokenBuffer || !tokenSize)
+ tokenBuffer = new CxxToken *[tokenSize = 256];
+ else if (tokenWriteIndex >= tokenSize)
+ {
+ CxxToken **oldTokenBuffer = tokenBuffer;
+ size_t oldTokenSize = tokenSize;
+ tokenBuffer = new CxxToken *[tokenSize *= 2];
+ memcpy(tokenBuffer, oldTokenBuffer, oldTokenSize * sizeof(*oldTokenBuffer));
+ delete[] oldTokenBuffer;
+ }
+ tokenBuffer[tokenWriteIndex++] = aToken;
+ tokenReadIndex = tokenWriteIndex;
+}
+
+//
+// Pop a marked context off the stack.
+//
+void unmark(const CxxToken *aToken)
+{
+ if (bang_depth)
+ bang_depth--;
+ else
+ ERRMSG("BUG - should not unmark with 0 bang.");
+ if (tokenMarkDepth <= 0)
+ ERRMSG("Unexpected unmark.");
+ else
+ tokenMarkDepth--;
+}
--- /dev/null
+#include <CxxToken.hxx>
+#include <stdio.h>
+#ifndef _MSC_VER
+#include <alloca.h>
+#else
+#include <malloc.h>
+//#define alloca _alloca
+#endif
+void advance_search();
+void end_search(CxxToken *aToken);
+YACC_MARK_TYPE mark();
+YACC_MARK_TYPE mark_type1();
+size_t nest() { return 0; }
+void pop_bang(YACC_BANG_TYPE bangValue);
+YACC_BANG_TYPE push_bang();
+void remark(YACC_MARK_TYPE anIndex);
+void remark_type1(YACC_MARK_TYPE anIndex);
+void rewind_colon(YACC_MARK_TYPE anIndex, const CxxToken *aToken);
+void start_search(bool enableType1);
+void template_test();
+void unmark(const CxxToken *aToken = 0);
+void unnest(size_t aNest) {}
+
+void classify_argument();
+void classify_function();
+void dollar_kill();
+CxxTokens *get_code(CxxToken *);
+CxxTokens *get_expr();
+CxxTokens *get_for_init();
+CxxTokens *get_for_next();
+CxxTokens *get_for_test();
+CxxTokens *get_func();
+CxxTokens *get_raw(CxxToken *);
+CxxTokens *get_statement();
+void make(CxxToken *);
+void queue(CxxToken *);
+int set_replace_formals(int);
+
+extern CxxToken *_list_token;
+
+#ifndef BISON_PP_CLASS
+void yyerror(const char *s);
+#define yylex buffered_yylex
+int yylex();
+#endif
+
+#define YACC_ABSTRACT_ARRAY_EXPRESSION(a) make_abstract_array_expression(a)
+#define YACC_ABSTRACT_FUNCTION_EXPRESSION(a) make_abstract_function_expression(a)
+#define YACC_ACCESSIBILITY_SPECIFIER(a) make_accessibility_specifier(a)
+#define YACC_ACCESS_BASE_SPECIFIER(a,b) make_access_base_specifier(a,b)
+#define YACC_ACCESS_SPECIFIER_ID(a) make_access_specifier_id(a)
+#define YACC_ADD_EXPRESSION(a,b) make_add_expression(a, b)
+#define YACC_AND_EXPRESSION(a,b) make_and_expression(a,b)
+#define YACC_ARRAY_EXPRESSION(a,b) make_array_expression(a,b)
+#define YACC_ARROW_EXPRESSION(a,b) make_arrow_expression(a,b)
+#define YACC_ARROW_STAR_EXPRESSION(a,b) make_arrow_star_expression(a,b)
+#define YACC_ASM_DEFINITION(a) make_asm_definition(a)
+#define YACC_ASSIGNMENT_EXPRESSION(a,b,c) make_assignment_expression(a,b,c)
+#define YACC_BASE_SPECIFIER(a) make_base_specifier(a)
+#define YACC_BASE_SPECIFIERS(a,b) make_base_specifiers(a,b)
+#define YACC_BIT_FIELD_EXPRESSION(a,b) make_bit_field_expression(a,b)
+#define YACC_BREAK_STATEMENT() make_break_statement()
+#define YACC_BUILT_IN_ID(a) make_built_in_id(a)
+#define YACC_BUILT_IN_ID_ID(a) make_built_in_id_id(a)
+#define YACC_BUILT_IN_IDS(a,b) make_built_in_ids(a,b)
+#define YACC_BUILT_IN_NAME(a,b) make_built_in_name(a,b)
+#define YACC_CALL_EXPRESSION(a,b) make_call_expression(a,b)
+#define YACC_CASE_STATEMENT(a,b) make_case_statement(a,b)
+#define YACC_CAST_EXPRESSION(a,b) make_cast_expression(a,b)
+#define YACC_CHARACTER_LITERAL_EXPRESSION(a) make_character_literal_expression(a)
+#define YACC_CLASS_MEMBERS(a,b) make_class_members(a,b)
+#define YACC_CLASS_SPECIFIER_ID(a,b,c) make_class_specifier_id(a,b,c)
+#define YACC_CLASS_TEMPLATE_PARAMETER(a) make_class_template_parameter(a)
+#define YACC_CLASS_TYPE_PARAMETER(a) make_class_type_parameter(a)
+#define YACC_COMPILE_DECLARATION(a,b) compile_declaration(a,b)
+#define YACC_COMPILE_STATEMENT(a) compile_statement(a)
+#define YACC_COMPLEMENT_EXPRESSION(a) make_complement_expression(a)
+#define YACC_COMPOUND_STATEMENT(a) make_compound_statement(a)
+#define YACC_CONDITION(a) make_condition(a)
+#define YACC_CONDITIONAL_EXPRESSION(a,b,c) make_conditional_expression(a,b,c)
+#define YACC_CONST_CAST_EXPRESSION(a,b) make_const_cast_expression(a,b)
+#define YACC_CONTINUE_STATEMENT() make_continue_statement()
+#define YACC_CONVERSION_FUNCTION_ID(a) make_conversion_function_id(a)
+#define YACC_CTOR_DEFINITION(a,b) make_ctor_definition(a,b)
+#define YACC_CTOR_FUNCTION_BLOCK(a,b) make_ctor_function_block(a,b)
+#define YACC_CV_DECLARATOR(a,b) make_cv_declarator(a,b)
+#define YACC_CV_DECL_SPECIFIER(a) make_cv_decl_specifier(a)
+#define YACC_CV_QUALIFIERS(a,b) make_cv_qualifiers(a,b)
+#define YACC_DECLARATIONS(a,b) make_declarations(a,b)
+#define YACC_DECLARATION_STATEMENT(a) make_declaration_statement(a)
+#define YACC_DECL_SPECIFIER_DECLARATION(a,b) make_decl_specifier_declaration(a,b)
+#define YACC_DECL_SPECIFIER_EXPRESSION(a,b) make_decl_specifier_expression(a,b)
+#define YACC_DECL_SPECIFIER_NAME(a,b) make_decl_specifier_name(a,b)
+#define YACC_DECL_SPECIFIER_PARAMETER(a,b) make_decl_specifier_parameter(a,b)
+#define YACC_DECL_SPECIFIERS(a,b) make_decl_specifiers(a,b)
+#define YACC_DECL_SPECIFIER_TREE_ARGUMENT(a,b) make_decl_specifier_tree_argument(a,b)
+#define YACC_DECL_SPECIFIER_TREE_ARGUMENTS(a,b) make_decl_specifier_tree_arguments(a,b)
+#define YACC_DEFAULT_STATEMENT(a) make_default_statement(a)
+#define YACC_DELETE_EXPRESSION(a) make_delete_expression(a)
+#define YACC_DERIVED_CLAUSE(a,b) make_derived_clause(a,b)
+#define YACC_DESTRUCTOR_ID(a) make_destructor_id(a)
+#define YACC_DIVIDE_EXPRESSION(a,b) make_divide_expression(a,b)
+#define YACC_DOT_EXPRESSION(a,b) make_dot_expression(a,b)
+#define YACC_DOT_STAR_EXPRESSION(a,b) make_dot_star_expression(a,b)
+#define YACC_DO_WHILE_STATEMENT(a,b) make_do_while_statement(a,b)
+#define YACC_DYNAMIC_CAST_EXPRESSION(a,b) make_dynamic_cast_expression(a,b)
+#define YACC_ELABORATED_TYPE_SPECIFIER(a,b) make_elaborated_type_specifier(a,b)
+#define YACC_ELLIPSIS_EXPRESSION() make_ellipsis_expression()
+#define YACC_ENUMERATOR(a,b) make_enumerator(a,b)
+#define YACC_ENUMERATORS(a,b) make_enumerators(a,b)
+#define YACC_ENUM_SPECIFIER_ID(a,b) make_enum_specifier_id(a,b)
+#define YACC_ENUM_TREE_ID(a) make_enum_tree_id(a)
+#define YACC_EPSILON() make_epsilon()
+#define YACC_EQUAL_EXPRESSION(a,b) make_equal_expression(a,b)
+#define YACC_EXCEPTION_DECLARATION(a) make_exception_declaration(a)
+#define YACC_EXCEPTION_SPECIFICATION(a) make_exception_specification(a)
+#define YACC_EXCLUSIVE_OR_EXPRESSION(a,b) make_exclusive_or_expression(a,b)
+#define YACC_EXPLICIT_IMPLEMENTATION_DECLARATION(a) make_explicit_implementation_declaration(a)
+#define YACC_EXPLICIT_INTERFACE_DECLARATION(a) make_explicit_interface_declaration(a)
+#define YACC_EXPLICIT_SPECIALIZATION(a) make_explicit_specialization(a)
+#define YACC_EXPORT_IMPLEMENTATION_DECLARATION(a) make_export_implementation_declaration(a)
+#define YACC_EXPORT_INTERFACE_DECLARATION(a) make_export_interface_declaration(a)
+#define YACC_EXPORT_NOIMPLEMENTATION_DECLARATION() make_export_noimplementation_declaration()
+#define YACC_EXPRESSION(a) make_expression(a)
+#define YACC_EXPRESSIONS(a,b) make_expressions(a,b)
+#define YACC_EXPRESSION_PARAMETER(a) make_expression_parameter(a)
+#define YACC_FALSE_EXPRESSION() make_false_expression()
+#define YACC_FILESPACE_DECLARATION(a) make_filespace_declaration(a)
+#define YACC_FILESPACE_SPECIFIER(a,b) make_filespace_specifier(a,b)
+#define YACC_FILE_ID(a) make_file_id(a)
+#define YACC_FILE_ID_IMPLEMENTATION(a) make_file_id_implementation(a)
+#define YACC_FILE_ID_INTERFACE(a) make_file_id_interface(a)
+#define YACC_FILE_IDS(a,b) make_file_ids(a,b)
+#define YACC_FILE_NAME(a) make_file_name(a)
+#define YACC_FILE_NAME_GUARD(a,b) make_file_name_guard(a,b)
+#define YACC_FILE_NAME_IMPLEMENTATION(a) make_file_name_implementation(a)
+#define YACC_FILE_NAME_INTERFACE(a) make_file_name_interface(a)
+#define YACC_FILE_NAME_NOGUARD(a) make_file_name_noguard(a)
+#define YACC_FILE_NAME_PATH(a,b) make_file_name_path(a,b)
+#define YACC_FILE_NAME_PREFIX(a,b) make_file_name_prefix(a,b)
+#define YACC_FILE_NAME_SUFFIX(a,b) make_file_name_suffix(a,b)
+#define YACC_FILE_NAME_TEMPLATE(a) make_file_name_template(a)
+#define YACC_FILE_NAME_UTILITY(a,b) make_file_name_utility(a,b)
+#define YACC_FLOATING_LITERAL_EXPRESSION(a) make_floating_literal_expression(a)
+#define YACC_FOR_STATEMENT(a,b,c,d) make_for_statement(a,b,c,d)
+#define YACC_FUNCTION_BLOCK(a) make_function_block(a)
+#define YACC_FUNCTION_DECLARATIONS(a,b) make_function_declarations(a,b)
+#define YACC_FUNCTION_DEFINITION(a,b) make_function_definition(a,b)
+#define YACC_GLOBAL_DECLARATOR(a,b) make_global_declarator(a,b)
+#define YACC_GLOBAL_EXPRESSION(a, b) make_global_expression(a,b)
+#define YACC_GLOBAL_ID(a,b) make_global_id(a,b)
+#define YACC_GOTO_STATEMENT(a) make_goto_statement(a)
+#define YACC_GREATER_EQUAL_EXPRESSION(a,b) make_greater_equal_expression(a,b)
+#define YACC_GREATER_THAN_EXPRESSION(a,b) make_greater_than_expression(a,b)
+#define YACC_HANDLER(a,b) make_handler(a,b)
+#define YACC_HANDLERS(a,b) make_handlers(a,b)
+#define YACC_IF_STATEMENT(a,b,c) make_if_statement(a,b,c)
+#define YACC_INCLUDE_DECLARATION(a,b) make_include_declaration(a,b)
+#define YACC_INCLUSIVE_OR_EXPRESSION(a,b) make_inclusive_or_expression(a,b)
+#define YACC_INITIALIZED_PARAMETER(a,b) make_initialized_parameter(a, b)
+#define YACC_INITIALIZER_CLAUSES(a,b) make_initializer_clauses(a,b)
+#define YACC_INITIALIZER_EXPRESSION_CLAUSE(a) make_initializer_expression_clause(a)
+#define YACC_INITIALIZER_LIST_CLAUSE(a) make_initializer_list_clause(a)
+#define YACC_INIT_SIMPLE_TYPE_PARAMETER(a,b) make_init_simple_type_parameter(a,b)
+#define YACC_INIT_TEMPLATED_PARAMETER(a,b) make_init_templated_parameter(a,b)
+#define YACC_INLINE_AS_FRIEND() make_inline_as_friend()
+#define YACC_INLINE_IF_SHORT() make_inline_if_short()
+#define YACC_INLINE_IN_IMPLEMENTATION() make_inline_in_implementation()
+#define YACC_INLINE_IN_INTERFACE() make_inline_in_interface()
+#define YACC_INDEX_CAST_EXPRESSION(a,b) make_index_cast_expression(a,b)
+#define YACC_INPUT_FILE(a) make_input_file(a)
+#define YACC_INTEGER_LITERAL_EXPRESSION(a) make_integer_literal_expression(a)
+#define YACC_LABEL_STATEMENT(a,b) make_label_statement(a,b)
+#define YACC_LESS_EQUAL_EXPRESSION(a,b) make_less_equal_expression(a,b)
+#define YACC_LESS_THAN_EXPRESSION(a,b) make_less_than_expression(a,b)
+#define YACC_LINE() make_line()
+#define YACC_LINED_DECLARATION(a,b) make_lined_declaration(a,b)
+#define YACC_LINED_STATEMENT(a,b) make_lined_statement(a,b)
+#define YACC_LINED_TOKEN(a,b) make_lined_token(a,b)
+#define YACC_LINKAGE_SPECIFICATION(a) make_linkage_specification(a)
+#define YACC_LINKAGE_SPECIFIER(a,b) make_linkage_specifier(a,b)
+#define YACC_LOGICAL_AND_EXPRESSION(a,b) make_logical_and_expression(a,b)
+#define YACC_LOGICAL_OR_EXPRESSION(a,b) make_logical_or_expression(a,b)
+#define YACC_MEMBER_DECLARATIONS(a,b) make_member_declarations(a,b)
+#define YACC_MEM_INITIALIZER(a,b) make_mem_initializer(a,b)
+#define YACC_MEM_INITIALIZERS(a,b) make_mem_initializers(a,b)
+#define YACC_META_ASSIGNMENT_EXPRESSION(a,b,c) make_meta_assignment_expression(a,b,c)
+#define YACC_META_BASE_SPECIFIER(a) make_meta_base_specifier(a)
+#define YACC_META_BREAK_STATEMENT() make_meta_break_statement()
+#define YACC_META_BUILT_IN_TYPE(a) make_meta_built_in_type(a)
+#define YACC_META_CASE_STATEMENT(a,b) make_meta_case_statement(a,b)
+#define YACC_META_CLASS(a,b,c) make_meta_class(a,b,c)
+#define YACC_META_CONTINUE_STATEMENT() make_meta_continue_statement()
+#define YACC_META_DEFAULT_STATEMENT(a) make_meta_default_statement(a)
+#define YACC_META_DO_WHILE_STATEMENT(a,b,c) make_meta_do_while_statement(a,b,c)
+#define YACC_META_FOR_STATEMENT(a,b,c,d,e) make_meta_for_statement(a,b,c,d,e)
+#define YACC_META_FUNCTION(a,b,c) make_meta_function(a,b,c)
+#define YACC_META_IF_STATEMENT(a,b,c,d) make_meta_if_statement(a,b,c,d)
+#define YACC_META_INITIALIZER(a,b) make_meta_initializer(a,b)
+#define YACC_META_INITIALIZERS(a,b) make_meta_initializers(a,b)
+#define YACC_META_RETURN_STATEMENT(a) make_meta_return_statement(a)
+#define YACC_META_STATEMENT(a) make_meta_statement(a)
+#define YACC_META_STATEMENT_DECLARATION(a) make_meta_statement_declaration(a)
+#define YACC_META_SWITCH_STATEMENT(a,b,c) make_meta_switch_statement(a,b,c)
+#define YACC_META_TYPE(a) make_meta_type(a)
+#define YACC_META_TYPE_ID(a) make_meta_type_id(a)
+#define YACC_META_WHILE_STATEMENT(a,b,c) make_meta_while_statement(a,b,c)
+#define YACC_MINUS_EXPRESSION(a) make_minus_expression(a)
+#define YACC_MODULUS_EXPRESSION(a,b) make_modulus_expression(a,b)
+#define YACC_MULTIPLY_EXPRESSION(a,b,c) make_multiply_expression(a,b,c)
+#define YACC_NAME(a) make_name(a)
+#define YACC_NAMESPACE_ALIAS_DEFINITION(a,b) make_namespace_alias_definition(a,b)
+#define YACC_NAMESPACE_DECLARATION(a) make_namespace_declaration(a)
+#define YACC_NAMESPACE_DEFINITION(a,b) make_namespace_definition(a,b)
+#define YACC_NAME_EXPRESSION(a) make_name_expression(a)
+#define YACC_NESTED_DECLARATOR(a,b) make_nested_declarator(a,b)
+#define YACC_NESTED_ID(a,b) make_nested_id(a,b)
+#define YACC_NESTED_SCOPE(a) make_nested_scope(a)
+#define YACC_NEW_EXPRESSION(a,b,c) make_new_expression(a,b,c)
+#define YACC_NEW_TYPE_ID_EXPRESSION(a,b,c) make_new_type_id_expression(a,b,c)
+#define YACC_NOT_CONST() make_not_const()
+#define YACC_NOT_EQUAL_EXPRESSION(a,b) make_not_equal_expression(a,b)
+#define YACC_NOT_EXPRESSION(a) make_not_expression(a)
+#define YACC_NOT_INLINE() make_not_inline()
+#define YACC_NOT_STATIC() make_not_static()
+#define YACC_NOT_VIRTUAL() make_not_virtual()
+#define YACC_NOT_VIRTUAL_BASE_SPECIFIER(a) make_not_virtual_base_specifier(a)
+#define YACC_NOT_VOLATILE() make_not_volatile()
+#define YACC_NUMBER_LITERAL_EXPRESSION(a) make_number_literal_expression(a)
+#define YACC_OBJECT_SCOPE_EXPRESSION(a,b) make_object_scope_expression(a,b)
+#define YACC_OPERATOR_ADD_ID() make_operator_add_id()
+#define YACC_OPERATOR_ARROW_ID() make_operator_arrow_id()
+#define YACC_OPERATOR_ARROW_STAR_ID() make_operator_arrow_star_id()
+#define YACC_OPERATOR_ASS_ADD_ID() make_operator_ass_add_id()
+#define YACC_OPERATOR_ASS_BIT_AND_ID() make_operator_ass_bit_and_id()
+#define YACC_OPERATOR_ASS_BIT_OR_ID() make_operator_ass_bit_or_id()
+#define YACC_OPERATOR_ASS_DIV_ID() make_operator_ass_div_id()
+#define YACC_OPERATOR_ASS_ID() make_operator_ass_id()
+#define YACC_OPERATOR_ASS_MOD_ID() make_operator_ass_mod_id()
+#define YACC_OPERATOR_ASS_MUL_ID() make_operator_ass_mul_id()
+#define YACC_OPERATOR_ASS_SHL_ID() make_operator_ass_shl_id()
+#define YACC_OPERATOR_ASS_SHR_ID() make_operator_ass_shr_id()
+#define YACC_OPERATOR_ASS_SUB_ID() make_operator_ass_sub_id()
+#define YACC_OPERATOR_ASS_XOR_ID() make_operator_ass_xor_id()
+#define YACC_OPERATOR_BIT_AND_ID() make_operator_bit_and_id()
+#define YACC_OPERATOR_BIT_NOT_ID() make_operator_bit_not_id()
+#define YACC_OPERATOR_BIT_OR_ID() make_operator_bit_or_id()
+#define YACC_OPERATOR_CALL_ID() make_operator_call_id()
+#define YACC_OPERATOR_COMMA_ID() make_operator_comma_id()
+#define YACC_OPERATOR_DEC_ID() make_operator_dec_id()
+#define YACC_OPERATOR_DELETE_ID() make_operator_delete_id()
+#define YACC_OPERATOR_DIV_ID() make_operator_div_id()
+#define YACC_OPERATOR_EQ_ID() make_operator_eq_id()
+#define YACC_OPERATOR_FUNCTION_ID(a) make_operator_function_id(a)
+#define YACC_OPERATOR_GE_ID() make_operator_ge_id()
+#define YACC_OPERATOR_GT_ID() make_operator_gt_id()
+#define YACC_OPERATOR_INC_ID() make_operator_inc_id()
+#define YACC_OPERATOR_INDEX_ID() make_operator_index_id()
+#define YACC_OPERATOR_LE_ID() make_operator_le_id()
+#define YACC_OPERATOR_LOG_AND_ID() make_operator_log_and_id()
+#define YACC_OPERATOR_LOG_NOT_ID() make_operator_log_not_id()
+#define YACC_OPERATOR_LOG_OR_ID() make_operator_log_or_id()
+#define YACC_OPERATOR_LT_ID() make_operator_lt_id()
+#define YACC_OPERATOR_MOD_ID() make_operator_mod_id()
+#define YACC_OPERATOR_MUL_ID() make_operator_mul_id()
+#define YACC_OPERATOR_NE_ID() make_operator_ne_id()
+#define YACC_OPERATOR_NEW_ID() make_operator_new_id()
+#define YACC_OPERATOR_SHL_ID() make_operator_shl_id()
+#define YACC_OPERATOR_SHR_ID() make_operator_shr_id()
+#define YACC_OPERATOR_SUB_ID() make_operator_sub_id()
+#define YACC_OPERATOR_XOR_ID() make_operator_xor_id()
+#define YACC_PARAMETERS(a,b) make_parameters(a,b)
+#define YACC_PARENTHESISED(a,b,c) make_parenthesised(a,b,c)
+#define YACC_POINTER_DECLARATOR() make_pointer_declarator()
+#define YACC_POINTER_EXPRESSION(a,b) make_pointer_expression(a,b)
+#define YACC_PLUS_EXPRESSION(a) make_plus_expression(a)
+#define YACC_POSITION(a,b) make_position(a)
+#define YACC_POSITION_FUNCTION_BLOCK(a,b) make_position_function_block(a,b)
+#define YACC_POST_DECREMENT_EXPRESSION(a) make_post_decrement_expression(a)
+#define YACC_POST_INCREMENT_EXPRESSION(a) make_post_increment_expression(a)
+#define YACC_PRE_DECREMENT_EXPRESSION(a) make_pre_decrement_expression(a)
+#define YACC_PRE_INCREMENT_EXPRESSION(a) make_pre_increment_expression(a)
+#define YACC_PSEUDO_DESTRUCTOR_ID(a,b) make_pseudo_destructor_id(a,b)
+#define YACC_PURE_VIRTUAL() make_pure_virtual()
+#define YACC_READ_ONLY_RESULT(a) make_read_only_result(a)
+#define YACC_READ_WRITE_RESULT(a) make_read_write_result(a)
+#define YACC_REFERENCE_DECLARATOR() make_reference_declarator()
+#define YACC_REINTERPRET_CAST_EXPRESSION(a,b) make_reinterpret_cast_expression(a,b)
+#define YACC_RESULT(a) make_result(a)
+#define YACC_RETURN_STATEMENT(a) make_return_statement(a)
+#define YACC_SCOPED_POINTER_EXPRESSION(a,b,c) make_scoped_pointer_expression(a,b,c)
+#define YACC_SCOPED_ID(a,b) make_scoped_id(a,b)
+#define YACC_SEGMENT(a,b) make_segment(a)
+#define YACC_SEGMENT_FUNCTION_BLOCK(a,b) make_segment_function_block(a,b)
+#define YACC_SET_TEMPLATE_DECLARATION(a) make_set_template_declaration(a)
+#define YACC_SET_TEMPLATE_DECL_SPECIFIER(a) make_set_template_decl_specifier(a)
+#define YACC_SET_TEMPLATE_EXPRESSION(a) make_set_template_expression(a)
+#define YACC_SET_TEMPLATE_ID(a) make_set_template_id(a)
+#define YACC_SET_TEMPLATE_NAME(a) make_set_template_name(a)
+#define YACC_SET_TEMPLATE_SCOPE(a) make_set_template_scope(a)
+#define YACC_SHIFT_LEFT_EXPRESSION(a,b) make_shift_left_expression(a,b)
+#define YACC_SHIFT_RIGHT_EXPRESSION(a,b) make_shift_right_expression(a,b)
+#define YACC_SIMPLE_DECLARATION(a) make_simple_declaration(a)
+#define YACC_SIZEOF_EXPRESSION(a) make_sizeof_expression(a)
+#define YACC_STATEMENTS(a,b) make_statements(a,b)
+#define YACC_STATIC_CAST_EXPRESSION(a,b) make_static_cast_expression(a,b)
+#define YACC_STRINGS(a,b) make_strings(a,b)
+#define YACC_STRING_LITERAL_EXPRESSION(a) make_string_literal_expression(a)
+#define YACC_SUBTRACT_EXPRESSION(a,b) make_subtract_expression(a,b)
+#define YACC_SWITCH_STATEMENT(a,b) make_switch_statement(a,b)
+#define YACC_SYNTAX_MACRO_DEFINITION(a,b,c,d,e) make_syntax_macro_definition(a,b,c,d,e)
+#define YACC_SYNTAX_MACRO_PARAMETER(a,b,c) make_syntax_macro_parameter(a,b,c)
+#define YACC_SYNTAX_MACRO_PARAMETERS(a,b) make_syntax_macro_parameters(a,b)
+#define YACC_TEMPLATE_ARGUMENT(a) make_template_argument(a)
+#define YACC_TEMPLATE_ARGUMENTS(a,b) make_template_arguments(a,b)
+#define YACC_TEMPLATED_TEMPLATE_PARAMETER(a,b) make_templated_template_parameter(a,b)
+#define YACC_TEMPLATED_TYPE_PARAMETER(a,b) make_templated_type_parameter(a,b)
+#define YACC_TEMPLATE_DECLARATION(a,b) make_template_declaration(a,b)
+#define YACC_TEMPLATE_NAME(a,b) make_template_name(a,b)
+#define YACC_TEMPLATE_PARAMETER(a) make_template_parameter(a)
+#define YACC_TEMPLATE_PARAMETERS(a,b) make_template_parameters(a,b)
+#define YACC_THIS_EXPRESSION() make_this_expression()
+#define YACC_THROW_EXPRESSION(a) make_throw_expression(a)
+#define YACC_TOKENS_EXPRESSION(a) make_tokens_expression(a)
+#define YACC_TREE_ARGUMENT(a) make_tree_argument(a)
+#define YACC_TREE_ARGUMENTS(a,b) make_tree_arguments(a,b)
+#define YACC_TREE_ARRAY_EXPRESSION(a,b) make_tree_array_expression(a,b)
+#define YACC_TREE_ARROW_EXPRESSION(a,b) make_tree_arrow_expression(a,b)
+#define YACC_TREE_ARROW_CALL_EXPRESSION(a,b,c) make_tree_arrow_call_expression(a,b,c)
+#define YACC_TREE_CALL_EXPRESSION(a,b) make_tree_call_expression(a,b)
+#define YACC_TREE_DOT_EXPRESSION(a,b) make_tree_dot_expression(a,b)
+#define YACC_TREE_DOT_CALL_EXPRESSION(a,b,c) make_tree_dot_call_expression(a,b,c)
+#define YACC_TREE_EXPRESSION(a) make_tree_expression(a)
+#define YACC_TREE_ID(a) make_tree_id(a)
+#define YACC_TREE_POINTER_EXPRESSION(a) make_tree_pointer_expression(a)
+#define YACC_TRUE_EXPRESSION() make_true_expression()
+#define YACC_TRY_BLOCK(a,b) make_try_block(a,b)
+#define YACC_TRY_BLOCK_STATEMENT(a) make_try_block_statement(a)
+#define YACC_TRY_FUNCTION_BLOCK(a,b) make_try_function_block(a,b)
+#define YACC_TYPE1_EXPRESSION(a,b,c) make_type1_expression(a,b,c)
+#define YACC_TYPE1_PARAMETERS(a,b) make_type1_parameters(a,b)
+#define YACC_TYPED_EXPRESSION(a,b) make_typed_expression(a,b)
+#define YACC_TYPED_NAME(a,b) make_typed_name(a,b)
+#define YACC_TYPEID_EXPRESSION(a) make_typeid_expression(a)
+#define YACC_TYPENAME_TEMPLATE_PARAMETER(a) make_typename_template_parameter(a)
+#define YACC_TYPENAME_TYPE_PARAMETER(a) make_typename_type_parameter(a)
+#define YACC_TYPE_TEMPLATE_PARAMETER(a,b) make_type_template_parameter(a,b)
+#define YACC_USING_DECLARATION(a,b) make_using_declaration(a,b)
+#define YACC_USING_DIRECTIVE(a) make_using_directive(a)
+#define YACC_USING_FUNCTION_BLOCK(a,b) make_using_function_block(a,b)
+#define YACC_USING_IMPLEMENTATION_DECLARATION(a) make_using_implementation_declaration(a)
+#define YACC_USING_INTERFACE_DECLARATION(a) make_using_interface_declaration(a)
+#define YACC_UTILITY(a) make_utility(0)
+#define YACC_UTILITY_MODE() make_utility_mode()
+#define YACC_VIRTUAL_BASE_SPECIFIER(a) make_virtual_base_specifier(a)
+#define YACC_WHILE_STATEMENT(a,b) make_while_statement(a,b)
+
+CxxDeclaration *compile_declaration(CxxUtility *utilityMode, CxxDeclaration *aDeclaration) { return 0; }
+CxxStatement *compile_statement(CxxStatement *aDeclaration) { return 0; }
+void make_result(CxxToken *aResult) {}
+
+CxxExpression *make_abstract_array_expression(CxxExpression *sizeExpr) { return 0; }
+CxxExpression *make_abstract_function_expression(CxxParenthesised *aparenthesis) { return 0; }
+CxxBaseSpecifier *make_access_base_specifier(CxxBaseSpecifier *baseSpecifier, CxxAccessSpecifier *accessSpecifier) { return 0; }
+CxxDeclSpecifierId *make_access_specifier_id(CxxAccessSpecifier *aName) { return 0; }
+CxxDeclaration *make_accessibility_specifier(CxxAccessSpecifier *accessSpecifier) { return 0; }
+CxxExpression *make_add_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_and_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_array_expression(CxxExpression *anExpr, CxxExpression *indexExpr) { return 0; }
+CxxExpression *make_arrow_expression(CxxExpression *anExpr, CxxName *aName) { return 0; }
+CxxExpression *make_arrow_star_expression(CxxExpression *anExpr, CxxExpression *memberExpr) { return 0; }
+CxxDeclaration *make_asm_definition(CxxStrings *aString) { return 0; }
+CxxExpression *make_assignment_expression(CxxExpression *leftExpr, CxxToken *assOp, CxxExpression *rightExpr) { return 0; }
+CxxBaseSpecifier *make_base_specifier(CxxName *aName) { return 0; }
+CxxBaseSpecifiers *make_base_specifiers(CxxBaseSpecifiers *aList, CxxBaseSpecifier *anElement) { return 0; }
+CxxExpression *make_bit_field_expression(CxxExpression *nameExpr, CxxExpression *sizeExpr) { return 0; }
+CxxStatement *make_break_statement() { return 0; }
+CxxName *make_built_in_id(CxxBuiltInId *aName) { return 0; }
+CxxName *make_built_in_id_id(CxxBuiltInId *aName) { return 0; }
+CxxBuiltInId *make_built_in_ids(CxxBuiltInId *anExpr, CxxBuiltInId *anElement) { return 0; }
+CxxName *make_built_in_name(CxxName *aName, CxxBuiltInId *anElement) { return 0; }
+CxxExpression *make_call_expression(CxxExpression *anExpr, CxxParenthesised *aParenthesis) { return 0; }
+CxxStatement *make_case_statement(CxxExpression *anExpr, CxxStatement *aStmt) { return 0; }
+CxxExpression *make_cast_expression(CxxExpression *aCast, CxxExpression *anExpr) { return 0; }
+CxxExpression *make_character_literal_expression(CxxCharacterLiteral *aLiteral) { return 0; }
+CxxName *make_class_members(CxxClass *aClass, CxxMemberDeclarations *memberDeclarations) { return 0; }
+CxxClass *make_class_specifier_id(CxxClassKey *classKey, CxxName *aName, CxxBaseSpecifiers *baseSpecifiers) { return 0; }
+CxxSimpleTypeParameter *make_class_template_parameter(CxxName *aName) { return 0; }
+CxxSimpleTypeParameter *make_class_type_parameter(CxxName *aName) { return 0; }
+CxxStatement *make_compound_statement(CxxStatements *statementList) { return 0; }
+CxxExpression *make_complement_expression(CxxExpression *anExpr) { return 0; }
+CxxCondition *make_condition(CxxParameters *aList) { return 0; }
+CxxExpression *make_conditional_expression(CxxExpression *testExpr, CxxExpression *trueExpr, CxxExpression *falseExpr) { return 0; }
+CxxExpression *make_const_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
+CxxStatement *make_continue_statement() { return 0; }
+CxxName *make_conversion_function_id(CxxExpression *typeId) { return 0; }
+CxxExpression *make_ctor_definition(CxxExpressions *anExpr, CxxFunctionBody *functionBody) { return 0; }
+CxxFunctionBody *make_ctor_function_block(CxxFunctionBody *functionBody, CxxMemInitializers *ctorList) { return 0; }
+CxxDeclSpecifierId *make_cv_decl_specifier(CxxCvQualifiers *cvQualifiers) { return 0; }
+CxxPointerDeclarator *make_cv_declarator(CxxPointerDeclarator *aDeclarator, CxxCvQualifiers *cvQualifiers) { return 0; }
+CxxCvQualifiers *make_cv_qualifiers(CxxCvQualifiers *aList, CxxCvQualifiers *anElement) { return 0; }
+CxxDeclaration *make_decl_specifier_declaration(CxxDeclaration *aDeclaration, CxxDeclSpecifierId *declSpecifier) { return 0; }
+CxxExpression *make_decl_specifier_expression(CxxExpression *anExpr, CxxDeclSpecifierId *declSpecifier) { return 0; }
+CxxName *make_decl_specifier_name(CxxName *aName, CxxDeclSpecifierId *declSpecifier) { return 0; }
+CxxParameter *make_decl_specifier_parameter(CxxParameter *aName, CxxDeclSpecifierId *declSpecifier) { return 0; }
+CxxToken *make_decl_specifier_tree_argument(CxxToken *treeArgument, CxxDeclSpecifierId *aName) { return 0; }
+CxxTokens *make_decl_specifier_tree_arguments(CxxTokens *treeArguments, CxxDeclSpecifierId *aName) { return 0; }
+CxxDeclSpecifierId *make_decl_specifiers(CxxDeclSpecifierId *aList, CxxDeclSpecifierId *anElement) { return 0; }
+CxxDeclarations *make_declarations(CxxDeclarations *aList, CxxDeclaration *anElement) { return 0; }
+CxxStatement *make_declaration_statement(CxxDeclaration *aDecl) { return 0; }
+CxxStatement *make_default_statement(CxxStatement *aStmt) { return 0; }
+CxxExpression *make_delete_expression(CxxExpression *anExpr) { return 0; }
+CxxDeclaration *make_derived_clause(CxxExpression *derivedPredicate, CxxDeclaration *aDeclaration) { return 0; }
+CxxName *make_destructor_id(CxxName *aName) { return 0; }
+CxxExpression *make_divide_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxStatement *make_do_while_statement(CxxStatement *aStmt, CxxExpression *testExpr) { return 0; }
+CxxExpression *make_dot_expression(CxxExpression *anExpr, CxxName *aName) { return 0; }
+CxxExpression *make_dot_star_expression(CxxExpression *anExpr, CxxExpression *memberExpr) { return 0; }
+CxxExpression *make_dynamic_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
+CxxName *make_elaborated_type_specifier(CxxClassKey *classKey, CxxName *aName) { return 0; }
+CxxParameter *make_ellipsis_expression() { return 0; }
+CxxName *make_enum_specifier_id(CxxName *aName, CxxEnumerators *aList) { return 0; }
+CxxEnumerator *make_enumerator(CxxName *aName, CxxExpression *anExpr) { return 0; }
+CxxEnumerators *make_enumerators(CxxEnumerators *aList, CxxEnumerator *anElement) { return 0; }
+CxxName *make_epsilon() { return 0; }
+CxxExpression *make_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExceptionDeclaration *make_exception_declaration(CxxParameter *aParameter) { return 0; }
+CxxExceptionSpecification *make_exception_specification(CxxExpressions *typeIds) { return 0; }
+CxxExpression *make_exclusive_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxDeclaration *make_explicit_implementation_declaration(CxxTokens *someTokens) { return 0; }
+CxxDeclaration *make_explicit_interface_declaration(CxxTokens *someTokens) { return 0; }
+CxxDeclaration *make_explicit_specialization(CxxDeclaration *aDeclaration) { return 0; }
+CxxDeclaration *make_export_implementation_declaration(CxxFileId *fileId) { return 0; }
+CxxDeclaration *make_export_interface_declaration(CxxFileId *fileId) { return 0; }
+CxxDeclaration *make_export_noimplementation_declaration() { return 0; }
+CxxExpression *make_expression(CxxExpressions *aList) { return 0; }
+CxxParameter *make_expression_parameter(CxxExpression *anExpr) { return 0; }
+CxxExpressions *make_expressions(CxxExpressions *aList, CxxExpression *anElement) { return 0; }
+CxxExpression *make_false_expression() { return 0; }
+CxxFileId *make_file_id(CxxFileName *fileName) { return 0; }
+CxxFileId *make_file_id_implementation(CxxName *aName) { return 0; }
+CxxFileId *make_file_id_interface(CxxName *aName) { return 0; }
+CxxFileIds *make_file_ids(CxxFileIds *aList, CxxFileId *anElement) { return 0; }
+CxxFileName *make_file_name(CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_guard(CxxFileName *fileName, CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_implementation(CxxFileName *fileName) { return 0; }
+CxxFileName *make_file_name_interface(CxxFileName *fileName) { return 0; }
+CxxFileName *make_file_name_noguard(CxxFileName *fileName) { return 0; }
+CxxFileName *make_file_name_path(CxxFileName *fileName, CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_prefix(CxxFileName *fileName, CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_suffix(CxxFileName *fileName, CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_template(CxxFileName *fileName) { return 0; }
+CxxFileName *make_file_name_utility(CxxFileName *fileName, CxxUtility *aUtility) { return 0; }
+CxxDeclaration *make_filespace_declaration(CxxName *aName) { return 0; }
+CxxName *make_filespace_specifier(CxxFileName *fileName, CxxDeclarations *aDeclaration) { return 0; }
+CxxExpression *make_floating_literal_expression(CxxFloatingLiteral *aLiteral) { return 0; }
+CxxStatement *make_for_statement(CxxExpression *initExpr, CxxCondition *testExpr, CxxExpression *stepExpr, CxxStatement *aStmt) { return 0; }
+CxxFunctionBody *make_function_block(CxxStatement *aStatement) { return 0; }
+CxxFunctionDeclarations *make_function_declarations(CxxFunctionDeclarations *aList, CxxDeclaration *anElement) { return 0; }
+CxxExpression *make_function_definition(CxxExpression *anExpr, CxxFunctionBody *functionBody) { return 0; }
+CxxDeclarator *make_global_declarator(CxxIsTemplate isTemplate, CxxDeclarator *aDeclarator) { return 0; }
+CxxExpression *make_global_expression(CxxIsTemplate isTemplate, CxxNewExpression *anExpr) { return 0; }
+CxxName *make_global_id(CxxIsTemplate isTemplate, CxxName *nestedId) { return 0; }
+CxxStatement *make_goto_statement(CxxToken *aLabel) { return 0; }
+CxxExpression *make_greater_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_greater_than_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxHandler *make_handler(CxxExceptionDeclaration *exceptionDeclaration, CxxStatement *aStatement) { return 0; }
+CxxHandlers *make_handlers(CxxHandlers *aList, CxxHandler *anElement) { return 0; }
+CxxStatement *make_if_statement(CxxCondition *testExpr, CxxStatement *trueStmt, CxxStatement *falseStmt) { return 0; }
+CxxDeclaration *make_include_declaration(CxxStrings *aString, CxxUtility *aUtility) { return 0; }
+CxxExpression *make_inclusive_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_index_cast_expression(CxxExpression *aCast, CxxExpression *anExpr) { return 0; }
+CxxParameter *make_initialized_parameter(CxxParameter *aParameter, CxxExpression *anExpr) { return 0; }
+CxxInitializerClauses *make_initializer_clauses(CxxInitializerClauses *aList, CxxInitializerClause *anElement) { return 0; }
+CxxInitializerClause *make_initializer_expression_clause(CxxExpression *anExpr) { return 0; }
+CxxInitializerClause *make_initializer_list_clause(CxxInitializerClauses *aList) { return 0; }
+CxxSimpleTypeParameter *make_init_simple_type_parameter(CxxSimpleTypeParameter *templateParameters, CxxExpression *anExpr) { return 0; }
+CxxTemplatedTypeParameter *make_init_templated_parameter(CxxTemplatedTypeParameter *typeParameter, CxxName *aName) { return 0; }
+CxxDeclSpecifierId *make_inline_as_friend() { return 0; }
+CxxDeclSpecifierId *make_inline_if_short() { return 0; }
+CxxDeclSpecifierId *make_inline_in_implementation() { return 0; }
+CxxDeclSpecifierId *make_inline_in_interface() { return 0; }
+CxxFileId *make_input_file(CxxFileId *fileId) { return 0; }
+CxxExpression *make_integer_literal_expression(CxxIntegerLiteral *aLiteral) { return 0; }
+CxxStatement *make_label_statement(CxxToken *aLabel, CxxStatement *aStmt) { return 0; }
+CxxExpression *make_less_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_less_than_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxLine *make_line() { return 0; }
+CxxDeclaration *make_lined_declaration(CxxDeclaration *aDeclaration, CxxLine *aLine) { return 0; }
+CxxStatement *make_lined_statement(CxxStatement *aStatement, CxxLine *aLine) { return 0; }
+CxxToken *make_lined_token(CxxToken *aToken, CxxLine *aLine) { return 0; }
+CxxName *make_linkage_specifier(CxxStrings *aString, CxxDeclaration *aDeclaration) { return 0; }
+CxxExpression *make_logical_and_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_logical_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxMemInitializer *make_mem_initializer(CxxName *aName, CxxExpression *anExpr) { return 0; }
+CxxMemInitializers *make_mem_initializers(CxxMemInitializers *aList, CxxMemInitializer *anElement) { return 0; }
+CxxMemberDeclarations *make_member_declarations(CxxMemberDeclarations *aList, CxxDeclaration *aDeclaration) { return 0; }
+CxxExpression *make_meta_assignment_expression(CxxExpression *leftExpr, CxxToken *assOp, CxxToken *rightExpr) { return 0; }
+CxxBaseSpecifier *make_meta_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; }
+CxxMetaType *make_meta_built_in_type(CxxBuiltInId *aName) { return 0; }
+CxxStatement *make_meta_break_statement() { return 0; }
+CxxStatement *make_meta_case_statement(CxxExpression *anExpr, CxxToken *someTokens) { return 0; }
+CxxMetaClass *make_meta_class(CxxName *metaClass, CxxBaseSpecifiers *baseSpecifiers, CxxToken *classBody) { return 0; }
+CxxStatement *make_meta_continue_statement() { return 0; }
+CxxDeclaration *make_meta_declaration_declaration(CxxDeclaration *metaDeclaration) { return 0; }
+CxxStatement *make_meta_default_statement(CxxToken *someTokens) { return 0; }
+CxxStatement *make_meta_do_while_statement(CxxLine *aLine, CxxToken *bodyTokens, CxxToken *testTokens) { return 0; }
+CxxStatement *make_meta_expression_statement(CxxName *aName, CxxToken *bodyTokens) { return 0; }
+CxxStatement *make_meta_for_statement(CxxLine *aLine, CxxExpression *initTokens, CxxToken *testTokens,
+ CxxToken *stepTokens, CxxToken *bodyTokens) { return 0; }
+CxxExpression *make_meta_function(CxxExpression *anExpr, CxxTokens *aList, CxxToken *aBody) { return 0; }
+CxxStatement *make_meta_if_statement(CxxLine *aLine, CxxExpression *testTokens, CxxToken *trueTokens, CxxToken *falseTokens) { return 0; }
+CxxDeclaration *make_linkage_specification(CxxName *aName) { return 0; }
+//CxxMetaInitializers *make_meta_initializers(CxxMetaInitializers *aList, CxxToken *anElement) { return 0; }
+CxxMetaParameter *make_meta_parameter(CxxMetaType *metaType, CxxIsTree isTree, CxxName *aName, CxxToken *anInit) { return 0; }
+CxxMetaParameters *make_meta_parameters(CxxMetaParameters *aList, CxxMetaParameter *anElement) { return 0; }
+CxxStatement *make_meta_return_statement(CxxExpression *anExpr) { return 0; }
+CxxStatement *make_meta_statement(CxxStatement *aStatement) { return 0; }
+CxxDeclaration *make_meta_statement_declaration(CxxStatement *metaStatement) { return 0; }
+CxxStatement *make_meta_statement_statement(CxxStatement *metaStatement) { return 0; }
+CxxStatement *make_meta_switch_statement(CxxLine *aLine, CxxExpression *testTokens, CxxToken *bodyTokens) { return 0; }
+CxxMetaType *make_meta_type(CxxName *aName) { return 0; }
+CxxName *make_meta_type_id(CxxMetaType *metaType) { return 0; }
+CxxStatement *make_meta_while_statement(CxxLine *aLine, CxxToken *testTokens, CxxToken *bodyTokens) { return 0; }
+CxxExpression *make_minus_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_modulus_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_multiply_expression(CxxExpression *leftExpr, CxxDeclarator *aDeclarator, CxxExpression *rightExpr) { return 0; }
+CxxName *make_name(CxxName *aName) { return 0; }
+CxxName *make_name_expression(CxxName *aName) { return 0; }
+CxxDeclaration *make_namespace_alias_definition(CxxName *aName, CxxName *forId) { return 0; }
+CxxDeclaration *make_namespace_declaration(CxxName *aName) { return 0; }
+CxxName *make_namespace_definition(CxxName *aName, CxxDeclarations *aDeclaration) { return 0; }
+CxxDeclarator *make_nested_declarator(CxxName *aName, CxxDeclarator *aDeclarator) { return 0; }
+CxxName *make_nested_id(CxxName *nestingId, CxxName *nestedId) { return 0; }
+CxxName *make_nested_scope(CxxName *nestingId) { return 0; }
+CxxExpression *make_new_expression(CxxParameters *aPlace, CxxParameters *aType, CxxExpression *anInit) { return 0; }
+CxxExpression *make_new_type_id_expression(CxxParameters *aPlace, CxxExpression *aType, CxxExpression *anInit) { return 0; }
+CxxDeclSpecifierId *make_not_const() { return 0; }
+CxxExpression *make_not_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_not_expression(CxxExpression *anExpr) { return 0; }
+CxxDeclSpecifierId *make_not_inline() { return 0; }
+CxxDeclSpecifierId *make_not_static() { return 0; }
+CxxDeclSpecifierId *make_not_virtual() { return 0; }
+CxxBaseSpecifier *make_not_virtual_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; }
+CxxDeclSpecifierId *make_not_volatile() { return 0; }
+CxxExpression *make_number_literal_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_object_scope_expression(CxxExpression *anExpr, CxxDeclaration *functionDeclarations) { return 0; }
+CxxName *make_operator_add_id() { return 0; }
+CxxName *make_operator_arrow_id() { return 0; }
+CxxName *make_operator_arrow_star_id() { return 0; }
+CxxName *make_operator_ass_add_id() { return 0; }
+CxxName *make_operator_ass_bit_and_id() { return 0; }
+CxxName *make_operator_ass_bit_or_id() { return 0; }
+CxxName *make_operator_ass_div_id() { return 0; }
+CxxName *make_operator_ass_id() { return 0; }
+CxxName *make_operator_ass_mod_id() { return 0; }
+CxxName *make_operator_ass_mul_id() { return 0; }
+CxxName *make_operator_ass_shl_id() { return 0; }
+CxxName *make_operator_ass_shr_id() { return 0; }
+CxxName *make_operator_ass_sub_id() { return 0; }
+CxxName *make_operator_ass_xor_id() { return 0; }
+CxxName *make_operator_bit_and_id() { return 0; }
+CxxName *make_operator_bit_not_id() { return 0; }
+CxxName *make_operator_bit_or_id() { return 0; }
+CxxName *make_operator_call_id() { return 0; }
+CxxName *make_operator_comma_id() { return 0; }
+CxxName *make_operator_dec_id() { return 0; }
+CxxName *make_operator_delete_id() { return 0; }
+CxxName *make_operator_div_id() { return 0; }
+CxxName *make_operator_eq_id() { return 0; }
+CxxName *make_operator_function_id(CxxName *operatorId) { return 0; }
+CxxName *make_operator_ge_id() { return 0; }
+CxxName *make_operator_gt_id() { return 0; }
+CxxName *make_operator_inc_id() { return 0; }
+CxxName *make_operator_index_id() { return 0; }
+CxxName *make_operator_le_id() { return 0; }
+CxxName *make_operator_log_and_id() { return 0; }
+CxxName *make_operator_log_not_id() { return 0; }
+CxxName *make_operator_log_or_id() { return 0; }
+CxxName *make_operator_lt_id() { return 0; }
+CxxName *make_operator_mod_id() { return 0; }
+CxxName *make_operator_mul_id() { return 0; }
+CxxName *make_operator_ne_id() { return 0; }
+CxxName *make_operator_new_id() { return 0; }
+CxxName *make_operator_shl_id() { return 0; }
+CxxName *make_operator_shr_id() { return 0; }
+CxxName *make_operator_sub_id() { return 0; }
+CxxName *make_operator_xor_id() { return 0; }
+CxxParameters *make_parameters(CxxParameters *aList, CxxParameter *anElement) { return 0; }
+CxxParenthesised *make_parenthesised(CxxParameters *aList, CxxCvQualifiers *cvQualifiers, CxxExceptionSpecification *exceptionSpecification) { return 0; }
+CxxExpression *make_plus_expression(CxxExpression *anExpr) { return 0; }
+CxxPointerDeclarator *make_pointer_declarator() { return 0; }
+CxxExpression *make_pointer_expression(CxxDeclarator *aDeclarator, CxxExpression *anExpr) { return 0; }
+CxxExpression *make_post_decrement_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_post_increment_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_pre_decrement_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_pre_increment_expression(CxxExpression *anExpr) { return 0; }
+CxxName *make_pseudo_destructor_id(CxxBuiltInId *aScope, CxxBuiltInId *aName) { return 0; }
+CxxDeclSpecifierId *make_pure_virtual() { return 0; }
+CxxDeclarator *make_reference_declarator() { return 0; }
+CxxExpression *make_reinterpret_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
+CxxStatement *make_return_statement(CxxExpression *anExpr) { return 0; }
+CxxName *make_scoped_id(CxxName *globalId, CxxName *nestedId) { return 0; }
+CxxExpression *make_scoped_pointer_expression(CxxExpression *aScope, CxxDeclarator *aDeclarator, CxxExpression *anExpr) { return 0; }
+CxxSegment *make_segment(CxxSegment *aSegment) { return 0; }
+CxxFunctionBody *make_segment_function_block(CxxFunctionBody *functionBody, CxxSegment *aSegment) { return 0; }
+CxxDeclSpecifierId *make_set_template_decl_specifier(CxxDeclSpecifierId *aName) { return 0; }
+CxxDeclaration *make_set_template_declaration(CxxDeclaration *aDeclaration) { return 0; }
+CxxExpression *make_set_template_expression(CxxExpression *anExpr) { return 0; }
+CxxName *make_set_template_id(CxxName *aName) { return 0; }
+CxxName *make_set_template_name(CxxName *aName) { return 0; }
+CxxName *make_set_template_scope(CxxName *aName) { return 0; }
+CxxExpression *make_shift_left_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_shift_right_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxDeclaration *make_simple_declaration(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_sizeof_expression(CxxExpression *anExpr) { return 0; }
+CxxStatements *make_statements(CxxStatements *, CxxStatement *aStmt) { return 0; }
+CxxExpression *make_static_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
+CxxExpression *make_string_literal_expression(CxxStrings *aString) { return 0; }
+CxxStrings *make_strings(CxxStringLiteral *anElement, CxxStrings *aList) { return 0; }
+CxxExpression *make_subtract_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxStatement *make_switch_statement(CxxCondition *testExpr, CxxStatement *aStmt) { return 0; }
+CxxExpression *make_syntax_macro_definition(CxxMetaType *metaType, CxxIsTree isTree, CxxName *aName, CxxSyntaxMacroParameters *aList, CxxToken *aBody) { return 0; }
+CxxSyntaxMacroParameter *make_syntax_macro_parameter(CxxToken *metaType, CxxIsTree isTree, CxxName *aName) { return 0; }
+CxxSyntaxMacroParameters *make_syntax_macro_parameters(CxxSyntaxMacroParameters *aList, CxxSyntaxMacroParameter *anElement) { return 0; }
+CxxTemplateArgument *make_template_argument(CxxParameter *aParameter) { return 0; }
+CxxTemplateArguments *make_template_arguments(CxxTemplateArguments *aList, CxxTemplateArgument *anElement) { return 0; }
+CxxDeclaration *make_template_declaration(CxxTemplateParameters *aList, CxxDeclaration *aDeclaration) { return 0; }
+CxxName *make_template_name(CxxName *aName, CxxTemplateArguments *templateArguments) { return 0; }
+CxxTemplateParameter *make_templated_template_parameter(CxxTemplateParameter *typeParameter, CxxName *aName) { return 0; }
+CxxTemplateParameter *make_template_parameter(CxxParameter *aParameter) { return 0; }
+CxxTemplateParameters *make_template_parameters(CxxTemplateParameters *aList, CxxTemplateParameter *anElement) { return 0; }
+CxxTemplatedTypeParameter *make_templated_type_parameter(CxxTemplateParameters *templateParameters, CxxName *aName) { return 0; }
+CxxExpression *make_this_expression() { return 0; }
+CxxExpression *make_throw_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_tokens_expression(CxxTokens *someTokens) { return 0; }
+CxxToken *make_tree_argument(CxxToken *aToken) { return 0; }
+CxxTokens *make_tree_arguments(CxxTokens *aList, CxxToken *anElement) { return 0; }
+CxxTreeExpression *make_tree_array_expression(CxxTreeExpression *anExpr, CxxExpression *indexExpr) { return 0; }
+CxxTreeExpression *make_tree_arrow_expression(CxxTreeExpression *anExpr, CxxName *aName) { return 0; }
+CxxTreeExpression *make_tree_call_expression(CxxTreeExpression *anExpr, CxxTokens *aList) { return 0; }
+CxxTreeExpression *make_tree_dot_expression(CxxTreeExpression *anExpr, CxxName *aName) { return 0; }
+CxxTreeExpression *make_tree_expression(CxxName *aName) { return 0; }
+CxxName *make_tree_id(CxxName *aName) { return 0; }
+CxxTreeExpression *make_tree_pointer_expression(CxxTreeExpression *anExpr) { return 0; }
+CxxExpression *make_true_expression() { return 0; }
+CxxFunctionBody *make_try_block(CxxStatement *aStatement, CxxHandlers *exceptionHandlers) { return 0; }
+CxxStatement *make_try_block_statement(CxxFunctionBody *tryBlock) { return 0; }
+CxxFunctionBody *make_try_function_block(CxxFunctionBody *functionBody, CxxHandlers *exceptionHandlers) { return 0; }
+CxxExpression *make_type1_expression(CxxExpression *functionName, CxxParenthesised *aParenthesis, CxxType1Parameters *type1Parameters) { return 0; }
+CxxTemplateParameter *make_type_template_parameter(CxxSimpleTypeParameter *typeParameter, CxxExpression *typeId) { return 0; }
+CxxExpression *make_typed_expression(CxxName *frontName, CxxExpression *backName) { return 0; }
+CxxName *make_typed_name(CxxName *frontName, CxxName *backName) { return 0; }
+CxxExpression *make_typeid_expression(CxxExpression *aList) { return 0; }
+CxxSimpleTypeParameter *make_typename_template_parameter(CxxName *aName) { return 0; }
+CxxSimpleTypeParameter *make_typename_type_parameter(CxxName *aName) { return 0; }
+CxxType1Parameters *make_type1_parameters(CxxType1Parameters *aList, CxxParameters *someParameters) { return 0; }
+CxxDeclaration *make_using_declaration(bool isTypename, CxxName *aName) { return 0; }
+CxxDeclaration *make_using_directive(CxxName *aName) { return 0; }
+CxxFunctionBody *make_using_function_block(CxxFunctionBody *functionBody, CxxFileIds *fileIds) { return 0; }
+CxxDeclaration *make_using_implementation_declaration(CxxFileId *fileId) { return 0; }
+CxxDeclaration *make_using_interface_declaration(CxxFileId *fileId) { return 0; }
+CxxUtility *make_utility(CxxUtility *aUtility) { return 0; }
+CxxUtility *make_utility_mode() { return 0; }
+CxxBaseSpecifier *make_virtual_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; }
+CxxStatement *make_while_statement(CxxCondition *testExpr, CxxStatement *aStmt) { return 0; }
+
--- /dev/null
+//
+// Title: C++ Grammar Token support compilation unit.
+//
+// File Name: CxxToken.cpp
+//
+// Author: E.D.Willink
+//END
+//
+#include <CxxToken.cxx>
--- /dev/null
+#include <CxxToken.hxx>
+#include <memory.h>
+
+//CxxToken::CxxToken()
+//:
+// _value(0)
+//{}
+
+CxxNaffToken::CxxNaffToken(int tokenValue, const char *yyText, int yyLeng)
+:
+ Super(tokenValue), _text(new char[yyLeng+1]), _leng(yyLeng)
+{
+ memcpy(_text, yyText, yyLeng);
+ _text[_leng] = 0;
+}
+
+CxxNaffToken::~CxxNaffToken() { delete[] _text; }
--- /dev/null
+#ifndef CXXTOKEN_HXX
+#define CXXTOKEN_HXX
+
+#include <iostream.h>
+#include <stdlib.h>
+
+#define YYSTYPE CxxTokenType
+#define YY_parse_STYPE CxxTokenType
+#define YACC_BANG_TYPE size_t
+#define YACC_MARK_TYPE size_t
+
+#define YACC_BANG() push_bang()
+#define YACC_UNBANG(bangValue, msg) pop_bang(bangValue); yyerrok; yyclearin; yyerror(msg);
+
+#define ERRMSG(a) do { cout << "ERROR -- " << a << endl; increment_error_count(); } while (0)
+
+#ifdef NEEDS_BOOL
+enum bool { false, true };
+#endif
+
+#ifdef BISON_PP_CLASS
+#define PARSE_TOKEN(a) BISON_PP_CLASS::a
+#else
+#define PARSE_TOKEN(a) a
+#endif
+
+extern size_t line_number;
+extern bool c_keywords;
+extern bool echo_line_numbers;
+extern bool echo_line_text;
+extern void increment_error_count();
+extern int tokenMarkDepth;
+
+class CxxToken
+{
+ int _value;
+private:
+ CxxToken(const CxxToken&);
+ CxxToken& operator=(const CxxToken&);
+public:
+ CxxToken(int tokenValue = 0) : _value(tokenValue) {}
+ virtual ~CxxToken() {}
+ int value() const { return _value; }
+};
+
+enum CxxIsTemplate { IS_DEFAULT, IS_TEMPLATE };
+enum CxxIsTree { IS_SCALAR, IS_TREE };
+typedef CxxToken CxxTreeArgument;
+
+class CxxStatement : public CxxToken {};
+typedef CxxStatement CxxDeclaration;
+class CxxExpression : public CxxStatement {};
+class CxxName : public CxxExpression {};
+class CxxTokens : public CxxToken {};
+class CxxMetaObject : public CxxExpression {};
+class CxxMetaStatement : public CxxStatement {};
+
+class CxxStatements : public CxxStatement {};
+typedef CxxStatements CxxDeclarations;
+typedef CxxDeclarations CxxMemberDeclarations;
+typedef CxxExpression CxxTreeExpression;
+
+class CxxKeyword : public CxxName {};
+class CxxDeclSpecifierId : public CxxKeyword {};
+
+class CxxAccessSpecifier : public CxxKeyword {};
+class CxxBaseSpecifier : public CxxToken {};
+class CxxBaseSpecifiers : public CxxTokens {};
+class CxxBrace : public CxxToken {};
+class CxxBuiltInId : public CxxName {};
+class CxxCharacterLiteral : public CxxToken {};
+class CxxClass : public CxxToken {};
+class CxxClassKey : public CxxKeyword {};
+class CxxCondition : public CxxExpression {};
+class CxxCvQualifiers : public CxxDeclSpecifierId {};
+class CxxDeclarator : public CxxToken {};
+typedef CxxExpression CxxDeleteExpression;
+//class CxxDerived : public CxxToken {};
+//class CxxEnum : public CxxToken {};
+class CxxEnumerator : public CxxToken {};
+class CxxEnumerators : public CxxTokens {};
+class CxxExceptionDeclaration : public CxxToken {};
+class CxxExceptionSpecification : public CxxToken {};
+class CxxExpressions : public CxxExpression {};
+class CxxFileId : public CxxToken {};
+class CxxFileIds : public CxxTokens {};
+class CxxFileName : public CxxToken {};
+class CxxFloatingLiteral : public CxxToken {};
+class CxxFunctionBody : public CxxStatement {};
+class CxxFunctionDeclarations : public CxxDeclarations {};
+class CxxHandler : public CxxToken {};
+class CxxHandlers : public CxxTokens {};
+class CxxIdentifier : public CxxName {};
+//class CxxIds : public CxxTokens {};
+class CxxInitializerClause : public CxxExpression {};
+class CxxInitializerClauses : public CxxInitializerClause {};
+class CxxIntegerLiteral : public CxxToken {};
+class CxxLine : public CxxToken {};
+//class CxxList : public CxxTokens {};
+class CxxMemInitializer : public CxxToken {};
+class CxxMemInitializers : public CxxTokens {};
+class CxxMetaClass : public CxxStatement {};
+class CxxMetaFunction : public CxxMetaObject {};
+class CxxMetaInitializer : public CxxToken {};
+class CxxMetaInitializers : public CxxTokens {};
+class CxxMetaParameter : public CxxToken {};
+class CxxMetaParameters : public CxxTokens {};
+//class CxxMetaPrototype : public CxxToken {};
+//class CxxMetaPrototypes : public CxxTokens {};
+class CxxMetaType : public CxxName {};
+class CxxMetaVariable : public CxxMetaObject {};
+class CxxNamespace : public CxxToken {};
+typedef CxxExpression CxxNewExpression;
+class CxxNumberLiteral : public CxxExpression {};
+class CxxParameter : public CxxExpression {};
+class CxxParameters : public CxxExpression {};
+class CxxParenthesised : public CxxToken {};
+class CxxPointerDeclarator : public CxxDeclarator {};
+class CxxPosition : public CxxName {};
+class CxxSegment : public CxxName {};
+class CxxSpacing : public CxxToken {};
+class CxxStrings : public CxxToken {};
+typedef CxxStrings CxxStringLiteral;
+class CxxSubspace : public CxxToken {};
+class CxxSyntaxMacroParameter : public CxxToken {};
+class CxxSyntaxMacroParameters : public CxxTokens {};
+class CxxTemplateArgument : public CxxToken {};
+class CxxTemplateArguments : public CxxTokens {};
+class CxxTemplateParameter : public CxxToken {};
+class CxxTemplateParameters : public CxxTokens {};
+class CxxSimpleTypeParameter : public CxxTemplateParameter {};
+class CxxTemplatedTypeParameter : public CxxTemplateParameter {};
+class CxxTokenStatements : public CxxTokens {};
+class CxxTreeArguments : public CxxTokens {};
+class CxxType1Parameters : public CxxTokens {};
+class CxxTypeId : public CxxToken {};
+class CxxTypeIds : public CxxTokens {};
+class CxxUtility : public CxxToken {};
+
+#define FOGPARSERVALUE_ENUM(T,N) \
+ const T *name2(u_,N); \
+ const T& N() const { return *name2(u_,N); } \
+ const T* & N() { return name2(u_,N); }
+#define FOGPARSERVALUE_POINTER(T,N) T *N;
+#define FOGPARSERVALUE_VALUE(T,N) T N;
+
+union CxxTokenType
+{
+ CxxToken *_token;
+
+ FOGPARSERVALUE_VALUE(bool, _bool)
+ FOGPARSERVALUE_VALUE(long, _long)
+ FOGPARSERVALUE_POINTER(CxxBrace, brace)
+ FOGPARSERVALUE_POINTER(CxxSpacing, spacing)
+
+ FOGPARSERVALUE_POINTER(CxxAccessSpecifier, access_specifier)
+ FOGPARSERVALUE_POINTER(CxxBaseSpecifier, base_specifier)
+ FOGPARSERVALUE_POINTER(CxxBaseSpecifiers, base_specifiers)
+ FOGPARSERVALUE_POINTER(CxxBuiltInId, built_in_id)
+ FOGPARSERVALUE_POINTER(CxxCharacterLiteral, character_literal)
+ FOGPARSERVALUE_POINTER(CxxClass, _class)
+ FOGPARSERVALUE_POINTER(CxxClassKey, class_key)
+ FOGPARSERVALUE_POINTER(CxxCondition, condition)
+ FOGPARSERVALUE_POINTER(CxxCvQualifiers, cv_qualifiers)
+ FOGPARSERVALUE_POINTER(CxxDeclSpecifierId, decl_specifier_id)
+ FOGPARSERVALUE_POINTER(CxxDeclaration, declaration)
+ FOGPARSERVALUE_POINTER(CxxDeclarations, declarations)
+ FOGPARSERVALUE_POINTER(CxxDeclarator, declarator)
+ FOGPARSERVALUE_POINTER(CxxDeleteExpression, delete_expression)
+ FOGPARSERVALUE_POINTER(CxxEnumerator, enumerator)
+ FOGPARSERVALUE_POINTER(CxxEnumerators, enumerators)
+ FOGPARSERVALUE_POINTER(CxxExceptionDeclaration, exception_declaration)
+ FOGPARSERVALUE_POINTER(CxxExceptionSpecification, exception_specification)
+ FOGPARSERVALUE_POINTER(CxxExpression, expression)
+ FOGPARSERVALUE_POINTER(CxxExpressions, expressions)
+ FOGPARSERVALUE_POINTER(CxxFileId, file_id)
+ FOGPARSERVALUE_POINTER(CxxFileIds, file_ids)
+ FOGPARSERVALUE_POINTER(CxxFileName, file_name)
+ FOGPARSERVALUE_POINTER(CxxFloatingLiteral, floating_literal)
+ FOGPARSERVALUE_POINTER(CxxFunctionBody, function_body)
+ FOGPARSERVALUE_POINTER(CxxHandler, handler)
+ FOGPARSERVALUE_POINTER(CxxHandlers, handlers)
+ FOGPARSERVALUE_POINTER(CxxIdentifier, identifier)
+ FOGPARSERVALUE_POINTER(CxxInitializerClause, initializer_clause)
+ FOGPARSERVALUE_POINTER(CxxInitializerClauses, initializer_clauses)
+ FOGPARSERVALUE_POINTER(CxxIntegerLiteral, integer_literal)
+ FOGPARSERVALUE_POINTER(CxxKeyword, keyword)
+ FOGPARSERVALUE_POINTER(CxxLine, line)
+ FOGPARSERVALUE_POINTER(CxxMemInitializer, mem_initializer)
+ FOGPARSERVALUE_POINTER(CxxMemInitializers, mem_initializers)
+ FOGPARSERVALUE_POINTER(CxxMemberDeclarations, member_declarations)
+ FOGPARSERVALUE_POINTER(CxxMetaClass, meta_class)
+ FOGPARSERVALUE_POINTER(CxxMetaFunction, meta_function)
+ FOGPARSERVALUE_POINTER(CxxMetaInitializer, meta_initializer)
+ FOGPARSERVALUE_POINTER(CxxMetaInitializers, meta_initializers)
+ FOGPARSERVALUE_POINTER(CxxMetaObject, meta_object)
+ FOGPARSERVALUE_POINTER(CxxMetaStatement, meta_statement)
+ FOGPARSERVALUE_POINTER(CxxMetaType, meta_type)
+ FOGPARSERVALUE_POINTER(CxxMetaVariable, meta_variable)
+ FOGPARSERVALUE_POINTER(CxxName, name)
+ FOGPARSERVALUE_POINTER(CxxNewExpression, new_expression)
+ FOGPARSERVALUE_POINTER(CxxNumberLiteral, number_literal)
+ FOGPARSERVALUE_POINTER(CxxParameter, parameter)
+ FOGPARSERVALUE_POINTER(CxxParameters, parameters)
+ FOGPARSERVALUE_POINTER(CxxParenthesised, parenthesised)
+ FOGPARSERVALUE_POINTER(CxxPointerDeclarator, pointer_declarator)
+ FOGPARSERVALUE_POINTER(CxxPosition, position)
+ FOGPARSERVALUE_POINTER(CxxSegment, segment)
+ FOGPARSERVALUE_POINTER(CxxSimpleTypeParameter, simple_type_parameter)
+ FOGPARSERVALUE_POINTER(CxxStatement, statement)
+ FOGPARSERVALUE_POINTER(CxxStatements, statements)
+ FOGPARSERVALUE_POINTER(CxxStringLiteral, string_literal)
+ FOGPARSERVALUE_POINTER(CxxStrings, strings)
+ FOGPARSERVALUE_POINTER(CxxSubspace, subspace)
+ FOGPARSERVALUE_POINTER(CxxSyntaxMacroParameter, syntax_macro_parameter)
+ FOGPARSERVALUE_POINTER(CxxSyntaxMacroParameters, syntax_macro_parameters)
+ FOGPARSERVALUE_POINTER(CxxTemplateArgument, template_argument)
+ FOGPARSERVALUE_POINTER(CxxTemplateArguments, template_arguments)
+ FOGPARSERVALUE_POINTER(CxxTemplateParameter, template_parameter)
+ FOGPARSERVALUE_POINTER(CxxTemplateParameters, template_parameters)
+ FOGPARSERVALUE_POINTER(CxxTemplatedTypeParameter, templated_type_parameter)
+ FOGPARSERVALUE_POINTER(CxxToken, token)
+ FOGPARSERVALUE_POINTER(CxxTokenStatements, token_statements)
+ FOGPARSERVALUE_POINTER(CxxTokens, tokens)
+ FOGPARSERVALUE_POINTER(CxxTreeArgument, tree_argument)
+ FOGPARSERVALUE_POINTER(CxxTreeArguments, tree_arguments)
+ FOGPARSERVALUE_POINTER(CxxTreeExpression, tree_expression)
+ FOGPARSERVALUE_POINTER(CxxType1Parameters, type1_parameters)
+ FOGPARSERVALUE_POINTER(CxxUtility, utility)
+
+ FOGPARSERVALUE_VALUE(int, bang)
+ FOGPARSERVALUE_VALUE(CxxIsTemplate, is_template)
+ FOGPARSERVALUE_VALUE(YACC_MARK_TYPE, mark)
+ FOGPARSERVALUE_VALUE(size_t, nest)
+#if 0
+ CxxAccessSpecifier *access_specifier;
+ CxxBaseSpecifier *base_specifier;
+ CxxBaseSpecifiers *base_specifiers;
+ CxxBuiltInId *built_in_id;
+ CxxCharacterLiteral *character_literal;
+ CxxClass *_class;
+ CxxClassKey *class_key;
+ CxxCondition *condition;
+ CxxCvQualifiers *cv_qualifiers;
+ CxxDeclaration *declaration;
+ CxxDeclarations *declarations;
+ CxxDeclarator *declarator;
+ CxxDeclSpecifierId *decl_specifier_id;
+// CxxDerived *derived;
+// CxxEnum *_enum;
+ CxxEnumerator *enumerator;
+ CxxEnumerators *enumerators;
+ CxxExceptionDeclaration *exception_declaration;
+ CxxExceptionSpecification *exception_specification;
+ CxxExpression *expression;
+ CxxExpressions *expressions;
+ CxxFileId *file_id;
+ CxxFileIds *file_ids;
+ CxxFileName *file_name;
+ CxxFloatingLiteral *floating_literal;
+ CxxFunctionBody *function_body;
+ CxxFunctionDeclarations *function_declarations;
+ CxxHandler *handler;
+ CxxHandlers *handlers;
+ CxxIdentifier *identifier;
+// CxxIds *ids;
+ CxxInitializerClause *initializer_clause;
+ CxxInitializerClauses *initializer_clauses;
+ CxxIntegerLiteral *integer_literal;
+ CxxKeyword *keyword;
+ CxxLine *line;
+// CxxList *list;
+ CxxMemInitializer *mem_initializer;
+ CxxMemInitializers *mem_initializers;
+ CxxMemberDeclarations *member_declarations;
+ CxxMetaClass *meta_class;
+// CxxMetaFunction *meta_function;
+// CxxMetaInitializer *meta_initializer;
+// CxxMetaInitializers *meta_initializers;
+// CxxMetaObject *meta_object;
+ CxxMetaParameter *meta_parameter;
+ CxxMetaParameters *meta_parameters;
+// CxxMetaPrototype *meta_prototype;
+// CxxMetaPrototypes *meta_prototypes;
+// CxxMetaStatement *meta_statement;
+ CxxMetaType *meta_type;
+// CxxMetaVariable *meta_variable;
+ CxxName *name;
+// CxxNamespace *_namespace;
+ CxxNumberLiteral *number_literal;
+ CxxParameter *parameter;
+ CxxParameters *parameters;
+ CxxParenthesised *parenthesised;
+ CxxPointerDeclarator *pointer_declarator;
+ CxxSegment *segment;
+ CxxSimpleTypeParameter *simple_type_parameter;
+ CxxStatement *statement;
+ CxxStatements *statements;
+ CxxStringLiteral *string_literal;
+ CxxStrings *strings;
+ CxxSyntaxMacroParameter *syntax_macro_parameter;
+ CxxSyntaxMacroParameters *syntax_macro_parameters;
+ CxxTemplateArgument *template_argument;
+ CxxTemplateArguments *template_arguments;
+ CxxTemplateParameter *template_parameter;
+ CxxTemplateParameters *template_parameters;
+ CxxTemplatedTypeParameter *templated_type_parameter;
+ CxxToken *token;
+ CxxTokens *tokens;
+// CxxTreeArgument *tree_argument;
+// CxxTreeArguments *tree_arguments;
+// CxxTreeExpression *tree_expression;
+ CxxType1Parameters *type1_parameters;
+// CxxTypeId *type_id;
+// CxxTypeIds *type_ids;
+ CxxUtility *utility;
+ YACC_BANG_TYPE bang;
+ YACC_MARK_TYPE mark;
+ size_t nest;
+#endif
+};
+
+class CxxNaffToken : public CxxToken
+{
+ typedef CxxToken Super;
+ char *_text;
+ int _leng;
+private:
+ CxxNaffToken(const CxxNaffToken&);
+ CxxNaffToken& operator=(const CxxNaffToken&);
+public:
+ CxxNaffToken(int tokenValue, const char *yyText, int yyLeng);
+ virtual ~CxxNaffToken();
+};
+
+#endif
--- /dev/null
+This directory tree comprises a pre-built demonstration of the superset C++ grammar
+from FOG..
+
+Contents
+--------
+
+ Release/grammar.exe -- the statically bound executable (on NT)
+ sun4o/grammar -- the statically bound executable (on Unix)
+
+It is a command line based utility. See index.html for details.
+
+Bug reporting
+-------------
+
+Please report any bugs to Ed.Willink@rrl.co.uk. I will endeavour to fix them,
+but since this code is a one man effort and my time is primarily devoted to
+my other activities for Thales Research, only simple and easy fixes are likely.
+I am more likely to be able to fix the problem if you can trim your problem to
+just a few lines.
+
--- /dev/null
+<html>
+
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
+<title>Ed's Toolkit</title>
+</head>
+
+<body bgcolor="#FFFFFF">
+
+<h1 align="center">Superset C++ Grammar</h1>
+
+<hr>
+
+<p>This work area supports a demonstration of the superset C++
+grammar described in Chapter 5 of <a
+href="mailto:Ed.Willink@rrl.co.uk">Ed Willink</a>'s thesis on <a
+href="http://www.computing.surrey.ac.uk/research/dsrg/fog/FogThesis.html">Meta-Compilation
+for C++</a>. It contains working lex and yacc grammars that
+enable C++ source to be lexically analysed, then syntactically
+analysed without semantic knowlege. The lex and yacc grammar have
+their action routines defined by macros in the hope that
+reconfiguration may be possible without editing the grammars
+directly. The dummy implementations of the yacc macros do nothing
+other than count statements and diagnose the back-tracking
+behaviour. Users may add their own syntactic level code. A proper
+C++ parser needs semantic analysis as well, including correction
+of minor misprses at the syntactic level. Semantic interpretaion
+is provided by <a
+href="http://www.computing.surrey.ac.uk/research/dsrg/fog/">FOG</a>
+from which this demonstration is split off.</p>
+
+<p>The work area is self-sufficient, requiring only <em>lex</em>
+and <em>yacc</em>, or <em>flex</em> and <em>bison</em>.</p>
+
+<hr>
+
+<h2>Command Line</h2>
+
+<p>The test grammar is a simple command line utility, for
+analysing a single <strong>pre-processed</strong> source file
+(use CC -E to run just the preprocessor on your source files)..</p>
+
+<pre> grammar [options] < source-file</pre>
+
+<p>The full set of command line options is:</p>
+
+<pre> -c Recognise only C keywords - approximates C rather than C++ parsing
+ -m Display mark activity.
+ -n Echo line numbers.
+ -t Echo source line text.
+ -y Display yacc diagnostics.</pre>
+
+<p>On completion a three line diagnostic summarises the search
+activity. </p>
+
+<hr>
+
+<h2>Files</h2>
+
+<p><a href="CxxSrc.tgz">CxxSrc.tgz</a>, <a href="CxxNtSrc.tgz">CxxNtSrc.tgz</a>
+The source distribution kit including a Sun or NT executable.</p>
+
+<p><a href="CxxLexer.l">CxxLexer.l</a> A simple lexer for all C
+and/or C++ tokens</p>
+
+<p><a href="CxxParser.y">CxxParser.y</a> The parser,
+automatically extracted from FogParser.y.</p>
+
+<p><a href="CxxToken.hxx">CxxToken.hxx</a>, <a
+href="CxxToken.cxx">CxxToken.cxx</a> A trivial class used by the
+parser to represent each parsed token.</p>
+
+<p><a href="CxxLexing.hxx">CxxLexing.hxx</a>, <a
+href="CxxLexing.cxx">CxxLexing.cxx</a> Interface and
+implementation of token creation routines for the lexer.</p>
+
+<p><a href="CxxParsing.hxx">CxxParsing.hxx</a>, <a
+href="CxxParsing.cxx">CxxParsing.cxx</a> Interface and
+implementation of token manioulation routines for the parser.</p>
+
+<p><a href="CxxLexer.cpp">CxxLexer.cpp</a>, <a
+href="CxxParser.cpp">CxxParser.cpp</a>, <a href="CxxToken.cpp">CxxToken.cpp</a>
+Degenerate compilation units for the above.</p>
+
+<p><a href="makefile">makefile</a>, <a href="makefile.macros">makefile.macros</a>,
+<a href="CxxLexer.l">makefile.unix</a> Unix build scripts</p>
+
+<p><a href="makefile.gmake">makefile.gmake</a>, <a
+href="makefile.macros">makefile.macros</a>, <a href="grammar.dsw">grammar.dsw</a>,
+<a href="grammar.dsp">grammar.dsp</a> NT build scripts and
+DevStudio workspace and project</p>
+
+<p><a><u>sun4o/grammar</u></a> Built executable (on Unix)</p>
+
+<p><a><u>Release/grammar.exe</u></a> Built executable (on NT)</p>
+
+<hr>
+
+<h2>Unix Builds</h2>
+
+<p>The code builds under Solaris 2.5 and with Sun C++ 4.2.</p>
+
+<pre> make sun</pre>
+
+<p>or Gnu egcs-1.0.2 release, with flex 2.3.7, bison 1.16</p>
+
+<pre> make gnu</pre>
+
+<hr>
+
+<h2>NT Builds</h2>
+
+<p>The code builds under NT 4 and has been tested with DevStudio
+V6 and cygwin 1.1.</p>
+
+<h3>a) cygwin</h3>
+
+<p>You need cygwin, the latest version of which is available <a
+href="ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/setup.exe">ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/setup.exe</a></p>
+
+<p>A slightly easier to install earlier version (used by the
+author) is <a
+href="ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/old/cygwin-b20/full.exe">ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/old/cygwin-b20/full.exe</a></p>
+
+<p>Use a mirror site listed at <a
+href="http://sources.redhat.com/cygwin/mirrors.html">http://sources.redhat.com/cygwin/mirrors.html</a>.</p>
+
+<p>The older cygwin is a simple standard NT installation - just
+run full.exe (with administrator rights) and accept the default
+installation paths (gnu tools build them in). The newer cygwin is
+much smarter, doing automatic selective downloads - which the
+author's firewall messes up.</p>
+
+<h3>b) Path configuration</h3>
+
+<p>You may want to make cygwin tools accessible from command
+prompts so</p>
+
+<pre>Start->Settings->ControlPanel
+ System|Environment
+ Add Variable PATH
+ Value C:\cygwin\cygwin-b20\H-i586-cygwin32\BIN</pre>
+
+<h3>c) DevStudio configuration</h3>
+
+<p>You need to configure DevStudio to use cygwin.</p>
+
+<p>In DevStudio:</p>
+
+<pre>Tools->Options->Directories
+ Show Directories For Executable files
+ Add C:\cygwin\bin</pre>
+
+<h3>d) Unpacking</h3>
+
+<p>Then use winzip or gunzip to extract all of <a
+href="CxxNtSrc.tgz">CxxNtSrc.tgz</a>:</p>
+
+<pre>double click in Explorer on <a href="CxxNtSrc.tgz">CxxNtSrc.tgz</a>
+ Yes to decompress archive to temporary file
+ Wait a few moments
+ Actions...->Extract
+ All Files, to e.g. C:\CxxGrammar, use Folder names, Extract
+ Close Winzip</pre>
+
+<h3>e) DevStudio build</h3>
+
+<pre>Double click in Explorer on <a href="grammar.dsw">grammar.dsw</a>
+ If prompted to browse for a SourceSafe project Click No.
+ If prompted to attempt SourceSafe connection in another session click No.
+ Select your preferred configuration (Win32 Debug is default)
+ Select FileView|grammar Files->Targets->executable
+ <Ctrl>F7
+ after a few seconds everything is built</pre>
+
+<p>DevStudio reports 0 errors and 1 warnings</p>
+
+<pre>Build : warning : failed to (or don't know how to) build 'C:\CxxGrammar\Targets\executable'</pre>
+
+<p>The warning is an artefact of fake build targets</p>
+
+<p>Everything in DevStudio is compiled using a makefile.gmake
+target which is selected for a <CTRL>F7 in the Workspace
+window. Steer clear of the standard DevStudio F7 which builds all
+targets: backup then clean then executables then realclean then
+test etc. No harm is done but it takes a long time.</p>
+
+<hr>
+
+<p><i>Last updated <!--webbot bot="Timestamp" startspan
+s-type="EDITED" s-format="%d %B, %Y" -->28 July, 2001<!--webbot
+bot="Timestamp" i-checksum="21078" endspan -->.</i> </p>
+</body>
+</html>
--- /dev/null
+#
+# Title: Make file for Cxx Grammar tester.
+#
+# Author: E.D.Willink
+#
+# SCCS: %W% %G%
+#
+# Description:
+# This makefile wrapper redirects all activity to makefile.unix after first ensuring that
+# any .INIT provided by ../import.make has executed to load required source files.
+#
+# Targets:
+# executable, normal
+# builds $(ARCH)o/grammar
+# sun
+# builds $(ARCH)o/grammar using sun compiler, yacc and lex
+# gnu
+# builds $(ARCH)o/grammar using gnu compiler, bison and flex
+# clean
+# eliminates $(ARCH)o* intermediates
+# realclean
+# eliminates $(ARCH)o* intermediates and executables
+# source_kit
+# generates the distribution kits
+#
+# Switch settings are appropriate for Sun C++ 4.2.
+# Commented settings indicate what might be appropriate for gcc once it supports templates plausibly.
+#
+# Latest Modification:
+# EDW Date: 14-Jun-2001 Original
+#END
+
+.SUFFIXES:
+
+SRCDIR = sources
+ARCH = sun4
+OBJ_DIR = $(ARCH)o
+OBJ_DIR_PI = $(ARCH)o_pi
+OBJ_DIR_G = $(ARCH)o_g
+OBJ_DIR_PI_G = $(ARCH)o_pi_g
+
+default : executable
+
+#../import.make is empty by default, but may be provided to copy sources from somewhere.
+../import.make :
+ echo > $@
+IMPORT_PATH = grammar
+include ../import.make
+
+clean executable gnu realclean source_kit sun %.tar \
+$(SRCDIR)/% $(OBJ_DIR)/% $(OBJ_DIR_PI)/% $(OBJ_DIR_G)/% $(OBJ_DIR_PI_G)/% \
+ : makefile makefile.unix .FORCE
+ $(MAKE) -f makefile.unix $(MFLAGS) $(MAKEFLAGS) $@
+
+.FORCE:
\ No newline at end of file
--- /dev/null
+#
+# Title: makefile.gmake
+#
+# Author: E.D.Willink
+#
+# Description: GNU make file for Cxx Grammar tester under NT
+#
+# Environment
+# INTDIR intermediate directory for objects (defaults to ".\Release")
+# OUTDIR output directory for executable (defaults to ".\Release")
+# MSINCDIR path of main system include directory (defaults to $(MSVCDIR)\Include)
+#
+# Public Targets
+# executable
+# builds '$(OUTDIR)'/grammar.exe
+# clean
+# eliminates $(INTDIR) intermediates
+# realclean
+# eliminates $(INTDIR) and '$(OUTDIR)' intermediates
+# source_kit
+# generates the distribution kits
+# Private Targets
+# backup
+# copies changed sources from C: to $(BACKUPDIR)
+# tar_delta
+# tars up changes ready for transfer to Unix
+#
+#
+# Build is error and warning free as
+# nmake -f makefile.gmake
+# (after using - Visual C++ 6
+# "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
+# or - Visual C++ 5
+# "C:\Program Files\DevStudio\VC\Bin\vcvars32.bat"
+# in a Command Prompt to set up the Visual C++ environment).
+# Alternatively do a "Compile xxx" to compile target xxx from the "grammar files->Targets"
+# after loading root.dsw into DevStudio.
+#
+.SUFFIXES:
+.SUFFIXES: .l .y .hxx .cxx .cpp .obj
+
+TARGET = grammar
+INTDIR = .\Release
+OUTDIR = $(INTDIR)
+SRCDIR = Sources
+DUMMYDIR = Dummy
+LSTDIR = Listings
+MSINCDIR = $(MSVCDIR)\Include
+BACKUPDIR = Q:/P541/C/BackUp/grammar
+TARDELTADIR = P:/$(USERNAME)
+
+CPRINT = "../tools/cprint/$(OUTDIR)/cprint.exe" -b -c150 -e -h0 -f1 -l69 -n25 -t4
+WIDE_CPRINT = "../tools/cprint/$(OUTDIR)/cprint.exe" -b -c150 -e -h0 -f1 -l69 -n0 -t4
+
+CCP = "../tools/ccp/$(OUTDIR)/ccp.exe"
+CCP_FLAGS =
+MV = mv
+#LEX = "../tools/flex_pp/$(OUTDIR)/flex_pp.exe" -S../tools/flex_pp/flexskel.cc -H../tools/flex_pp/flexskel.h
+#LEX_FLAGS = -8
+LEX = flex
+LEX_FLAGS =
+#YACC = "../tools/bison_pp/$(OUTDIR)/bison_pp.exe" -S ../tools/bison_pp/bison.cc -H ../tools/bison_pp/bison.h
+#YACC_FLAGS = -t -v
+YACC = bison -d -t -v
+YACC_FLAGS =
+
+CPP = cl.exe /nologo
+CPP_RELEASE_FLAGS = /ML /O2 /D "NDEBUG"
+CPP_DEBUG_FLAGS = /MLd /Gm /ZI /Od /D "_DEBUG" /GZ
+CPP_COMMON_FLAGS = /W3 /GX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/$(TARGET)" /c
+CPP_DEFS = /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "NEEDS_YYWRAP"
+CPP_INCS = /I "$(SRCDIR)" /I "." /I "$(DUMMYDIR)"
+
+LINK32 = link.exe /nologo /machine:I386 /subsystem:console
+LINK_RELEASE_FLAGS = /incremental:no
+LINK_DEBUG_FLAGS = /incremental:yes /debug /pdbtype:sept
+LINK32_LIBS = kernel32.lib
+
+MAKEFILE = makefile.gmake
+DUMMIES = $(DUMMYDIR)/unistd.h
+
+include makefile.macros
+
+OBJECTS = $(COMPOSITE_SOURCES:%.cpp=$(INTDIR)/%.obj)
+
+all : $(ALL_FILES) executable
+
+executable : $(OUTDIR)/$(TARGET).exe
+
+$(DUMMYDIR)/unistd.h :
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
+ @echo '$@'
+ @- sh -c 'echo "#include <io.h>" > "$@"'
+ @- sh -c 'chmod -w "$@"'
+
+$(SRCDIR)/%.cxx : %.l
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f $(@D)/$*.cxx; fi'
+ - sh -c '$(LEX) $(LEX_FLAGS) $*.l'
+ @- sh -c 'mv -f lex.yy.c $(@D)/$*.cxx'
+ @- sh -c 'chmod -w $(@D)/$*.cxx'
+
+$(SRCDIR)/%.cxx $(SRCDIR)/%.hxx : %.y
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f $(@D)/$*.output $(@D)/$*.cxx $(@D)/$*.hxx; fi'
+ - sh -c '$(YACC) $(YACC_FLAGS) $*.y'
+ @- sh -c 'mv -f $*.tab.c $(@D)/$*.cxx'
+ @- sh -c 'mv -f $*.tab.h $(@D)/$*.hxx'
+ @- sh -c 'mv -f $*.output $(@D)/$*.output'
+ @- sh -c 'chmod -w $(@D)/$*.cxx $(@D)/$*.hxx $(@D)/$*.output'
+
+.\Release/%.obj : %.cpp
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+ @- sh -c '$(CPP) $(CPP_INCS) $(CPP_DEFS) $(CPP_RELEASE_FLAGS) $(CPP_COMMON_FLAGS) "$<"'
+
+.\Debug/%.obj : %.cpp
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+ @- sh -c '$(CPP) $(CPP_INCS) $(CPP_DEFS) $(CPP_DEBUG_FLAGS) $(CPP_COMMON_FLAGS) "$<"'
+
+.\Release/$(TARGET).exe : $(OBJECTS) $(MAKEFILE)
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
+ @echo '$@'
+ @- sh -c '$(LINK32) /pdb:"$(@D)/$(TARGET).pdb" /out:"$@" $(LINK_RELEASE_FLAGS) $(OBJECTS:%="%") $(LINK32_LIBS)'
+
+.\Debug/$(TARGET).exe : $(OBJECTS) $(MAKEFILE)
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
+ @echo '$@'
+ @- sh -c '$(LINK32) /pdb:"$(@D)/$(TARGET).pdb" /out:"$@" $(LINK_DEBUG_FLAGS) $(OBJECTS:%="%") $(LINK32_LIBS)'
+
+$(LSTDIR)/CxxLexer.list : CxxLexer.cpp $(LEXER_FILES) $(L_FILES)
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+ sh -c '$(CPRINT) $? > "$@"'
+
+$(LSTDIR)/CxxParser.list : CxxParser.cpp $(PARSER_FILES) $(Y_FILES)
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+ sh -c '$(CPRINT) $? > "$@"'
+
+$(LSTDIR)/CxxToken.list : CxxToken.cpp $(TOKEN_FILES)
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+ sh -c '$(CPRINT) $? > "$@"'
+
+$(LSTDIR)/CxxMake.list : $(MAKE_FILES)
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+ sh -c '$(CPRINT) $? > "$@"'
+
+source_kit: CxxNtSrc.tgz
+
+CxxNtSrc.tgz : CxxNtSrc.tar
+ @echo $@
+ @- sh -c 'rm -f "$@"'
+ @- sh -c 'gzip "$<" -c > "$@"'
+ @- sh -c 'chmod -w "$@"'
+
+CxxNtSrc.tar : FORCE
+ @echo $@
+ @- sh -c 'rm -f "$@"'
+ @- sh -c 'tar cf "$@" $(ALL_FILES:%="$(MAKE_TAR_PATH)%") "Release/grammar.exe"'
+ @- sh -c 'chmod -w "$@"'
+
+$(PWD)/%.tar : FORCE
+ @- sh -c 'cd $(PWD); tar rf "$(@F)" $(ALL_FILES:%="$(MAKE_TAR_PATH)%")'
+
+FORCE :
+
+tar_delta : $(TARDELTADIR)/$(TARGET)_delta.tar
+
+$(TARDELTADIR)/$(TARGET)_delta.tar : $(ALL_FILES)
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+ - sh -c 'tar cf - $(?:%="%") > "$@"'
+ @- sh -c 'chmod -w "$@"'
+
+backup : $(ALL_FILES:%=$(BACKUPDIR)/%) $(BACKUPDIR)/grammar.dsp
+
+$(BACKUPDIR)/% : %
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+ @echo $<
+ @- sh -c 'cp "$<" "$@"'
+ @- sh -c 'chmod -w "$@"'
+
+clean :
+ @- sh -c 'if test -d "$(INTDIR)"; then rm -f "$(INTDIR)"/*.idb "$(INTDIR)"/*.ilk "$(INTDIR)"/*.obj "$(INTDIR)"/*.pch "$(INTDIR)"/*.pdb; fi'
+ @- sh -c 'rm -f "$(SRCDIR)"/*.xxh'
+
+realclean : clean
+ @- sh -c 'rm -rf "$(DUMMYDIR)" Release Debug $(SRCDIR)'
+ @- sh -c 'rm -f "tests/*/results/*"'
+
+$(INTDIR)/CxxLexer.obj : CxxLexing.cxx CxxLexing.hxx $(SRCDIR)/CxxLexer.cxx $(SRCDIR)/CxxParser.hxx $(DUMMIES)
+$(INTDIR)/CxxParser.obj : CxxParsing.cxx CxxParsing.hxx $(SRCDIR)/CxxParser.cxx $(SRCDIR)/CxxParser.hxx
+$(INTDIR)/CxxToken.obj : CxxToken.cxx CxxToken.hxx
--- /dev/null
+#
+# Title: Common make macros for the Cxx Grammar tester.
+#
+# Author: E.D.Willink
+#
+# Description:
+#
+# These macros are shared by
+# makefile for Unix make
+# makefile.gmake for NT (g)make
+#END
+
+L_FILES = \
+ CxxLexer.l
+
+Y_FILES = \
+ CxxParser.y
+
+LEXER_FILES = \
+ CxxLexing.cxx \
+ CxxLexing.hxx
+
+PARSER_FILES = \
+ CxxParsing.cxx \
+ CxxParsing.hxx
+
+TOKEN_FILES = \
+ CxxToken.cxx \
+ CxxToken.hxx
+
+CLASS_SOURCES = \
+ $(LEXER_FILES) \
+ $(PARSER_FILES) \
+ $(TOKEN_FILES)
+
+#
+# list of all compilation units
+#
+COMPOSITE_SOURCES = \
+ CxxLexer.cpp \
+ CxxParser.cpp \
+ CxxToken.cpp
+
+Y_CXX_FILES = $(Y_FILES:%.y=$(SRCDIR)/%.cxx)
+GENERATED_INCLUDES = \
+ $(L_FILES:%.l=$(SRCDIR)/%.cxx) \
+ $(Y_FILES:%.y=$(SRCDIR)/%.cxx) \
+ $(Y_FILES:%.y=$(SRCDIR)/%.hxx)
+
+MAKE_FILES = \
+ makefile \
+ makefile.gmake \
+ makefile.macros \
+ makefile.unix
+
+# list of all other files for listing purposes
+OTHER_SOURCES = \
+ $(MAKE_FILES) \
+ $(CLASS_SOURCES) \
+ $(L_FILES) \
+ $(Y_FILES)
+
+CPP_SOURCES = $(COMPOSITE_SOURCES)
+
+INCLUDES = $(GENERATED_INCLUDES)
+
+SOURCES = \
+ $(CPP_SOURCES) \
+ $(CLASS_SOURCES) \
+ $(L_FILES) \
+ $(Y_FILES) \
+ $(MAKE_FILES)
+
+DOCUMENTATION_FILES = \
+ index.html \
+ README
+
+# List of all primary files (to be copied to a secondary environment)
+ALL_FILES = \
+ $(SOURCES) \
+ $(DOCUMENTATION_FILES) \
+ grammar.dsp \
+ grammar.dsw
--- /dev/null
+#
+# Title: Make file for Cxx Grammar tester.
+#
+# Author: E.D.Willink
+#
+# SCCS: %W% %G%
+#
+# Description: This stripped down make file builds the Cxx Grammar tester.
+#
+# Targets:
+# default, executable, normal
+# builds $(ARCH)o/grammar using default (sun) compiler
+# sun
+# builds $(ARCH)o/grammar using sun compiler, yacc and lex
+# gnu
+# builds $(ARCH)o/grammar using gnu compiler, bison and flex
+# debug
+# builds $(ARCH)o_g/grammar
+# clean
+# eliminates $(ARCH)o* intermediates
+# realclean
+# eliminates $(ARCH)o* intermediates and executables
+# source_kit
+# generates the distribution kits
+#
+# Switch settings are appropriate for Sun C++ 4.2.
+# Commented settings indicate what might be appropriate for gcc once it supports templates plausibly.
+#
+# Latest Modification:
+# EDW Date: 14-Jun-2001 Original
+#END
+
+.SUFFIXES:
+
+COMPILER = SUN_4_2
+TARGET = grammar
+ARCH = sun4
+FOG_PATH = $(PWD)
+SRCDIR = sources
+PCHDIR = $(SRCDIR)
+STDDIR = std
+DUMMYDIR = dummy
+OBJ_DIR = $(ARCH)o
+OBJ_DIR_PI = $(ARCH)o_pi
+OBJ_DIR_G = $(ARCH)o_g
+OBJ_DIR_PI_G = $(ARCH)o_pi_g
+PRECIOUS_DIRECTORIES = $(SRCDIR) $(OBJ_DIR) $(OBJ_DIR_PI) $(OBJ_DIR_G) $(OBJ_DIR_PI_G)
+PRECIOUS_LIBRARIES = $(OBJ_DIR)/lib$(TARGET).a $(OBJ_DIR_PI)/lib$(TARGET).so \
+ $(OBJ_DIR_G)/lib$(TARGET).a $(OBJ_DIR_PI_G)/lib$(TARGET).so
+
+.PRECIOUS: $(PRECIOUS_DIRECTORIES) $(PRECIOUS_LIBRARIES) $(SRCDIR)/$(TARGET).dep
+
+LINK = $(PURIFY) $(CC)
+LFLAGS =
+EGCS_1_0_2_LINK_LIBS = -ll
+SUN_4_2_LINK_LIBS = -lsunmath -lm /usr/ccs/lib/libl.a
+LINK_LIBS = $($(COMPILER)_LINK_LIBS)
+
+SUN_4_2_CC = CC
+EGCS_1_0_2_CC = g++
+CC = $($(COMPILER)_CC)
+
+SUN_4_2_G = -g0
+EGCS_1_0_2_G = -g
+_G = $($(COMPILER)_G)
+
+SUN_4_2_PIC = -PIC
+EGCS_1_0_2_PIC =
+_PIC = $($(COMPILER)_PIC)
+
+SUN_4_2_CFLAGS = -temp=. -ptr. -noex
+EGCS_1_0_2_CFLAGS =
+CFLAGS = $($(COMPILER)_CFLAGS)
+
+SUN_4_2_CC_INCS =
+EGCS_1_0_2_CC_INCS = -I../$(DUMMYDIR)
+CC_INCS = -I../$(SRCDIR) -I.. $($(COMPILER)_CC_INCS)
+
+SUN_4_2_CC_DEFS = -D__EXTERN_C__ -DNEEDS_BOOL -DNEEDS_YYWRAP
+EGCS_1_0_2_CC_DEFS =
+CC_DEFS = $($(COMPILER)_CC_DEFS)
+
+SUN_4_2_LFLAGS =
+EGCS_1_0_2_LFLAGS =
+LFLAGS = $($(COMPILER)_LFLAGS)
+
+CP = cp
+MV = mv
+RM = rm
+
+SUN_4_2_LEX = lex
+EGCS_1_0_2_LEX = flex
+LEX = $($(COMPILER)_LEX)
+
+SUN_4_2_LEX_FLAGS = -n
+EGCS_1_0_2_LEX_FLAGS =
+LEX_FLAGS = $($(COMPILER)_LEX_FLAGS)
+
+SUN_4_2_YACC = yacc
+EGCS_1_0_2_YACC = bison
+YACC = $($(COMPILER)_YACC)
+
+SUN_4_2_YACC_FLAGS = -d -t -v
+EGCS_1_0_2_YACC_FLAGS = -d -t -v -y
+YACC_FLAGS = $($(COMPILER)_YACC_FLAGS)
+
+default : executable $(ALL_FILES)
+
+#../import.make is empty by default, but may be provided to copy sources from somewhere.
+../import.make :
+ echo > $@
+IMPORT_PATH = grammar
+include ../import.make
+
+include makefile.macros
+
+LIB_OBJS = $(COMPOSITE_SOURCES:%.cpp=%.o)
+LIB_OBJS_G = $(COMPOSITE_SOURCES:%.cpp=$(OBJ_DIR_G)/%.o)
+DUMMIES = $(DUMMYDIR)/osfcn.h
+
+executable : $(ALL_FILES) normal
+
+normal : $(OBJ_DIR)/$(TARGET)
+
+debug : $(OBJ_DIR_G)/$(TARGET)
+
+sun :
+ $(MAKE) -f makefile.unix $(MFLAGS) COMPILER=SUN_4_2 normal
+
+gnu :
+ $(MAKE) -f makefile.unix $(MFLAGS) COMPILER=EGCS_1_0_2 normal
+
+$(DUMMYDIR)/osfcn.h :
+ @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
+ @echo '$@'
+ @- sh -c 'echo "extern \"C\" int read(int, char *, int);" > "$@"'
+ @- sh -c 'chmod -w "$@"'
+
+$(SRCDIR)/%.cxx : %.l
+ @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else $(RM) -f $(@D)/$*.cxx; fi
+ - $(LEX) $(LEX_FLAGS) $*.l
+ @- mv -f lex.yy.c $(@D)/$*.cxx
+ @- chmod -w $(@D)/$*.cxx
+
+$(SRCDIR)/%.cxx $(SRCDIR)/%.hxx : %.y
+ @- if test ! -r $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else $(RM) -f $(@D)/$*.output $(@D)/$*.cxx $(@D)/$*.hxx; fi
+ - $(YACC) $(YACC_FLAGS) $*.y
+ @- mv -f y.tab.c $(@D)/$*.cxx
+ @- mv -f y.tab.h $(@D)/$*.hxx
+ @- mv -f y.output $(@D)/$*.output
+ @- chmod -w $(@D)/$*.cxx $(@D)/$*.hxx $(@D)/$*.output
+
+$(OBJ_DIR)/%.o : %.cpp
+ @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+ @- echo $@
+ @- cd $(OBJ_DIR) ; if $(CC) -c -O $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
+ then : ; else $(RM) -f $*.o; fi
+
+$(OBJ_DIR_PI)/%.o : %.cpp
+ @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+ @- echo $@
+ @- cd $(OBJ_DIR_PI) ; if $(CC) -c -O $(_PIC) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
+ then : ; else $(RM) -f $*.o; fi
+
+$(OBJ_DIR_G)/%.o : %.cpp
+ @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+ @- echo $@
+ @- cd $(OBJ_DIR_G) ; if $(CC) -c $(_G) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
+ then : ; else $(RM) -f $*.o; fi
+
+$(OBJ_DIR_PI_G)/%.o : %.cpp
+ @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+ @- echo $@
+ @- cd $(OBJ_DIR_PI_G) ; if $(CC) -c $(_PIC) $(_G) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
+ then : ; else $(RM) -f $*.o; fi
+
+$(TARGET) : makefile $(LIB_OBJS:%.o=$(OBJ_DIR)/%.o)
+ @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+ @- echo $@
+ - cd $(OBJ_DIR) ; $(LINK) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o ../$(TARGET) -Bstatic \
+ $(LIB_OBJS) $(LINK_LIBS)
+
+$(OBJ_DIR)/$(TARGET) : makefile $(LIB_OBJS:%.o=$(OBJ_DIR)/%.o)
+ @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else rm -f $@; fi
+ @- echo $@
+ - cd $(OBJ_DIR) ; $(LINK) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $(TARGET) $(LIB_OBJS) $(LINK_LIBS)
+
+$(OBJ_DIR_G)/$(TARGET) : makefile $(LIB_OBJS:%.o=$(OBJ_DIR_G)/%.o)
+ @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else rm -f $@; fi
+ @- echo $@
+ - cd $(OBJ_DIR_G) ; $(LINK) $(CFLAGS) $(CC_INCS) $(CC_DEFS) $$(_G) -o $(TARGET) $(LIB_OBJS) $(LINK_LIBS)
+
+source_kit : CxxSrc.tgz
+
+CxxSrc.tgz : CxxSrc.tar
+ @- rm -f $@
+ - gzip CxxSrc.tar -c > $@
+ @- chmod -w $@
+
+CxxSrc.tar : $(ALL_FILES) FORCE $(OBJ_DIR)/grammar
+ @- rm -f "$@
+ @- tar cf "$@" $(ALL_FILES:%="$(MAKE_TAR_PATH)%") "$(MAKE_TAR_PATH)$(OBJ_DIR)/grammar"
+ @- chmod -w "$@"
+
+$(TAR_FILE) : $(ALL_FILES) FORCE
+ @- cd $(@D); tar rf $(@F) $(ALL_FILES:%=$(MAKE_TAR_PATH)%)
+
+FORCE :
+
+#
+# Cleanup rules
+#
+clean :
+ - $(RM) -f $(DUMMYDIR)/* $(SRCDIR)/* $(OBJ_DIR)/*.o $(OBJ_DIR_PI)/*.o $(OBJ_DIR_G)/*.o $(OBJ_DIR_PI_G)/*.o
+
+realclean :
+ - $(RM) -rf $(DUMMYDIR) $(SRCDIR) $(OBJ_DIR) $(OBJ_DIR_PI) $(OBJ_DIR_G) $(OBJ_DIR_PI_G)
+
+$(OBJ_DIR)/CxxLexer.o $(OBJ_DIR_PI)/CxxLexer.o $(OBJ_DIR_G)/CxxLexer.o $(OBJ_DIR_PI_G)/CxxLexer.o : \
+ CxxLexing.cxx CxxLexing.hxx CxxToken.hxx $(SRCDIR)/CxxLexer.cxx $(SRCDIR)/CxxParser.hxx $(DUMMIES)
+$(OBJ_DIR)/CxxParser.o $(OBJ_DIR_PI)/CxxParser.o $(OBJ_DIR_G)/CxxParser.o $(OBJ_DIR_PI_G)/CxxParser.o : \
+ CxxParsing.cxx CxxParsing.hxx CxxToken.hxx $(SRCDIR)/CxxParser.cxx $(SRCDIR)/CxxParser.hxx
+$(OBJ_DIR)/CxxToken.o $(OBJ_DIR_PI)/CxxToken.o $(OBJ_DIR_G)/CxxToken.o $(OBJ_DIR_PI_G)/CxxToken.o : \
+ CxxToken.cxx CxxToken.hxx
--- /dev/null
+From: Ed.Willink [mailto:Ed.Willink@uk.thalesgroup.com]
+Sent: Thursday, January 15, 2004 12:23 PM
+To: 'Chris Koeritz'
+Cc: 'Ed.Willink@thalesgroup.com'
+Subject: RE: question regarding your c++ grammar and lexer...
+Hi Chris
+
+
+[Please use Ed.Willink@thalesgroup.com for further coirrespondence. ]
+The grammar's the most re-usable bit. Overall it came from my extended C++ language
+FOG that allowed meta-execution at compile time ..,
+It is very Open Source - no license at all. You may use it as you like. It would
+be nice if you give an appropriate acknowledgement..
+The ISO compliance is the result of best endeavours comparison and interpretation
+rather than rigourous application of conformance suites.
+Be aware that it is a context free syntax only parser. It requires a subsequent semantic
+phase to resolve certain ambiguities that require type context.. If you need to
+implement this, you really should read the Grammar chapter of my thesis posted
+on the same site, and maybe use the FOG semantic parsing as a starting point.
+I hope you make lots and lots of money, so that you may feel generously disposed
+to giving me some.
+Regards
+Ed Willink
+
+
+-----Original Message-----
+From: Chris Koeritz
+Sent: 14 January 2004 19:35
+To: 'Ed.Willink@rrl.co.uk'
+Subject: question regarding your c++ grammar and lexer...
+dear mr. willink,
+first, thank you very much for posting your c++ grammar online. it is, well, awesome that it is compliant with the ansi standard.
+i am wondering though about what copyrights apply to it. i am considering using the grammar in a project that might be included in a tool which might eventually be sold.
+my concerns are: (1) is it appropriate to include your grammar in a GPLed open source application? and (2) do you allow the grammar to be used in a project that might be sold commercially without any royalty requirements for the use of it?
+please feel free to push my nose into any FAQ sites or other information that may already be available. i came by your grammar from the site here: http://www.parashift.com/c++-faq-lite/compiler-dependencies.html#faq-37.11
+and they were a bit skimpy on links to anything besides the grammar itself.
+thanks for your time and i hope releasing this grammar has been more fun than trouble for you...
+-chris koeritz
+