This commit is contained in:
codeboss 2025-02-12 21:50:45 +08:00
parent b2d221f9ff
commit 77e8e73625
8 changed files with 191 additions and 182 deletions

View File

@ -26,13 +26,18 @@ int main(int argc, char *argv[])
auto rst = parser.parse(vwords);
for (auto one : rst) {
qDebug() << "===================================================";
qDebug().noquote() << one->totalErrors();
QList<QString> words_list;
auto vtoken = one->currentToken();
while (vtoken) {
if(vtoken->defines())
qDebug() << vtoken->content();
words_list.prepend(vtoken->content());
vtoken = vtoken->prevToken();
}
qDebug() << QString("Row:%1,Col:%2,Position:%3,ErrorCount:%4,Errors:")
.arg(one->currentToken()->row()).arg(one->currentToken()->column()).arg(one->currentToken()->position()).arg(one->exprsErrorCount())
<< one->totalErrors();
qDebug() << words_list;
}
return a.exec();

View File

@ -16,7 +16,7 @@ QList<std::shared_ptr<const MatchCursor>> SyntaxParser::parse(std::shared_ptr<co
auto list = this->_rule_bind->parse(cursor);
std::sort(list.begin(), list.end(),
[&](std::shared_ptr<const MatchCursor> a, std::shared_ptr<const MatchCursor> b) {
return a->totalErrorCount() < b->totalErrorCount();
return a->currentToken()->position() > b->currentToken()->position();
});
return list;

View File

@ -194,6 +194,7 @@ namespace lib_syntax {
}
virtual QList<std::shared_ptr<const MatchCursor>> parse(std::shared_ptr<const MatchCursor> current) const override {
auto w_this = current->currentWords();
// 如果提前结束,记录错误并返回
if (!w_this) {
auto clone_ins = std::make_shared<MatchCursor>(current);
clone_ins->logExprsError(QString("Syntax[0x00001]语法匹配错误,缺失\"%1\"<file<%2>>")
@ -204,8 +205,8 @@ namespace lib_syntax {
auto t_this = current->currentToken();
auto match_result = _define_peers->analysis(w_this);
// 解析成功
if (std::get<0>(match_result)) {
auto chain = std::make_shared<lib_token::ActionToken<ELEM, XProc>>(std::get<0>(match_result), t_this);
auto remains = w_this->nextWord();
@ -220,16 +221,13 @@ namespace lib_syntax {
else {
QList<std::shared_ptr<const MatchCursor>> retvals;
// 少一个
{
auto short_one = std::make_shared<MatchCursor>(current);
short_one->logExprsError(QString("Syntax[0x00001]语法匹配错误,缺失\"%1\"<row:%2,col:%3,file<%4>>")
.arg(this->_define_peers->reviseWords())
.arg(w_this->row()).arg(w_this->column()).arg(w_this->file()));
retvals << short_one;
}
// 错一个
{
auto error_one = std::make_shared<MatchCursor>(current);
error_one->logExprsError(QString("Syntax[0x00001]语法匹配错误,请修正\"%1\"<row:%2,col:%3,file<%4>>")
.arg(w_this->content()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file()));
@ -240,7 +238,6 @@ namespace lib_syntax {
auto tkchain = std::make_shared<lib_token::ActionToken<ELEM, XProc>>(tkins, t_this);
error_one->setCurrent(tkchain, w_this->nextWord());
retvals << error_one;
}
// 多一个
if (w_this->nextWord()) {
@ -288,33 +285,23 @@ namespace lib_syntax {
}
virtual QList<std::shared_ptr<const MatchCursor>> parse(std::shared_ptr<const MatchCursor> cursor) const override {
// 提前结束,直接返回
if (cursor->mustStop())
return QList<std::shared_ptr<const MatchCursor>>() << cursor;
auto t_this = cursor->currentToken();
auto w_this = cursor->currentWords();
// 起始Token打点
auto split_begin = std::make_shared<lib_token::ExprBeginToken<ExprType>>(shared_from_this(), t_this);
auto ncursor = std::make_shared<MatchCursor>(cursor);
ncursor->setCurrent(split_begin, w_this);
ncursor->enterExprs();
// 表达式语法解析
auto nbranch = this->expr_rule_parse(ncursor);
decltype(nbranch) list_ok;
// 选择完全匹配成功的
std::copy_if(nbranch.begin(), nbranch.end(), std::back_inserter(list_ok),
[](std::shared_ptr<const MatchCursor> ins) { return !ins->exprsErrorCount(); });
if (!list_ok.size()) {
// 选择被修正的
std::copy_if(nbranch.begin(), nbranch.end(), std::back_inserter(list_ok),
[](std::shared_ptr<const MatchCursor> ins) { return !ins->mustStop(); });
// 匹配失败的
if (!list_ok.size())
list_ok = nbranch;
}
decltype(list_ok) branch_procs;
std::for_each(list_ok.begin(), list_ok.end(), [&](std::shared_ptr<const MatchCursor> curs) {
decltype(nbranch) branch_procs;
std::for_each(nbranch.begin(), nbranch.end(), [&](std::shared_ptr<const MatchCursor> curs) {
if (curs->mustStop()) {
branch_procs.append(curs);
}

View File

@ -172,6 +172,7 @@ public:
// 通过 ElementRule 继承
QList<std::shared_ptr<const MatchCursor>> expr_rule_parse(std::shared_ptr<const MatchCursor> cursor) const override {
auto text = _children_store->present();
return _children_store->parse(cursor);
}
};

View File

@ -110,11 +110,11 @@ namespace lib_token {
// 通过 IActionToken 继承
QString file() const override {
throw new lib_token::TokenException("不应该直接访问ExprBeginToken");
return this->prevToken()->file();
}
uint64_t position() const override {
throw new lib_token::TokenException("不应该直接访问ExprBeginToken");
return this->prevToken()->position();
}
QString content() const override {
@ -122,11 +122,11 @@ namespace lib_token {
}
int row() const override {
throw new lib_token::TokenException("不应该直接访问ExprBeginToken");
return this->prevToken()->row();
}
int column() const override {
throw new lib_token::TokenException("不应该直接访问ExprBeginToken");
return this->prevToken()->column();
}
std::shared_ptr<const ITokenDefine> defines() const override {
@ -160,19 +160,19 @@ namespace lib_token {
// 通过 IActionToken 继承
QString file() const override {
throw new lib_token::TokenException("不应该直接访问ExprEndToken");
return this->prevToken()->file();
}
uint64_t position() const override {
throw new lib_token::TokenException("不应该直接访问ExprEndToken");
return this->prevToken()->position();
}
QString content() const override {
throw new lib_token::TokenException("不应该直接访问ExprEndToken");
}
int row() const override {
throw new lib_token::TokenException("不应该直接访问ExprEndToken");
return this->prevToken()->row();
}
int column() const override {
throw new lib_token::TokenException("不应该直接访问ExprEndToken");
return this->prevToken()->column();
}
std::shared_ptr<const ITokenDefine> defines() const override {
return nullptr;

View File

@ -7,14 +7,17 @@ using namespace lib_token;
using namespace lib_words;
QString LBracket::reviseWords() const { return "{"; }
QString LBracket::reviseWords() const {
return "{";
}
int LBracket::typeMark() const
{
int LBracket::typeMark() const {
return 0x01000000;
}
QString LBracket::regex() const { return "{"; }
QString LBracket::regex() const {
return "{";
}
std::tuple<std::shared_ptr<const IToken>, std::shared_ptr<const IPrimitiveWord>>
LBracket::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
@ -27,41 +30,49 @@ LBracket::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
auto t_remains = content->content().mid(regex().length());
if (t_remains.length() > 0) {
auto remains = std::make_shared<WordContent>(content->row(), content->column() + regex().length(),
content->position() + regex().length(), t_remains, content->file());
auto remains = std::make_shared<WordContent>(content->row(), content->column() + regex().length(), t_remains, content->file());
return std::make_tuple(token_inst, remains);
}
return std::make_tuple(token_inst, nullptr);
}
QString RBracket::reviseWords() const { return "}"; }
QString RBracket::reviseWords() const {
return "}";
}
int RBracket::typeMark() const
{
int RBracket::typeMark() const {
return 0x02000000;
}
QString RBracket::regex() const { return "}"; }
QString RBracket::regex() const {
return "}";
}
QString ReferMk::reviseWords() const { return "@"; }
QString ReferMk::reviseWords() const {
return "@";
}
int ReferMk::typeMark() const
{
int ReferMk::typeMark() const {
return 0x03000000;
}
QString ReferMk::regex() const { return "@"; }
QString ReferMk::regex() const {
return "@";
}
__keywords::__keywords(const QString& val, uint type_code) : means_store(val), type_code(type_code) {}
__keywords::__keywords(const QString& val, uint type_code) : means_store(val), type_code(type_code) { }
QString __keywords::reviseWords() const { return means_store; }
QString __keywords::reviseWords() const {
return means_store;
}
int __keywords::typeMark() const
{
int __keywords::typeMark() const {
return 0x06000000 | (0x00ffffff & type_code);
}
QString __keywords::regex() const { return means_store; }
QString __keywords::regex() const {
return means_store;
}
std::tuple<std::shared_ptr<const IToken>, std::shared_ptr<const IPrimitiveWord>>
__keywords::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
@ -74,14 +85,17 @@ __keywords::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
return std::make_tuple(token_inst, nullptr);
}
QString Numbers::reviseWords() const { return "正整数"; }
QString Numbers::reviseWords() const {
return "正整数";
}
int Numbers::typeMark() const
{
int Numbers::typeMark() const {
return 0x07000000;
}
QString Numbers::regex() const { return "^([0-9]+)$"; }
QString Numbers::regex() const {
return "^([0-9]+)$";
}
std::tuple<std::shared_ptr<const IToken>, std::shared_ptr<const IPrimitiveWord>>
Numbers::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
@ -95,14 +109,17 @@ Numbers::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
return std::make_tuple(tinst, nullptr);
}
QString NormalText::reviseWords() const { return "文本"; }
QString NormalText::reviseWords() const {
return "文本";
}
int NormalText::typeMark() const
{
int NormalText::typeMark() const {
return 0x09000000;
}
QString NormalText::regex() const { return "^([^\\{\\}@&]+)"; }
QString NormalText::regex() const {
return "^([^\\{\\}@&]+)";
}
std::tuple<std::shared_ptr<const IToken>, std::shared_ptr<const IPrimitiveWord>>
NormalText::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
@ -118,34 +135,38 @@ NormalText::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
auto tinst = std::make_shared<TokenContent>(content->row(), content->column(), content->position(),
match, content->file(), shared_from_this());
if (remains.length()) {
auto t_remains = std::make_shared<WordContent>(content->row(), content->column(),
content->position() + match.length(), remains, content->file());
auto t_remains = std::make_shared<WordContent>(content->row(), content->column() + match.length(), remains, content->file());
return std::make_tuple(tinst, t_remains);
}
return std::make_tuple(tinst, nullptr);
}
QString SplitMk::reviseWords() const { return "&"; }
QString SplitMk::reviseWords() const {
return "&";
}
int SplitMk::typeMark() const
{
int SplitMk::typeMark() const {
return 0x05000000;
}
QString SplitMk::regex() const { return "&"; }
QString SplitMk::regex() const {
return "&";
}
QString NameText::reviseWords() const { return "名称"; }
QString NameText::reviseWords() const {
return "名称";
}
int NameText::typeMark() const
{
int NameText::typeMark() const {
return 0x08000000;
}
QString NameText::regex() const { return "^([^\\{\\}@&]+)"; }
QString NameText::regex() const {
return "^([^\\{\\}@&]+)";
}
std::tuple<std::shared_ptr<const IToken>, std::shared_ptr<const IPrimitiveWord> >
NameText::analysis(std::shared_ptr<const IPrimitiveWord> content) const
{
NameText::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
auto text = content->content();
QRegExp regx(regex());
if (regx.indexIn(text) == -1) {
@ -158,8 +179,7 @@ NameText::analysis(std::shared_ptr<const IPrimitiveWord> content) const
auto tinst = std::make_shared<TokenContent>(content->row(), content->column(), content->position(),
match, content->file(), shared_from_this());
if (remains.length()) {
auto t_remains = std::make_shared<WordContent>(content->row(), content->column(),
content->position() + match.length(), remains, content->file());
auto t_remains = std::make_shared<WordContent>(content->row(), content->column() + match.length(), remains, content->file());
return std::make_tuple(tinst, t_remains);
}
return std::make_tuple(tinst, nullptr);
@ -169,19 +189,16 @@ QString DeclareSymbo::reviseWords() const {
return "#";
}
int DeclareSymbo::typeMark() const
{
int DeclareSymbo::typeMark() const {
return 0x0A000000;
}
QString DeclareSymbo::regex() const
{
QString DeclareSymbo::regex() const {
return "#";
}
std::tuple<std::shared_ptr<const IToken>, std::shared_ptr<const IPrimitiveWord>>
DeclareSymbo::analysis(std::shared_ptr<const IPrimitiveWord> content) const
{
DeclareSymbo::analysis(std::shared_ptr<const IPrimitiveWord> content) const {
auto text = content->content();
if (content->column() != 1 && !text.startsWith(regex())) {
return std::make_tuple(nullptr, content);
@ -192,8 +209,7 @@ DeclareSymbo::analysis(std::shared_ptr<const IPrimitiveWord> content) const
auto tinst = std::make_shared<TokenContent>(content->row(), content->column(), content->position(),
"#", content->file(), shared_from_this());
if (remains.length()) {
auto t_remains = std::make_shared<WordContent>(content->row(), content->column()+1,
content->position() + regex().length(), remains, content->file());
auto t_remains = std::make_shared<WordContent>(content->row(), content->column() + regex().length(), remains, content->file());
return std::make_tuple(tinst, t_remains);
}
return std::make_tuple(tinst, nullptr);

View File

@ -40,7 +40,7 @@ QList<std::shared_ptr<const IWordBase>> WordReader::parse_line(uint64_t start_po
int columns_offset = 0;
for (auto& w : words) {
auto column_start = line_text.indexOf(w, columns_offset);
auto token = std::make_shared<WordContent>(row, column_start + 1, start_pos + column_start, w, path);
auto token = std::make_shared<WordContent>(row, column_start + 1, w, path);
primary_words << token;
columns_offset = column_start + w.length();
@ -84,8 +84,8 @@ QString WordsException::message() const {
}
WordContent::WordContent(int r, int c, uint64_t pos, const QString& t, const QString& p)
: row_n(r), col_n(c), doc_offset(pos), text_n(t), path_p(p) { }
WordContent::WordContent(int r, int c, const QString& t, const QString& p)
: row_n(r), col_n(c), doc_offset(r * std::pow(2, 20) + c), text_n(t), path_p(p) { }
QString WordContent::file() const {
return path_p;

View File

@ -59,7 +59,7 @@ namespace lib_words {
QString text_n, path_p;
public:
WordContent(int r, int c, uint64_t pos, const QString& t, const QString& p);
WordContent(int r, int c, const QString& t, const QString& p);
// WordBase interface
public: