修复无尽膨胀等待问题
This commit is contained in:
parent
ec98c062cb
commit
ca04e572be
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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"
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
Loading…
Reference in New Issue