QtNovelUI/libParse/libParse.cpp

449 lines
9.7 KiB
C++

#include "libParse.h"
#include "SyntaxBase.h"
#include "StoryUnitDocumentParser.h"
#include <QFileInfo>
using namespace Parse;
using namespace Lex;
using namespace Syntax;
using namespace Parse::Result;
namespace Parse {
class Unknown : public DesNode
{
public:
explicit Unknown(DocCore *ins) : DesNode(ins, NODE_UNKNOWNHOST, nullptr){}
// 通过 DesNode 继承
virtual bool check(QList<ErrorMessage>&) const override
{
return true;
}
virtual QString toString() const override
{
return QString();
}
void xClear(){
clear_refers();
}
};
}
ErrorMessage::ErrorMessage(const DesNode *obj): object(obj){}
NamedNode::NamedNode(const QString &name, DocCore *core, int type, DesNode *pnode)
: Result::DesNode(core, type, pnode), name_store(name){}
QList<QString> NamedNode::name() const
{
return QList<QString>() << name_store;
}
DesNode::DesNode(DocCore *core, int type_value, DesNode *pnode)
: doc_store(core), type_value(type_value), parent_node(pnode)
{
}
DesNode::~DesNode()
{
for(auto &i : children())
delete i;
children_nodes.clear();
}
int DesNode::depth() const
{
if(parent_node==nullptr)
return 0;
return parent_node->depth() + 1;
}
DocCore *DesNode::doc() const
{
return this->doc_store;
}
int DesNode::typeValue() const
{
return type_value;
}
DesNode *DesNode::parent() const
{
return parent_node;
}
void DesNode::appendChild(DesNode *ins)
{
children_nodes << ins;
}
QList<DesNode *> DesNode::children() const
{
return children_nodes;
}
void DesNode::registerWords(Words *ins)
{
words_collection << ins;
}
QList<Words *> DesNode::refered() const
{
return words_collection;
}
void DesNode::clear_refers()
{
this->words_collection.clear();
}
ParseCore::ParseCore()
{
}
void ParseCore::registerDoc(DocCore *ins)
{
if(!nodes_map.contains(ins))
nodes_map[ins] = new QList<DesNode*>();
}
void ParseCore::registerNode(DocCore *doc, DesNode *node)
{
if(!nodes_map.contains(doc))
nodes_map[doc] = new QList<DesNode*>();
nodes_map[doc]->append(node);
}
void ParseCore::clearNodes(DocCore *ins)
{
if(!nodes_map.contains(ins))
return;
auto c = nodes_map[ins];
for(auto &i : *c)
delete i;
c->clear();
}
QList<DocCore *> ParseCore::allDocuments() const
{
return nodes_map.keys();
}
QList<DesNode *> ParseCore::queryRootNodes(DocCore *doc) const
{
if(!nodes_map.contains(doc))
return QList<DesNode*>();
return *nodes_map[doc];
}
DocCore *ParseCore::queryDocument(const QFileInfo &file_src) const
{
for(auto &d : nodes_map.keys()){
auto anchor_file = d->filePath();
if(anchor_file == file_src.absoluteFilePath())
return d;
}
return nullptr;
}
void ParseCore::deleteDocument(DocCore *ins)
{
ins->clear();
nodes_map.remove(ins);
delete ins;
}
QList<DesNode *> ParseCore::allStoryChains() const
{
QList<Result::DesNode*> retlist;
auto keys = nodes_map.keys();
for(auto &k : keys)
if(k->docType() == DocType::STORYCHAIN)
for(auto &n : *nodes_map[k])
if(n->typeValue()==NODE_STORYCHAIN)
retlist << n;
return retlist;
}
QList<Result::DesNode*> ParseCore::queryStoryChain(const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &xnode : allStoryChains())
if(static_cast<NamedNode*>(xnode)->name()[0] == name)
retlist << xnode;
return retlist;
}
QList<Result::DesNode*> ParseCore::queryStoryPoint(DesNode *chain, const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &n : chain->children())
if(n->typeValue() == NODE_STORYPOINT &&
static_cast<NamedNode*>(n)->name()[0] == name)
retlist << n;
return retlist;
}
QList<DesNode *> ParseCore::allStoryUnits() const
{
QList<Result::DesNode*> retlist;
auto keys = nodes_map.keys();
for(auto &k : keys)
if(k->docType() == DocType::STORYUNIT)
for(auto &n : *nodes_map[k]){
if(n->typeValue()==NODE_STORYUNIT)
retlist << n;
}
return retlist;
}
QList<Result::DesNode*> ParseCore::queryStoryUnit(const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &k : allStoryUnits())
if(static_cast<NamedNode*>(k)->name()[0] == name)
retlist << k;
return retlist;
}
QList<Result::DesNode*> ParseCore::queryStoryFragment(DesNode *unit, const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &n : unit->children())
if(n->typeValue() == NODE_STORYFRAGMENT &&
static_cast<NamedNode*>(n)->name()[0] == name)
retlist << n;
return retlist;
}
QList<std::pair<NamedNode *, double> > ParseCore::queryOrdersFragment() const
{
QList<std::pair<NamedNode*, double>> node_list;
auto units = allStoryUnits();
for(auto &uins : units){
auto children = uins->children();
for(auto &c : children){
if(c->typeValue() != NODE_STORYFRAGMENT)
continue;
bool isvalid;
auto fragment = static_cast<NodeStoryFragment*>(c);
node_list << std::make_pair(fragment, fragment->orderValue(isvalid));
}
}
std::sort(node_list.begin(), node_list.end(),
[](const std::pair<NamedNode*, double> &a, const std::pair<NamedNode*, double> &b)->bool{
bool valid;
auto val_a = static_cast<NodeStoryFragment*>(a.first)->orderValue(valid);
auto val_b = static_cast<NodeStoryFragment*>(b.first)->orderValue(valid);
return val_a < val_b;
});
return node_list;
}
QList<DesNode *> ParseCore::allStoryBoards() const
{
QList<Result::DesNode*> retlist;
auto keys = nodes_map.keys();
for(auto &k : keys)
if(k->docType() == DocType::STORYBOARD)
for(auto &n : *nodes_map[k]){
if(n->typeValue() == NODE_STORYBOARD)
retlist << n;
}
return retlist;
}
QList<Result::DesNode*> ParseCore::queryStoryBoard(const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &it : allStoryBoards())
if(static_cast<NamedNode*>(it)->name()[0] == name)
retlist << it;
return retlist;
}
QList<DesNode *> ParseCore::queryStoryFragmentRefer(DesNode *unit, const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &it : unit->children()){
if(it->typeValue() == NODE_FRAGMENTREFERENCE && static_cast<NamedNode*>(it)->name()[0] == name)
retlist << it;
}
return retlist;
}
QList<DesNode *> ParseCore::allStoryConcept() const
{
QList<DesNode*> rets;
for(auto &it : nodes_map.keys()){
if(it->docType() == DocType::STORYCONCEPTS)
for(auto n : *nodes_map[it])
if(n->typeValue() == NODE_STORYCONCEPT)
rets << n;
}
return rets;
}
QList<DesNode *> ParseCore::queryStoryConcept(const QString &name) const
{
QList<DesNode*> rets;
for(auto &it : allStoryConcept()){
if(static_cast<NamedNode*>(it)->name()[0] == name)
rets << it;
}
return rets;
}
QList<DesNode *> ParseCore::queryStoryStrongPoint(DesNode *concept, const QString &name) const
{
QList<DesNode*> rets;
for(auto &it : concept->children()){
if(it->typeValue() == NODE_STORYSTRONGPOINT &&
static_cast<NamedNode*>(it)->name()[0] == name)
rets << it;
}
return rets;
}
QList<DesNode *> ParseCore::queryStoryDepiction(const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &it : nodes_map.keys()) {
if(it->docType() == DocType::STORYOUTLINES)
for(auto &n : *nodes_map[it])
if(n->typeValue() == NODE_STORYDEPICTION &&
static_cast<NamedNode*>(n)->name()[0] == name)
retlist << n;
}
return retlist;
}
Words::Words(Result::DesNode *host, DocCore *doc, const QString & value, int row, int col)
: value_store(value), row_store(row), col_store(col), desnode_store(host), docpresent_store(doc)
{
host->registerWords(this);
}
int Words::row() const
{
return row_store;
}
int Words::column() const
{
return col_store;
}
int Words::length() const
{
return value_store.length();
}
DesNode * Words::host() const
{
return desnode_store;
}
DocCore * Words::doc() const
{
return docpresent_store;
}
QString Words::toString() const
{
return value_store;
}
DocCore::DocCore(ParseCore * core, DocType type, const QFileInfo & path, const QString &doc_name)
: unknown_host(new Unknown(this)), core_store(core), doc_name(doc_name),
file_path_store(path.absoluteFilePath()), type_store(type)
{
}
DesNode * DocCore::unknowns() const
{
return unknown_host;
}
ParseCore * DocCore::core() const
{
return core_store;
}
DocType DocCore::docType() const
{
return type_store;
}
QString DocCore::filePath() const
{
return file_path_store;
}
QString DocCore::docName() const
{
return doc_name;
}
void DocCore::clear()
{
for(auto &it : words_store)
delete it;
words_store.clear();
core()->clearNodes(this);
static_cast<Unknown*>(unknown_host)->xClear();
}
int DocCore::append(Words * ins)
{
words_store << ins;
return 0;
}
QList<Words *> DocCore::getWords(int row, int col) const
{
QList<Words*> list;
for (auto it : words_store)
if (it->row() == row){
if(col >= 0 && it->column() <= col && it->column() + it->length() >= col)
list << it;
else{
list << it;
}
}
return list;
}