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 + -
显示快捷键?