Parser::Decl Parser::Type() { Decl d; const char *p = lex.Pos(); Qualifier(); SimpleType(); Declarator(d, p); return Finish(d, p); }
Node* Parser::StructDeclarator(Symbol *type) { Node *decl = Declarator(type); if(decl == NULL) return ConditionalExpr(); return decl; }
Node* Parser::FunctionDefinitionStmt() { Symbol *type = TypeSpec(); if(type != NULL) { Node *name = Declarator(type); if(name != NULL) { if(oper != ROUND_LEFT_BRACKET) { if(oper == SEMICOLON) { Next(); return name; } if(oper == OPER_ASSIGN) { Next(); Node *node = new NodeBinary(name, OPER_ASSIGN, Initialiser()); if(oper == SEMICOLON) { Next(); return node; } if(oper == COMMA) { Next(); return new NodeStmt("(,)", node, InitDeclaratorList(type)); } } if(oper == COMMA) { Next(); return new NodeStmt("(,)", name, InitDeclaratorList(type)); } } SymTable *table = new SymTable(); symStack->Push(table); Next(); Node* args = FunctionArgumentList(); if(oper != ROUND_RIGHT_BRACKET) throw ParserException(currentToken, "Function definition without ')'"); Next(); Node *stmt = CompoundStmt(); if(stmt == NULL) throw ParserException(currentToken, "Function definition without statement"); symStack->Pop(); symStack->GetTopTable()->AddVar(new SymFunction(type, name->GetName())); return new NodeFunc(table, type, name, args, stmt); } } return NULL; }
Node* Parser::InitDeclarator(Symbol *type) { Node *decl = Declarator(type); if(oper == OPER_ASSIGN) { Next(); Node *init = Initialiser(); if(init == NULL) throw ParserException(currentToken, "Init declarator without initialiser"); return new NodeBinary(decl, OPER_ASSIGN, init); } return decl; }
static void ParmDeclList( void ) /* process old style function definitions */ { TYPEPTR typ; PARMPTR parm; decl_state state; SYM_ENTRY sym; decl_info info; size_t len; while( CurToken != T_LEFT_BRACE ) { FullDeclSpecifier( &info ); if( info.stg == SC_NONE && info.typ == NULL ) { if( CurToken == T_ID ) { CErr2p( ERR_MISSING_DATA_TYPE, Buffer ); } } if( info.stg != SC_NONE && info.stg != SC_REGISTER ) { CErr1( ERR_INVALID_STG_CLASS_FOR_PARM ); info.stg = SC_NONE; } state = DECL_STATE_NONE; typ = info.typ; if( typ == NULL ) { state |= DECL_STATE_NOTYPE; typ = TypeDefault(); } if( info.stg == SC_NONE ) info.stg = SC_AUTO; for( ;; ) { if( CurToken == T_SEMI_COLON ) { Chk_Struct_Union_Enum( typ ); } else { sym.name = NULL; Declarator( &sym, info.mod, typ, state ); if( sym.name == NULL || sym.name[0] == '\0' ) { InvDecl(); } else { len = strlen( sym.name ) + 1; for( parm = ParmList; parm != NULL; parm = parm->next_parm ) { if( parm->sym.name != NULL ) { if( memcmp( parm->sym.name, sym.name, len ) == 0 ) { break; } } } if( parm == NULL ) { CErr2p( ERR_SYM_NOT_IN_PARM_LIST, sym.name ); } else if( parm->sym.sym_type != NULL ) { CErr2p( ERR_PARM_ALREADY_DECLARED, sym.name ); } else { ArgPromotion( &sym ); parm->sym.sym_type = sym.sym_type; parm->sym.attribs.stg_class = info.stg; } } CMemFree( sym.name ); } if( CurToken == T_SEMI_COLON ) { NextToken(); break; } if( CurToken == T_LEFT_BRACE ) { CErr1( ERR_MISSING_SEMICOLON ); break; } if( CurToken == T_EOF ) return; MustRecog( T_COMMA ); } } ReverseParms(); if( CurFunc->sym_type->u.fn.parms == NULL ) { CurFunc->flags |= SYM_OLD_STYLE_FUNC; AddParms(); } else { ChkParms(); } ParmList = NULL; if( VarParm( CurFunc ) ) { CurFunc->flags &= ~ SYM_OK_TO_RECURSE; } }
Array<Parser::Decl> Parser::Declaration(bool l0, bool more) { Array<Decl> r; Decla d; const char *p = lex.Pos(); if(Key(tk_typedef)) { r = Declaration(); r.Top().type_def = true; r.Top().natural = String(p, lex.Pos()); return r; } if(Key(tk_friend)) d.isfriend = true; // if(Key(tk_template)) { // d.istemplate = true; // d.template_params = TemplateParams(d.tnames); // } for(;;) { if(Key(tk_static)) d.s_static = true; else if(Key(tk_extern)) d.s_extern = true; else if(Key(tk_auto)) d.s_auto = true; else if(Key(tk_register)) d.s_register = true; else if(Key(tk_mutable)) d.s_mutable = true; else if(Key(tk_explicit)) d.s_explicit = true; else if(Key(tk_virtual)) d.s_virtual = true; else if(!Key(tk_inline)) break; } Qualifier(); bool isdestructor = Key('~'); if(l0 && context.typenames.Find(lex) >= 0 && lex[1] == '(') { Decl& a = r.Add(); a.name = lex.GetId(); a.isdestructor = isdestructor; a.function = true; a.istructor = true; a.header = String(p, lex.Pos()); ++lex; ParamList(a); const char *p1 = lex.Pos(); Qualifier(); a.ender = String(p1, lex.Pos()); a.natural = String(p, lex.Pos()); EatInitializers(); return r; } if(lex == tk_operator) { Decl& a = r.Add(); (Decla&)a = d; a.name = ReadOper(); a.header = String(p, lex.Pos()); Key('('); ParamList(a); const char *p1 = lex.Pos(); Qualifier(); a.ender = String(p1, lex.Pos()); a.function = true; a.natural = String(p, lex.Pos()); return r; } String st = SimpleType(); if(!st.IsEmpty()) { Decl& a = r.Add(); a.name = st; a.isdestructor = st.Find('~') > 0; a.function = true; a.istructor = true; a.header = String(p, lex.Pos()); if(Key('(')) ParamList(a); const char *p1 = lex.Pos(); Qualifier(); a.ender = String(p1, lex.Pos()); a.natural = String(p, lex.Pos()); EatInitializers(); return r; } String natural1 = String(p, lex.Pos()); do { const char *p1 = lex.Pos(); Decl& a = r.Add(); (Decla&)a = d; Declarator(a, p); a.natural = natural1 + String(p1, lex.Pos()); p = lex.Pos(); } while(more && Key(',')); return r; }
void Parser::Declarator(Decl& d, const char *p) { int n = RPtr(); if(n) { while(n--) lex.Get(); Declarator(d, p); d.isptr = true; return; } if(Key('&')) { Declarator(d, p); return; } if(Key(tk_const)) { Declarator(d, p); return; } if(Key('(')) { Declarator(d, p); if(d.isptr) d.nofn = true; CheckKey(')'); } if(lex == tk_operator) d.name = ReadOper(); else if(lex.IsId() || lex == t_dblcolon) { d.name = Name(); if(Key(':')) if(!Key(t_integer)) Name(); } if(Key('(')) { if((lex < 256 || lex == tk_true || lex == tk_false) && lex != ')') { int level = 0; for(;;) { if(lex == t_eof) break; if(Key('(')) level++; else if(Key(')')) { if(--level < 0) break; } else ++lex; } return; } else { d.header = String(p, lex.Pos() - 1); d.function = !d.nofn; ParamList(d); p = lex.Pos(); Qualifier(); d.ender = String(p, lex.Pos()); } } EatInitializers(); while(Key('[')) { const char *p = lex.Pos(); int level = 1; while(level && lex != t_eof) { if(Key('[')) level++; else if(Key(']')) level--; else ++lex; } } if(Key('=')) { Constant(); } }