⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.cpp

📁 用Qt4编写的linux IDE开发环境
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			case ']':				if (in_ident)				{					start++;					goto extract;				}				square_brackets++;				break;			default:				start++;				goto extract;			}		}	}extract:	/* ident is the leftmost token, stack[*] the ones to the right	 * Example: str.left(2,5).toUpper()	 *          ^^^ ^^^^      ^^^^^^^	 *        ident stack[1]  stack[0]	 */	ident = scanForIdent(&start);	if (!ident)		return false;	/* we need this little kludge with old_type to avoid mem leaks */	QString type, old_type;	/* for static access, parsing is done, just return the identifier */	if (exp->access != AccessStatic)	{		QString saved_start = start;	// start can change, so we save it		getScopeAndLocals(scope, expr, ident);		/* if we have the start of a function/method, don't return the type		 * of this function, but className, which it is member of */		type = getTypeOfToken(ident, NULL, scope, scanForFuncdef(saved_start));		/* members can't be local variables */		scope->localdef[0] = '\0';		while (type!="" && num_stack > 0)		{			ident = scanForIdent(&stack[--num_stack]);			old_type = type;			//<brc code>: namespace workaround: if the "type" of an identifier is namespace ignore it			if (type == "namespace")				old_type = "";			//<\end brc code>			type = getTypeOfToken(ident, old_type.toAscii(), scope,			                      scanForFuncdef(stack[num_stack]));		}	}	else			/* static member */		type = ident;	/* copy result into passed Expression argument */	if (type!="" && !(exp->access == AccessInFunction))	{		exp->className = type;		exp->function[0] = '\0';		return true;	}	else if (exp->access == AccessInFunction)	{		exp->className = old_type;		exp->function = ident;		return true;	}	return false;}Expression Parse::parseExpression(QString expression, Scope * scope, bool showAllResults){	Expression exp;	exp.access = ParseError;	int len = expression.length();	if (len < 1)		return exp;	// we found that the user has beginning to write	if(!showAllResults)	{        QByteArray array(expression.toLocal8Bit() );         if( !array.count() )         	return exp;         const char *start = array.data(), *p = start;		//const char *start = expression.toLocal8Bit(), *p = start;		while (*p)			p++;		p--;		while (p != start && *p != '.' && *p != '\n' && *p != '\r' && *p != ' ' && *p != '\t' && *p != ';' && *p != '{' && *p != '}' && *p != '(' && *p != ',' && (p-1) != start && (*p != '>' || *(p - 1) != '-') && (*p != ':' || *(p - 1) != ':'))			p--;		exp.writing = p+1;	}	/* A global function should be completed, if nothing else is found */	exp.access = AccessGlobal;	bool allow_AccessInFunction = true;	// false, when other characters than whitespace were typed	/* search for the type of the correct completion */	while (--len >= 0)	{		char last = ((const char*)expression.toAscii())[len];		switch (last)		{		case ' ':		case '\t':			/* skip initial spaces */			if (exp.access == AccessGlobal)			{				/*                    exp.access = ParseError;*/				continue;			}			else			{				exp.access = AccessGlobal;				goto extract;			}		case '>':			if (len && expression[len - 1] == '-')			{				exp.access = AccessPointer;				expression[len + 1] = '\0';	/* truncate the string */				goto extract;			}			else			{				exp.access = AccessGlobal;	/* XXX: AccessError ? */				goto extract;			}		case '.':			exp.access = AccessMembers;			expression[len + 1] = '\0';	/* truncate the string */			goto extract;		case ':':			if (len && expression[len - 1] == ':')			{				exp.access = AccessStatic;				expression[len + 1] = '\0';	/* truncate the string */				goto extract;			}			else			{				exp.access = AccessGlobal;				goto extract;			}		case '(':			if (allow_AccessInFunction)			{				exp.access = AccessInFunction;				expression[len + 1] = '\0';	/* truncate the string */			}			goto extract;		default:			if (isalpha(last) || last == '_')			{				/* we only list function definitions if after the opening				 * ( bracket of the function is no identifier */				allow_AccessInFunction = false;				break;			}			else				goto extract;		}	}extract:	/* now extract the type out of the string */	if (exp.access == AccessMembers || exp.access == AccessPointer	        || exp.access == AccessStatic || exp.access == AccessInFunction)	{		if (!getTypeOfExpression(expression.toAscii(), &exp, scope))			exp.access = ParseError;	}	else if (exp.access == AccessGlobal)		getScopeAndLocals(scope, expression.toAscii(), NULL);	return exp;}Tag Parse::prettifyTag(const tagEntry * entry){	Tag tag;	tag.name = entry->name;	tag.kind = tagsField(entry, "kind");	tag.access = tagsField(entry, "access");	tag.signature = tagsField(entry, "signature");	tag.isFunction = (tag.signature.length());	char *p = (char *) entry->address.pattern;	/* for a macro the pattern is already parsed */	if (tag.kind == "macro")	{		/* NOTE: exuberant-ctags 5.5.4 does not provide a valid pattern for found macros		 * work around it, by getting the line myself */		char pat_macro[512];		unsigned long line = entry->address.lineNumber;		if (line == 0)		/* sometimes ctags can't find the correct line */			return tag;		FILE *fileMacro = fopen(entry->file, "r");		if (fileMacro)		{			while ((p = fgets(pat_macro, 512, fileMacro)) != NULL)			{				line--;				if (line <= 0)				{					/* remove leading spaces */					p++;	/* skip over # - it is added later again */					while (*p == ' ' || *p == '\t')						p++;					tag.longName = '#' + p;					/* remove new line at the end */					tag.longName.remove(tag.longName.length() - 1, 1);					break;				}			}			tag.longName += " [macro]";			fclose(fileMacro);			return tag;		}	}	/* special handling for enumerator */	if (tag.kind == "enumerator")	{		/* skip whitespace from variable/function patterns */		size_t skip = strspn(p, "/^ \t");		p += skip;		/* remove trailing $/ characters */		char *pos = NULL;		if ((pos = strstr(p, "$/")) != NULL)			*pos = '\0';		/* replace \/\/ and \/ * *\/ to correctly show comments */		while ((pos = strstr(p, "\\/\\/")) != NULL)			memcpy(pos, "  //", 4);		while ((pos = strstr(p, "\\/*")) != NULL)			memcpy(pos, " /*", 3);		while ((pos = strstr(p, "*\\/")) != NULL)			memcpy(pos, " */", 3);		tag.longName += QString(p) + " [enumerator]";		return tag;	}	size_t skip = strspn(p, "/^ \t");	p += skip;	/* remove trailing $/ characters */	char *pos = NULL;	if ((pos = strstr(p, "$/")) != NULL)		*pos = '\0';	tag.longName += p;	/* if it is a function, add signature as well */	if (tag.signature.length())		tag.parameters += tag.signature;	if (tag.access.length() && tag.access == "private" || tag.access == "protected")		tag.longName += '[' + tag.access + ']';	return tag;}bool Parse::getScopeAndLocals(Scope * sc, const QString &expr, const QString &ident){	// initialize scope if nothing better is found	sc->scope = "";	sc->localdef = "";	/* create a tags file for `expr' with function names only.	 * The function with the highest line number is our valid scope	 * --sort=no, because tags generation probably faster, and	 * so I just have to look for the last entry to find 'my' tag	 */	QString command =	    ctagsCmdPath +	    " --language-force=c++ --sort=no --fields=fKmnsz --c++-kinds=fn -o \"" +	    smallTagsFilePath + "\" \"" + parsedFilePath + '\"';	// I don't process any user input, so system() should be safe enough	QProcess ctags;	ctags.execute(command);	QFile::remove (parsedFilePath);	if (ctags.exitStatus() == QProcess::CrashExit)		return false;	/* find the last entry, this is our current scope */	tagFileInfo info;	tagFile *tfile = tagsOpen(smallTagsFilePath.toAscii(), &info);	tagEntry entry;	const char *scope = NULL;	if (tfile && info.status.opened)	{		if (tagsFirst(tfile, &entry) == TagSuccess)		{			do				scope = tagsField(&entry, "class");			while (tagsNext(tfile, &entry) == TagSuccess);		}		tagsClose(tfile);	}	/* must be before the 'type = extract_type_qualifier()' code, which modifies scope */	if (scope)		sc->scope = scope;	/* get local definition (if any) */	if (ident!="")	{		QString type = extractTypeQualifier(expr, ident);		if (type.length())		{			sc->localdef = type;		}		else			sc->localdef = "";	}	QFile::remove (smallTagsFilePath); 		return true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -