Compare commits

..

No commits in common. "881cfb8198501be1d42f7f55efb6038c4cc47162" and "ec98c062cb201a544aab1c861daf7276789d03bc" have entirely different histories.

9 changed files with 26 additions and 110 deletions

View File

@ -22,20 +22,17 @@ int main(int argc, char* argv[]) {
auto rst = parser.parse(vwords); auto rst = parser.parse(vwords);
if (rst.first()->totalErrorCount()) { if (rst.first()->totalErrorCount()) {
int err_count = 0;
auto pos_mark = rst.first()->token()->position(); auto pos_mark = rst.first()->token()->position();
for (auto item : rst) for (auto item : rst)
if (item->token()->position() == pos_mark) if (item->token()->position() == pos_mark)
for (auto line : item->totalErrors()){ for (auto line : item->totalErrors())
err_count++;
qDebug().noquote() << line; qDebug().noquote() << line;
} }
qDebug() << err_count << "===========finished==========================";
}
else { else {
auto prag_root = std::make_shared<example_novel::NGlobalElement>("HelloWorld!"); auto prag_root = std::make_shared<example_novel::NGlobalElement>("HelloWorld!");
auto structx = parser.getAst(rst.first(), prag_root); auto structx = parser.getAst(rst.first(), prag_root);
parser.astPresent(structx); parser.astPresent(structx);
} }
qDebug() << "===========finished==========================";
return a.exec(); return a.exec();
} }

View File

@ -1,6 +0,0 @@
// For more information see https://aka.ms/fsharp-console-apps
open System
let args = System.Environment.GetCommandLineArgs() |> Array.toList
if args.Length <> 5 then
failwith $"程序启动参数错误:<nsm> -in story_dir -out html_out"

View File

@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>nsm</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
</Project>

View File

