update
This commit is contained in:
parent
b4e1f2a34c
commit
74ce31b072
|
@ -14,7 +14,7 @@ int main(int argc, char* argv[]) {
|
|||
QFile in("D:\\Projects\\Cpp\\WsNovelParser\\x64\\test_file\\description - 副本.story");
|
||||
in.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
QTextStream tt(&in);
|
||||
tt.setCodec("UTF-8");
|
||||
//tt.setCodec("UTF-8");
|
||||
lib_words::WordReader reader;
|
||||
auto vwords = reader.wordsFrom(tt, "D:\\Projects\\Cpp\\WsNovelParser\\x64\\test_file\\description - 副本.story");
|
||||
|
||||
|
|
|
@ -8,8 +8,24 @@
|
|||
#include <parse_novel.h>
|
||||
|
||||
namespace printer {
|
||||
/**
|
||||
* 概括页面
|
||||
* 故事分卷汇总
|
||||
* 故事脉络汇总
|
||||
* 故事脉络关系图.
|
||||
*
|
||||
* 故事脉络发展页面
|
||||
* 故事剧情节点汇总
|
||||
* 内容展示
|
||||
*
|
||||
* 剧情节点汇总页面
|
||||
* 引用来源汇总
|
||||
* 各节点内容展示
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @brief 所有可访问元素的基类:卷宗、故事线、剧情、节点等
|
||||
* @brief 所有可访问元素的基类:卷宗、章节、故事线、剧情、节点、引用等
|
||||
*/
|
||||
class Access : public std::enable_shared_from_this<Access> {
|
||||
public:
|
||||
|
|
|
@ -19,7 +19,7 @@ QString TextSection::content() const {
|
|||
}
|
||||
|
||||
QString TextSection::signature() const {
|
||||
return "::section";
|
||||
return parent().lock()->signature() + "&::section";
|
||||
}
|
||||
|
||||
PointRefers::PointRefers(std::shared_ptr<const ExprRule> rule_bind)
|
||||
|
|
|
@ -131,13 +131,9 @@ namespace example_novel {
|
|||
|
||||
template<NovelNode type, bool named>
|
||||
class AbstractImpl : public ast_basic::ExprInstance, public ast_gen::SyntaxElement {
|
||||
private:
|
||||
std::weak_ptr<const SyntaxElement> parent_store;
|
||||
|
||||
public:
|
||||
AbstractImpl(std::shared_ptr<const lib_syntax::ExprRule> rule_bind)
|
||||
: ExprInstance(rule_bind) {
|
||||
parent_store.reset();
|
||||
}
|
||||
|
||||
// 通过 SyntaxElement 继承
|
||||
|
|
|
@ -9,7 +9,18 @@ using namespace lib_token;
|
|||
using namespace lib_words;
|
||||
using namespace ast_basic;
|
||||
|
||||
__anyone_impl::__anyone_impl(const QList<std::shared_ptr<const IBasicRule>> mbrs) : mbrs_store(mbrs) { }
|
||||
auto content_extractm = [](std::shared_ptr<const lib_token::IActionToken> token) {
|
||||
QString content;
|
||||
while (token) {
|
||||
if (token->defines())
|
||||
content.prepend(token->content() + " ");
|
||||
token = token->prevToken();
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
__anyone_impl::__anyone_impl(const QList<std::shared_ptr<const IBasicRule>> mbrs) : mbrs_store(mbrs) {
|
||||
}
|
||||
|
||||
QList<std::shared_ptr<const IBasicRule>> __anyone_impl::children() const {
|
||||
return mbrs_store;
|
||||
|
@ -24,23 +35,31 @@ QList<std::shared_ptr<const MatchCursor>> __anyone_impl::parse(std::shared_ptr<c
|
|||
for (auto rx : this->children())
|
||||
result_list.append(rx->parse(cursor));
|
||||
|
||||
// 完全匹配分支
|
||||
// 完全匹配分支,必须有匹配进展
|
||||
decltype(result_list) completely_list;
|
||||
std::copy_if(result_list.begin(), result_list.end(), std::back_inserter(completely_list),
|
||||
[&](std::shared_ptr<const MatchCursor> ins) {
|
||||
return cursor->totalErrorCount() == ins->totalErrorCount() || ins->parseComplete();
|
||||
return (cursor->totalErrorCount() == ins->totalErrorCount() && ins->operator>(*cursor))
|
||||
|| ins->parseComplete();
|
||||
});
|
||||
if (completely_list.size())
|
||||
return completely_list;
|
||||
return completely_list.mid(0,1);
|
||||
|
||||
// 经过修正的分支
|
||||
// 经过修正的分支,必须有变化
|
||||
decltype(result_list) modify_list;
|
||||
std::copy_if(result_list.begin(), result_list.end(), std::back_inserter(modify_list),
|
||||
[&](std::shared_ptr<const MatchCursor> ins) { return !ins->parseFailure(); });
|
||||
std::copy_if(result_list.begin(), result_list.end(),
|
||||
std::back_inserter(modify_list),
|
||||
[&](std::shared_ptr<const MatchCursor> ins) {
|
||||
return !ins->parseFailure() && ins->totalErrorCount() > cursor->totalErrorCount();
|
||||
});
|
||||
if (modify_list.size())
|
||||
return modify_list;
|
||||
|
||||
return result_list;
|
||||
// 匹配失败的分支
|
||||
decltype(result_list) errors_list;
|
||||
std::copy_if(result_list.begin(), result_list.end(),
|
||||
std::back_inserter(errors_list), [](std::shared_ptr<const MatchCursor> it) { return it->parseFailure(); });
|
||||
return errors_list;
|
||||
}
|
||||
|
||||
QString __anyone_impl::present() const {
|
||||
|
@ -51,7 +70,9 @@ QString __anyone_impl::present() const {
|
|||
return members_content.mid(0, members_content.size() - 1);
|
||||
}
|
||||
|
||||
__sequence_impl::__sequence_impl(const QList<std::shared_ptr<const IBasicRule>> mbrs) : mbrs_store(mbrs) { }
|
||||
__sequence_impl::__sequence_impl(const QList<std::shared_ptr<const IBasicRule>> mbrs)
|
||||
: mbrs_store(mbrs) {
|
||||
}
|
||||
|
||||
QList<std::shared_ptr<const IBasicRule>> __sequence_impl::children() const {
|
||||
return mbrs_store;
|
||||
|
@ -77,7 +98,7 @@ QList<std::shared_ptr<const MatchCursor>> __sequence_impl::parse(std::shared_ptr
|
|||
return cursor->totalErrorCount() == ins->totalErrorCount() || ins->parseComplete();
|
||||
});
|
||||
if (temprary_list.size()) {
|
||||
bridge_list = temprary_list;
|
||||
bridge_list = temprary_list.mid(0,1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -95,7 +116,19 @@ QList<std::shared_ptr<const MatchCursor>> __sequence_impl::parse(std::shared_ptr
|
|||
break;
|
||||
}
|
||||
|
||||
return bridge_list;
|
||||
decltype(bridge_list) temprary_list;
|
||||
// 匹配代码有进展或者匹配成功
|
||||
std::copy_if(bridge_list.begin(), bridge_list.end(),
|
||||
std::back_inserter(temprary_list), [&](std::shared_ptr<const MatchCursor> ins) {
|
||||
return ins->operator>(*cursor) || ins->parseComplete();
|
||||
});
|
||||
|
||||
if (temprary_list.size())
|
||||
return temprary_list;
|
||||
|
||||
std::copy_if(bridge_list.begin(), bridge_list.end(),
|
||||
std::back_inserter(temprary_list), [](std::shared_ptr<const MatchCursor> ins) { return ins->parseFailure(); });
|
||||
return temprary_list;
|
||||
}
|
||||
|
||||
QString __sequence_impl::present() const {
|
||||
|
@ -106,23 +139,14 @@ QString __sequence_impl::present() const {
|
|||
}
|
||||
|
||||
__repeat_impl::__repeat_impl(std::shared_ptr<const IBasicRule> rule, int min, int max)
|
||||
: rule_peer(rule), min_match(min), max_match(max) { }
|
||||
: rule_peer(rule), min_match(min), max_match(max) {
|
||||
}
|
||||
|
||||
QList<std::shared_ptr<const IBasicRule>> __repeat_impl::children() const {
|
||||
return QList<std::shared_ptr<const IBasicRule>>() << rule_peer;
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
auto content_extractw = [](std::shared_ptr<const lib_token::IActionToken> token) {
|
||||
QString content;
|
||||
while (token) {
|
||||
if (token->defines())
|
||||
content.prepend(token->content() + " ");
|
||||
token = token->prevToken();
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
QList<std::shared_ptr<const MatchCursor>> __repeat_impl::parse(std::shared_ptr<const MatchCursor> cursor) const {
|
||||
if (cursor->parseFailure() && cursor->parseComplete())
|
||||
return QList<std::shared_ptr<const MatchCursor>>() << cursor;
|
||||
|
@ -164,24 +188,23 @@ QList<std::shared_ptr<const MatchCursor>> __repeat_impl::parse(std::shared_ptr<c
|
|||
|
||||
QList<QString> contents;
|
||||
for (auto bx : current_list)
|
||||
contents << content_extractw(bx->token()) + QStringList(bx->totalErrors()).join(',');
|
||||
contents << content_extractm(bx->token()) + QStringList(bx->totalErrors()).join(',');
|
||||
|
||||
// 提取完全匹配的分支
|
||||
QList<std::shared_ptr<const MatchCursor>> temprary_branchs;
|
||||
std::copy_if(current_list.begin(), current_list.end(),
|
||||
std::back_inserter(temprary_branchs), [&](std::shared_ptr<const MatchCursor> ins) {
|
||||
return ins->parseComplete() || (cursor->totalErrorCount() == ins->totalErrorCount() &&
|
||||
ins->token()->position() > cursor->token()->position());
|
||||
return (cursor->totalErrorCount() == ins->totalErrorCount() && (*ins) > (*cursor)) || ins->parseComplete();
|
||||
});
|
||||
if (temprary_branchs.size()) {
|
||||
bridge_list = temprary_branchs;
|
||||
bridge_list = temprary_branchs.mid(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 提取语法修正分支
|
||||
std::copy_if(current_list.begin(), current_list.end(),
|
||||
std::back_inserter(temprary_branchs), [&](std::shared_ptr<const MatchCursor> ins) {
|
||||
return !ins->parseFailure() && ins->token()->position() > cursor->token()->position();
|
||||
return !ins->parseFailure() && (*ins) > (*cursor);
|
||||
});
|
||||
if (temprary_branchs.size()) {
|
||||
bridge_list = temprary_branchs;
|
||||
|
@ -193,21 +216,17 @@ QList<std::shared_ptr<const MatchCursor>> __repeat_impl::parse(std::shared_ptr<c
|
|||
results.append(bridge_list);
|
||||
std::sort(results.begin(), results.end(),
|
||||
[](std::shared_ptr<const MatchCursor> a, std::shared_ptr<const MatchCursor> b) {
|
||||
return a->token()->position() > b->token()->position();
|
||||
return a->operator>(*b);
|
||||
});
|
||||
|
||||
// 提取完全匹配的分支
|
||||
decltype(results) rets_completely;
|
||||
for (auto ins : results) {
|
||||
if (ins->totalErrorCount() == cursor->totalErrorCount()) {
|
||||
if (!rets_completely.size()) {
|
||||
rets_completely.append(ins);
|
||||
}
|
||||
else if (rets_completely.last()->token()->position() == ins->token()->position()) {
|
||||
rets_completely.append(ins);
|
||||
}
|
||||
if (ins->totalErrorCount() == cursor->totalErrorCount() && !rets_completely.size()) {
|
||||
rets_completely.append(ins);
|
||||
break;
|
||||
}
|
||||
else if(ins->parseComplete())
|
||||
else if (ins->parseComplete())
|
||||
rets_completely.append(ins);
|
||||
}
|
||||
|
||||
|
@ -255,7 +274,8 @@ QString SyntaxException::message() const {
|
|||
}
|
||||
|
||||
ExprRule::ExprRule(const QString& rule_name, int expr_mark)
|
||||
: name_store(rule_name), mark_store(expr_mark) { }
|
||||
: name_store(rule_name), mark_store(expr_mark) {
|
||||
}
|
||||
|
||||
QString ExprRule::name() const {
|
||||
return name_store;
|
||||
|
@ -266,7 +286,8 @@ int ExprRule::typeMark() const {
|
|||
}
|
||||
|
||||
#include <ast_novel.h>
|
||||
MatchCursor::MatchCursor(const QString& path) :_file_path(path) { }
|
||||
MatchCursor::MatchCursor(const QString& path) :_file_path(path) {
|
||||
}
|
||||
|
||||
MatchCursor::MatchCursor(std::shared_ptr<const MatchCursor> other_ptr)
|
||||
: _prev_cursor(other_ptr),
|
||||
|
@ -279,6 +300,11 @@ MatchCursor::MatchCursor(std::shared_ptr<const MatchCursor> other_ptr)
|
|||
}
|
||||
}
|
||||
|
||||
bool lib_syntax::MatchCursor::operator>(const MatchCursor& other) const {
|
||||
return _current_token->position() > other._current_token->position() ||
|
||||
(_current_token->position() == other._current_token->position() && _total_errors.size() > other._total_errors.size());
|
||||
}
|
||||
|
||||
std::shared_ptr<const MatchCursor> MatchCursor::previous() const {
|
||||
return _prev_cursor;
|
||||
}
|
||||
|
@ -367,10 +393,12 @@ std::shared_ptr<const IPrimitiveWord> MatchCursor::words() const {
|
|||
return this->_remains_word;
|
||||
}
|
||||
|
||||
lib_syntax::MatchCursor::ErrsPack::ErrsPack() { }
|
||||
lib_syntax::MatchCursor::ErrsPack::ErrsPack() {
|
||||
}
|
||||
|
||||
lib_syntax::MatchCursor::ErrsPack::ErrsPack(const ErrsPack& other)
|
||||
: _error_collection(other._error_collection) { }
|
||||
: _error_collection(other._error_collection) {
|
||||
}
|
||||
|
||||
void MatchCursor::ErrsPack::addError(const QString& msg) {
|
||||
this->_error_collection.append(msg);
|
||||
|
|
|
@ -52,6 +52,8 @@ namespace lib_syntax {
|
|||
MatchCursor(std::shared_ptr<const MatchCursor> other_ptr);
|
||||
virtual ~MatchCursor() = default;
|
||||
|
||||
bool operator>(const MatchCursor & other) const;
|
||||
|
||||
virtual std::shared_ptr<const MatchCursor> previous() const;
|
||||
virtual QString filePath() const;
|
||||
virtual QString parseSyntax() const;
|
||||
|
@ -239,18 +241,19 @@ namespace lib_syntax {
|
|||
// 少一个
|
||||
auto short_one = std::make_shared<MatchCursor>(current);
|
||||
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(),
|
||||
QString("<+%1>").arg(this->_define_peers->reviseWords()), w_this->file(), this->_define_peers);
|
||||
auto tkchain0 = std::make_shared<lib_token::ActionToken<ELEM, XProc>>(tkins0, t_this);
|
||||
short_one->setCurrent(tkchain0, w_this);
|
||||
retvals << short_one;
|
||||
|
||||
// 错一个
|
||||
auto error_one = std::make_shared<MatchCursor>(current);
|
||||
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()));
|
||||
auto tkins = std::make_shared<lib_token::TokenContent>(
|
||||
w_this->row(), w_this->column(), w_this->position(),
|
||||
QString("%2_%1").arg((uint64_t) error_one.get()).arg(this->_define_peers->reviseWords()),
|
||||
w_this->file(), this->_define_peers);
|
||||
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);
|
||||
auto tkchain = std::make_shared<lib_token::ActionToken<ELEM, XProc>>(tkins, t_this);
|
||||
error_one->setCurrent(tkchain, w_this->nextWord());
|
||||
retvals << error_one;
|
||||
|
@ -340,8 +343,9 @@ namespace lib_syntax {
|
|||
|
||||
decltype(nbranch) results_fnl;
|
||||
for (auto curs : branch_procs) {
|
||||
if (curs->parseFailure())
|
||||
if (curs->parseFailure()) {
|
||||
results_fnl.append(curs);
|
||||
}
|
||||
else {
|
||||
auto t_end = curs->token();
|
||||
auto w_end = curs->words();
|
||||
|
@ -352,6 +356,12 @@ namespace lib_syntax {
|
|||
auto split_end = std::make_shared<lib_token::ExprEndToken<ExprType>>(split_begin, t_end);
|
||||
ecursor->setCurrent(split_end, w_end);
|
||||
results_fnl.append(ecursor);
|
||||
|
||||
if (curs->totalErrorCount() == cursor->totalErrorCount()) {
|
||||
results_fnl.clear();
|
||||
results_fnl.append(ecursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,15 +49,15 @@ void rank_set(std::shared_ptr<RankDeclare> inst, std::shared_ptr<const lib_token
|
|||
inst->setRank(token->content().toInt());
|
||||
}
|
||||
|
||||
auto content_extract = [](std::shared_ptr<const lib_token::IActionToken> token) {
|
||||
QString content;
|
||||
while (token) {
|
||||
if (token->defines())
|
||||
content.prepend(token->content() + " ");
|
||||
token = token->prevToken();
|
||||
}
|
||||
return content;
|
||||
};
|
||||
//auto content_extract = [](std::shared_ptr<const lib_token::IActionToken> token) {
|
||||
// QString content;
|
||||
// while (token) {
|
||||
// if (token->defines())
|
||||
// content.prepend(token->content() + " ");
|
||||
// token = token->prevToken();
|
||||
// }
|
||||
// return content;
|
||||
// };
|
||||
|
||||
using TextDeclsSyntaxDef = Any<Match<Numbers>, Match<NormalText>>;
|
||||
class DeclSyntax : public ElementRule<TextSection, (int) NovelNode::TextSection, TextDeclsSyntaxDef> {
|
||||
|
@ -192,13 +192,13 @@ public:
|
|||
// 通过 ElementRule 继承
|
||||
QList<std::shared_ptr<const MatchCursor>> expr_rule_parse(std::shared_ptr<const MatchCursor> cursor) const override {
|
||||
auto syntax = this->present();
|
||||
auto current_rst = content_extract(cursor->token());
|
||||
//auto current_rst = content_extract(cursor->token());
|
||||
auto rst = _children_store->parse(cursor);
|
||||
|
||||
QString result_list;
|
||||
/* QString result_list;
|
||||
for (auto c : rst) {
|
||||
result_list += content_extract(c->token()) += "\n";
|
||||
}
|
||||
}*/
|
||||
|
||||
return rst;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue