WsParser_VS/libParse/parse_novel.cpp

226 lines
6.0 KiB
C++
Raw Normal View History

2024-03-17 07:58:28 +00:00
#include "parse_novel.h"
#include <ast_novel.h>
#include <iterator>
2024-06-15 01:18:33 +00:00
#include <QTime>
2024-03-17 07:58:28 +00:00
using namespace example_novel;
using namespace ast_basic;
using namespace ast_gen;
using namespace lib_syntax;
using namespace example_novel;
2024-06-19 14:45:55 +00:00
void FragmentExistsCheck::exists_check(std::shared_ptr<const GlobalElement> root,
std::shared_ptr<const ElementAccess> target) const {
2024-06-15 08:09:19 +00:00
if (target->element()->typeMark() == (int)NovelNode::FragmentRefer) {
auto refer = std::dynamic_pointer_cast<const FragmentRefers>(target->element());
2024-03-17 07:58:28 +00:00
auto signature = refer->storyRefer() + u8"&" + refer->fragmentRefer();
2024-06-15 08:09:19 +00:00
root->getNamedNodeBy((int)NovelNode::FragmentDefine, signature);
2024-03-17 07:58:28 +00:00
}
for (auto& xit : target->children()) {
exists_check(root, xit);
}
}
2024-06-19 14:45:55 +00:00
void FragmentExistsCheck::validCheck(std::shared_ptr<const ElementAccess> root) const {
this->exists_check(std::dynamic_pointer_cast<const GlobalElement>(root->element()), root);
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
QString FragmentExistsCheck::name() const {
return u8"FragmentExistsCheck";
2024-03-17 07:58:28 +00:00
}
2024-06-19 14:45:55 +00:00
QList<std::shared_ptr<FragmentGraphHelper>> FragmentGraphCheck::refers_cycle_check(
2024-06-15 08:52:16 +00:00
std::shared_ptr<FragmentGraphHelper> item, QList<std::shared_ptr<FragmentGraphHelper>> prevs) const {
if (prevs.contains(item)) {
return prevs << item;
}
auto next_list = item->nextList();
if (next_list.size()) {
prevs << item;
for (auto next : next_list) {
auto ref_link = refers_cycle_check(next, prevs);
if (ref_link.size())
return ref_link;
}
}
return QList<std::shared_ptr<FragmentGraphHelper>>();
}
2024-06-15 08:09:19 +00:00
void FragmentGraphCheck::setElement(std::shared_ptr<FragmentGraphHelper> inst)
2024-03-17 07:58:28 +00:00
{
2024-06-15 08:09:19 +00:00
elements_store[inst->nodePeer()->signature()] = inst;
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
std::shared_ptr<FragmentGraphHelper> FragmentGraphCheck::getElement(const QString& signature) const
{
return elements_store[signature];
2024-03-17 07:58:28 +00:00
}
2024-06-19 14:45:55 +00:00
QList<std::shared_ptr<FragmentGraphHelper>> FragmentGraphCheck::getHangoutNodes() {
2024-06-15 08:09:19 +00:00
QList<std::shared_ptr<FragmentGraphHelper>> values;
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
for (auto node_item : elements_store) {
if (!node_item->inDegree())
values.append(node_item);
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
for (auto inst : values) {
auto name = inst->nodePeer()->signature();
elements_store.remove(name);
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
return values;
2024-03-17 07:58:28 +00:00
}
2024-06-19 14:45:55 +00:00
bool FragmentGraphCheck::nodeDismantle(std::shared_ptr<FragmentGraphHelper> inst) {
2024-06-15 08:09:19 +00:00
bool flag = false;
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
for (auto item : inst->nextList()) {
item->inDegree()--;
flag = true;
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
return flag;
2024-05-04 15:34:21 +00:00
}
2024-06-19 14:45:55 +00:00
void FragmentGraphCheck::validCheck(std::shared_ptr<const ElementAccess> root) const
2024-03-17 07:58:28 +00:00
{
2024-06-19 14:45:55 +00:00
std::function<QList<std::shared_ptr<const ElementAccess>>(std::shared_ptr<const ElementAccess>)> story_peak
= [&](std::shared_ptr<const ElementAccess> root)->QList<std::shared_ptr<const ElementAccess>> {
QList<std::shared_ptr<const ElementAccess>> return_temp;
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
auto type_mark = (NovelNode)root->element()->typeMark();
if (type_mark == NovelNode::StoryDefine) {
return_temp << root;
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
for (auto child : root->children()) {
return_temp.append(story_peak(child));
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
return return_temp;
};
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
auto self = std::const_pointer_cast<FragmentGraphCheck>(this->shared_from_this());
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD>
auto all_story = story_peak(root);
// ע<><D7A2>ͼ<EFBFBD>ڵ<EFBFBD>
for (auto story : all_story) {
auto fragment_items = story->children();
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڽڵ<DABD><DAB5>б<EFBFBD>
for (auto frag_primitive : fragment_items) {
switch (frag_primitive->element()->typeMark()) {
case (int)NovelNode::FragmentDefine: {
auto target_node = std::dynamic_pointer_cast<const FragmentDefine>(frag_primitive->element());
auto finst = std::make_shared<FragmentGraphHelper>(target_node);
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
self->setElement(finst);
}break;
default: break;
}
}
}
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>
for (auto story : all_story) {
auto fragment_items = story->children();
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
// <20><><EFBFBD>˻<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>ڽڵ<DABD>
for (auto idx = 0; idx < fragment_items.size(); idx++) {
auto fragment_inst = fragment_items[idx];
switch (fragment_inst->element()->typeMark())
{
case (int)NovelNode::FragmentDefine:
case (int)NovelNode::FragmentRefer:
break;
2024-03-17 07:58:28 +00:00
default:
2024-06-15 08:09:19 +00:00
fragment_items.removeAt(idx);
idx--;
2024-03-17 07:58:28 +00:00
break;
}
}
2024-06-19 14:45:55 +00:00
auto get_name = [](std::shared_ptr<const ElementAccess> node)->QString {
2024-06-15 08:09:19 +00:00
switch (node->element()->typeMark()) {
case (int)NovelNode::FragmentDefine: {
2024-06-19 14:45:55 +00:00
auto def_node = std::dynamic_pointer_cast<const FragmentDefine>(node->element());
2024-06-15 08:09:19 +00:00
return def_node->signature();
}break;
case (int)NovelNode::FragmentRefer: {
2024-06-19 14:45:55 +00:00
auto ref_node = std::dynamic_pointer_cast<const FragmentRefers>(node->element());
2024-06-15 08:09:19 +00:00
return ref_node->referSignature();
}break;
}
return QString();
};
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD>
for (auto fidx = 1; fidx < fragment_items.size(); fidx++) {
auto tail_name = get_name(fragment_items[fidx - 1]);
auto head_name = get_name(fragment_items[fidx]);
auto tail_helper = getElement(tail_name);
auto head_helper = getElement(head_name);
tail_helper->appendNext(head_helper);
head_helper->inDegree()++;
2024-03-17 07:58:28 +00:00
}
}
2024-06-15 08:09:19 +00:00
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
auto values = self->getHangoutNodes();
for (auto idx = 0; idx < values.size(); ++idx) {
auto target = values[idx];
2024-05-04 15:34:21 +00:00
2024-06-15 08:09:19 +00:00
self->nodeDismantle(target);
auto x_values = self->getHangoutNodes();
values.append(x_values);
2024-05-04 15:34:21 +00:00
}
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
// <20><><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>в<EFBFBD><D0B2><EFBFBD>
2024-06-15 08:52:16 +00:00
if (elements_store.size()) {
for (auto node : elements_store.values()) {
auto cycle_link = refers_cycle_check(node);
QString error_msg = u8"Parse[0x0006]<5D><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ڻ<EFBFBD><DABB>ν<CEBD><E1B9B9>\n";
for (auto n : cycle_link) {
error_msg += QString(u8"%1->").arg(n->nodePeer()->signature());
}
if (cycle_link.size())
throw new lib_parse::CheckException(error_msg);
}
}
2024-03-17 07:58:28 +00:00
}
2024-06-19 14:45:55 +00:00
QString FragmentGraphCheck::name() const {
2024-06-15 08:09:19 +00:00
return u8"FragmentGraphCheck";
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
FragmentGraphHelper::FragmentGraphHelper(std::shared_ptr<const FragmentDefine> node) : node_peer(node) {}
2024-03-17 07:58:28 +00:00
2024-06-15 08:09:19 +00:00
std::shared_ptr<const FragmentDefine> FragmentGraphHelper::nodePeer() const
2024-03-17 07:58:28 +00:00
{
2024-06-15 08:09:19 +00:00
return this->node_peer;
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
void FragmentGraphHelper::appendNext(std::shared_ptr<FragmentGraphHelper> node) {
this->next_nodes.append(node);
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
QList<std::shared_ptr<FragmentGraphHelper>> FragmentGraphHelper::nextList() const
{
return next_nodes;
2024-03-17 07:58:28 +00:00
}
2024-06-15 08:09:19 +00:00
uint& FragmentGraphHelper::inDegree()
{
return this->indegree;
2024-03-17 07:58:28 +00:00
}