Mercurial > ~dholland > hg > ag > index.cgi
view tests/agcl/parsifal/cpp.syn @ 20:bb115deb6fb2
Improve agfiles rule.
(1) It didn't depend on $(AGCL) and it absolutely should have.
(2) allow AGFORCE=1 to make it rebuild whether or not it looks out of
date.
(3) Document this.
author | David A. Holland |
---|---|
date | Mon, 13 Jun 2022 00:02:15 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/* * AnaGram, A System for Syntax Directed Programming * Copyright 1993-2002 Parsifal Software. All Rights Reserved. * See the file COPYING for license and usage terms. */ { // class AstNode; #include "cppdefs.h" #include "agstk.h" #include <stdio.h> #include "mpp.h" extern int columnNumber; #define INPUT_CODE(t) inputCode(t) #ifndef SYNTAX_ERROR #define SYNTAX_ERROR printf("%s\n", (PCB).error_message) #endif parse_pcb_type *pcbPointer = 0; #define PCB (*pcbPointer) extern char *inputName[]; InputToken *trackPointer; int inputCode(const InputToken &t) { int code = t.code; if (code == IDENTIFIER) code = getTokenType(t.handle); PCB.column = t.column; if (PCB.pointer == trackPointer) return code; trackPointer = PCB.pointer; if (code == LINE) printf("[%02d] %s(%d): %d\n", scopeStack.size(), inputName[code], code, t.handle); else printf("[%02d] %s(%d): %s\n", scopeStack.size(), inputName[code], code, td[t.handle]); return code; } AgStack<ParserState> stateStack; #include "cpp.h" } [ pointer input pointer type = InputToken * default Input type = InputToken //default token type = AstNode * context type = ParserState input values ~declare PCB ~lines and columns parser name = parse parser file name = "#.cpp" line numbers disregard line number error trace ~allow macros sticky { statement, // resolve if/else conflict type specifier seq, // conflict between * as dereference and as multiply ptr operator, // conflict between * as dereference and as multiply class name, // qualifying :: on type and global :: on declarator IDENTIFIER, // Resolves ctor/bitfield conflict explicitly typed identifier, nested name specifier, NEW, DELETE } enum { // See TOKEN.H eof =0, SPACE =' ', AND ='A', // "&&" ADD_EQ, // "+=" AND_EQ, // "&=" ARROW, // "->" CONCAT, // "##" DECR, // "--" DIV_EQ, // "/=" ELLIPSIS, // "..." EQ, // "==" GE, // ">=" INCR, // "++" LE, // "<=" LS, // "<<" LS_EQ, // "<<=" MOD_EQ, // "%=" MULT_EQ, // "*=" NE, // "!=" OR, // "||" OR_EQ, // "|=" RS, // ">>" RS_EQ, // ">>=" SUB_EQ, // "-=" XOR_EQ, // "^=" CHARACTERconstant, // character constant STRINGliteral, // character string DOT_STAR = 'a', ARROW_STAR, QUAL, LINE, IDENTIFIER = 129, CLASS_NAME, ENUM_NAME, TYPEDEF_NAME, TEMPLATE_NAME, NAMESPACE_NAME, NAMESPACE_ALIAS, UNSIGNEDqualifier, LONGqualifier, FLOATqualifier, HEXconstant, OCTconstant, DECconstant, FLOATconstant, // real AUTO, // "auto" BREAK, // "break" CASE, // "case" CHAR, // "char" CONSTANT, // "const" CONTINUE, // "continue" DEFAULT, // "default" DO, // "do" DOUBLE, // "double" ELSE, // "else" ENUM, // "enum" EXTERN, // "extern" FLOAT, // "float" FOR, // "for" GOTO, // "goto" IF, // "if" INT, // "int" LONG, // "long" REGISTER, // "register" RETURN, // "return" SHORT, // "short" SIGNED, // "signed" SIZEOF, // "sizeof" STATIC, // "static" STRUCT, // "struct" SWITCH, // "switch" TYPEDEF, // "typedef" UNION, // "union" UNSIGNED, // "unsigned" VOID, // "void" VOLATILE, // "volatile" WHILE, // "while" ASM, BITAND, BITOR, BOOL, CATCH, CLASS, COMPL, CONST_CAST, DELETE, DYNAMIC_CAST, EXPLICIT, EXPORT, FALSE, FRIEND, INLINE, MUTABLE, NAMESPACE, NEW, NOT, NOT_EQ, OPERATOR, PRIVATE, PROTECTED, PUBLIC, REINTERPRET_CAST, STATIC_CAST, TEMPLATE, THIS, THROW, TRUE, TRY, TYPEID, TYPENAME, USING, VIRTUAL, WCHAR_T, CDECL, PASCAL, RTLENTRY, NEAR, FAR, UNRECOGNIZED } ] (void) line number -> LINE:x =PCB.line = x.handle; -> CDECL + PASCAL +RTLENTRY + NEAR + FAR //hack to skip non ANSI stuff skip = LINE + CDECL + PASCAL + RTLENTRY + NEAR + FAR translation unit $ -> declaration list, eof // 3.5 literal -> HEXconstant -> OCTconstant -> DECconstant -> FLOATconstant -> CHARACTERconstant -> STRINGliteral... //Concatenate adjacent strings (TypeDefinition) class name -> CLASS_NAME:n =TypeDefinition(n); // -> TYPEDEF_NAME -> template id:n =TypeDefinition(n); // 5.1 primary expression -> literal -> THIS -> QUAL, IDENTIFIER -> QUAL, operator function id -> qualified id -> '(', expression hack 1, ')' -> unqualified id id expression -> unqualified id -> qualified id unqualified id -> IDENTIFIER:n ={ TypeDefinition d(n); if (typedefFlag) { d.tokenType = TYPEDEF_NAME; typedefFlag = 0; } scopeStack.top()->addIdentifier(d); } -> operator function id -> conversion function id (Scope *) qualified id -> nested name specifier:s, QUAL, unqualified id =s; -> nested name specifier:s, QUAL, TEMPLATE, unqualified id =s; (Scope *) nested name specifier -> class name:n =n.scope; -> namespace name:n =n.scope; -> QUAL, class name:n = scopeStack[0]->getNestedScope(n.handle); -> QUAL, namespace name:n = scopeStack[0]->getNestedScope(n.handle); -> nested name specifier:s, QUAL, class name:n = (s == 0) ? 0 : s->getNestedScope(n.handle); -> nested name specifier:s, QUAL, namespace name:n =(s == 0) ? 0 : s->getNestedScope(n.handle); //5.2 postfix expression -> primary expression -> postfix expression, '[', expression, ']' -> postfix expression, '(', expression list?, ')' -> simple type specifier, '(', expression list?, ')' -> postfix expression, '.', id expression -> postfix expression, '.', TEMPLATE, id expression -> postfix expression, ARROW, id expression -> postfix expression, ARROW, TEMPLATE, id expression -> postfix expression, '.', pseudo destructor name -> postfix expression, ARROW, pseudo destructor name -> postfix expression, INCR -> postfix expression, DECR -> DYNAMIC_CAST, '<', type id, '>', '(', expression, ')' -> STATIC_CAST, '<', type id, '>', '(', expression, ')' -> REINTERPRET_CAST, '<', type id, '>', '(', expression, ')' -> CONST_CAST, '<', type id, '>', '(', expression, ')' -> TYPEID, '(', expression hack 1, ')' -> TYPEID, '(', type id, ')' expression list -> assignment expression -> expression list, ',', assignment expression pseudo destructor name -> nonclass type name, QUAL, '~', nonclass type name -> nested name specifier, QUAL, nonclass type name, QUAL, '~', nonclass type name -> QUAL, nonclass type name, QUAL, '~', nonclass type name -> '~', nonclass type name -> nested name specifier, QUAL, '~', nonclass type name -> QUAL, '~', nonclass type name // 5.3 unary expression -> postfix expression -> INCR, cast expression -> DECR, cast expression -> unary operator, cast expression -> SIZEOF, unary expression -> SIZEOF, '(', type id, ')' -> new expression -> delete expression unary operator -> '&' | '*' | '+' | '-' | '~' | '!' new expression -> new, new type id, new initializer? -> new, new placement, new type id, new initializer? -> new, '(', type id, ')', new initializer? -> new, new placement, '(', type id, ')', new initializer? new -> NEW -> QUAL, NEW new placement -> '(', expression list hack 2, ')' expression list hack 2 -> retry, expression list -> retry, retry, resynch =diagnose("expression list hack 2"); new type id -> type specifier seq -> type specifier seq, new declarator new declarator -> ptr operator -> ptr operator, new declarator -> direct new declarator direct new declarator -> '[', expression, ']' -> direct new declarator, '[', constant expression, ']' new initializer -> '(', expression list?, ')' delete expression -> delete, cast expression -> delete, '[', ']', cast expression delete -> DELETE -> QUAL, DELETE cast expression -> unary expression -> '(', type id, ')', cast expression expression hack 1 -> retry, expression -> retry, error, resynch =diagnose("expression hack 1"); restricted assignment expression hack 5 -> retry, restricted assignment expression -> retry, error, resynch =diagnose("expression hack 1"); pm expression -> cast expression -> pm expression, DOT_STAR, cast expression -> pm expression, ARROW_STAR, cast expression multiplicative expression -> pm expression -> multiplicative expression, '*', pm expression -> multiplicative expression, '/', pm expression -> multiplicative expression, '%', pm expression additive expression -> multiplicative expression -> additive expression, '+', multiplicative expression -> additive expression, '-', multiplicative expression shift expression -> additive expression -> shift expression, LS, additive expression -> shift expression, RS, additive expression relational expression -> shift expression -> relational expression, '<', shift expression -> relational expression, '>', shift expression -> relational expression, LE, shift expression -> relational expression, GE, shift expression equality expression -> relational expression -> equality expression, EQ, relational expression -> equality expression, NE, relational expression and expression -> equality expression -> and expression, '&', equality expression exclusive or expression -> and expression -> exclusive or expression, '^', and expression inclusive or expression -> exclusive or expression -> inclusive or expression, '|', exclusive or expression logical and expression -> inclusive or expression -> logical and expression, AND, inclusive or expression logical or expression -> logical and expression -> logical or expression, OR, logical and expression conditional expression -> logical or expression -> logical or expression, '?', expression, ':', conditional expression assignment expression -> conditional expression -> logical or expression, assignment operator, assignment expression -> throw expression assignment operator -> '=' | MULT_EQ | DIV_EQ | MOD_EQ | ADD_EQ | SUB_EQ -> LS_EQ | RS_EQ | AND_EQ | OR_EQ | XOR_EQ expression -> assignment expression -> expression, ',', assignment expression constant expression -> conditional expression statement -> labeled statement -> compound statement -> selection statement -> iteration statement -> jump statement -> try block -> block declaration -> variable declaration -> function definition 2 -> retry, statement try 2 statement try 2 -> type qualifier?, declarator list, ';' -> function definition 1 -> retry, statement try 3 statement try 3 -> expression statement -> retry, resynch =diagnose("statement try 3"); labeled statement -> IDENTIFIER, ':', statement -> CASE, constant expression, ':', statement -> DEFAULT, ':', statement expression statement -> expression, ';' compound statement -> begin block , statement seq?, '}' =restoreScope(); begin block -> '{' =nestScope(); statement seq -> statement -> statement seq, statement selection statement -> IF, '(', condition, ')', statement -> IF, '(', condition, ')', statement, ELSE, statement -> SWITCH, '(', condition, ')', statement condition -> condition kernel condition kernel -> type specifier seq, declarator, '=', assignment expression -> retry, condition kernel 2 condition kernel 2 -> expression -> retry, resynch =diagnose("condition kernel 2"); iteration statement -> WHILE, '(', condition, ')', statement -> DO, statement, WHILE, '(', condition, ')', ';' -> for header, for init statement?, ';', condition?, ';', expression?, ')', statement =restoreScope(); for header -> FOR, '(' =nestScope(); for init statement -> for init for init -> for variable declaration -> retry, for init 2 for variable declaration -> decl specifier seq -> decl specifier seq, init declarator list for init 2 -> expression -> retry, resynch =diagnose("for init 2"); jump statement -> BREAK, ';' -> CONTINUE, ';' -> RETURN, expression?, ';' -> GOTO, IDENTIFIER, ';' (int) declaration seq -> =0; -> declaration seq, declaration hack declaration list -> declaration seq declaration hack -> declaration =printf("declaration hack complete\n"); declaration -> block declaration -> simple declaration //-> template declaration -> explicit instantiation -> explicit specialization -> linkage specification -> namespace definition block declaration -> asm definition -> namespace alias definition -> using declaration -> using directive (void) retry -> error =CONTEXT.restore(); simple declaration -> variable declaration =printf("variable declaration\n"); -> template header, variable declaration =printf("variable declaration\n"), restoreScope(); -> EXPORT, template header, variable declaration =printf("variable declaration\n"), restoreScope(); -> function definition 2 =printf("function definition 2\n"); -> template header, function definition 2 =printf("function definition 2\n"), restoreScope(); -> EXPORT, template header, function definition 2 =printf("function definition 2\n"), restoreScope(); -> retry, attempt declarator list attempt declarator list -> type qualifier?, declarator list, ';' =printf("declarator list\n"); -> template header, type qualifier?, declarator list, ';' =printf("declarator list\n"), restoreScope(); -> function definition 1 =printf("function definition 1\n"); -> retry, resynch =diagnose("attempt declarator list"); resynch -> resynch text, ';' -> resynch text, balanced braces -> resynch text, eof =PCB.pointer--; resynch text // -> resynch item -> -> resynch text, resynch item resynch item -> ~(eof + skip + '(' + ')' + '[' + ']' + '{' + '}' + ';') -> balanced parens -> balanced brackets (void) balanced parens -> '(', not right paren, ')' (void) balanced brackets -> '[', not right bracket, ']' (void) balanced braces -> '{', not right brace, '}' not right paren -> -> not right paren, resynch item -> not right paren, ';' + ']' + '}' -> not right paren, balanced braces not right bracket -> -> not right bracket, resynch item -> not right bracket, ';' + ')' + '}' -> not right bracket, balanced braces not right brace -> -> not right brace, resynch item -> not right brace, ';' + ')' + ']' -> not right brace, balanced braces variable declaration -> decl specifier seq?, ';' -> decl specifier seq, init declarator list, ';' /* If there are no decl specifiers, then the declarator must be a constructor, destructor, or type conversion operator. In this case, there can be no initialization, so we use a declarator list instead of an init declarator list */ declarator list -> declarator -> declarator list, ',', declarator decl specifier seq -> fundamental type -> fundamental type, predefined specifier... -> type qualifier..., fundamental type, predefined specifier?... -> user defined specifier, type qualifier?... -> type qualifier..., user defined specifier, type qualifier?... restricted decl specifier seq -> fundamental type -> fundamental type, predefined specifier... -> type qualifier..., fundamental type, predefined specifier?... -> restricted specifier, type qualifier?... -> type qualifier..., restricted specifier, type qualifier?... restricted specifier -> qualified type name storage class specifier -> AUTO -> REGISTER -> STATIC -> EXTERN -> MUTABLE function specifier -> INLINE -> VIRTUAL -> EXPLICIT simple type specifier -> qualified type name -> fundamental type predefined specifier -> type qualifier -> fundamental type type qualifier -> storage class specifier -> function specifier -> FRIEND -> TYPEDEF =typedefFlag = 1; -> cv qualifier fundamental type -> CHAR -> WCHAR_T -> BOOL -> SHORT -> INT -> LONG -> SIGNED -> UNSIGNED -> FLOAT -> DOUBLE -> VOID user defined specifier -> class specifier -> enum specifier -> elaborated type specifier -> qualified type name user type specifier -> elaborated type specifier -> qualified type name qualified type name -> ENUM_NAME -> TYPEDEF_NAME -> nested name specifier -> nested name specifier, QUAL, ENUM_NAME -> nested name specifier, QUAL, TYPEDEF_NAME nonclass type name -> ENUM_NAME -> TYPEDEF_NAME elaborated type specifier -> class key, IDENTIFIER:n ={ TypeDefinition d(n); if (templateFlag) { d.tokenType = TEMPLATE_NAME; scopeStack[scopeStack.size() - 2]->addIdentifier(d); } else { d.tokenType = CLASS_NAME; scopeStack.top()->addIdentifier(d); } } -> class key, class name:d ={ if (templateFlag) { d.tokenType = TEMPLATE_NAME; scopeStack[scopeStack.size() - 2]->addIdentifier(d); } else { d.tokenType = CLASS_NAME; scopeStack.top()->addIdentifier(d); } } -> class key, name qualifier:scope, IDENTIFIER:n ={ TypeDefinition d(n); d.tokenType = templateFlag ? TEMPLATE_NAME : CLASS_NAME; scope->addIdentifier(d); } -> class key, name qualifier:scope, class name:d ={ d.tokenType = templateFlag ? TEMPLATE_NAME : CLASS_NAME; scope->addIdentifier(d); } -> ENUM, IDENTIFIER -> ENUM, name qualifier, IDENTIFIER -> explicitly typed identifier -> explicitly typed identifier, '<', template argument list, '>' explicitly typed identifier -> TYPENAME, nested name specifier, QUAL, IDENTIFIER enum specifier -> ENUM, '{', enumerator list?, '}' -> ENUM, IDENTIFIER:n, '{', enumerator list?, '}' ={ TypeDefinition d(n); d.tokenType = ENUM_NAME; scopeStack.top()->addIdentifier(d); } enumerator list -> enumerator definition -> enumerator list, ',', enumerator definition enumerator definition -> IDENTIFIER -> IDENTIFIER, '=', constant expression (TypeDefinition) namespace name -> NAMESPACE_NAME:n =TypeDefinition(n); -> NAMESPACE_ALIAS:n =TypeDefinition(n); namespace definition -> named namespace definition -> unnamed namespace definition named namespace definition -> original namespace definition -> extension namespace definition original namespace definition -> NAMESPACE, IDENTIFIER, '{', namespace body, '}' extension namespace definition -> NAMESPACE, NAMESPACE_NAME, '{', namespace body, '}' unnamed namespace definition -> NAMESPACE, '{', namespace body, '}' namespace body -> declaration seq namespace alias definition -> NAMESPACE, IDENTIFIER, '=', qualified namespace specifier, ';' qualified namespace specifier -> name qualifier, namespace name using declaration -> USING, nested name specifier, QUAL, unqualified id, ';' -> USING, TYPENAME, nested name specifier, QUAL, unqualified id, ';' -> USING, QUAL, unqualified id, ';' using directive -> USING, NAMESPACE, namespace name, ';' -> USING, NAMESPACE, name qualifier, namespace name, ';' (Scope *) name qualifier -> QUAL =scopeStack[0]; -> class name:n, QUAL =getNestedScope(n.handle); -> namespace name:n, QUAL =getNestedScope(n.handle); -> name qualifier:s, class name:n, QUAL =s->getNestedScope(n.handle); -> name qualifier:s, namespace name:n, QUAL =(s == 0) ? 0 : s->getNestedScope(n.handle); asm definition -> ASM, '(', STRINGliteral, ')', ';' linkage specification -> EXTERN, STRINGliteral, '{', declaration list, '}' -> EXTERN, STRINGliteral, declaration init declarator list -> init declarator -> init declarator list, ',', init declarator init declarator -> direct declarator -> direct declarator, initializer -> ptr operator, init declarator (Scope *) declarator -> direct declarator:s =s; -> ptr operator, declarator:s =s; (Scope *) direct declarator -> declarator id:s =s; -> direct declarator:s, '(', parameter declaration clause hack 4, ')', cv qualifier seq?, exception specification? =s; -> direct declarator:s, '[', constant expression?, ']' =s; -> '(', declarator:s, ')' =s; declarator hack -> direct declarator hack -> ptr operator, declarator hack direct declarator hack -> declarator id -> direct declarator hack, '(', parameter declaration clause hack 4, ')', cv qualifier seq?, exception specification? -> direct declarator hack, '[', constant expression?, ']' -> '(', declarator hack 3, ')' ptr operator -> '*', cv qualifier seq? -> '&' -> nested name specifier, QUAL, '*', cv qualifier seq? cv qualifier seq -> cv qualifier, cv qualifier seq? cv qualifier -> CONSTANT -> VOLATILE (Scope *) declarator id -> unqualified id =new Scope; -> nested name specifier:s, QUAL, unqualified id =s; -> nested name specifier:s, QUAL, CLASS_NAME =s; -> nested name specifier:s, QUAL, '~', CLASS_NAME =s; -> nested name specifier:s, QUAL, TEMPLATE_NAME =s; -> nested name specifier:s, QUAL, '~', TEMPLATE_NAME =s; -> CLASS_NAME:n ={ TypeDefinition d(n); if (typedefFlag) { d.tokenType = TYPEDEF_NAME; typedefFlag = 0; scopeStack.top()->addIdentifier(d); } return new Scope; } -> TEMPLATE_NAME:n ={ TypeDefinition d(n); if (typedefFlag) { d.tokenType = TYPEDEF_NAME; typedefFlag = 0; scopeStack.top()->addIdentifier(d); } return new Scope; } -> '~', CLASS_NAME:n =TypeDefinition(n).scope; // '~' is a unary operator -> '~', TEMPLATE_NAME:n =TypeDefinition(n).scope; // '~' is a unary operator type id -> type specifier seq, abstract declarator? type specifier seq -> fundamental type -> fundamental type, predefined specifier... -> cv qualifier..., fundamental type -> cv qualifier..., fundamental type, predefined specifier... -> user type specifier, cv qualifier?... -> cv qualifier..., user type specifier, cv qualifier?... abstract declarator hack -> ptr operator, abstract declarator hack? -> direct abstract declarator hack direct abstract declarator hack -> '(', ')', cv qualifier seq?, exception specification? -> '(', parameter declaration clause hack 3, ')', cv qualifier seq?, exception specification? -> '[', constant expression?, ']' -> '(', /* hack 3 */ abstract declarator, ')' -> direct abstract declarator hack, '(', parameter declaration clause?, ')', cv qualifier seq?, exception specification? -> direct abstract declarator hack, '[', constant expression?, ']' abstract declarator -> ptr operator, abstract declarator? -> direct abstract declarator direct abstract declarator -> '(', ')', cv qualifier seq?, exception specification? -> '(', parameter declaration clause, ')', cv qualifier seq?, exception specification? -> '[', constant expression?, ']' -> '(', abstract declarator, ')' -> direct abstract declarator, '(', parameter declaration clause?, ')', cv qualifier seq?, exception specification? -> direct abstract declarator, '[', constant expression?, ']' parameter declaration clause -> parameter declaration list -> ELLIPSIS -> parameter declaration list, ELLIPSIS -> parameter declaration list, ',', ELLIPSIS parameter declaration list -> parameter declaration -> parameter declaration list, ',', parameter declaration parameter declaration -> decl specifier seq, declarator hack -> decl specifier seq, declarator hack, '=', assignment expression -> decl specifier seq, abstract declarator hack? -> decl specifier seq, abstract declarator hack?, '=', assignment expression parameter declaration clause hack 3 -> parameter declaration clause declarator hack 3 -> retry, declarator -> retry, error, ~eof, resynch =diagnose("declarator hack 3"); parameter declaration clause hack 4 -> parameter declaration clause? expression list hack 4 -> retry, expression list -> retry, error, ~(eof + skip + ')')?... =diagnose("expression list hack 4"); function definition 1 -> constructor identifier, ctor initializer?, function body ={if (templateFlag) restoreScope();} -> constructor identifier, constructor try block ={if (templateFlag) restoreScope();} constructor try block -> TRY, ctor initializer?, function body, handler seq constructor identifier -> type qualifier?, declarator:s =nestScope(s); -> template header, type qualifier?, declarator:s =nestScope(s); -> EXPORT, template header, type qualifier?, declarator:s =nestScope(s); function definition 2 -> function identifier, function body -> function identifier, function try block function identifier -> decl specifier seq, declarator:s =nestScope(s); function body -> '{', statement seq?, '}' =restoreScope(); function try block -> TRY, function body, handler seq initializer -> '=', initializer clause -> '(', expression list hack 4, ')' initializer clause -> assignment expression -> '{', initializer list, ','?, '}' -> '{', '}' initializer list -> initializer clause -> initializer list, ',', initializer clause class specifier -> class head, '{', member specification?, '}' =restoreScope(); -> class head, ':', base clause, '{', member specification?, '}' =restoreScope(); specifier lookahead -> '{'+ ':' =CONTEXT.restore(); class head -> class key, specifier lookahead ={ nestScope(); } -> class key, IDENTIFIER:n, specifier lookahead ={ TypeDefinition d(n); int flag = templateFlag; d.scope = nestScope(d.handle); if (flag) { d.tokenType = TEMPLATE_NAME; scopeStack[scopeStack.size() - 3]->addIdentifier(d); } else { d.tokenType = CLASS_NAME; scopeStack[scopeStack.size() - 2]->addIdentifier(d); } } -> class key, class name:d, specifier lookahead ={ d.tokenType = templateFlag? TEMPLATE_NAME : CLASS_NAME; int flag = templateFlag; d.scope = nestScope(d.handle); if (flag) scopeStack[scopeStack.size() - 3]->addIdentifier(d); else scopeStack[scopeStack.size() - 2]->addIdentifier(d); } -> class key, TEMPLATE_NAME:n, specifier lookahead ={ TypeDefinition d(n); d.tokenType = templateFlag? TEMPLATE_NAME : CLASS_NAME; int flag = templateFlag; d.scope = nestScope(d.handle); if (flag) scopeStack[scopeStack.size() - 3]->addIdentifier(d); else scopeStack[scopeStack.size() - 2]->addIdentifier(d); } -> class key, name qualifier:s, IDENTIFIER:n, specifier lookahead ={ if (s != 0) s->nest(new Scope(n.handle)); } -> class key, name qualifier:s, TEMPLATE, template id:h, specifier lookahead ={ if (s != 0) s->nest(new Scope(h.handle)); } class key -> CLASS -> STRUCT -> UNION member specification -> member declaration hack -> member specification, member declaration hack member declaration hack -> member declaration -> member restore, type qualifier?, member declarator list, ';' -> member restore, function definition 1 -> member restore, error, resynch =diagnose("member specification"); member restore -> retry =printf("try member declarator list\n"); member declaration -> ';' -> decl specifier seq, member declarator list?, ';' -> function definition 2 -> using declaration // -> template declaration -> access specifier, ':' member declarator list -> member declarator -> member declarator list, ',', member declarator member declarator -> declarator -> declarator, pure specifier -> declarator, constant intializer -> ':', constant expression -> IDENTIFIER, ':', constant expression pure specifier -> '=', '0' constant intializer -> '=', constant expression base clause -> base specifier list base specifier list -> base specifier:s =scopeStack.top()->addBase(s); -> base specifier list, ',', base specifier:s =scopeStack.top()->addBase(s); (Scope *) base specifier -> CLASS_NAME:n =getNestedScope(n.handle); -> TEMPLATE_NAME:n =getNestedScope(n.handle); -> qualified class name:s =s; -> VIRTUAL, access specifier?, qualified class name:s =s; -> access specifier, VIRTUAL?, qualified class name:s =s; -> access specifier, VIRTUAL?, CLASS_NAME:n =getNestedScope(n.handle); -> access specifier, VIRTUAL?, TEMPLATE_NAME:n =getNestedScope(n.handle); (Scope *) qualified class name -> name qualifier:s, class name:n =(s == 0) ? 0 : s->getNestedScope(n.handle); access specifier -> PRIVATE -> PROTECTED -> PUBLIC conversion function id -> OPERATOR, conversion type id conversion type id -> type specifier seq, conversion declarator? conversion declarator -> ptr operator, conversion declarator? ctor initializer -> ':', mem initializer list mem initializer list -> mem initializer -> mem initializer list, ',', mem initializer mem initializer -> mem initializer id, '(', expression list?, ')' mem initializer id -> qualified class name -> class name -> IDENTIFIER operator function id -> OPERATOR, operator operator -> NEW -> DELETE -> NEW, '[', ']' -> DELETE, '[', ']' -> '+' // =PLUS_OP; -> '-' // =MINUS_OP; -> '*' // =MUL_OP; -> '/' // =DIV_OP; -> '%' // =MOD_OP; -> '^' // =XOR_OP; -> '&' // =AND_OP; -> '|' // =OR_OP; -> '~' // =COM_OP; -> '!' // =NOT_OP; -> '=' // =ASSIGN_OP; -> '<' // =LT_OP; -> '>' // =GT_OP; -> MULT_EQ -> DIV_EQ -> MOD_EQ -> ADD_EQ -> SUB_EQ -> LS_EQ -> RS_EQ -> AND_EQ -> OR_EQ -> XOR_EQ -> LS -> RS -> EQ -> NE -> LE -> GE -> AND -> OR -> INCR -> DECR -> ',' -> ARROW_STAR -> ARROW -> '(', ')' // =PAREN_OP; -> '[', ']' // =BRACKET_OP; /* template declaration -> template header, declaration =restoreScope(); -> EXPORT, template header, declaration =restoreScope(); */ template header -> TEMPLATE, '<', !nestScope();, template parameter list, '>' =templateFlag = 1; template parameter list -> template parameter -> template parameter list, ',', template parameter template parameter -> type parameter -> template parameter declaration template parameter declaration -> restricted decl specifier seq, declarator hack -> restricted decl specifier seq, declarator hack, '=', restricted assignment expression -> restricted decl specifier seq, abstract declarator hack? -> restricted decl specifier seq, abstract declarator hack?, '=', restricted assignment expression restricted assignment expression -> restricted conditional expression -> shift expression, assignment operator, restricted assignment expression -> restricted throw expression restricted conditional expression -> shift expression -> shift expression, '?', shift expression, ':', restricted conditional expression restricted throw expression -> THROW, restricted assignment expression? type parameter -> CLASS -> CLASS, IDENTIFIER:n =scopeStack.top()->addIdentifier(TypeDefinition(n.handle, CLASS_NAME)); -> CLASS, '=', type id -> CLASS, IDENTIFIER, '=', type id -> TYPENAME, IDENTIFIER? -> TYPENAME, IDENTIFIER?, '=', type id -> TEMPLATE, '<', template parameter list, '>', CLASS, IDENTIFIER? -> TEMPLATE, '<', template parameter list, '>', CLASS, IDENTIFIER?, '=', TEMPLATE_NAME (InputToken) template id -> TEMPLATE_NAME:n, '<', template argument list, '>' =n; template argument list -> template argument -> template argument list, ',', template argument template argument -> restricted assignment expression hack 5 -> TEMPLATE_NAME -> type id explicit instantiation -> TEMPLATE, declaration explicit specialization -> TEMPLATE, '<', '>', declaration try block -> TRY, compound statement, handler seq handler seq -> handler -> handler seq, handler handler -> CATCH, '(', exception declaration, ')', compound statement exception declaration -> type specifier seq, declarator hack -> type specifier seq, abstract declarator hack -> type specifier seq -> ELLIPSIS throw expression -> THROW, assignment expression? exception specification -> THROW, '(', type id list?, ')' type id list -> type id -> type id list, ',', type id { #include "mpp.h" #include "token.h" #define GET_CONTEXT CONTEXT = ParserState() int typedefFlag = 0; AgStack<int> typedefStack; int templateFlag = 0; AgStack<int> templateStack; AgStack<InputToken> tokenStack; ParserState::ParserState() : pointer(pcbPointer ? pcbPointer->pointer : 0), line(pcbPointer ? pcbPointer->line : 0), scopeStackDepth(scopeStack.size()), typedefStackDepth(typedefStack.size()), nLocalVariables(scopeStackDepth ? scopeStack.top()->nLocals(): 0), templateStackDepth(templateStack.size()), typedefFlag(::typedefFlag), templateFlag(::templateFlag) { } void ParserState::restore() { PCB.pointer = pointer; PCB.line = line; while (scopeStack.size() > scopeStackDepth) scopeStack.pop(); while (typedefStack.size() > typedefStackDepth) typedefStack.pop(); while (templateStack.size() > templateStackDepth) templateStack.pop(); scopeStack.top()->restoreLocals(nLocalVariables); ::typedefFlag = typedefFlag; ::templateFlag = templateFlag; } void diagnose(char *msg) { printf("Error: %s\n", msg); PCB.exit_flag = AG_SEMANTIC_ERROR_CODE; } c_parser::c_parser() { pcbPointer = &pcb; //init_parse(); // init parse } // Destructor c_parser::~c_parser() { } // Reset Parser c_parser &reset(c_parser &c) { return c; } // Transmit token to c_parser /* The overloaded operator "<<" is used to transmit data to a parser. Newline tokens are filtered out, since they are passed along by the token scanner only in case text output of the preprocessor is required. If the parser has encountered an error, there is no point in giving it any further input. Otherwise, the input_code and input_value fields of the pcb are set up and cc() is called to deal with the token. */ token_sink &c_parser::operator << (InputToken c) { printf("%d\n", c.code); if (c.code == 10) return *this; tokenStack.push(c); if (c.code == END_OF_FILE) { int k = tokenStack.size(); int n = k; InputToken *tokenArray = new InputToken[k]; while (k--) { tokenStack.pop(tokenArray[k]); } PCB.pointer = tokenArray; trackPointer = tokenArray - 1; PCB.line = 1; scopeStack.push(new Scope); // global scope parse(); } return *this; } token_sink &c_parser::operator << (InputToken *s) { while (s->code != END_OF_FILE) { if ((int) s->code == 10) continue; tokenStack.push(*s++); } return *this; } }