修复无尽膨胀等待问题

This commit is contained in:
codeboss 2025-02-24 15:02:23 +08:00
parent ec98c062cb
commit ca04e572be
8 changed files with 107 additions and 24 deletions

View File

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

View File

@ -0,0 +1,6 @@
// 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

@ -0,0 +1,13 @@
<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,7 +38,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoreTest", "CoreTest\CoreTe
{EF557F71-99AA-4F2B-A5F5-1A4518A11C19} = {EF557F71-99AA-4F2B-A5F5-1A4518A11C19}
EndProjectSection
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "AstConv", "AstConv\AstConv.fsproj", "{0C77216C-6484-4C94-BE06-D5D9FF18EA81}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -134,6 +136,18 @@ Global
{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.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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

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 {
if (cursor->parseFailure() && cursor->parseComplete())
if (cursor->parseFailure() || cursor->parseComplete())
return QList<std::shared_ptr<const MatchCursor>>() << cursor;
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 {
if (cursor->parseFailure() && cursor->parseComplete())
if (cursor->parseFailure() || cursor->parseComplete())
return QList<std::shared_ptr<const MatchCursor>>() << 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>
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;
auto syntax = present();
@ -338,9 +338,15 @@ void MatchCursor::enterExprs() {
this->_exprs_errors.push_back(new_expr);
}
void MatchCursor::logExprsError(const QString& msg) {
this->_total_errors.push_back(msg);
this->_exprs_errors.last()->addError(msg);
void lib_syntax::MatchCursor::logExprsError(std::shared_ptr<const lib_words::IPrimitiveWord> t, const QString& msg) {
if(!this->_total_errors.contains(t->position()))
this->_total_errors[t->position()] = QStringList();
auto exists = this->_total_errors[t->position()];
exists.append(msg);
this->_total_errors[t->position()] = exists;
this->_exprs_errors.last()->addError(t, msg);
// 普适性质的判定标准
this->setFailure(this->exprsErrorCount() > 1);
@ -377,7 +383,28 @@ int MatchCursor::totalErrorCount() const {
}
QList<QString> MatchCursor::totalErrors() const {
return this->_total_errors;
QStringList flist;
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) {
@ -400,11 +427,11 @@ lib_syntax::MatchCursor::ErrsPack::ErrsPack(const ErrsPack& other)
: _error_collection(other._error_collection) {
}
void MatchCursor::ErrsPack::addError(const QString& msg) {
this->_error_collection.append(msg);
void lib_syntax::MatchCursor::ErrsPack::addError(std::shared_ptr<const lib_words::IPrimitiveWord> t, const QString& msg) {
this->_error_collection << std::make_pair(t, msg);
}
QList<QString> MatchCursor::ErrsPack::errors() const {
QList<std::pair<std::shared_ptr<const lib_words::IPrimitiveWord>, QString>> MatchCursor::ErrsPack::errors() const {
return _error_collection;
}

View File

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

View File

@ -110,3 +110,9 @@ int WordContent::column() const {
std::shared_ptr<const IPrimitiveWord> WordContent::nextWord() const {
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,4 +117,8 @@ namespace lib_words {
WordsException(const QString& message);
virtual QString message() const;
};
LIBWORDS_EXPORT uint qHash(const std::shared_ptr<const IPrimitiveWord>& t, uint seed = 0) Q_DECL_NOTHROW;
}