Compare commits
2 Commits
16f89a2ee7
...
e84bb426f5
Author | SHA1 | Date |
---|---|---|
|
e84bb426f5 | |
|
44c93754dd |
|
@ -12,7 +12,7 @@ NovelParser::NovelParser()
|
||||||
{
|
{
|
||||||
this->syntax_defines = example_novel::NovalSyntax::getParseTree();
|
this->syntax_defines = example_novel::NovalSyntax::getParseTree();
|
||||||
checker_list << std::make_shared<example_novel::FragmentExistsCheck>();
|
checker_list << std::make_shared<example_novel::FragmentExistsCheck>();
|
||||||
checker_list << std::make_shared<example_novel::FragmentOrdersCheck>();
|
checker_list << std::make_shared<example_novel::FragmentGraphCheck>();
|
||||||
|
|
||||||
analyzer_ref = std::make_shared<lib_parse::Analyzer>(checker_list);
|
analyzer_ref = std::make_shared<lib_parse::Analyzer>(checker_list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,10 @@ using namespace example_novel;
|
||||||
|
|
||||||
void FragmentExistsCheck::exists_check(std::shared_ptr<const ast_gen::GlobalElement> root,
|
void FragmentExistsCheck::exists_check(std::shared_ptr<const ast_gen::GlobalElement> root,
|
||||||
std::shared_ptr<const ast_gen::ElementAccess> target) const {
|
std::shared_ptr<const ast_gen::ElementAccess> target) const {
|
||||||
if (target->element()->typeMark() == (int)example_novel::NovelNode::FragmentRefer) {
|
if (target->element()->typeMark() == (int)NovelNode::FragmentRefer) {
|
||||||
auto refer = std::dynamic_pointer_cast<const example_novel::FragmentRefers>(target->element());
|
auto refer = std::dynamic_pointer_cast<const FragmentRefers>(target->element());
|
||||||
auto signature = refer->storyRefer() + u8"&" + refer->fragmentRefer();
|
auto signature = refer->storyRefer() + u8"&" + refer->fragmentRefer();
|
||||||
root->getNamedNodeBy((int)example_novel::NovelNode::FragmentDefine, signature);
|
root->getNamedNodeBy((int)NovelNode::FragmentDefine, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& xit : target->children()) {
|
for (auto& xit : target->children()) {
|
||||||
|
@ -27,268 +27,199 @@ void FragmentExistsCheck::validCheck(std::shared_ptr<const ast_gen::ElementAcces
|
||||||
this->exists_check(std::dynamic_pointer_cast<const ast_gen::GlobalElement>(root->element()), root);
|
this->exists_check(std::dynamic_pointer_cast<const ast_gen::GlobalElement>(root->element()), root);
|
||||||
}
|
}
|
||||||
|
|
||||||
FragmentSortHelper::FragmentSortHelper(std::shared_ptr<const ast_gen::ElementAccess> node_bind, int story_sort) {
|
QString FragmentExistsCheck::name() const {
|
||||||
if (node_bind->element()->typeMark() == (int)example_novel::NovelNode::FragmentDefine) {
|
return u8"FragmentExistsCheck";
|
||||||
type_marks = Type::ELEMENT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
type_marks = Type::REFER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
element_bind = node_bind;
|
QList<std::shared_ptr<FragmentGraphHelper>> example_novel::FragmentGraphCheck::refers_cycle_check(
|
||||||
next_attachment = nullptr;
|
std::shared_ptr<FragmentGraphHelper> item, QList<std::shared_ptr<FragmentGraphHelper>> prevs) const {
|
||||||
this->story_sort = story_sort;
|
if (prevs.contains(item)) {
|
||||||
|
return prevs << item;
|
||||||
}
|
}
|
||||||
|
|
||||||
FragmentSortHelper::Type FragmentSortHelper::nodeType() const { return type_marks; }
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<const ast_gen::ElementAccess> FragmentSortHelper::nodeBind() const { return element_bind; }
|
return QList<std::shared_ptr<FragmentGraphHelper>>();
|
||||||
|
}
|
||||||
|
|
||||||
int FragmentSortHelper::storySort() const
|
void FragmentGraphCheck::setElement(std::shared_ptr<FragmentGraphHelper> inst)
|
||||||
{
|
{
|
||||||
return story_sort;
|
elements_store[inst->nodePeer()->signature()] = inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FragmentSortHelper> FragmentSortHelper::next() const {
|
std::shared_ptr<FragmentGraphHelper> FragmentGraphCheck::getElement(const QString& signature) const
|
||||||
return next_attachment;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FragmentSortHelper::attachNext(std::shared_ptr<FragmentSortHelper> fragment) {
|
|
||||||
this->next_attachment = fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FragmentSortHelper::assignSibling(std::shared_ptr<FragmentSortHelper> other)
|
|
||||||
{
|
{
|
||||||
auto temp_list = this->siblings_store;
|
return elements_store[signature];
|
||||||
temp_list.append(other->siblings_store);
|
|
||||||
temp_list.append(other);
|
|
||||||
temp_list.append(shared_from_this());
|
|
||||||
|
|
||||||
QHash<QString, std::shared_ptr<FragmentSortHelper>> helpers;
|
|
||||||
for (auto& it : temp_list) {
|
|
||||||
helpers[it->element_bind->element()->signature()] = it;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_list = helpers.values();
|
QList<std::shared_ptr<FragmentGraphHelper>> example_novel::FragmentGraphCheck::getHangoutNodes() {
|
||||||
for (auto& it : temp_list) {
|
QList<std::shared_ptr<FragmentGraphHelper>> values;
|
||||||
auto vlist = temp_list;
|
|
||||||
vlist.removeAll(it);
|
|
||||||
|
|
||||||
it->siblings_store = vlist;
|
for (auto node_item : elements_store) {
|
||||||
}
|
if (!node_item->inDegree())
|
||||||
|
values.append(node_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<std::shared_ptr<FragmentSortHelper> > FragmentSortHelper::siblings() const
|
for (auto inst : values) {
|
||||||
|
auto name = inst->nodePeer()->signature();
|
||||||
|
elements_store.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool example_novel::FragmentGraphCheck::nodeDismantle(std::shared_ptr<FragmentGraphHelper> inst) {
|
||||||
|
bool flag = false;
|
||||||
|
|
||||||
|
for (auto item : inst->nextList()) {
|
||||||
|
item->inDegree()--;
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FragmentGraphCheck::validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const
|
||||||
{
|
{
|
||||||
return siblings_store;
|
std::function<QList<std::shared_ptr<const ast_gen::ElementAccess>>(std::shared_ptr<const ast_gen::ElementAccess>)> story_peak
|
||||||
|
= [&](std::shared_ptr<const ast_gen::ElementAccess> root)->QList<std::shared_ptr<const ast_gen::ElementAccess>> {
|
||||||
|
QList<std::shared_ptr<const ast_gen::ElementAccess>> return_temp;
|
||||||
|
|
||||||
|
auto type_mark = (NovelNode)root->element()->typeMark();
|
||||||
|
if (type_mark == NovelNode::StoryDefine) {
|
||||||
|
return_temp << root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto child : root->children()) {
|
||||||
void FragmentOrdersCheck::elements_link_build(const QList<std::shared_ptr<StorySortHelper> >& stories)
|
return_temp.append(story_peak(child));
|
||||||
{
|
|
||||||
QHash<QString, std::shared_ptr<StorySortHelper>> helper;
|
|
||||||
for (auto& i : stories)
|
|
||||||
helper[i->storyName()] = i;
|
|
||||||
|
|
||||||
auto auto_refer = [&](std::shared_ptr<StorySortHelper> story) {
|
|
||||||
auto fragment_head = story->fragmentSort();
|
|
||||||
while (fragment_head) {
|
|
||||||
switch (fragment_head->nodeType()) {
|
|
||||||
case FragmentSortHelper::Type::REFER:
|
|
||||||
{
|
|
||||||
auto access = fragment_head->nodeBind();
|
|
||||||
auto elm = std::dynamic_pointer_cast<const example_novel::FragmentRefers>(access->element());
|
|
||||||
if (!helper.contains(elm->storyRefer())) {
|
|
||||||
throw new lib_parse::CheckException(QString(u8"Parse[0x0001]故事线“%1”不存在!").arg(elm->storyRefer()));
|
|
||||||
}
|
|
||||||
auto story_target = helper[elm->storyRefer()];
|
|
||||||
auto fragm_target = story_target->fragment(elm->fragmentRefer());
|
|
||||||
if (!fragm_target) {
|
|
||||||
throw new lib_parse::CheckException(
|
|
||||||
QString(u8"Parse[0x0002]故事线“%1”的情节“%2”不存在!").arg(elm->storyRefer()).arg(elm->fragmentRefer()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment_head->assignSibling(fragm_target);
|
return return_temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto self = std::const_pointer_cast<FragmentGraphCheck>(this->shared_from_this());
|
||||||
|
|
||||||
|
// 获取所有故事线
|
||||||
|
auto all_story = story_peak(root);
|
||||||
|
// 注册图节点
|
||||||
|
for (auto story : all_story) {
|
||||||
|
auto fragment_items = story->children();
|
||||||
|
|
||||||
|
// 构建情节节点列表
|
||||||
|
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);
|
||||||
|
|
||||||
|
self->setElement(finst);
|
||||||
}break;
|
}break;
|
||||||
default:
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建图连接
|
||||||
|
for (auto story : all_story) {
|
||||||
|
auto fragment_items = story->children();
|
||||||
|
|
||||||
|
// 过滤获取情节节点
|
||||||
|
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;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
fragment_head = fragment_head->next();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (auto& vit : stories) {
|
|
||||||
auto_refer(vit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class InputIt, class OutputIt, class Operate>
|
|
||||||
void cast(InputIt Begin, InputIt End, OutputIt Dst, Operate fn) {
|
|
||||||
while (Begin != End) {
|
|
||||||
*Dst++ = fn(*Begin++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void FragmentOrdersCheck::sort_cycle_check(const QList<std::shared_ptr<FragmentSortHelper>>& tracks, std::shared_ptr<FragmentSortHelper> _current, int story_sort_source)
|
|
||||||
{
|
|
||||||
if (!_current || !_current->next())
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto target = _current->next();
|
|
||||||
|
|
||||||
if (tracks.contains(peaks_appoint_element(target))) {
|
|
||||||
QString error_cycle;
|
|
||||||
for (auto& it : tracks)
|
|
||||||
error_cycle += u8"->" + it->nodeBind()->element()->signature() + u8"\n";
|
|
||||||
error_cycle += u8"->" + target->nodeBind()->element()->signature() + u8"。";
|
|
||||||
|
|
||||||
throw new lib_parse::CheckException(u8"Parse[0x0003]排序异常:\n" + error_cycle);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto nlist = tracks;
|
|
||||||
nlist.append(peaks_appoint_element(target));
|
|
||||||
|
|
||||||
if (target->nodeType() == example_novel::FragmentSortHelper::Type::REFER) {
|
|
||||||
decltype (target->siblings()) sibling_forks;
|
|
||||||
|
|
||||||
auto siblings = target->siblings();
|
|
||||||
for (auto& vit : siblings) {
|
|
||||||
if (vit->storySort() <= story_sort_source)
|
|
||||||
sibling_forks << vit;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& fork : sibling_forks) {
|
|
||||||
sort_cycle_check(nlist, fork, story_sort_source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort_cycle_check(nlist, target, story_sort_source);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<FragmentSortHelper> example_novel::FragmentOrdersCheck::peaks_appoint_element(std::shared_ptr<FragmentSortHelper> refer_n) const
|
|
||||||
{
|
|
||||||
if (refer_n->nodeType() == example_novel::FragmentSortHelper::Type::ELEMENT)
|
|
||||||
return refer_n;
|
|
||||||
|
|
||||||
auto sibs = refer_n->siblings();
|
|
||||||
for (auto ptr : sibs) {
|
|
||||||
if (ptr->nodeType() == example_novel::FragmentSortHelper::Type::ELEMENT)
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void FragmentOrdersCheck::validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const {
|
|
||||||
std::function<QList<std::shared_ptr<const ast_gen::ElementAccess>>(std::shared_ptr<const ast_gen::ElementAccess>)> peak_story =
|
|
||||||
[&](std::shared_ptr<const ast_gen::ElementAccess> pnode) -> QList<std::shared_ptr<const ast_gen::ElementAccess>> {
|
|
||||||
QList<std::shared_ptr<const ast_gen::ElementAccess>> listret;
|
|
||||||
|
|
||||||
if (pnode->element()->typeMark() == (int)example_novel::NovelNode::StoryDefine)
|
|
||||||
listret << pnode;
|
|
||||||
|
|
||||||
for (auto& vit : pnode->children())
|
|
||||||
listret.append(peak_story(vit));
|
|
||||||
|
|
||||||
return listret;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto stories = peak_story(root);
|
|
||||||
std::sort(std::begin(stories), std::end(stories),
|
|
||||||
[](std::shared_ptr<const ast_gen::ElementAccess> itema, std::shared_ptr<const ast_gen::ElementAccess> itemb) -> bool {
|
|
||||||
auto storya = std::dynamic_pointer_cast<const example_novel::StoryDefine>(itema->element());
|
|
||||||
auto storyb = std::dynamic_pointer_cast<const example_novel::StoryDefine>(itemb->element());
|
|
||||||
return storya->sort() < storyb->sort();
|
|
||||||
});
|
|
||||||
|
|
||||||
for (auto& sit : stories) {
|
|
||||||
auto story_sort = std::make_shared<StorySortHelper>(sit);
|
|
||||||
const_cast<FragmentOrdersCheck*>(this)->stories_list << story_sort;
|
|
||||||
|
|
||||||
auto children = sit->children();
|
|
||||||
std::shared_ptr<FragmentSortHelper> temp_ptr = nullptr;
|
|
||||||
for (auto& nf : children) {
|
|
||||||
switch ((example_novel::NovelNode)nf->element()->typeMark()) {
|
|
||||||
case example_novel::NovelNode::FragmentDefine:
|
|
||||||
case example_novel::NovelNode::FragmentRefer: {
|
|
||||||
auto frag_sort = std::make_shared<FragmentSortHelper>(nf, story_sort->sortValue());
|
|
||||||
if (!temp_ptr) {
|
|
||||||
story_sort->attachFragmentSort(frag_sort);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
temp_ptr->attachNext(frag_sort);
|
|
||||||
}
|
|
||||||
temp_ptr = frag_sort;
|
|
||||||
} break;
|
|
||||||
default:
|
default:
|
||||||
|
fragment_items.removeAt(idx);
|
||||||
|
idx--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 重复排序检查
|
auto get_name = [](std::shared_ptr<const ast_gen::ElementAccess> node)->QString {
|
||||||
int prev_sort = 0;
|
switch (node->element()->typeMark()) {
|
||||||
for (auto& s : stories_list) {
|
case (int)NovelNode::FragmentDefine: {
|
||||||
if (s->sortValue() < 1)
|
auto def_node = std::dynamic_pointer_cast<const example_novel::FragmentDefine>(node->element());
|
||||||
throw new lib_parse::CheckException(u8"Parse[0x0006]故事“%1”的排序<1。");
|
return def_node->signature();
|
||||||
if (prev_sort >= s->sortValue()) {
|
}break;
|
||||||
auto idx = stories_list.indexOf(s);
|
case (int)NovelNode::FragmentRefer: {
|
||||||
auto prev = stories_list[idx - 1];
|
auto ref_node = std::dynamic_pointer_cast<const example_novel::FragmentRefers>(node->element());
|
||||||
throw new lib_parse::CheckException(QString(u8"Parse[0x0007]故事“%1”与故事“%2”排序重复。").arg(s->storyName()).arg(prev->storyName()));
|
return ref_node->referSignature();
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 构建完整图结构
|
||||||
|
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()++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const_cast<FragmentOrdersCheck*>(this)->elements_link_build(this->stories_list);
|
// 获取拓扑排序序列
|
||||||
|
auto values = self->getHangoutNodes();
|
||||||
|
for (auto idx = 0; idx < values.size(); ++idx) {
|
||||||
|
auto target = values[idx];
|
||||||
|
|
||||||
for (auto& s : this->stories_list) {
|
self->nodeDismantle(target);
|
||||||
if(!s->fragmentSort())
|
auto x_values = self->getHangoutNodes();
|
||||||
continue;
|
values.append(x_values);
|
||||||
|
}
|
||||||
|
|
||||||
QList<std::shared_ptr<FragmentSortHelper>> tracks;
|
// 理论上不应该有残余
|
||||||
tracks << peaks_appoint_element(s->fragmentSort());
|
if (elements_store.size()) {
|
||||||
const_cast<FragmentOrdersCheck*>(this)->sort_cycle_check(tracks, s->fragmentSort(), s->sortValue());
|
for (auto node : elements_store.values()) {
|
||||||
|
auto cycle_link = refers_cycle_check(node);
|
||||||
|
|
||||||
|
QString error_msg = u8"Parse[0x0006]情节图存在环形结构:\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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StorySortHelper::StorySortHelper(std::shared_ptr<const ast_gen::ElementAccess> story_bind) {
|
QString example_novel::FragmentGraphCheck::name() const {
|
||||||
this->story_bind = story_bind;
|
return u8"FragmentGraphCheck";
|
||||||
this->fragments_bind = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const example_novel::StoryDefine> StorySortHelper::storyElement() const {
|
FragmentGraphHelper::FragmentGraphHelper(std::shared_ptr<const FragmentDefine> node) : node_peer(node) {}
|
||||||
return std::dynamic_pointer_cast<const example_novel::StoryDefine>(story_bind->element());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString StorySortHelper::storyName() const { return storyElement()->name(); }
|
std::shared_ptr<const FragmentDefine> FragmentGraphHelper::nodePeer() const
|
||||||
|
|
||||||
int StorySortHelper::sortValue() const
|
|
||||||
{
|
{
|
||||||
return storyElement()->sort();
|
return this->node_peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FragmentSortHelper> StorySortHelper::fragmentSort() const {
|
void FragmentGraphHelper::appendNext(std::shared_ptr<FragmentGraphHelper> node) {
|
||||||
return this->fragments_bind;
|
this->next_nodes.append(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorySortHelper::attachFragmentSort(std::shared_ptr<FragmentSortHelper> refer) {
|
QList<std::shared_ptr<FragmentGraphHelper>> FragmentGraphHelper::nextList() const
|
||||||
this->fragments_bind = refer;
|
{
|
||||||
|
return next_nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FragmentSortHelper> StorySortHelper::fragment(const QString& name) const {
|
uint& FragmentGraphHelper::inDegree()
|
||||||
auto temp_ptr = fragments_bind;
|
{
|
||||||
|
return this->indegree;
|
||||||
do {
|
|
||||||
if (temp_ptr->nodeType() == FragmentSortHelper::Type::ELEMENT) {
|
|
||||||
auto node = std::dynamic_pointer_cast<const example_novel::FragmentDefine>(temp_ptr->nodeBind()->element());
|
|
||||||
if (node->name() == name)
|
|
||||||
return temp_ptr;
|
|
||||||
}
|
}
|
||||||
temp_ptr = temp_ptr->next();
|
|
||||||
} while (temp_ptr);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -12,81 +12,45 @@ namespace example_novel {
|
||||||
public:
|
public:
|
||||||
// ͨ¹ý CheckProvider ¼Ì³Ð
|
// ͨ¹ý CheckProvider ¼Ì³Ð
|
||||||
virtual void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;
|
virtual void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;
|
||||||
virtual QString name() const override {
|
virtual QString name() const override;
|
||||||
return u8"FragmentExistsCheck";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FragmentGraphHelper;
|
||||||
|
class LIBPARSE_EXPORT FragmentGraphCheck : public std::enable_shared_from_this<FragmentGraphCheck>, public lib_parse::CheckProvider {
|
||||||
|
private:
|
||||||
|
QHash<QString, std::shared_ptr<FragmentGraphHelper>> elements_store;
|
||||||
|
|
||||||
class StorySortHelper;
|
QList<std::shared_ptr<FragmentGraphHelper>> refers_cycle_check(
|
||||||
class FragmentSortHelper;
|
std::shared_ptr<FragmentGraphHelper> item, QList<std::shared_ptr<FragmentGraphHelper>> prevs = QList<std::shared_ptr<FragmentGraphHelper>>()) const;
|
||||||
class LIBPARSE_EXPORT FragmentOrdersCheck : public lib_parse::CheckProvider {
|
|
||||||
protected:
|
|
||||||
QList<std::shared_ptr<StorySortHelper>> stories_list;
|
|
||||||
|
|
||||||
void elements_link_build(const QList<std::shared_ptr<StorySortHelper>>& stories);
|
public:
|
||||||
void sort_cycle_check(const QList<std::shared_ptr<FragmentSortHelper>>& tracks, std::shared_ptr<FragmentSortHelper> current,
|
void setElement(std::shared_ptr<FragmentGraphHelper> inst);
|
||||||
int story_sort_source);
|
std::shared_ptr<FragmentGraphHelper> getElement(const QString &signature) const;
|
||||||
|
|
||||||
std::shared_ptr<FragmentSortHelper> peaks_appoint_element(std::shared_ptr<FragmentSortHelper> refer_n) const;
|
QList<std::shared_ptr<FragmentGraphHelper>> getHangoutNodes();
|
||||||
|
bool nodeDismantle(std::shared_ptr<FragmentGraphHelper> inst);
|
||||||
|
|
||||||
// CheckProvider interface
|
// CheckProvider interface
|
||||||
public:
|
public:
|
||||||
virtual void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;
|
virtual void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;
|
||||||
virtual QString name() const override {
|
virtual QString name() const override;
|
||||||
return u8"FragmentOrdersCheck";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
class FragmentGraphHelper : public std::enable_shared_from_this<FragmentGraphHelper> {
|
||||||
* @brief Çé½ÚÅÅÐò¸¨ÖúÀà
|
|
||||||
*/
|
|
||||||
class LIBPARSE_EXPORT FragmentSortHelper : public std::enable_shared_from_this<FragmentSortHelper> {
|
|
||||||
public:
|
|
||||||
enum class Type {
|
|
||||||
REFER, ELEMENT
|
|
||||||
};
|
|
||||||
|
|
||||||
FragmentSortHelper(std::shared_ptr<const ast_gen::ElementAccess> node_bind, int story_sort);
|
|
||||||
|
|
||||||
Type nodeType() const;
|
|
||||||
std::shared_ptr<const ast_gen::ElementAccess> nodeBind() const;
|
|
||||||
int storySort() const;
|
|
||||||
|
|
||||||
std::shared_ptr<FragmentSortHelper> next() const;
|
|
||||||
void attachNext(std::shared_ptr<FragmentSortHelper> fragment);
|
|
||||||
|
|
||||||
void assignSibling(std::shared_ptr<FragmentSortHelper> other);
|
|
||||||
QList<std::shared_ptr<FragmentSortHelper>> siblings() const;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type type_marks;
|
std::shared_ptr<const example_novel::FragmentDefine> node_peer;
|
||||||
int story_sort;
|
QList<std::shared_ptr<FragmentGraphHelper>> next_nodes;
|
||||||
std::shared_ptr<const ast_gen::ElementAccess> element_bind;
|
uint indegree = 0;
|
||||||
std::shared_ptr<FragmentSortHelper> next_attachment;
|
|
||||||
QList<std::shared_ptr<FragmentSortHelper>> siblings_store;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief ¹ÊÊÂÅÅÐò¸¨ÖúÀà
|
|
||||||
*/
|
|
||||||
class LIBPARSE_EXPORT StorySortHelper {
|
|
||||||
private:
|
|
||||||
std::shared_ptr<const ast_gen::ElementAccess> story_bind;
|
|
||||||
std::shared_ptr<FragmentSortHelper> fragments_bind;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StorySortHelper(std::shared_ptr<const ast_gen::ElementAccess> story_bind);
|
FragmentGraphHelper(std::shared_ptr<const example_novel::FragmentDefine> node);
|
||||||
|
|
||||||
std::shared_ptr<const example_novel::StoryDefine> storyElement() const;
|
std::shared_ptr<const example_novel::FragmentDefine> nodePeer() const;
|
||||||
QString storyName() const;
|
|
||||||
int sortValue() const;
|
|
||||||
|
|
||||||
std::shared_ptr<FragmentSortHelper> fragmentSort() const;
|
void appendNext(std::shared_ptr<FragmentGraphHelper> node);
|
||||||
void attachFragmentSort(std::shared_ptr<FragmentSortHelper> refer);
|
QList<std::shared_ptr<FragmentGraphHelper>> nextList() const;
|
||||||
|
|
||||||
std::shared_ptr<FragmentSortHelper> fragment(const QString& name) const;
|
uint& inDegree();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue