work save

This commit is contained in:
royqh1979@gmail.com 2021-08-14 22:52:37 +08:00
parent 8a4a397e17
commit 821aaee3e7
7 changed files with 137 additions and 45 deletions

View File

@ -16,6 +16,7 @@ SOURCES += \
compiler/executablerunner.cpp \
compiler/filecompiler.cpp \
compiler/stdincompiler.cpp \
parser/cppparser.cpp \
parser/cpppreprocessor.cpp \
parser/cpptokenizer.cpp \
parser/parserutils.cpp \
@ -77,6 +78,7 @@ HEADERS += \
compiler/executablerunner.h \
compiler/filecompiler.h \
compiler/stdincompiler.h \
parser/cppparser.h \
parser/cpppreprocessor.h \
parser/cpptokenizer.h \
parser/parserutils.h \

View File

@ -0,0 +1,6 @@
#include "cppparser.h"
CppParser::CppParser(QObject *parent) : QObject(parent)
{
}

View File

@ -0,0 +1,65 @@
#ifndef CPPPARSER_H
#define CPPPARSER_H
#include <QObject>
#include "statementmodel.h"
#include "cpptokenizer.h"
#include "cpppreprocessor.h"
class CppParser : public QObject
{
Q_OBJECT
public:
explicit CppParser(QObject *parent = nullptr);
signals:
private:
int mParserId;
int mSerialCount;
int mSerialId;
int mUniqId;
bool mEnabled;
int mIndex;
bool mIsHeader;
bool mIsSystemHeader;
QString mCurrentFile;
// stack list , each element is a list of one/many scopes(like intypedef struct s1,s2;
// It's used for store scope nesting infos
QVector<PStatement> mCurrentScope;
QVector<StatementClassScope> mCurrentClassScope;
// the start index in tokens to skip to ; when parsing typedef struct we need to skip
// the names after the closing bracket because we have processed it
QVector<int> mSkipList; // TList<Integer>
StatementClassScope mClassScope;
StatementModel mStatementList;
std::shared_ptr<QHash<QString,PFileIncludes>> mIncludesList; //List of scaned files and it's infos
//It's used in preprocessor, so we can't use fIncludeList instead
std::shared_ptr<QSet<QString>> mScannedFiles; // List of scaned file names
CppTokenizer mTokenizer;
CppPreprocessor mPreprocessor;
{ List of current compiler set's include path}
fIncludePaths: TStringList;
{ List of current project's include path }
fProjectIncludePaths: TStringList;
{ List of current project's include path }
fProjectFiles: TStringList;
fBlockBeginSkips: TIntList; //list of for/catch block begin token index;
fBlockEndSkips: TIntList; //list of for/catch block end token index;
fInlineNamespaceEndSkips: TIntList; // list for inline namespace end token index;
fFilesToScan: TStringList; // list of base files to scan
fFilesScannedCount: Integer; // count of files that have been scanned
fFilesToScanCount: Integer; // count of files and files included in files that have to be scanned
fParseLocalHeaders: boolean;
fParseGlobalHeaders: boolean;
fIsProjectFile: boolean;
//fMacroDefines : TList;
fLockCount: integer; // lock(don't reparse) when we need to find statements in a batch
fParsing: boolean;
fNamespaces :TDevStringList; //TStringList<String,List<Statement>> namespace and the statements in its scope
//fRemovedStatements: THashedStringList; //THashedStringList<String,PRemovedStatements>
fCriticalSection: TCriticalSection;
fOnGetFileStream : TGetFileStreamEvent;
};
#endif // CPPPARSER_H

View File

@ -4,7 +4,7 @@
#include <QFile>
#include <QTextCodec>
CppPreprocessor::CppPreprocessor(QObject *parent) : QObject(parent)
CppPreprocessor::CppPreprocessor()
{
}

View File

@ -16,10 +16,8 @@ struct ParsedFile {
};
using PParsedFile = std::shared_ptr<ParsedFile>;
class CppPreprocessor : public QObject
class CppPreprocessor
{
Q_OBJECT
enum class ContentType {
AnsiCComment,
CppComment,
@ -33,7 +31,7 @@ class CppPreprocessor : public QObject
public:
explicit CppPreprocessor(QObject *parent = nullptr);
explicit CppPreprocessor();
void clear();
void addDefineByParts(const QString& name, const QString& args,
const QString& value, bool hardCoded);

View File

@ -1,15 +1,25 @@
#include "cpptokenizer.h"
cpptokenizer::cpptokenizer(QObject *parent) : QObject(parent)
#include <QFile>
#include <QTextStream>
CppTokenizer::CppTokenizer()
{
}
void cpptokenizer::tokenize(const QStringList &buffer)
void CppTokenizer::reset()
{
mTokenList.clear();
mBuffer.clear();
mBufferStr.clear();
}
void CppTokenizer::tokenize(const QStringList &buffer)
{
reset();
mBuffer = buffer;
mBufferStr.clear();
if (mBuffer.isEmpty())
return;
mBufferStr = mBuffer[0];
@ -35,7 +45,19 @@ void cpptokenizer::tokenize(const QStringList &buffer)
}
}
void cpptokenizer::addToken(const QString &sText, int iLine)
void CppTokenizer::dumpTokens(const QString &fileName)
{
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QTextStream stream(&file);
for (PToken token:mTokenList) {
stream<<QString("%1,%2").arg(token->line).arg(token->text)<<Qt::endl;
}
}
}
void CppTokenizer::addToken(const QString &sText, int iLine)
{
PToken token = std::make_shared<Token>();
token->text = sText;
@ -43,7 +65,7 @@ void cpptokenizer::addToken(const QString &sText, int iLine)
mTokenList.append(token);
}
void cpptokenizer::countLines()
void CppTokenizer::countLines()
{
while ((*mLineCount != '\0') && (mLineCount < mCurrent)) {
if (*mLineCount == '\n')
@ -52,7 +74,7 @@ void cpptokenizer::countLines()
}
}
QString cpptokenizer::getArguments()
QString CppTokenizer::getArguments()
{
QChar* offset = mCurrent;
skipPair('(', ')');
@ -74,7 +96,7 @@ QString cpptokenizer::getArguments()
return result;
}
QString cpptokenizer::getForInit()
QString CppTokenizer::getForInit()
{
QChar* startOffset = mCurrent;
@ -98,7 +120,7 @@ QString cpptokenizer::getForInit()
return "";
}
QString cpptokenizer::getNextToken(bool bSkipParenthesis, bool bSkipArray, bool bSkipBlock)
QString CppTokenizer::getNextToken(bool bSkipParenthesis, bool bSkipArray, bool bSkipBlock)
{
QString result;
bool done = false;
@ -179,7 +201,7 @@ QString cpptokenizer::getNextToken(bool bSkipParenthesis, bool bSkipArray, bool
return result;
}
QString cpptokenizer::getNumber()
QString CppTokenizer::getNumber()
{
QChar* offset = mCurrent;
@ -190,7 +212,7 @@ QString cpptokenizer::getNumber()
}
QString result;
if (offset != mpCurrent) {
if (offset != mCurrent) {
result = QString(offset,mCurrent-offset);
if (*mCurrent=='.') // keep '.' for decimal
result += *mCurrent;
@ -198,14 +220,14 @@ QString cpptokenizer::getNumber()
return result;
}
QString cpptokenizer::getPreprocessor()
QString CppTokenizer::getPreprocessor()
{
QChar *offset = mCurrent;
skipToEOL();
return QString(offset, mCurrent-offset);
}
QString cpptokenizer::getWord(bool bSkipParenthesis, bool bSkipArray, bool bSkipBlock)
QString CppTokenizer::getWord(bool bSkipParenthesis, bool bSkipArray, bool bSkipBlock)
{
bool bFoundTemplate = false;
// bIsSmartPointer:=False;
@ -288,27 +310,27 @@ QString cpptokenizer::getWord(bool bSkipParenthesis, bool bSkipArray, bool bSkip
return result;
}
bool cpptokenizer::isArguments()
bool CppTokenizer::isArguments()
{
return *mCurrent == '(';
}
bool cpptokenizer::isForInit()
bool CppTokenizer::isForInit()
{
return (*mCurrent == '(') && (mLastToken == "for");
}
bool cpptokenizer::isNumber()
bool CppTokenizer::isNumber()
{
return isDigitChar(*mCurrent);
}
bool cpptokenizer::isPreprocessor()
bool CppTokenizer::isPreprocessor()
{
return *mCurrent=='#';
}
bool cpptokenizer::isWord()
bool CppTokenizer::isWord()
{
bool result = isLetterChar(*mCurrent);
if (result && (*(mCurrent+1) == '"'))
@ -316,7 +338,7 @@ bool cpptokenizer::isWord()
return result;
}
void cpptokenizer::simplify(QString &output)
void CppTokenizer::simplify(QString &output)
{
//remove \n \r;
QString temp;
@ -327,7 +349,7 @@ void cpptokenizer::simplify(QString &output)
output = temp.trimmed();
}
void cpptokenizer::simplifyArgs(QString &output)
void CppTokenizer::simplifyArgs(QString &output)
{
QString temp;
QString lastSpace = "";
@ -360,7 +382,7 @@ void cpptokenizer::simplifyArgs(QString &output)
output = temp;
}
void cpptokenizer::skipAssignment()
void CppTokenizer::skipAssignment()
{
while (true) {
switch ((*mCurrent).unicode()) {
@ -390,7 +412,7 @@ void cpptokenizer::skipAssignment()
}
}
void cpptokenizer::skipDoubleQuotes()
void CppTokenizer::skipDoubleQuotes()
{
mCurrent++;
while (!(*mCurrent=='"' || *mCurrent == '\0')) {
@ -404,7 +426,7 @@ void cpptokenizer::skipDoubleQuotes()
}
}
void cpptokenizer::skipPair(const QChar &cStart, const QChar cEnd, const QSet<QChar>& failChars)
void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd, const QSet<QChar>& failChars)
{
mCurrent++;
while (*mCurrent != '\0') {
@ -442,7 +464,7 @@ void cpptokenizer::skipPair(const QChar &cStart, const QChar cEnd, const QSet<QC
}
}
void cpptokenizer::skipRawString()
void CppTokenizer::skipRawString()
{
mCurrent++; //skip R
bool noEscape = false;
@ -465,7 +487,7 @@ void cpptokenizer::skipRawString()
mCurrent++;
}
void cpptokenizer::skipSingleQuote()
void CppTokenizer::skipSingleQuote()
{
mCurrent++;
while (!(*mCurrent=='\'' || *mCurrent == '\0')) {
@ -479,14 +501,14 @@ void cpptokenizer::skipSingleQuote()
}
}
void cpptokenizer::skipSplitLine()
void CppTokenizer::skipSplitLine()
{
mCurrent++; // skip '\'
while ( isLineChar(*mCurrent)) // skip newline
mCurrent++;
}
void cpptokenizer::skipTemplateArgs()
void CppTokenizer::skipTemplateArgs()
{
if (*mCurrent != '<')
return;
@ -503,7 +525,7 @@ void cpptokenizer::skipTemplateArgs()
mCurrent = start;
}
void cpptokenizer::skipToEOL()
void CppTokenizer::skipToEOL()
{
while (true) {
while (!isLineChar(*mCurrent) && (*mCurrent!='\0')) {
@ -522,13 +544,13 @@ void cpptokenizer::skipToEOL()
}
}
void cpptokenizer::skipToNextToken()
void CppTokenizer::skipToNextToken()
{
while (isSpaceChar(*mCurrent) || isLineChar(*mCurrent))
advance();
}
void cpptokenizer::advance()
void CppTokenizer::advance()
{
switch(mCurrent->unicode()) {
case '\"': skipDoubleQuotes();
@ -571,7 +593,7 @@ void cpptokenizer::advance()
}
}
bool cpptokenizer::isLetterChar(const QChar &ch)
bool CppTokenizer::isLetterChar(const QChar &ch)
{
return (ch>= 'A' && ch<='Z')
|| (ch>='a' && ch<='z')
@ -581,7 +603,7 @@ bool cpptokenizer::isLetterChar(const QChar &ch)
|| ch == '~';
}
bool cpptokenizer::isHexChar(const QChar &ch)
bool CppTokenizer::isHexChar(const QChar &ch)
{
return (ch >= 'A' && ch<='F')
|| (ch>='a' && ch<='f')
@ -589,27 +611,27 @@ bool cpptokenizer::isHexChar(const QChar &ch)
|| ch == 'L';
}
bool cpptokenizer::isDigitChar(const QChar &ch)
bool CppTokenizer::isDigitChar(const QChar &ch)
{
return (ch>='0' && ch<='9');
}
bool cpptokenizer::isSpaceChar(const QChar &ch)
bool CppTokenizer::isSpaceChar(const QChar &ch)
{
return (ch == ' ' || ch == '\t');
}
bool cpptokenizer::isLineChar(const QChar &ch)
bool CppTokenizer::isLineChar(const QChar &ch)
{
return (ch=='\n' || ch=='\r');
}
bool cpptokenizer::isBlankChar(const QChar &ch)
bool CppTokenizer::isBlankChar(const QChar &ch)
{
return (ch<=32);
}
bool cpptokenizer::isOperatorChar(const QChar &ch)
bool CppTokenizer::isOperatorChar(const QChar &ch)
{
switch (ch.unicode()) {
case '+':
@ -632,7 +654,7 @@ bool cpptokenizer::isOperatorChar(const QChar &ch)
}
}
bool cpptokenizer::currentWordEquals(QChar *wordStart, QChar *wordEnd, const QString& text)
bool CppTokenizer::currentWordEquals(QChar *wordStart, QChar *wordEnd, const QString& text)
{
QString currentWord(wordStart, wordEnd-wordStart);
return currentWord == text;

View File

@ -4,9 +4,8 @@
#include <QObject>
#include "parserutils.h"
class cpptokenizer : public QObject
class CppTokenizer
{
Q_OBJECT
public:
struct Token {
QString text;
@ -14,7 +13,7 @@ public:
};
using PToken = std::shared_ptr<Token>;
using TokenList = QVector<PToken>;
explicit cpptokenizer(QObject *parent = nullptr);
explicit CppTokenizer();
void reset();
void tokenize(const QStringList& buffer);