parser.cc
来自「这个程序是关于OpenC++的反射植入机制的编译器」· CC 代码 · 共 3,111 行 · 第 1/5 页
CC
3,111 行
#if defined(_MSC_VER) || t == INT64#endif ){ Token tk; Ptree* kw; lex->GetToken(tk); switch(t){ case CHAR : type = 'c'; kw = new LeafCHAR(tk); break;// !!! new case WCHAR : type = 'w'; // hope that is OK kw = new LeafWCHAR(tk); break; case INT :#if defined(_MSC_VER) case INT64 : // an int64 is *NOT* an int but...#endif if(type != 's' && type != 'l' && type != 'j' && type != 'r') type = 'i'; kw = new LeafINT(tk); break; case SHORT : type = 's'; kw = new LeafSHORT(tk); break; case LONG : if(type == 'l') type = 'j'; // long long else if(type == 'd') type = 'r'; // double long else type = 'l'; kw = new LeafLONG(tk); break; case SIGNED : flag = 'S'; kw = new LeafSIGNED(tk); break; case UNSIGNED : flag = 'U'; kw = new LeafUNSIGNED(tk); break; case FLOAT : type = 'f'; kw = new LeafFLOAT(tk); break; case DOUBLE : if(type == 'l') type = 'r'; // long double else type = 'd'; kw = new LeafDOUBLE(tk); break; case VOID : type = 'v'; kw = new LeafVOID(tk); break; case BOOLEAN : type = 'b'; kw = new LeafBOOLEAN(tk); break; default : errorLog_.Report( MopMsg(Msg::Fatal, "optIntegralTypeOrClassSpec()", "fatal")); kw = 0; break; } p = PtreeUtil::Snoc(p, kw); is_integral = true; } else break; } if(is_integral){ if(flag == 'S' && type != 'c') flag = ' '; if(flag != ' ') encode.Append(flag); if(type == ' ') type = 'i'; // signed, unsigned encode.Append(type); return true; } if(t == CLASS || t == STRUCT || t == UNION || t == UserKeyword) return rClassSpec(p, encode); else if(t == ENUM) return rEnumSpec(p, encode); else{ p = 0; return true; }}/* constructor.decl : '(' {arg.decl.list} ')' {cv.qualify} {throw.decl} {member.initializers} {'=' Constant}*/bool Parser::rConstructorDecl(Ptree*& constructor, Encoding& encode){ Token op, cp; Ptree *args, *cv, *throw_decl, *mi; if(lex->GetToken(op) != '(') return false; if(lex->LookAhead(0) == ')'){ args = 0; encode.StartFuncArgs(); encode.Void(); encode.EndFuncArgs(); } else if(!rArgDeclList(args, encode)) return false; lex->GetToken(cp); constructor = PtreeUtil::List(new Leaf(op), args, new Leaf(cp)); optCvQualify(cv); if(cv != 0){ encode.CvQualify(cv); constructor = PtreeUtil::Nconc(constructor, cv); } optThrowDecl(throw_decl); // ignore in this version if(lex->LookAhead(0) == ':') if(rMemberInitializers(mi)) constructor = PtreeUtil::Snoc(constructor, mi); else return false; if(lex->LookAhead(0) == '='){ Token eq, zero; lex->GetToken(eq); if(lex->GetToken(zero) != Constant) return false; constructor = PtreeUtil::Nconc(constructor, PtreeUtil::List(new Leaf(eq), new Leaf(zero))); } encode.NoReturnType(); return true;}/* throw.decl : THROW '(' (name {','})* {name} ')'*/bool Parser::optThrowDecl(Ptree*& throw_decl){ Token tk; int t; Ptree* p = 0; if(lex->LookAhead(0) == THROW){ lex->GetToken(tk); p = PtreeUtil::Snoc(p, new LeafReserved(tk)); if(lex->GetToken(tk) != '(') return false; p = PtreeUtil::Snoc(p, new Leaf(tk)); for(;;){ Ptree* q; Encoding encode; t = lex->LookAhead(0); if(t == '\0') return false; else if(t == ')') break; else if(rName(q, encode)) p = PtreeUtil::Snoc(p, q); else return false; if(lex->LookAhead(0) == ','){ lex->GetToken(tk); p = PtreeUtil::Snoc(p, new Leaf(tk)); } else break; } if(lex->GetToken(tk) != ')') return false; p = PtreeUtil::Snoc(p, new Leaf(tk)); } throw_decl = p; return true;}/* declarators : declarator.with.init (',' declarator.with.init)* is_statement changes the behavior of rArgDeclListOrInit().*/bool Parser::rDeclarators(Ptree*& decls, Encoding& type_encode, bool should_be_declarator, bool is_statement){ Ptree* d; Token tk; Encoding encode; decls = 0; for(;;){ encode.Reset(type_encode); if(!rDeclaratorWithInit(d, encode, should_be_declarator, is_statement)) return false; decls = PtreeUtil::Snoc(decls, d); if(lex->LookAhead(0) == ','){ lex->GetToken(tk); decls = PtreeUtil::Snoc(decls, new Leaf(tk)); } else return true; };}/* declarator.with.init : ':' expression | declarator {'=' initialize.expr | ':' expression}*/bool Parser::rDeclaratorWithInit(Ptree*& dw, Encoding& type_encode, bool should_be_declarator, bool is_statement){ Ptree *d, *e; Token tk; Encoding name_encode; if(lex->LookAhead(0) == ':'){ // bit field lex->GetToken(tk); if(!rExpression(e)) return false; dw = PtreeUtil::List(new Leaf(tk), e); return true; } else{ if(!rDeclarator(d, kDeclarator, false, type_encode, name_encode, should_be_declarator, is_statement)) return false; int t = lex->LookAhead(0); if(t == '='){ lex->GetToken(tk); if(!rInitializeExpr(e)) return false; dw = PtreeUtil::Nconc(d, PtreeUtil::List(new Leaf(tk), e)); return true; } else if(t == ':'){ // bit field lex->GetToken(tk); if(!rExpression(e)) return false; dw = PtreeUtil::Nconc(d, PtreeUtil::List(new Leaf(tk), e)); return true; } else{ dw = d; return true; } }}/* declarator : (ptr.operator)* (name | '(' declarator ')') ('[' comma.expression ']')* {func.args.or.init} func.args.or.init : '(' arg.decl.list.or.init ')' {cv.qualify} {throw.decl} {member.initializers} Note: We assume that '(' declarator ')' is followed by '(' or '['. This is to avoid accepting a function call F(x) as a pair of a type F and a declarator x. This assumption is ignored if should_be_declarator is true. Note: An argument declaration list and a function-style initializer take a different Ptree structure. e.g. int f(char) ==> .. [f ( [[[char] 0]] )] Point f(1) ==> .. [f [( [1] )]] Note: is_statement changes the behavior of rArgDeclListOrInit().*/bool Parser::rDeclarator(Ptree*& decl, DeclKind kind, bool recursive, Encoding& type_encode, Encoding& name_encode, bool should_be_declarator, bool is_statement){ return rDeclarator2(decl, kind, recursive, type_encode, name_encode, should_be_declarator, is_statement, 0);}bool Parser::rDeclarator2(Ptree*& decl, DeclKind kind, bool recursive, Encoding& type_encode, Encoding& name_encode, bool should_be_declarator, bool is_statement, Ptree** declared_name){ Encoding recursive_encode; Ptree *d; int t; bool recursive_decl = false; Ptree *declared_name0 = 0; if(declared_name == 0) declared_name = &declared_name0; if(!optPtrOperator(d, type_encode)) return false; t = lex->LookAhead(0); if(t == '('){ Token op, cp; Ptree* decl2; lex->GetToken(op); recursive_decl = true; if(!rDeclarator2(decl2, kind, true, recursive_encode, name_encode, true, false, declared_name)) return false; if(lex->GetToken(cp) != ')') return false; if(!should_be_declarator) if(kind == kDeclarator && d == 0){ t = lex->LookAhead(0); if(t != '[' && t != '(') return false; } d = PtreeUtil::Snoc(d, PtreeUtil::List(new Leaf(op), decl2, new Leaf(cp))); } else if(kind != kCastDeclarator && (kind == kDeclarator || t == Identifier || t == Scope)){ // if this is an argument declarator, "int (*)()" is valid. Ptree* name; if(rName(name, name_encode)) d = PtreeUtil::Snoc(d, name); else return false; *declared_name = name; } else name_encode.Clear(); // empty for(;;){ t = lex->LookAhead(0); if(t == '('){ // function Encoding args_encode; Token op, cp; Ptree *args, *cv, *throw_decl, *mi; bool is_args = true; lex->GetToken(op); if(lex->LookAhead(0) == ')'){ args = 0; args_encode.StartFuncArgs(); args_encode.Void(); args_encode.EndFuncArgs(); } else if(!rArgDeclListOrInit(args, is_args, args_encode, is_statement)) return false; if(lex->GetToken(cp) != ')') return false; if(is_args){ d = PtreeUtil::Nconc(d, PtreeUtil::List(new Leaf(op), args, new Leaf(cp))); optCvQualify(cv); if(cv != 0){ args_encode.CvQualify(cv); d = PtreeUtil::Nconc(d, cv); } } else d = PtreeUtil::Snoc(d, PtreeUtil::List(new Leaf(op), args, new Leaf(cp))); if(!args_encode.IsEmpty()) type_encode.Function(args_encode); optThrowDecl(throw_decl); // ignore in this version if(lex->LookAhead(0) == ':') if(rMemberInitializers(mi)) d = PtreeUtil::Snoc(d, mi); else return false; break; // "T f(int)(char)" is invalid. } else if(t == '['){ // array Token ob, cb; Ptree* expr; lex->GetToken(ob); if(lex->LookAhead(0) == ']') expr = 0; else if(!rCommaExpression(expr)) return false; if(lex->GetToken(cb) != ']') return false; type_encode.Array(); d = PtreeUtil::Nconc(d, PtreeUtil::List(new Leaf(ob), expr, new Leaf(cb))); } else break; } if(recursive_decl) type_encode.Recursion(recursive_encode); if(recursive) decl = d; else if(d == 0) decl = new PtreeDeclarator(type_encode.Get(), name_encode.Get(), *declared_name); else decl = new PtreeDeclarator(d, type_encode.Get(), name_encode.Get(), *declared_name); return true;}/* ptr.operator : (('*' | '&' | ptr.to.member) {cv.qualify})+*/bool Parser::optPtrOperator(Ptree*& ptrs, Encoding& encode){ ptrs = 0; for(;;){ int t = lex->LookAhead(0); if(t != '*' && t != '&' && !isPtrToMember(0)) break; else{ Ptree *op, *cv; if(t == '*' || t == '&'){ Token tk; lex->GetToken(tk); op = new Leaf(tk); encode.PtrOperator(t); } else if(!rPtrToMember(op, encode)) return false; ptrs = PtreeUtil::Snoc(ptrs, op); optCvQualify(cv); if(cv != 0){ ptrs = PtreeUtil::Nconc(ptrs, cv); encode.CvQualify(cv); } } } return true;}/* member.initializers : ':' member.init (',' member.init)**/bool Parser::rMemberInitializers(Ptree*& init){ Token tk; Ptree* m; if(lex->GetToken(tk) != ':') return false; init = PtreeUtil::List(new Leaf(tk)); if(!rMemberInit(m)) return false; init = PtreeUtil::Snoc(init, m); while(lex->LookAhead(0) == ','){ lex->GetToken(tk); init = PtreeUtil::Snoc(init, new Leaf(tk)); if(!rMemberInit(m)) return false; init = PtreeUtil::Snoc(init, m); } return true;}/* member.init : name '(' function.arguments ')'*/bool Parser::rMemberInit(Ptree*& init){ Ptree *name, *args; Token tk1, tk2; Encoding encode; if(!rName(name, encode)) return false; if(!name->IsLeaf()) name = new PtreeName(name, encode.Get()); if(lex->GetToken(tk1) != '(') return false; if(!rFunctionArguments(args)) return false; if(lex->GetToken(tk2) != ')') return false; init = PtreeUtil::List(name, new Leaf(tk1), args, new Leaf(tk2)); return true;}/* name : {'::'} name2 ('::' name2)* name2 : Identifier {template.args} | '~' Identifier | OPERATOR operator.name {template.args} Don't use this function for parsing an expression It always regards '<' as the beginning of template arguments.*/bool Parser::rName(Ptree*& name, Encoding& encode){ Token tk, tk2; int t; int length = 0; if(lex->LookAhead(0) == Scope){ lex->GetToken(tk); name = PtreeUtil::List(new Leaf(tk)); encode.GlobalScope(); ++length; } else { name = 0; // gcc keyword typeof(rName) means type of the given name if(lex->LookAhead(0) == TYPEOF){ t = lex->GetToken(tk); if ((t = lex->GetToken(tk2)) != '(') return false; Ptree* type = PtreeUtil::List(new Leaf(tk2)); Encoding name_encode; if (!rName(name, name_encode)) return false; if (!name->IsLeaf()) name = new PtreeName(name, name_encode.Get()); else name = new PtreeName(PtreeUtil::List(name), name_encode.Get()); type = PtreeUtil::Snoc(type, name); if ((t = lex->GetToken(tk2)) != ')') return false; type = PtreeUtil::Snoc(type, new Leaf(tk2)); name = new PtreeTypeofExpr(new Leaf(tk), type); return true; } } for(;;){ t = lex->GetToken(tk);#if 1 // proposed by Chalky (Stephen Davies) !!! if(t == TEMPLATE) { // Skip template token, next will be identifier t = lex->GetToken(tk); }#endif if(t == Identifier){ Ptree* n = new Leaf(tk); t = lex->LookAhead(0); if(t == '<'){ Ptree* args; Encoding args_encode; if(!rTemplateArgs(args, args_encode)) return false; encode.Template(n, args_encode); ++length; n = PtreeUtil::List(n, args); t = lex->LookAhead(0); } else{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?