- enhancement: Improve parsing for operator overloading.

This commit is contained in:
Roy Qu 2023-02-06 14:04:38 +08:00
parent 7085318197
commit 4fc3900796
5 changed files with 298 additions and 315 deletions

View File

@ -2,7 +2,8 @@ Red Panda C++ Version 2.11
- fix: Can't correctly handle definitions for "operator,"
- enhancement: Auto suggest keyword "operator" when define functions.
- fix: Differentiate class and constructors.
- enhancement: Differentiate class and constructors in syntax color and jupming to declarations.
- enhancement: Improve parsing for operator overloading.
Red Panda C++ Version 2.10

View File

@ -1463,8 +1463,8 @@ void CppParser::addSoloScopeLevel(PStatement& statement, int line, bool shouldRe
mClassScope = StatementClassScope::Public; // structs are public by default
mCurrentClassScope.append(mClassScope);
#ifdef QT_DEBUG
// if (mCurrentClassScope.count()==2)
// qDebug()<<"++add scope"<<mCurrentFile<<line<<mCurrentClassScope.count();
if (mCurrentClassScope.count()<=2)
qDebug()<<"++add scope"<<mCurrentFile<<line<<mCurrentClassScope.count();
#endif
}
@ -1474,8 +1474,8 @@ void CppParser::removeScopeLevel(int line)
if (mCurrentScope.isEmpty())
return; // TODO: should be an exception
#ifdef QT_DEBUG
// if (mCurrentClassScope.count()==2)
// qDebug()<<"--remove scope"<<mCurrentFile<<line<<mCurrentClassScope.count();
if (mCurrentClassScope.count()<=2)
qDebug()<<"--remove scope"<<mCurrentFile<<line<<mCurrentClassScope.count();
#endif
PStatement currentScope = getCurrentScope();
PFileIncludes fileIncludes = mPreprocessor.includesList().value(mCurrentFile);
@ -1603,123 +1603,6 @@ bool CppParser::checkForKeyword(KeywordType& keywordType)
}
}
bool CppParser::checkForMethod(QString &sType, QString &sName, int &argStartIndex,
int &argEndIndex, bool &isStatic, bool &isFriend)
{
PStatement scope = getCurrentScope();
if (scope && !(scope->kind == StatementKind::skNamespace
|| scope->kind == StatementKind::skClass)) { //don't care function declaration in the function's
return false;
}
// Function template:
// compiler directives (>= 0 words), added to type
// type (>= 1 words)
// name (1 word)
// (argument list)
// ; or {
isStatic = false;
isFriend = false;
sType = ""; // should contain type "int"
sName = ""; // should contain function name "foo::function"
bool bTypeOK = false;
bool bNameOK = false;
bool bArgsOK = false;
// Don't modify index
int indexBackup = mIndex;
// Gather data for the string parts
while ((mIndex < mTokenizer.tokenCount()) && !isSeperator(mTokenizer[mIndex]->text[0])) {
if ((mIndex + 1 < mTokenizer.tokenCount())
&& (mTokenizer[mIndex + 1]->text == '(')) { // and start of a function
int indexAfter = mTokenizer[mIndex + 1]->matchIndex+1;
//it's not a function define
if (indexAfter>=mTokenizer.tokenCount())
break;
//it's not a function define;
if (isInvalidFunctionArgsSuffixChar(mTokenizer[indexAfter]->text[0]))
break;
//it's not a function define
if (mTokenizer[indexAfter]->text[0] == ';') {
//function can only be defined in global/namespaces/classes
PStatement currentScope=getCurrentScope();
if (currentScope) {
//in namespace, it might be function or object initilization
if (currentScope->kind == StatementKind::skNamespace
&& isNotFuncArgs(mIndex + 1)) {
break;
//not in class, it can't be a valid function definition
} else if (currentScope->kind != StatementKind::skClass)
break;
//variable can't be initialized in class definition, it must be a function
} else if (isNotFuncArgs(mIndex + 1))
break;
}
sName = mTokenizer[mIndex]->text;
argStartIndex = mIndex+1;
argEndIndex = mTokenizer[mIndex + 1]->matchIndex;
bTypeOK = !sType.isEmpty();
bNameOK = !sName.isEmpty();
bArgsOK = true;
// Allow constructor/destructor too
if (!bTypeOK) {
// Check for constructor/destructor outside class body
int delimPos = sName.lastIndexOf("::");
if (delimPos >= 0) {
bTypeOK = true;
sType = sName.mid(0, delimPos);
// remove template staff
int pos1 = sType.indexOf('<');
if (pos1>=0) {
sType.truncate(pos1);
sName = sType+sName.mid(delimPos);
}
}
}
// Are we inside a class body?
if (!bTypeOK) {
sType = mTokenizer[mIndex]->text;
if (sType[0] == '~')
sType.remove(0,1);
bTypeOK = isCurrentScope(sType); // constructor/destructor
}
mIndex = argEndIndex+1;
break;
} else {
//if IsValidIdentifier(mTokenizer[mIndex]->text) then
// Still walking through type
QString s = mTokenizer[mIndex]->text;
if (s == "static")
isStatic = true;
if (s == "friend")
isFriend = true;
if (!s.isEmpty() && !(s=="extern"))
sType = sType + ' '+ s;
bTypeOK = !sType.isEmpty();
}
mIndex++;
}
// Correct function, don't jump over
if (bTypeOK && bNameOK && bArgsOK) {
sType = sType.trimmed(); // should contain type "int"
sName = sName.trimmed(); // should contain function name "foo::function"
return true;
} else {
mIndex = indexBackup;
return false;
}
}
bool CppParser::checkForNamespace(KeywordType keywordType)
{
return (keywordType==KeywordType::Namespace &&(mIndex < mTokenizer.tokenCount()-1))
@ -1862,23 +1745,24 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
handleMethod(StatementKind::skFunction,"",
mergeArgs(mIndex+1,mTokenizer[mIndex]->matchIndex-1),
indexAfterParentheis,false,false);
} else if (currentText.endsWith("::operator")) {
mIndex=indexAfterParentheis;
handleMethod(StatementKind::skFunction,"",
mergeArgs(mIndex+1,mTokenizer[mIndex]->matchIndex-1),
indexAfterParentheis,false,false);
// } else if (currentText.endsWith("::operator")) {
// mIndex=indexAfterParentheis;
// handleMethod(StatementKind::skFunction,"",
// mergeArgs(mIndex+1,mTokenizer[mIndex]->matchIndex-1),
// indexAfterParentheis,false,false);
} else {
//function pointer var
handleVar(currentText,false,false);
}
} else {
if (currentText.startsWith("operator")
&& currentText.length()>8
&& !isIdentChar(currentText[8])) {
if (currentText=="operator") {
// operator overloading
handleMethod(StatementKind::skFunction,"",
handleOperatorOverloading(
"",
currentText,
mIndex,false,false);
mIndex,
false,
false);
return;
}
//check for constructor like Foo::Foo()
@ -1918,6 +1802,7 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
}
} else if (mTokenizer[mIndex]->text.startsWith('*')
|| mTokenizer[mIndex]->text.startsWith('&')
|| mTokenizer[mIndex]->text.startsWith("::")
|| tokenIsIdentifier(mTokenizer[mIndex]->text)
) {
// it should be function/var
@ -1926,15 +1811,31 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
bool isFriend = false;
bool isExtern = false;
QString sType = currentText; // should contain type "int"
QString sName = ""; // should contain function name "foo::function"
QString sType; // should contain type "int"
QString sName; // should contain function name "foo::function"
if (mTokenizer[mIndex]->text=="::") {
mIndex--;
} else {
if (currentText=="::") {
sName = currentText;
} else {
sType = currentText;
}
}
// Gather data for the string parts
while (mIndex+1 < mTokenizer.tokenCount()) {
if (mTokenizer[mIndex + 1]->text == '(') {
if (mTokenizer[mIndex+2]->text == '*') {
if (mTokenizer[mIndex]->text=="operator") {
handleOperatorOverloading(sType,
sName,
mIndex,
isStatic,
isFriend);
return;
} else if (mTokenizer[mIndex + 1]->text == '(') {
if (mIndex+2<mTokenizer.tokenCount() && mTokenizer[mIndex+2]->text == '*') {
//foo(*blabla), it's a function pointer var
handleVar(sType,isExtern,isStatic);
handleVar(sType+" "+sName,isExtern,isStatic);
return;
}
@ -1946,28 +1847,15 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
}
//if it's like: foo(...)(...)
if (mTokenizer[indexAfter]->text=='(') {
if (mTokenizer[mIndex]->text=="operator"
|| mTokenizer[mIndex]->text.endsWith("::operator")) {
//operator()() , it's an operator overload for ()
handleMethod(StatementKind::skFunction,sType,
"operator()",indexAfter,isStatic,false);
return;
}
if (mTokenizer[mIndex]->text.endsWith("::operator")) {
// operator overloading
handleMethod(StatementKind::skFunction,"",
mTokenizer[mIndex]->text+"()",indexAfter,isStatic,false);
return;
}
//foo(...)(...), it's a function pointer var
handleVar(sType,isExtern,isStatic);
handleVar(sType+" "+sName,isExtern,isStatic);
//Won't implement: ignore function decl like int (text)(int x) { };
return;
}
//it's not a function define
if (mTokenizer[indexAfter]->text[0] == ',') {
// var decl with init
handleVar(sType,isExtern,isStatic);
handleVar(sType+" "+sName,isExtern,isStatic);
return;
}
if (mTokenizer[indexAfter]->text[0] == ';') {
@ -1978,18 +1866,18 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
if (currentScope->kind == StatementKind::skNamespace
&& isNotFuncArgs(mIndex + 1)) {
// var decl with init
handleVar(sType,isExtern,isStatic);
handleVar(sType+" "+sName,isExtern,isStatic);
return;
//not in class, it can't be a valid function definition
} else if (currentScope->kind != StatementKind::skClass) {
// var decl with init
handleVar(sType,isExtern,isStatic);
handleVar(sType+" "+sName,isExtern,isStatic);
return;
}
//variable can't be initialized in class definition, it must be a function
} else if (isNotFuncArgs(mIndex + 1)){
// var decl with init
handleVar(sType,isExtern,isStatic);
handleVar(sType+" "+sName,isExtern,isStatic);
return;
}
}
@ -2006,17 +1894,14 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
||mTokenizer[mIndex + 1]->text == ':'
||mTokenizer[mIndex + 1]->text == '{'
|| mTokenizer[mIndex + 1]->text == '=') {
QString s = mTokenizer[mIndex]->text;
if (s == "operator"
|| s.endsWith("::operator")) {
sName = s;
mIndex++;
} else {
handleVar(sType,isExtern,isStatic);
handleVar(sType+" "+sName,isExtern,isStatic);
return;
}
} else if ( mTokenizer[mIndex + 1]->text == "::") {
sName = sName + mTokenizer[mIndex]->text+mTokenizer[mIndex+1]->text;
mIndex+=2;
} else {
QString s = mTokenizer[mIndex]->text;
if (sName.isEmpty()) {
if (s == "static")
isStatic = true;
else if (s == "friend")
@ -2025,6 +1910,9 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
isExtern = true;
if (!s.isEmpty() && !(s=="extern"))
sType = sType + ' '+ s;
} else {
sName += s;
}
mIndex++;
}
}
@ -2600,7 +2488,7 @@ void CppParser::handleLambda(int index, int endIndex)
i++;
} else if (mTokenizer[i]->text=='(') {
i=mTokenizer[i]->matchIndex+1;
} else if (mTokenizer[i]->text=='=') {
} else if (mTokenizer[i]->text.endsWith('=')) {
i = skipAssignment(i, mTokenizer.tokenCount());
} else if (mTokenizer[i]->text=='{') {
tempType="";
@ -2617,6 +2505,47 @@ void CppParser::handleLambda(int index, int endIndex)
removeScopeLevel(mTokenizer[bodyEnd]->line);
}
void CppParser::handleOperatorOverloading(const QString &sType, const QString &prefix, int operatorTokenIndex, bool isStatic, bool isFriend)
{
//operatorTokenIndex is the token index of "operator"
int index=operatorTokenIndex+1;
QString op="";
if (index>=mTokenizer.tokenCount()) {
mIndex=index;
return;
}
if (mTokenizer[index]->text=="(") {
op="()";
index=mTokenizer[index]->matchIndex+1;
} else if (mTokenizer[index]->text=="new"
|| mTokenizer[index]->text=="delete") {
op=mTokenizer[index]->text;
index++;
if (index<mTokenizer.tokenCount()
&& mTokenizer[index]->text=="[]") {
op+="[]";
index++;
}
} else {
op=mTokenizer[index]->text;
index++;
}
while (index<mTokenizer.tokenCount()
&& mTokenizer[index]->text == ")")
index++;
if (index>=mTokenizer.tokenCount()
|| mTokenizer[index]->text!="(") {
mIndex=index;
return;
}
handleMethod(StatementKind::skFunction,
sType,
prefix+"operator"+op,
index,
isStatic,
isFriend);
}
void CppParser::handleMethod(StatementKind functionKind,const QString &sType, const QString &sName, int argStart, bool isStatic, bool isFriend)
{
bool isValid = true;
@ -2685,7 +2614,9 @@ void CppParser::handleMethod(StatementKind functionKind,const QString &sType, co
} else
scopelessName = sName;
// qDebug()<<sName<<scopelessName<<parentClassName;
// if (scopeStatement)
// qDebug()<<"--"<<scopeStatement->fullName;
// For function definitions, the parent class is given. Only use that as a parent
if (!isDeclaration) {
functionStatement=addStatement(
@ -3117,8 +3048,7 @@ bool CppParser::handleStatement()
// handleLambda();
} else if (mTokenizer[mIndex]->text=='(') {
if (mIndex+1<mTokenizer.tokenCount() &&
(mTokenizer[mIndex+1]->text=="operator"
|| mTokenizer[mIndex+1]->text.endsWith("::operator"))) {
mTokenizer[mIndex+1]->text=="operator") {
// things like (operator int)
mIndex++; //just skip '('
} else
@ -3135,12 +3065,10 @@ bool CppParser::handleStatement()
//error
mIndex=moveToEndOfStatement(mIndex,false);
}
} else if (mTokenizer[mIndex]->text=="::") {
checkAndHandleMethodOrVar(KeywordType::None);
} else if (!isIdentChar(mTokenizer[mIndex]->text[0])) {
mIndex=moveToEndOfStatement(mIndex,true);
} else if (mTokenizer[mIndex]->text.endsWith('.')
|| mTokenizer[mIndex]->text.endsWith("->")) {
mIndex=moveToEndOfStatement(mIndex,true);
} else if (checkForKeyword(keywordType)) { // includes template now
handleKeyword(keywordType);
} else if (keywordType==KeywordType::For) { // (for/catch)
@ -3567,7 +3495,7 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
} else if (typePrefix=="static") {
isStatic=true;
} else {
lastType=typePrefix;
lastType=typePrefix.trimmed();
}
PStatement addedVar;
@ -3700,7 +3628,7 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
}
mIndex++;
}
} else if (mTokenizer[mIndex]->text=='=') {
} else if (mTokenizer[mIndex]->text.endsWith('=')) {
if (mIndex+1<mTokenizer.tokenCount()
&& isIdentifier(mTokenizer[mIndex+1]->text)
&& addedVar
@ -3805,6 +3733,9 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
}
mIndex=mTokenizer[mIndex]->matchIndex+1;
addedVar.reset();
} else if (mTokenizer[mIndex]->text=="::") {
tempType+=mTokenizer[mIndex]->text;
mIndex++;
} else {
tempType="";
mIndex++;
@ -3842,7 +3773,7 @@ void CppParser::internalParse(const QString &fileName)
QStringList preprocessResult = mPreprocessor.result();
#ifdef QT_DEBUG
// stringsToFile(mPreprocessor.result(),QString("r:\\preprocess-%1.txt").arg(extractFileName(fileName)));
stringsToFile(mPreprocessor.result(),QString("r:\\preprocess-%1.txt").arg(extractFileName(fileName)));
// mPreprocessor.dumpDefinesTo("r:\\defines.txt");
// mPreprocessor.dumpIncludesListTo("r:\\includes.txt");
#endif
@ -3856,7 +3787,7 @@ void CppParser::internalParse(const QString &fileName)
if (mTokenizer.tokenCount() == 0)
return;
#ifdef QT_DEBUG
// mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName)));
mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName)));
#endif
#ifdef QT_DEBUG
lastIndex = -1;
@ -3867,8 +3798,8 @@ void CppParser::internalParse(const QString &fileName)
break;
}
#ifdef QT_DEBUG
// mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName)));
// mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName)));
mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName)));
mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName)));
#endif
//reduce memory usage
internalClear();
@ -5133,8 +5064,11 @@ void CppParser::scanMethodArgs(const PStatement& functionStatement, int argStart
i=mTokenizer[i]->matchIndex+1;
} else if (mTokenizer[i]->text=='(') {
i=mTokenizer[i]->matchIndex+1;
} else if (mTokenizer[i]->text=='=') {
} else if (mTokenizer[i]->text.endsWith('=')) {
i=skipAssignment(i,argEnd);
} else if (mTokenizer[i]->text=="::") {
varType+=mTokenizer[i]->text;
i++;
} else if (isWordChar(mTokenizer[i]->text[0])) {
QString cmd=mTokenizer[i]->text;
if (i+1==argEnd || mTokenizer[i+1]->text==',' || mTokenizer[i+1]->text=='=') {

View File

@ -215,8 +215,6 @@ private:
QStringList sortFilesByIncludeRelations(const QSet<QString> &files);
bool checkForKeyword(KeywordType &keywordType);
bool checkForMethod(QString &sType, QString &sName, int &argStartIndex,
int &argEndIndex, bool &isStatic, bool &isFriend); // caching of results
bool checkForNamespace(KeywordType keywordType);
bool checkForPreprocessor();
// bool checkForLambda();
@ -444,6 +442,12 @@ private:
void handleForBlock();
void handleKeyword(KeywordType skipType);
void handleLambda(int index, int endIndex);
void handleOperatorOverloading(
const QString& sType,
const QString& prefix,
int operatorTokenIndex,
bool isStatic,
bool isFriend);
void handleMethod(
StatementKind functionKind,
const QString& sType,

View File

@ -213,7 +213,7 @@ QString CppTokenizer::getNextToken(TokenType *pTokenType)
// done = (result != "");
} else if (isWord()) {
countLines();
result = getWord(false);
result = getWord();
// if (result=="noexcept" || result == "throw") {
// result="";
// if (*mCurrent=='(')
@ -236,8 +236,8 @@ QString CppTokenizer::getNextToken(TokenType *pTokenType)
result = "::";
skipToNextToken();
// Append next token to this one
if (isIdentChar(*mCurrent))
result+=getWord(true);
// if (isIdentChar(*mCurrent))
// result+=getWord(true);
done = true;
} else {
countLines();
@ -286,6 +286,7 @@ QString CppTokenizer::getNextToken(TokenType *pTokenType)
mCurrent++;
done = true;
break;
case '.':
case ';':
case ',': //just return the brace or the ';'
countLines();
@ -299,25 +300,35 @@ QString CppTokenizer::getNextToken(TokenType *pTokenType)
result = ">>";
mCurrent+=2;
done = true;
} else
mCurrent+=1;
break;
} else {
countLines();
result = *mCurrent;
mCurrent++;
done = true;
} break;
case '<':
if (*(mCurrent + 1) == '<') {
countLines();
result = "<<";
mCurrent+=2;
done = true;
} else
mCurrent+=1;
} else {
countLines();
result = *mCurrent;
mCurrent++;
done = true;
}
break;
case '=': {
if (*(mCurrent+1)=='=') {
// skip '=='
skipAssignment();
countLines();
result = "==";
mCurrent+=2;
done = true;
} else {
countLines();
mCurrent+=1;
mCurrent++;
result = "=";
done = true;
}
@ -326,9 +337,34 @@ QString CppTokenizer::getNextToken(TokenType *pTokenType)
break;
case '!':
if (*(mCurrent+1)=='=') {
skipAssignment();
} else
countLines();
result = "!=";
mCurrent+=2;
done = true;
} else {
countLines();
result = *mCurrent;
mCurrent++;
done = true;
}
break;
case '-':
if (*(mCurrent + 1) == '=') {
countLines();
result = "-=";
mCurrent+=2;
done = true;
} else if (*(mCurrent + 1) == '>') {
countLines();
mCurrent+=2;
result = "->";
done = true;
} else {
countLines();
result = *mCurrent;
mCurrent++;
done = true;
}
break;
case '/':
case '%':
@ -336,12 +372,19 @@ QString CppTokenizer::getNextToken(TokenType *pTokenType)
case '*':
case '|':
case '+':
case '-':
case '~':
if (*(mCurrent + 1) == '=') {
skipAssignment();
} else
countLines();
result = *mCurrent;
result += "=";
mCurrent+=2;
done = true;
} else {
countLines();
result = *mCurrent;
mCurrent++;
done = true;
}
break;
default:
advance();
@ -380,7 +423,7 @@ QString CppTokenizer::getPreprocessor()
return QString(offset, mCurrent-offset);
}
QString CppTokenizer::getWord(bool bSkipParenthesis)
QString CppTokenizer::getWord()
{
bool bFoundTemplate = false;
// bIsSmartPointer:=False;
@ -400,30 +443,31 @@ QString CppTokenizer::getWord(bool bSkipParenthesis)
if (offset != mCurrent) {
currentWord = QString(offset,mCurrent-offset);
}
// Append the operator characters and argument list to the operator word
if ((currentWord == "operator") ||
(currentWord == "&operator") ||
(currentWord == "operator*") ||
(currentWord == "operator&")) {
// Spaces between 'operator' and the operator itself are allowed
while (isSpaceChar(*mCurrent))
mCurrent++;
// Find end of operator
while (isOperatorChar(*mCurrent))
mCurrent++;
currentWord = QString(offset,mCurrent-offset);
} else if (currentWord == "template") {
// // Append the operator characters and argument list to the operator word
// if ((currentWord == "operator") ||
// (currentWord == "&operator") ||
// (currentWord == "operator*") ||
// (currentWord == "operator&")) {
// // Spaces between 'operator' and the operator itself are allowed
// while (isSpaceChar(*mCurrent))
// mCurrent++;
// // Find end of operator
// while (isOperatorChar(*mCurrent))
// mCurrent++;
// currentWord = QString(offset,mCurrent-offset);
// } else if (currentWord == "template") {
if (currentWord == "template") {
bFoundTemplate = true;
}
QString result;
// We found a word...
if (!currentWord.isEmpty()) {
if (!currentWord.isEmpty() ) {
result = currentWord;
// Skip whitespace
skipToNextToken();
if (currentWord!="operator") {
// Skip template contents, but keep template variable types
if (*mCurrent == '<') {
offset = mCurrent;
@ -448,23 +492,24 @@ QString CppTokenizer::getWord(bool bSkipParenthesis)
}
// Keep parent/child operators
if (*mCurrent == '.') {
result+=*mCurrent;
mCurrent++;
} else if ((*mCurrent == '-') && (*(mCurrent + 1) == '>')) {
result+=QString(mCurrent,2);
mCurrent+=2;
} else if ((*mCurrent == ':') && (*(mCurrent + 1) == ':') ) {
if (result != "using") {
result+=QString(mCurrent,2);
mCurrent+=2;
skipToNextToken();
if (isIdentChar(*mCurrent)) {
// Append next token to this one
QString s = getWord(bSkipParenthesis);
result += s;
}
}
// if (*mCurrent == '.') {
// result+=*mCurrent;
// mCurrent++;
// } else if ((*mCurrent == '-') && (*(mCurrent + 1) == '>')) {
// result+=QString(mCurrent,2);
// mCurrent+=2;
// } else if ((*mCurrent == ':') && (*(mCurrent + 1) == ':') ) {
// if (result != "using") {
// result+=QString(mCurrent,2);
// mCurrent+=2;
// skipToNextToken();
// if (isIdentChar(*mCurrent)) {
// // Append next token to this one
// QString s = getWord(bSkipParenthesis);
// result += s;
// }
// }
// }
}
}
return result;
@ -542,35 +587,35 @@ void CppTokenizer::simplifyArgs(QString &output)
output = temp;
}
void CppTokenizer::skipAssignment()
{
while (true) {
switch ((*mCurrent).unicode()) {
case '(': skipPair('(', ')');
break;
case '"': skipDoubleQuotes();
break;
case '\'': skipSingleQuote();
break;
case '{': skipPair('{', '}'); // support struct initializers
break;
case '/':
mCurrent++;
break;
default:
if ((*mCurrent == 'R') && (*(mCurrent+1) == '"'))
skipRawString();
else
mCurrent++;
}
if (*mCurrent == ','
|| *mCurrent ==';'
|| *mCurrent ==')'
|| *mCurrent =='}'
|| *mCurrent ==0)
break;
}
}
//void CppTokenizer::skipAssignment()
//{
// while (true) {
// switch ((*mCurrent).unicode()) {
// case '(': skipPair('(', ')');
// break;
// case '"': skipDoubleQuotes();
// break;
// case '\'': skipSingleQuote();
// break;
// case '{': skipPair('{', '}'); // support struct initializers
// break;
// case '/':
// mCurrent++;
// break;
// default:
// if ((*mCurrent == 'R') && (*(mCurrent+1) == '"'))
// skipRawString();
// else
// mCurrent++;
// }
// if (*mCurrent == ','
// || *mCurrent ==';'
// || *mCurrent ==')'
// || *mCurrent =='}'
// || *mCurrent ==0)
// break;
// }
//}
void CppTokenizer::skipDoubleQuotes()
{

View File

@ -80,8 +80,7 @@ private:
TokenType *pTokenType);
QString getNumber();
QString getPreprocessor();
QString getWord(
bool bSkipParenthesis);
QString getWord();
bool isArguments();
bool isForInit();
bool isNumber();
@ -89,7 +88,7 @@ private:
bool isWord();
void simplify(QString& output);
void simplifyArgs(QString& output);
void skipAssignment();
// void skipAssignment();
void skipDoubleQuotes();
void skipPair(const QChar& cStart, const QChar cEnd);
void skipParenthesis();
@ -130,27 +129,27 @@ private:
return (ch<=32) && (ch>0);
}
static bool isOperatorChar(const QChar& ch) {
switch (ch.unicode()) {
case '+':
case '-':
case '/':
case '*':
case '[':
case ']':
case '=':
case '%':
case '!':
case '&':
case '|':
case '>':
case '<':
case '^':
return true;
default:
return false;
}
}
// static bool isOperatorChar(const QChar& ch) {
// switch (ch.unicode()) {
// case '+':
// case '-':
// case '/':
// case '*':
// case '[':
// case ']':
// case '=':
// case '%':
// case '!':
// case '&':
// case '|':
// case '>':
// case '<':
// case '^':
// return true;
// default:
// return false;
// }
// }
static bool currentWordEquals(QChar* wordStart, QChar *wordEnd, const QString& text) {
QString currentWord(wordStart, wordEnd-wordStart);