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

📄 parse.cpp

📁 用Qt4编写的linux IDE开发环境
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************************************** * PROGRAM	  :  * DATE - TIME  : lundi 10 avril 2006 - 22:28 * AUTHOR	   : IComplete Team and Anacr0x ( fred.julian at gmail.com ) * FILENAME	 :  * LICENSE	  : GPL * COMMENTARY   : Modified file (with qt) of the icomplete project ********************************************************************************************************/#include <QRegExp>#include <QFile>#include <QProcess>#include <QDebug>#include "parse.h"#include "tree.h"#define QD qDebug() << __FILE__ << __LINE__ << ":"extern QString simplifiedText( QString );char* Parse::scanForIdent(const char **expr){	static char ident[256];	int valid_chars = 0;	/* number of identified characters in the ident string */	char c;	while ((c = **expr) != '\0')	{		if (valid_chars == 0 && isspace(c))		{			(*expr)++;			continue;		}		// XXX: Namespace support		else if (isalpha(c) || c == '_')	// ???: || c == ':')		{			ident[valid_chars] = c;			if (++valid_chars == 255)			{				ident[255] = '\0';				return ident;			}		}		/* a digit may be part of an ident but not from the start */		else if (isdigit(c))		{			if (valid_chars)			{				ident[valid_chars] = c;				if (++valid_chars == 255)				{					ident[255] = '\0';					return ident;				}			}			else				return NULL;		}		else			break;		(*expr)++;	}	if (valid_chars)	{		ident[valid_chars] = '\0';		return ident;	}	else		return NULL;}bool Parse::scanForFuncdef(const QString &expr){	const char *pExpr = expr.toAscii();	char c;	while ((c = *pExpr) != '\0')	{		switch (c)		{		case ' ':		case '\t':		case '\n':			pExpr++;			continue;		case '(':			return true;		default:			return false;		}	}	return false;}QString Parse::getTypeOfToken(const QString &ident, const QString &className,                              Scope * scope, bool token_is_function){	/* if we have a variable and already found a local definition, just return it after duplicating */	if (!token_is_function && scope->localdef.length() && ident!="this")		return scope->localdef;	/* if the identifier is this-> return the current class */	if (ident == "this")	{		return scope->scope;	}	Tree *tree = NULL;	if (className.length())	{		tree = Tree::buildInheritanceTree(className);		if (!tree)			return NULL;	}	tagFileInfo info;	tagEntry entry;	tagFile *tfile = tagsOpen(tagsFilePath.toAscii(), &info);	if (tfile && info.status.opened)	{		if (tagsFind(tfile, &entry, ident.toAscii(), TAG_OBSERVECASE | TAG_FULLMATCH) ==		        TagSuccess)		{			do			{				if (tree && !tree->isMemberOfScope(&entry, scope))					continue;				const char *kind = tagsField(&entry, "kind");				if (token_is_function)	/* only list if tag is a function */				{					if (!kind					        || (strcmp(kind, "function") && strcmp(kind, "prototype")))						continue;				}				else		/* or a variable */				{					//brc: add externvar for extern variables like cout					if (!kind					        || (strcmp(kind, "variable") && strcmp(kind, "externvar")					            //brc: namespace workarround: add namespace					            && strcmp(kind, "namespace") && strcmp(kind, "member")))						continue;				}				/* need to duplicate the pattern, don't ask me why */				QString type = extractTypeQualifier(entry.address.pattern, ident);				if(tree)					tree->freeTree();				tagsClose(tfile);				return type;			}			while (tagsFindNext(tfile, &entry) == TagSuccess);		}		tagsClose(tfile);	}	return NULL;}QString Parse::extractTypeQualifier(const QString &str, const QString &varName){#define STRING      "\".*\""#define BRACKETEXPR "\\{.*\\}"//#define IDENT       "[a-zA-Z_][a-zA-Z0-9_]*"//#define IDENT       "[a-zA-Z_:][a-zA-Z0-9_:]*"#define IDENT       "[a-zA-Z_:][a-zA-Z0-9_:]*"#define WS          "[ \t\r\n]*"#define PTR         "[\\*&]?\\*?"#define INITIALIZER "=(" WS IDENT WS ")|=(" WS STRING WS ")|=(" WS BRACKETEXPR WS ")"#define CONSTRUCTOR "(\\(" WS IDENT WS "\\))|(\\(" WS STRING WS "\\))"#define ARRAY       WS "\\[" WS "[0-9]*" WS "\\]" WS	QString pattern = "(" IDENT ")"				// the 'std' in example a)	                  "(::" IDENT ")*"			// ::vector	                  "(" WS "<[^>;]*>)?[ \t\n*&]{1}"	// <char *>	                  "(" WS PTR WS IDENT WS "(" ARRAY ")*" WS "((" INITIALIZER ")?|(" CONSTRUCTOR ")?)" WS "," WS ")*" // other variables for the same ident (string i,j,k;)	                  "(" WS "[*&])?";			// check again for pointer/reference type	QRegExp rx(pattern + WS + varName + "[^.-\\w]");	if( varName.isEmpty() )		return QString();	QString text = simplifiedText( str );	int pos = -1;	int begin = -1;	while( (pos = text.lastIndexOf(varName, begin) ) != -1 )	{		begin = pos;		while( begin>0 && text.at(begin)!= '\n' )			begin--;		int end = pos;		while( end<text.length()-1 && text.at(end)!= '\n' )			end++;		QString line = text.mid(begin, end-begin).simplified();		if( !line.isEmpty() )		{			int pos2 = 0;			while ((pos2 = rx.indexIn(line, pos2)) != -1)			{				if( !QString("|delete|else|endif|throw|return|").contains( "|"+rx.cap(1)+"|" ) && rx.cap(1)!=":")				{					return rx.cap(1);				}				pos2 += rx.matchedLength();			}		}	}	return QString();}bool Parse::getTypeOfExpression(const QString &expr, Expression * exp, Scope * scope){	char *ident = NULL;	/* very basic stack implementation to keep track of tokens */	const int max_items = 20;	const char *stack[max_items];	int num_stack = 0;	/* skip nested brackets */	int brackets = 0, square_brackets = 0;	bool in_ident = false;	/* if the current position is within an identifier */	bool extract_ident = false;	/* if we extract the next string which looks like an identifier - only after: . -> and ( */	QByteArray array(expr.toLocal8Bit() ); 	if( !array.count() ) 		return false; 	unsigned long len = array.length(); 	const char *first = array.data(), *start = first + len;	while (--start >= first && start < (first + len) ) 	{		/* skip brackets */		if (brackets > 0 || square_brackets > 0)		{			if (*start == '(')				--brackets;			else if (*start == ')')				++brackets;			else if (*start == '[')				--square_brackets;			else if (*start == ']')				++square_brackets;			continue;		}		/* identifier */		if (isdigit(*start))			in_ident = false;		else if (isalpha(*start) || *start == '_')			in_ident = true;		else		{			switch (*start)			{				/* skip whitespace */			case ' ':			case '\t':				if (in_ident)					goto extract;				else				{					in_ident = false;					continue;				}				/* continue searching to the left, if we				 * have a . or -> accessor */			case '.':				if (in_ident && extract_ident)				{					const char *ident = start + 1;					if (num_stack < max_items)						stack[num_stack++] = ident;					else						return false;				}				in_ident = false;				extract_ident = true;				continue;			case '>':		/* pointer access */			case ':':		/* static access */				if ((*start == '>' && (start - 1 >= first && *(start - 1) == '-'))				        || (*start == ':'				            && (start - 1 >= first && *(start - 1) == ':')))				{										if (in_ident && extract_ident)					{						const char *ident = start + 1;						if (num_stack < max_items)							stack[num_stack++] = ident;						else							return false;					}					in_ident = false;					extract_ident = true;					--start;					continue;				}				else				{					start++;					goto extract;				}			case '(':		/* start of a function */				if (extract_ident)				{					start++;					goto extract;				}				else				{					extract_ident = true;					in_ident = false;					break;				}			case ')':				if (in_ident)	/* probably a cast - (const char*)str */				{					start++;					goto extract;				}				brackets++;				break;

⌨️ 快捷键说明

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