parser.cc
来自「这个程序是关于OpenC++的反射植入机制的编译器」· CC 代码 · 共 3,111 行 · 第 1/5 页
CC
3,111 行
encode.SimpleName(n); ++length; } if(t == Scope){ lex->GetToken(tk); name = PtreeUtil::Nconc(name, PtreeUtil::List(n, new Leaf(tk))); } else{ if(name == 0) name = n; else name = PtreeUtil::Snoc(name, n); if(length > 1) encode.Qualified(length); return true; } } else if(t == '~'){ if(lex->LookAhead(0) != Identifier) return false; lex->GetToken(tk2); Ptree* class_name = new Leaf(tk2); Ptree* dt = PtreeUtil::List(new Leaf(tk), class_name); if(name == 0) name = dt; else name = PtreeUtil::Snoc(name, dt); encode.Destructor(class_name); if(length > 0) encode.Qualified(length + 1); return true; } else if(t == OPERATOR){ Ptree* op; Ptree* opf; if(!rOperatorName(op, encode)) return false; t = lex->LookAhead(0); if(t != '<') opf = PtreeUtil::List(new LeafReserved(tk), op); else { Ptree* args; Encoding args_encode; if(!rTemplateArgs(args, args_encode)) return false; // here, I must merge args_encode into encode. // I'll do it in future. :p opf = PtreeUtil::List(new LeafReserved(tk), op, args); } if(name == 0) name = opf; else name = PtreeUtil::Snoc(name, opf); if(length > 0) encode.Qualified(length + 1); return true; } else return false; }}/* operator.name : '+' | '-' | '*' | '/' | '%' | '^' | '&' | '|' | '~' | '!' | '=' | '<' | '>' | AssignOp | ShiftOp | EqualOp | RelOp | LogAndOp | LogOrOp | IncOp | ',' | PmOp | ArrowOp | NEW {'[' ']'} | DELETE {'[' ']'} | '(' ')' | '[' ']' | cast.operator.name*/bool Parser::rOperatorName(Ptree*& name, Encoding& encode){ Token tk; int t = lex->LookAhead(0); if(t == '+' || t == '-' || t == '*' || t == '/' || t == '%' || t == '^' || t == '&' || t == '|' || t == '~' || t == '!' || t == '=' || t == '<' || t == '>' || t == AssignOp || t == ShiftOp || t == EqualOp || t == RelOp || t == LogAndOp || t == LogOrOp || t == IncOp || t == ',' || t == PmOp || t == ArrowOp){ lex->GetToken(tk); name = new Leaf(tk); encode.SimpleName(name); return true; } else if(t == NEW || t == DELETE){ lex->GetToken(tk); if(lex->LookAhead(0) != '['){ name = new LeafReserved(tk); encode.SimpleName(name); return true; } else{ name = PtreeUtil::List(new LeafReserved(tk)); lex->GetToken(tk); name = PtreeUtil::Snoc(name, new Leaf(tk)); if(lex->GetToken(tk) != ']') return false; name = PtreeUtil::Snoc(name, new Leaf(tk)); if(t == NEW) encode.AppendWithLen("new[]", 5); else encode.AppendWithLen("delete[]", 8); return true; } } else if(t == '('){ lex->GetToken(tk); name = PtreeUtil::List(new Leaf(tk)); if(lex->GetToken(tk) != ')') return false; encode.AppendWithLen("()", 2); name = PtreeUtil::Snoc(name, new Leaf(tk)); return true; } else if(t == '['){ lex->GetToken(tk); name = PtreeUtil::List(new Leaf(tk)); if(lex->GetToken(tk) != ']') return false; encode.AppendWithLen("[]", 2); name = PtreeUtil::Snoc(name, new Leaf(tk)); return true; } else return rCastOperatorName(name, encode);}/* cast.operator.name : {cv.qualify} (integral.type.or.class.spec | name) {cv.qualify} {(ptr.operator)*}*/bool Parser::rCastOperatorName(Ptree*& name, Encoding& encode){ Ptree *cv1, *cv2, *type_name, *ptr; Encoding type_encode; if(!optCvQualify(cv1)) return false; if(!optIntegralTypeOrClassSpec(type_name, type_encode)) return false; if(type_name == 0){ type_encode.Clear(); if(!rName(type_name, type_encode)) return false; } if(!optCvQualify(cv2)) return false; if(cv1 != 0) if(cv2 == 0) type_name = PtreeUtil::Snoc(cv1, type_name); else type_name = PtreeUtil::Nconc(cv1, PtreeUtil::Cons(type_name, cv2)); else if(cv2 != 0) type_name = PtreeUtil::Cons(type_name, cv2); type_encode.CvQualify(cv1, cv2); if(!optPtrOperator(ptr, type_encode)) return false; encode.CastOperator(type_encode); if(ptr == 0){ name = type_name; return true; } else{ name = PtreeUtil::List(type_name, ptr); return true; }}/* ptr.to.member : {'::'} (identifier {template.args} '::')+ '*'*/bool Parser::rPtrToMember(Ptree*& ptr_to_mem, Encoding& encode){ Token tk; Ptree *p, *n; Encoding pm_encode; int length = 0; if(lex->LookAhead(0) == Scope){ lex->GetToken(tk); p = PtreeUtil::List(new Leaf(tk)); pm_encode.GlobalScope(); ++length; } else p = 0; for(;;){ if(lex->GetToken(tk) == Identifier) n = new Leaf(tk); else return false; int t = lex->LookAhead(0); if(t == '<'){ Ptree* args; Encoding args_encode; if(!rTemplateArgs(args, args_encode)) return false; pm_encode.Template(n, args_encode); ++length; n = PtreeUtil::List(n, args); t = lex->LookAhead(0); } else{ pm_encode.SimpleName(n); ++length; } if(lex->GetToken(tk) != Scope) return false; p = PtreeUtil::Nconc(p, PtreeUtil::List(n, new Leaf(tk))); if(lex->LookAhead(0) == '*'){ lex->GetToken(tk); p = PtreeUtil::Snoc(p, new Leaf(tk)); break; } } ptr_to_mem = p; encode.PtrToMember(pm_encode, length); return true;}/* template.args : '<' '>' | '<' template.argument {',' template.argument} '>' template.argument : type.name | logical.or.expr*/bool Parser::rTemplateArgs(Ptree*& temp_args, Encoding& encode){ Token tk1, tk2; Encoding type_encode; if(lex->GetToken(tk1) != '<') return false; // in case of Foo<> if(lex->LookAhead(0) == '>') { lex->GetToken(tk2); temp_args = PtreeUtil::List(new Leaf(tk1), new Leaf(tk2)); return true; } Ptree* args = 0; for(;;){ Ptree* a; char* pos = lex->Save(); type_encode.Clear(); if(rTypeName(a, type_encode)) encode.Append(type_encode); else{ lex->Restore(pos); if(!rLogicalOrExpr(a, true)) return false; encode.ValueTempParam(); } args = PtreeUtil::Snoc(args, a); switch(lex->GetToken(tk2)){ case '>' : temp_args = PtreeUtil::List(new Leaf(tk1), args, new Leaf(tk2)); return true; case ',' : args = PtreeUtil::Snoc(args, new Leaf(tk2)); break; case ShiftOp : if(*tk2.ptr == '>'){ lex->GetOnlyClosingBracket(tk2); temp_args = PtreeUtil::List(new Leaf(tk1), args, new Leaf(tk2.ptr, 1)); return true; } default : return false; } }}/* arg.decl.list.or.init : arg.decl.list | function.arguments This rule accepts function.arguments to parse declarations like: Point p(1, 3); "(1, 3)" is arg.decl.list.or.init. If maybe_init is true, we first examine whether tokens construct function.arguments. This ordering is significant if tokens are Point p(s, t); s and t can be type names or variable names.*/bool Parser::rArgDeclListOrInit(Ptree*& arglist, bool& is_args, Encoding& encode, bool maybe_init){ char* pos = lex->Save(); if(maybe_init) { if(rFunctionArguments(arglist)) if(lex->LookAhead(0) == ')') { is_args = false; encode.Clear(); return true; } lex->Restore(pos); return(is_args = rArgDeclList(arglist, encode)); } else if(is_args = rArgDeclList(arglist, encode)) return true; else{ lex->Restore(pos); encode.Clear(); return rFunctionArguments(arglist); }}/* arg.decl.list : empty | arg.declaration ( ',' arg.declaration )* {{ ',' } Ellipses}*/bool Parser::rArgDeclList(Ptree*& arglist, Encoding& encode){ Ptree* list; Ptree* d; int t; Token tk; Encoding arg_encode; encode.StartFuncArgs(); list = 0; for(;;){ arg_encode.Clear(); t = lex->LookAhead(0); if(t == ')'){ if(list == 0) encode.Void(); arglist = list; break; } else if(t == Ellipsis){ lex->GetToken(tk); encode.EllipsisArg(); arglist = PtreeUtil::Snoc(list, new Leaf(tk)); break; } else if(rArgDeclaration(d, arg_encode)){ encode.Append(arg_encode); list = PtreeUtil::Snoc(list, d); t = lex->LookAhead(0); if(t == ','){ lex->GetToken(tk); list = PtreeUtil::Snoc(list, new Leaf(tk)); } else if(t != ')' && t != Ellipsis) return false; } else{ arglist = 0; return false; } } encode.EndFuncArgs(); return true;}/* arg.declaration : {userdef.keyword | REGISTER} type.specifier arg.declarator {'=' initialize.expr}*/bool Parser::rArgDeclaration(Ptree*& decl, Encoding& encode){ Ptree *header, *type_name, *arg, *e; Token tk; Encoding name_encode; switch(lex->LookAhead(0)){ case REGISTER : lex->GetToken(tk); header = new LeafREGISTER(tk); break; case UserKeyword : if(!rUserdefKeyword(header)) return false; break; default : header = 0; break; } if(!rTypeSpecifier(type_name, true, encode)) return false; if(!rDeclarator(arg, kArgDeclarator, false, encode, name_encode, true)) return false; if(header == 0) decl = PtreeUtil::List(type_name, arg); else decl = PtreeUtil::List(header, type_name, arg); int t = lex->LookAhead(0); if(t == '='){ lex->GetToken(tk); if(!rInitializeExpr(e)) return false; decl = PtreeUtil::Nconc(decl, PtreeUtil::List(new Leaf(tk), e)); } return true;}/* initialize.expr : expression | '{' initialize.expr (',' initialize.expr)* {','} '}'*/bool Parser::rInitializeExpr(Ptree*& exp){ Token tk; Ptree *e, *elist; if(lex->LookAhead(0) != '{') return rExpression(exp); else{ lex->GetToken(tk); Ptree* ob = new Leaf(tk); elist = 0; int t = lex->LookAhead(0); while(t != '}'){ if(!rInitializeExpr(e)){ if(!SyntaxError()) return false; // too many errors SkipTo('}'); lex->GetToken(tk); exp = PtreeUtil::List(ob, 0, new Leaf(tk)); return true; // error recovery } elist = PtreeUtil::Snoc(elist, e); t = lex->LookAhead(0); if(t == '}') break; else if(t == ','){ lex->GetToken(tk); elist = PtreeUtil::Snoc(elist, new Leaf(tk)); t = lex->LookAhead(0); } else{ if(!SyntaxError()) return false; // too many errors SkipTo('}'); lex->GetToken(tk); exp = PtreeUtil::List(ob, 0, new Leaf(tk)); return true; // error recovery } } lex->GetToken(tk); exp = new PtreeBrace(ob, elist, new Leaf(tk)); return true; }}/* function.arguments : empty | expression (',' expression)* This assumes that the next token following function.arguments is ')'.*/bool Parser::rFunctionArguments(Ptree*& args){ Ptree* exp; Token tk; args = 0; if(lex->LookAhead(0) == ')') return true; for(;;){ if(!rExpression(exp)) return false; args = PtreeUtil::Snoc(args, exp); if(lex->LookAhead(0) != ',') return true; else{ lex->GetToken(tk); args = PtreeUtil::Snoc(args, new Leaf(tk)); } }}/* enum.spec : ENUM Identifier | ENUM {Identifier} '{' {enum.body} '}'*/bool Parser::rEnumSpec(Ptree*& spec, Encoding& encode){ Token tk, tk2; Ptree* body; if(lex->GetToken(tk) != ENUM) return false; spec = new PtreeEnumSpec(new Leaf(tk)); int t = lex->GetToken(tk); if(t == Identifier){ Ptree* name = new Leaf(tk); encode.SimpleName(name); ((PtreeEnumSpec*)spec)->encoded_name = encode.Get(); spec = PtreeUtil::Snoc(spec, name); if(lex->LookAhead(0) == '{') t = lex->GetToken(tk); else return true; } else{ encode.NoName(); ((PtreeEnumSpec*)spec)->encoded_name = encode.Get(); spec = PtreeUtil::Snoc(spec, 0); } if(t != '{') return false; if(lex->LookAhead(0) == '}') body = 0; else if(!rEnumBody(body)) return false; if(lex->GetToken(tk2) != '}') return false; spec = PtreeUtil::Snoc(spec, new PtreeBrace(new Leaf(tk), body, new Leaf(tk2))); return true;}/* enum.body : Identifier {'=' expression} (',' Identifier {'=' expression})* {','}*/bool Parser::rEnumBody(Ptree*& body){ Token tk, tk2; Ptree *name, *exp; body = 0; for(;;){ if(lex->LookAhead(0) == '}') return true; if(lex->GetToken(tk) != Identifier) return false; if(lex->LookAhead(0, tk2) != '=') name = new Leaf(tk); else{ lex->GetToken(tk2); if(!rExpression(exp)){ if(!SyntaxError()) return false; // too many errors SkipTo('}'); body = 0; // empty return true; // error recovery } name = PtreeUtil::List(new Leaf(tk), new Leaf(tk2), exp); } if(lex->LookAhead(0) != ','){ body = PtreeUtil::Snoc(body, name); return true;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?