@ -38,9 +38,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoreTest", "CoreTest\CoreTe
{EF557F71-99AA-4F2B-A5F5-1A4518A11C19} = {EF557F71-99AA-4F2B-A5F5-1A4518A11C19} {EF557F71-99AA-4F2B-A5F5-1A4518A11C19} = {EF557F71-99AA-4F2B-A5F5-1A4518A11C19}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AstConv", "AstConv\AstConv.fsproj", "{0C77216C-6484-4C94-BE06-D5D9FF18EA81}" Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "AstConv", "AstConv\AstConv.fsproj", "{0C77216C-6484-4C94-BE06-D5D9FF18EA81}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "WsNovelManager", "WsNovelManager\WsNovelManager.fsproj", "{D9350B75-3992-47A8-A0F3-41D16874D245}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -136,18 +134,6 @@ Global
{0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x64.Build.0 = Release|Any CPU {0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x64.Build.0 = Release|Any CPU
{0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x86.ActiveCfg = Release|Any CPU {0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x86.ActiveCfg = Release|Any CPU
{0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x86.Build.0 = Release|Any CPU {0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x86.Build.0 = Release|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Debug|x64.ActiveCfg = Debug|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Debug|x64.Build.0 = Debug|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Debug|x86.ActiveCfg = Debug|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Debug|x86.Build.0 = Debug|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Release|Any CPU.Build.0 = Release|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Release|x64.ActiveCfg = Release|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Release|x64.Build.0 = Release|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Release|x86.ActiveCfg = Release|Any CPU
{D9350B75-3992-47A8-A0F3-41D16874D245}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -6,7 +6,7 @@
<LocalDebuggerCommandArguments>--path "D:\Projects\Cpp\WsNovelParser\x64\test_file" --dest E:\</LocalDebuggerCommandArguments> <LocalDebuggerCommandArguments>--path "D:\Projects\Cpp\WsNovelParser\x64\test_file" --dest E:\</LocalDebuggerCommandArguments>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>--path "D:\Projects\Cpp\WsNovelParser\x64\test_file" --dest E:\</LocalDebuggerCommandArguments> <LocalDebuggerCommandArguments>--path "D:\CustomNovels\科学+修仙+创造世界" --dest E:\</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerWorkingDirectory>$(SolutionDir)$(Platform)\$(Configuration)\</LocalDebuggerWorkingDirectory> <LocalDebuggerWorkingDirectory>$(SolutionDir)$(Platform)\$(Configuration)\</LocalDebuggerWorkingDirectory>
</PropertyGroup> </PropertyGroup>

View File

@ -27,7 +27,7 @@ QList<std::shared_ptr<const IBasicRule>> __anyone_impl::children() const {
} }
QList<std::shared_ptr<const MatchCursor>> __anyone_impl::parse(std::shared_ptr<const MatchCursor> cursor) const { QList<std::shared_ptr<const MatchCursor>> __anyone_impl::parse(std::shared_ptr<const MatchCursor> cursor) const {
if (cursor->parseFailure() || cursor->parseComplete()) if (cursor->parseFailure() && cursor->parseComplete())
return QList<std::shared_ptr<const MatchCursor>>() << cursor; return QList<std::shared_ptr<const MatchCursor>>() << cursor;
auto syntax = present(); auto syntax = present();
@ -79,7 +79,7 @@ QList<std::shared_ptr<const IBasicRule>> __sequence_impl::children() const {
} }
QList<std::shared_ptr<const MatchCursor>> __sequence_impl::parse(std::shared_ptr<const MatchCursor> cursor) const { QList<std::shared_ptr<const MatchCursor>> __sequence_impl::parse(std::shared_ptr<const MatchCursor> cursor) const {
if (cursor->parseFailure() || cursor->parseComplete()) if (cursor->parseFailure() && cursor->parseComplete())
return QList<std::shared_ptr<const MatchCursor>>() << cursor; return QList<std::shared_ptr<const MatchCursor>>() << cursor;
QList<std::shared_ptr<const MatchCursor>> bridge_list{ cursor }; QList<std::shared_ptr<const MatchCursor>> bridge_list{ cursor };
@ -148,7 +148,7 @@ QList<std::shared_ptr<const IBasicRule>> __repeat_impl::children() const {
#include <algorithm> #include <algorithm>
QList<std::shared_ptr<const MatchCursor>> __repeat_impl::parse(std::shared_ptr<const MatchCursor> cursor) const { QList<std::shared_ptr<const MatchCursor>> __repeat_impl::parse(std::shared_ptr<const MatchCursor> cursor) const {
if (cursor->parseFailure() || cursor->parseComplete()) if (cursor->parseFailure() && cursor->parseComplete())
return QList<std::shared_ptr<const MatchCursor>>() << cursor; return QList<std::shared_ptr<const MatchCursor>>() << cursor;
auto syntax = present(); auto syntax = present();
@ -338,19 +338,12 @@ void MatchCursor::enterExprs() {
this->_exprs_errors.push_back(new_expr); this->_exprs_errors.push_back(new_expr);
} }
void lib_syntax::MatchCursor::logExprsError(std::shared_ptr<const lib_words::IPrimitiveWord> t, const QString& msg) { void MatchCursor::logExprsError(const QString& msg) {
auto pos_key = t?t->position():0; this->_total_errors.push_back(msg);
if(!this->_total_errors.contains(pos_key)) this->_exprs_errors.last()->addError(msg);
this->_total_errors[pos_key] = QStringList();
auto exists = this->_total_errors[pos_key];
exists.append(msg);
this->_total_errors[pos_key] = exists;
this->_exprs_errors.last()->addError(t, msg);
// 普适性质的判定标准 // 普适性质的判定标准
this->setFailure(this->exprsErrorCount() > 1 || this->_total_errors.size() > 300); this->setFailure(this->exprsErrorCount() > 1);
} }
void MatchCursor::quitExprs() { void MatchCursor::quitExprs() {
@ -384,28 +377,7 @@ int MatchCursor::totalErrorCount() const {
} }
QList<QString> MatchCursor::totalErrors() const { QList<QString> MatchCursor::totalErrors() const {
QStringList flist; return this->_total_errors;
for(auto set : this->_total_errors)
flist.append(set);
return flist;
}
void lib_syntax::MatchCursor::mergeWith(const MatchCursor& other) {
for(auto key : other._total_errors.keys()){
if (!this->_total_errors.contains(key))
this->_total_errors[key] = QStringList();
auto values = other._total_errors[key];
auto this_values = this->_total_errors[key];
this_values.append(values);
this->_total_errors[key] = this_values;
}
for (auto key : this->_total_errors.keys()) {
auto values = this->_total_errors[key];
values = values.toSet().toList();
this->_total_errors[key] = values;
}
} }
void MatchCursor::setCurrent(std::shared_ptr<const IActionToken> t, std::shared_ptr<const IPrimitiveWord> remains) { void MatchCursor::setCurrent(std::shared_ptr<const IActionToken> t, std::shared_ptr<const IPrimitiveWord> remains) {
@ -428,11 +400,11 @@ lib_syntax::MatchCursor::ErrsPack::ErrsPack(const ErrsPack& other)
: _error_collection(other._error_collection) { : _error_collection(other._error_collection) {
} }
void lib_syntax::MatchCursor::ErrsPack::addError(std::shared_ptr<const lib_words::IPrimitiveWord> t, const QString& msg) { void MatchCursor::ErrsPack::addError(const QString& msg) {
this->_error_collection << std::make_pair(t, msg); this->_error_collection.append(msg);
} }
QList<std::pair<std::shared_ptr<const lib_words::IPrimitiveWord>, QString>> MatchCursor::ErrsPack::errors() const { QList<QString> MatchCursor::ErrsPack::errors() const {
return _error_collection; return _error_collection;
} }

View File

@ -6,7 +6,6 @@
#include <memory> #include <memory>
#include <QtCore/QList> #include <QtCore/QList>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QHash>
#include <tuple> #include <tuple>
#include <functional> #include <functional>
#include "ast_basic.h" #include "ast_basic.h"
@ -41,12 +40,12 @@ namespace lib_syntax {
ErrsPack(); ErrsPack();
ErrsPack(const ErrsPack& other); ErrsPack(const ErrsPack& other);
void addError(std::shared_ptr<const lib_words::IPrimitiveWord>, const QString& msg); void addError(const QString& msg);
QList<std::pair<std::shared_ptr<const lib_words::IPrimitiveWord>, QString>> errors() const; QList<QString> errors() const;
uint64_t errorCount() const; uint64_t errorCount() const;
private: private:
QList<std::pair<std::shared_ptr<const lib_words::IPrimitiveWord>, QString>> _error_collection; QList<QString> _error_collection;
}; };
MatchCursor(const QString& path); MatchCursor(const QString& path);
@ -60,12 +59,11 @@ namespace lib_syntax {
virtual QString parseSyntax() const; virtual QString parseSyntax() const;
virtual void enterExprs(); virtual void enterExprs();
virtual void logExprsError(std::shared_ptr<const lib_words::IPrimitiveWord> t, const QString& msg); virtual void logExprsError(const QString& msg);
virtual void quitExprs(); virtual void quitExprs();
virtual int exprsErrorCount() const; virtual int exprsErrorCount() const;
virtual int totalErrorCount() const; virtual int totalErrorCount() const;
virtual QList<QString> totalErrors() const; virtual QList<QString> totalErrors() const;
virtual void mergeWith(const MatchCursor &other);
virtual bool parseFailure() const; virtual bool parseFailure() const;
virtual void setFailure(bool mark = true); virtual void setFailure(bool mark = true);
@ -81,7 +79,7 @@ namespace lib_syntax {
std::shared_ptr<const MatchCursor> _prev_cursor = nullptr; std::shared_ptr<const MatchCursor> _prev_cursor = nullptr;
bool _parse_stop_with_errors = false, _parse_complete = false; bool _parse_stop_with_errors = false, _parse_complete = false;
QHash<qulonglong, QStringList> _total_errors; // 所有解析错误 QList<QString> _total_errors; // 所有解析错误
QList<std::shared_ptr<ErrsPack>> _exprs_errors; // 当前表达式解析错误 QList<std::shared_ptr<ErrsPack>> _exprs_errors; // 当前表达式解析错误
std::shared_ptr<const lib_token::IActionToken> _current_token = nullptr; // 当前Token std::shared_ptr<const lib_token::IActionToken> _current_token = nullptr; // 当前Token
std::shared_ptr<const lib_words::IPrimitiveWord> _remains_word = nullptr; // 剩余词语 std::shared_ptr<const lib_words::IPrimitiveWord> _remains_word = nullptr; // 剩余词语
@ -211,7 +209,7 @@ namespace lib_syntax {
// 只有在表达式的起始点遇到nullptr才是正常结束。 // 只有在表达式的起始点遇到nullptr才是正常结束。
if (current->token()->tokenType() != lib_token::IActionToken::Type::ElementBegin) { if (current->token()->tokenType() != lib_token::IActionToken::Type::ElementBegin) {
auto ncurs = std::make_shared<MatchCursor>(current); auto ncurs = std::make_shared<MatchCursor>(current);
ncurs->logExprsError(nullptr, QString("SyntaxError[0x00001]输入错误,程序提前结束:%1。").arg(current->filePath())); ncurs->logExprsError(QString("SyntaxError[0x00001]输入错误,程序提前结束:%1。").arg(current->filePath()));
ncurs->setFailure(); ncurs->setFailure();
return QList<std::shared_ptr<const MatchCursor>>() << ncurs; return QList<std::shared_ptr<const MatchCursor>>() << ncurs;
} }
@ -243,7 +241,7 @@ namespace lib_syntax {
QList<std::shared_ptr<const MatchCursor>> retvals; QList<std::shared_ptr<const MatchCursor>> retvals;
// 少一个 // 少一个
auto short_one = std::make_shared<MatchCursor>(current); auto short_one = std::make_shared<MatchCursor>(current);
short_one->logExprsError(w_this, QString("SyntaxError[0x00002]语法匹配错误,缺失\"%1\"<row:%2,col:%3,file<%4>>") short_one->logExprsError(QString("SyntaxError[0x00002]语法匹配错误,缺失\"%1\"<row:%2,col:%3,file<%4>>")
.arg(this->_define_peers->reviseWords()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file())); .arg(this->_define_peers->reviseWords()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file()));
auto tkins0 = std::make_shared<lib_token::TokenContent>(w_this->row(), w_this->column(), w_this->position(), auto tkins0 = std::make_shared<lib_token::TokenContent>(w_this->row(), w_this->column(), w_this->position(),
QString("<+%1>").arg(this->_define_peers->reviseWords()), w_this->file(), this->_define_peers); QString("<+%1>").arg(this->_define_peers->reviseWords()), w_this->file(), this->_define_peers);
@ -253,7 +251,7 @@ namespace lib_syntax {
// 错一个 // 错一个
auto error_one = std::make_shared<MatchCursor>(current); auto error_one = std::make_shared<MatchCursor>(current);
error_one->logExprsError(w_this, QString("SyntaxError[0x00003]语法匹配错误,请修正\"%1\"<row:%2,col:%3,file<%4>>") error_one->logExprsError(QString("SyntaxError[0x00003]语法匹配错误,请修正\"%1\"<row:%2,col:%3,file<%4>>")
.arg(w_this->content()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file())); .arg(w_this->content()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file()));
auto tkins = std::make_shared<lib_token::TokenContent>(w_this->row(), w_this->column(), w_this->position(), auto tkins = std::make_shared<lib_token::TokenContent>(w_this->row(), w_this->column(), w_this->position(),
QString("<%1(%2)>").arg(w_this->content()).arg(this->_define_peers->reviseWords()), w_this->file(), this->_define_peers); QString("<%1(%2)>").arg(w_this->content()).arg(this->_define_peers->reviseWords()), w_this->file(), this->_define_peers);
@ -273,7 +271,7 @@ namespace lib_syntax {
} }
auto clone_ins = std::make_shared<MatchCursor>(current); auto clone_ins = std::make_shared<MatchCursor>(current);
clone_ins->logExprsError(w_this, QString("SyntaxError[0x00004]语法匹配错误,请删除\"%1\"<row:%2,col:%3,file<%4>>") clone_ins->logExprsError(QString("SyntaxError[0x00004]语法匹配错误,请删除\"%1\"<row:%2,col:%3,file<%4>>")
.arg(w_this->content()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file())); .arg(w_this->content()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file()));
clone_ins->setCurrent(chain, remains); clone_ins->setCurrent(chain, remains);
retvals << clone_ins; retvals << clone_ins;
@ -309,7 +307,7 @@ namespace lib_syntax {
virtual QList<std::shared_ptr<const MatchCursor>> parse(std::shared_ptr<const MatchCursor> cursor) const override { virtual QList<std::shared_ptr<const MatchCursor>> parse(std::shared_ptr<const MatchCursor> cursor) const override {
// 提前结束,直接返回 // 提前结束,直接返回
if (cursor->parseFailure() || cursor->parseComplete()) if (cursor->parseFailure() && cursor->parseComplete())
return QList<std::shared_ptr<const MatchCursor>>() << cursor; return QList<std::shared_ptr<const MatchCursor>>() << cursor;
auto syntax = present(); auto syntax = present();
@ -339,14 +337,6 @@ namespace lib_syntax {
std::copy_if(nbranch.begin(), nbranch.end(), std::copy_if(nbranch.begin(), nbranch.end(),
std::back_inserter(branch_procs), std::back_inserter(branch_procs),
[](std::shared_ptr<const MatchCursor> ins) { return !ins->parseFailure(); }); [](std::shared_ptr<const MatchCursor> ins) { return !ins->parseFailure(); });
if(branch_procs.size()){
auto first_cursor = branch_procs.first();
for (auto curr = ++branch_procs.begin(); curr != branch_procs.end(); curr++) {
std::const_pointer_cast<lib_syntax::MatchCursor>(first_cursor)->mergeWith(**curr);
}
branch_procs = { first_cursor };
}
} }
// 表达式匹配结尾 // 表达式匹配结尾
@ -373,7 +363,7 @@ namespace lib_syntax {
} }
// 匹配失败 // 匹配失败
return nbranch; return branch_procs;
} }
protected: protected:

View File

@ -110,9 +110,3 @@ int WordContent::column() const {
std::shared_ptr<const IPrimitiveWord> WordContent::nextWord() const { std::shared_ptr<const IPrimitiveWord> WordContent::nextWord() const {
return nullptr; return nullptr;
} }
LIBWORDS_EXPORT uint lib_words::qHash(const std::shared_ptr<const IPrimitiveWord>& t, uint seed) noexcept {
if(t)
return qHash(QString("W:%1").arg(t->position()), seed);
return qHash(QString(), seed);
}

View File

@ -117,8 +117,4 @@ namespace lib_words {
WordsException(const QString& message); WordsException(const QString& message);
virtual QString message() const; virtual QString message() const;
}; };
LIBWORDS_EXPORT uint qHash(const std::shared_ptr<const IPrimitiveWord>& t, uint seed = 0) Q_DECL_NOTHROW;
} }