尝试添加层次校验
This commit is contained in:
parent
adb6e326d2
commit
123cc2a05a
|
@ -31,7 +31,7 @@ std::shared_ptr<const SyntaxElement> ElementsCache::getNamedNodeBy(int paramType
|
||||||
return node_cache[mixed_key];
|
return node_cache[mixed_key];
|
||||||
}
|
}
|
||||||
|
|
||||||
void example_novel::FragmentExistsCheck::nodes_regist(std::shared_ptr<ElementsCache> cache, std::shared_ptr<const ast_gen::ElementAccess> target) {
|
void FragmentExistsCheck::nodes_regist(std::shared_ptr<ElementsCache> cache, std::shared_ptr<const ast_gen::ElementAccess> target) {
|
||||||
if (!target->element()->isAnonymous())
|
if (!target->element()->isAnonymous())
|
||||||
cache->appendToCache(target->element());
|
cache->appendToCache(target->element());
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ void FragmentExistsCheck::exists_check(std::shared_ptr<ElementsCache> root, std:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
example_novel::FragmentExistsCheck::FragmentExistsCheck()
|
FragmentExistsCheck::FragmentExistsCheck()
|
||||||
:_nodes_cache(std::make_shared<ElementsCache>()) { }
|
:_nodes_cache(std::make_shared<ElementsCache>()) { }
|
||||||
|
|
||||||
void FragmentExistsCheck::validCheck(std::shared_ptr<const ElementAccess> root) const {
|
void FragmentExistsCheck::validCheck(std::shared_ptr<const ElementAccess> root) const {
|
||||||
|
@ -200,11 +200,13 @@ void PointGraphCheck::validCheck(std::shared_ptr<const ElementAccess> root) cons
|
||||||
// 获取绑定节点名称
|
// 获取绑定节点名称
|
||||||
auto get_name = [](std::shared_ptr<const ElementAccess> node)->QString {
|
auto get_name = [](std::shared_ptr<const ElementAccess> node)->QString {
|
||||||
switch (node->element()->typeMark()) {
|
switch (node->element()->typeMark()) {
|
||||||
case (int) NovelNode::FragmentSlice: {
|
case (int) NovelNode::FragmentSlice:
|
||||||
|
{
|
||||||
auto def_node = std::dynamic_pointer_cast<const FragmentSlice>(node->element());
|
auto def_node = std::dynamic_pointer_cast<const FragmentSlice>(node->element());
|
||||||
return def_node->signature();
|
return def_node->signature();
|
||||||
}break;
|
}break;
|
||||||
case (int) NovelNode::FragmentRefers: {
|
case (int) NovelNode::FragmentRefers:
|
||||||
|
{
|
||||||
auto ref_node = std::dynamic_pointer_cast<const FragmentRefers>(node->element());
|
auto ref_node = std::dynamic_pointer_cast<const FragmentRefers>(node->element());
|
||||||
return ref_node->referSignature();
|
return ref_node->referSignature();
|
||||||
}break;
|
}break;
|
||||||
|
@ -227,7 +229,7 @@ void PointGraphCheck::validCheck(std::shared_ptr<const ElementAccess> root) cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建完整图结构:串联引用节点的顺序
|
// 构建完整图结构:串联引用节点的顺序
|
||||||
for(auto point : point_items){
|
for (auto point : point_items) {
|
||||||
auto first_name = get_name(point);
|
auto first_name = get_name(point);
|
||||||
auto first_helper = getElement(first_name);
|
auto first_helper = getElement(first_name);
|
||||||
|
|
||||||
|
@ -272,7 +274,7 @@ void PointGraphCheck::validCheck(std::shared_ptr<const ElementAccess> root) cons
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PointGraphCheck::name() const {
|
QString PointGraphCheck::name() const {
|
||||||
return "情节网络有效性检查器";
|
return "情节网络引用检查器";
|
||||||
}
|
}
|
||||||
|
|
||||||
PointGraphHelper::PointGraphHelper(std::shared_ptr<const FragmentSlice> node) : node_peer(node) { }
|
PointGraphHelper::PointGraphHelper(std::shared_ptr<const FragmentSlice> node) : node_peer(node) { }
|
||||||
|
@ -298,14 +300,16 @@ QList<std::shared_ptr<const ElementAccess>> StoryOrderCheck::valid_docs_peak(std
|
||||||
auto type_code = pnode->element()->typeMark();
|
auto type_code = pnode->element()->typeMark();
|
||||||
|
|
||||||
switch ((NovelNode) type_code) {
|
switch ((NovelNode) type_code) {
|
||||||
case NovelNode::GlobalElement: {
|
case NovelNode::GlobalElement:
|
||||||
|
{
|
||||||
auto children = pnode->children();
|
auto children = pnode->children();
|
||||||
for (auto& cinst : children) {
|
for (auto& cinst : children) {
|
||||||
values.append(valid_docs_peak(cinst));
|
values.append(valid_docs_peak(cinst));
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case NovelNode::Document: {
|
case NovelNode::Document:
|
||||||
|
{
|
||||||
auto elms_set = pnode->children();
|
auto elms_set = pnode->children();
|
||||||
|
|
||||||
decltype(elms_set) story_set;
|
decltype(elms_set) story_set;
|
||||||
|
@ -371,3 +375,99 @@ void StoryOrderCheck::validCheck(std::shared_ptr<const ElementAccess> root) cons
|
||||||
for (auto& story : story_docs)
|
for (auto& story : story_docs)
|
||||||
ranks_number = story_node_sort(story, ranks_number);
|
ranks_number = story_node_sort(story, ranks_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<FragmentNode> FragmentLayerCheck::_sets_fill(std::shared_ptr<const ElementAccess> node) {
|
||||||
|
switch ((NovelNode) node->element()->typeMark()) {
|
||||||
|
case NovelNode::FragmentSlice:
|
||||||
|
{
|
||||||
|
auto wins = std::make_shared<FragmentNode>(node);
|
||||||
|
this->_node_set[node->element()->signature()] = wins;
|
||||||
|
return wins;
|
||||||
|
}break;
|
||||||
|
case NovelNode::StoryDefine:
|
||||||
|
{
|
||||||
|
QList<std::shared_ptr<FragmentNode>> list;
|
||||||
|
for (auto nis : node->children()) {
|
||||||
|
auto ptr = _sets_fill(nis);
|
||||||
|
if (ptr) list << ptr;
|
||||||
|
}
|
||||||
|
for (auto node = ++list.begin(); node != list.end(); ++node) {
|
||||||
|
auto prev = *(node - 1);
|
||||||
|
auto curr = *node;
|
||||||
|
prev->appendNext(curr);
|
||||||
|
}
|
||||||
|
if (list.size())
|
||||||
|
this->_story_start << list.first();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
for (auto nis : node->children())
|
||||||
|
_sets_fill(nis);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FragmentLayerCheck::_refers_rebuild(std::shared_ptr<const FragmentNode> node) {
|
||||||
|
auto fragm = std::static_pointer_cast<FragmentSlice>(node->bind()->element());
|
||||||
|
for (auto node_t : fragm->children()) {
|
||||||
|
auto refn = std::static_pointer_cast<FragmentRefers>(node_t);
|
||||||
|
auto target_node = _node_set[refn->referSignature()];
|
||||||
|
std::const_pointer_cast<FragmentNode>(node)->appendNext(target_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FragmentLayerCheck::node_relayer(std::shared_ptr<FragmentNode> node, int curr_num) {
|
||||||
|
if (node->layerNumber() < curr_num) {
|
||||||
|
node->setLayer(curr_num);
|
||||||
|
|
||||||
|
for (auto nis : node->referNodes())
|
||||||
|
node_relayer(nis, curr_num + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FragmentLayerCheck::name() const {
|
||||||
|
return "情节时间层级校验器";
|
||||||
|
}
|
||||||
|
|
||||||
|
void FragmentLayerCheck::validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const {
|
||||||
|
auto chk = const_cast<FragmentLayerCheck*>(this);
|
||||||
|
chk->_sets_fill(root);
|
||||||
|
|
||||||
|
for (auto node : chk->_node_set)
|
||||||
|
chk->_refers_rebuild(node);
|
||||||
|
|
||||||
|
for (auto node : chk->_story_start)
|
||||||
|
chk->node_relayer(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
FragmentNode::FragmentNode(std::shared_ptr<ElementAccess> bind) :_src_fragm(bind) { }
|
||||||
|
|
||||||
|
std::shared_ptr<ElementAccess> FragmentNode::bind() const {
|
||||||
|
return this->_src_fragm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FragmentNode::setLayer(int number) {
|
||||||
|
this->_layer_number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FragmentNode::setLayer(int number) {
|
||||||
|
this->_layer_number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FragmentNode::layerNumber() const {
|
||||||
|
return this->_layer_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FragmentNode::layerNumber() const {
|
||||||
|
return this->_layer_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<std::shared_ptr<FragmentNode>> FragmentNode::referNodes() const {
|
||||||
|
return _next_fragms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FragmentNode::appendNext(std::shared_ptr<FragmentNode> ins) {
|
||||||
|
this->_next_fragms << ins;
|
||||||
|
}
|
||||||
|
|
|
@ -108,4 +108,51 @@ namespace example_novel {
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;
|
void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FragmentNode : public std::enable_shared_from_this<FragmentNode> {
|
||||||
|
private:
|
||||||
|
std::shared_ptr<ast_gen::ElementAccess> _src_fragm = nullptr;
|
||||||
|
QList<std::shared_ptr<FragmentNode>> _next_fragms;
|
||||||
|
int _layer_number = -1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FragmentNode(std::shared_ptr<ast_gen::ElementAccess> bind);
|
||||||
|
std::shared_ptr<ast_gen::ElementAccess> bind() const;
|
||||||
|
|
||||||
|
void setLayer(int number);
|
||||||
|
int layerNumber() const;
|
||||||
|
|
||||||
|
QList<std::shared_ptr<FragmentNode>> referNodes() const;
|
||||||
|
void appendNext(std::shared_ptr<FragmentNode> ins);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 情节时间顺序校验
|
||||||
|
*/
|
||||||
|
class LIBPARSE_EXPORT FragmentLayerCheck : public lib_parse::CheckProvider {
|
||||||
|
private:
|
||||||
|
QHash<QString, std::shared_ptr<FragmentNode>> _node_set;
|
||||||
|
QList<std::shared_ptr<FragmentNode>> _story_start;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 故事线转换
|
||||||
|
*/
|
||||||
|
std::shared_ptr<FragmentNode> _sets_fill(std::shared_ptr<const ast_gen::ElementAccess> node);
|
||||||
|
/**
|
||||||
|
* @brief 引用网络重构
|
||||||
|
*/
|
||||||
|
void _refers_rebuild(std::shared_ptr<const FragmentNode> node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 节点层级重排
|
||||||
|
*/
|
||||||
|
void node_relayer(std::shared_ptr<FragmentNode> node, int curr = 0);
|
||||||
|
|
||||||
|
void layer_check(std::shared_ptr<const ast_gen::ElementAccess> node){ }
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 通过 CheckProvider 继承
|
||||||
|
QString name() const override;
|
||||||
|
void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;
|
||||||
|
};
|
||||||
} // namespace example_novel
|
} // namespace example_novel
|
||||||
|
|
Loading…
Reference in New Issue