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