work save

This commit is contained in:
Roy Qu 2021-12-06 09:02:39 +08:00
parent 0360d704ed
commit b0f608a360
2 changed files with 203 additions and 95 deletions

View File

@ -407,7 +407,7 @@ PStatement CppParser::findStatementOf(const QString &fileName,
return statement; return statement;
} }
PStatement CppParser::findStatement( PStatement CppParser::evalExpression(
const QString &fileName, const QString &fileName,
const QStringList &phraseExpression, const QStringList &phraseExpression,
const PStatement &currentScope) const PStatement &currentScope)
@ -416,7 +416,12 @@ PStatement CppParser::findStatement(
if (mParsing) if (mParsing)
return PStatement(); return PStatement();
int pos = 0; int pos = 0;
return doFindStatement(fileName,phraseExpression,pos,currentScope,true); return doEvalExpression(fileName,
phraseExpression,
pos,
currentScope,
PStatement(),
true);
} }
PStatement CppParser::findStatementOf(const QString &fileName, const QString &phrase, const PStatement& currentClass, bool force) PStatement CppParser::findStatementOf(const QString &fileName, const QString &phrase, const PStatement& currentClass, bool force)
@ -3360,44 +3365,56 @@ PStatement CppParser::findStatementInNamespace(const QString &name, const QStrin
return PStatement(); return PStatement();
} }
PStatement CppParser::doParseSubExpression3(const QString &fileName, PStatement CppParser::doEvalCCast(const QString &fileName,
const QStringList &phraseExpression, const QStringList &phraseExpression,
int &pos, int &pos,
const PStatement &currentScope, const PStatement& scope,
const PStatement& previousResult,
bool freeScoped) bool freeScoped)
{ {
if (pos>=phraseExpression.length()) if (pos>=phraseExpression.length())
return PStatement(); return PStatement();
if (phraseExpression[pos]=="*") { if (phraseExpression[pos]=="*") {
pos++; //skip "*" pos++; //skip "*"
PStatement statement = doParseSubExpression3(fileName, PStatement statement = doEvalCCast(fileName,
phraseExpression, phraseExpression,
pos, pos,
currentScope, scope,
previousResult,
freeScoped); freeScoped);
//todo: //todo:
return statement; return statement;
} else if (phraseExpression[pos]=="&") { } else if (phraseExpression[pos]=="&") {
pos++; //skip "&" pos++; //skip "&"
PStatement statement = doParseSubExpression3(fileName, PStatement statement = doEvalCCast(fileName,
phraseExpression, phraseExpression,
pos, pos,
currentScope, scope,
previousResult,
freeScoped); freeScoped);
//todo: //todo:
return statement; return statement;
} else if (phraseExpression[pos]=="++" } else if (phraseExpression[pos]=="++"
|| phraseExpression[pos]=="--") { || phraseExpression[pos]=="--") {
pos++; //skip "++" or "--" pos++; //skip "++" or "--"
return doParseSubExpression3(fileName, return doEvalCCast(
fileName,
phraseExpression, phraseExpression,
pos, pos,
currentScope, scope,
previousResult,
freeScoped); freeScoped);
} else if (phraseExpression[pos]=="(") { } else if (phraseExpression[pos]=="(") {
//parse //parse
int startPos = pos;
pos++; pos++;
PStatement typeStatement = doFindStatement(fileName,phraseExpression,pos,currentScope,freeScoped); PStatement typeStatement = doEvalExpression(
fileName,
phraseExpression,
pos,
scope,
PStatement(),
true);
if (pos >= phraseExpression.length() || phraseExpression[pos]!=")") { if (pos >= phraseExpression.length() || phraseExpression[pos]!=")") {
return PStatement(); return PStatement();
} else if (typeStatement && } else if (typeStatement &&
@ -3405,59 +3422,99 @@ PStatement CppParser::doParseSubExpression3(const QString &fileName,
|| typeStatement->kind == StatementKind::skEnumType || typeStatement->kind == StatementKind::skEnumType
|| typeStatement->kind == StatementKind::skEnumClassType || typeStatement->kind == StatementKind::skEnumClassType
|| typeStatement->kind == StatementKind::skTypedef)) { || typeStatement->kind == StatementKind::skTypedef)) {
PStatement statement = doParseSubExpression3(fileName, //it's a type cast
PStatement statement = doEvalCCast(fileName,
phraseExpression, phraseExpression,
pos, pos,
currentScope, scope,
previousResult,
freeScoped); freeScoped);
return typeStatement; return typeStatement;
} else } else //it's not a type cast
return PStatement(); return doEvalMemberAccess(
fileName,
phraseExpression,
startPos, //we must reparse it
scope,
previousResult,
freeScoped);
} }
return doParseSubExpression2(fileName, return doEvalMemberAccess(
fileName,
phraseExpression, phraseExpression,
pos, pos,
currentScope, scope,
previousResult,
freeScoped); freeScoped);
} }
PStatement CppParser::doParseSubExpression2(const QString &fileName, PStatement CppParser::doEvalMemberAccess(const QString &fileName,
const QStringList &phraseExpression, const QStringList &phraseExpression,
int &pos, const PStatement &currentScope, int &pos,
const PStatement& scope,
const PStatement& previousResult,
bool freeScoped) bool freeScoped)
{ {
if (pos>=phraseExpression.length()) if (pos>=phraseExpression.length())
return PStatement(); return PStatement();
PStatement current = doParseSubExpression1(fileName, PStatement current = doEvalScopeResolution(
fileName,
phraseExpression, phraseExpression,
pos, pos,
currentScope, scope,
previousResult,
freeScoped); freeScoped);
bool isFreeScoped = freeScoped;
if (!current) if (!current)
return PStatement(); return PStatement();
pos++; pos++;
while (pos<phraseExpression.length()) { while (pos<phraseExpression.length()) {
if (!current)
break;
if (phraseExpression[pos]=="++" || phraseExpression[pos]=="--") { if (phraseExpression[pos]=="++" || phraseExpression[pos]=="--") {
pos++; pos++;
} else if (phraseExpression[pos] == "(") { } else if (phraseExpression[pos] == "(") {
//skip to ")" if (current->kind == StatementKind::skClass
if (current->kind == StatementKind::skClass) { || current->kind == StatementKind::skEnumClassType
|| current->kind == StatementKind::skEnumClassType
) {
pos++; // skip "("
PStatement s = doEvalExpression(
fileName,
phraseExpression,
pos,
scope,
PStatement(),
true);
//type cast //type cast
PStatement statement = std::make_shared<Statement>();
statement->kind = StatementKind::skVariable;
} else if (current->kind == StatementKind::skFunction) { } else if (current->kind == StatementKind::skFunction) {
//function call //function call
current = findTypeDefinitionOf(
fileName,
current->type,
current->parentScope.lock());
} }
//skip to ")"
doSkipInExpression("(",")");
return statement;
} else if (phraseExpression[pos] == "[") { } else if (phraseExpression[pos] == "[") {
//skip to "]" //skip to "]"
doSkipInExpression("[","]");
return
} else if (phraseExpression[pos] == ".") { } else if (phraseExpression[pos] == ".") {
pos++; pos++;
current = doParseSubExpression1(fileName, current = doEvalScopeResolution(fileName,
phraseExpression, phraseExpression,
pos, pos,
current, current,
false); false);
} else if (phraseExpression[pos] == "->") { } else if (phraseExpression[pos] == "->") {
pos++; pos++;
current = doParseSubExpression1(fileName, current = doEvalScopeResolution(fileName,
phraseExpression, phraseExpression,
pos, pos,
current, current,
@ -3468,15 +3525,16 @@ PStatement CppParser::doParseSubExpression2(const QString &fileName,
} }
PStatement CppParser::doParseSubExpression1(const QString &fileName, PStatement CppParser::doEvalScopeResolution(const QString &fileName,
const QStringList &phraseExpression, const QStringList &phraseExpression,
int &pos, int &pos,
const PStatement &currentScope, const PStatement& scope,
const PStatement& previousResult,
bool freeScoped) bool freeScoped)
{ {
if (pos>=phraseExpression.length()) if (pos>=phraseExpression.length())
return PStatement(); return PStatement();
PStatement current = doParseSubExpression0(fileName, PStatement current = doParseSubExpressionForType0(fileName,
phraseExpression, phraseExpression,
pos, pos,
currentScope, currentScope,
@ -3500,16 +3558,18 @@ PStatement CppParser::doParseSubExpression1(const QString &fileName,
return current; return current;
} }
PStatement CppParser::doParseSubExpression0(const QString &fileName, PStatement CppParser::doParseSubExpressionForType0(const QString &fileName,
const QStringList &phraseExpression, const QStringList &phraseExpression,
int &pos, const PStatement &currentScope, int &pos,
const PStatement& scope,
const PStatement& previousResult,
bool freeScoped) bool freeScoped)
{ {
if (pos>=phraseExpression.length()) if (pos>=phraseExpression.length())
return PStatement(); return PStatement();
if (phraseExpression[pos]=="(") { if (phraseExpression[pos]=="(") {
pos++; pos++;
PStatement statement = doFindStatement(fileName,phraseExpression,pos,currentScope,freeScoped); PStatement statement = doEvalExpression(fileName,phraseExpression,pos,currentScope,freeScoped);
if (pos >= phraseExpression.length() || phraseExpression[pos]!=")") if (pos >= phraseExpression.length() || phraseExpression[pos]!=")")
return PStatement(); return PStatement();
else else
@ -3526,29 +3586,59 @@ PStatement CppParser::doParseSubExpression0(const QString &fileName,
} }
PStatement CppParser::doFindStatement(const QString &fileName, PStatement CppParser::doEvalExpression(const QString& fileName,
const QStringList &phraseExpression, const QStringList& phraseExpression,
int& pos, int &pos,
const PStatement &currentScope, const PStatement& scope,
const PStatement& previousResult,
bool freeScoped) bool freeScoped)
{
//dummy function to easy later upgrades
return doEvalPointerToMembers(fileName,
phraseExpression,
pos,
scope,
previousResult,
freeScoped);
}
PStatement CppParser::doEvalPointerToMembers(const QString &fileName, const QStringList &phraseExpression, int &pos, const PStatement &scope, const PStatement &previousResult, bool freeScoped)
{ {
if (pos>=phraseExpression.length()) if (pos>=phraseExpression.length())
return PStatement(); return PStatement();
//find the start scope statement //find the start scope statement
PStatement currentStatement = doParseSubExpression3(fileName,phraseExpression,pos,currentScope, freeScoped); PStatement currentStatement = doEvalCCast(
fileName,
phraseExpression,
pos,
scope,
previousResult,
freeScoped);
while (pos < phraseExpression.length() ) { while (pos < phraseExpression.length() ) {
if (!currentStatement)
break;
if (currentStatement && if (currentStatement &&
(currentStatement->kind == StatementKind::skVariable) (currentStatement->kind == StatementKind::skVariable)
&& (phraseExpression[pos]==".*" && (phraseExpression[pos]==".*"
|| phraseExpression[pos]=="->*")) { || phraseExpression[pos]=="->*")) {
pos++; pos++;
PStatement currentStatementScope = findTypeDefinitionOf( PStatement statement =
doEvalCCast(
fileName, fileName,
currentStatement->type, phraseExpression,
currentStatement->parentScope.lock()); pos,
currentStatement = doParseSubExpression3(fileName,phraseExpression,pos,currentStatementScope,false); scope,
currentStatement,
false);
if (statement) {
currentStatement = std::make_shared<Statement>();
*currentStatement = * statement;
currentStatement->type = currentStatement->type+" *";
} else { } else {
break; currentStatement = PStatement();
}
} else {
currentStatement=PStatement();
} }
} }
return currentStatement; return currentStatement;

View File

@ -49,8 +49,15 @@ public:
const QString& phrase, const QString& phrase,
const PStatement& currentClass, const PStatement& currentClass,
bool force = false); bool force = false);
PStatement findStatement(const QString& fileName, /**
const QStringList& phraseExpression, * @brief evaluate the expression
* @param fileName
* @param expression
* @param currentScope
* @return the statement of the evaluation result
*/
PStatement evalExpression(const QString& fileName,
const QStringList& expression,
const PStatement& currentScope); const PStatement& currentScope);
//{Find statement starting from startScope} //{Find statement starting from startScope}
PStatement findStatementStartingFrom(const QString& fileName, PStatement findStatementStartingFrom(const QString& fileName,
@ -202,46 +209,57 @@ private:
const QString& name, const QString& name,
const QString& namespaceName); const QString& namespaceName);
PStatement doParseSubExpression3(
const QString& fileName,
const QStringList& phraseExpression,
int &pos,
const PStatement& currentScope,
bool freeScoped);
PStatement doParseSubExpression2(
const QString& fileName,
const QStringList& phraseExpression,
int &pos,
const PStatement& currentScope,
bool freeScoped);
PStatement doParseSubExpression1(
const QString& fileName,
const QStringList& phraseExpression,
int &pos,
const PStatement& currentScope,
bool freeScoped);
PStatement doParseSubExpression0(
const QString& fileName,
const QStringList& phraseExpression,
int &pos,
const PStatement& currentScope,
bool freeScoped);
/** /**
* @brief find the expression's corresponding statement in the specified file and scope * @brief evaluate the expression (starting from pos) in the scope
* If the statement is free scoped, if it's not member of the currentScope,
* we'll search it in the currentScope's outer scope recursively
* @param fileName * @param fileName
* @param phraseExpression * @param phraseExpression
* @param pos * @param pos
* @param currentScope * @param scope
* @param freeScope if the statement is free scoped. * @param previousResult the result of evalution for expression from 0 to pos-1
* @param freeScoped if the expression left is
* @return * @return
*/ */
PStatement doFindStatement(const QString& fileName, PStatement doEvalExpression(const QString& fileName,
const QStringList& phraseExpression, const QStringList& phraseExpression,
int &pos, int &pos,
const PStatement& currentScope, const PStatement& scope,
const PStatement& previousResult,
bool freeScoped);
PStatement doEvalPointerToMembers(
const QString& fileName,
const QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PStatement& previousResult,
bool freeScoped);
PStatement doEvalCCast(
const QString& fileName,
const QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PStatement& previousResult,
bool freeScoped);
PStatement doEvalMemberAccess(
const QString& fileName,
const QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PStatement& previousResult,
bool freeScoped);
PStatement doEvalScopeResolution(
const QString& fileName,
const QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PStatement& previousResult,
bool freeScoped);
PStatement doParseSubExpressionForType0(
const QString& fileName,
const QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PStatement& previousResult,
bool freeScoped); bool freeScoped);
int getBracketEnd(const QString& s, int startAt); int getBracketEnd(const QString& s, int startAt);