gpt4 book ai didi

c++ - 尝试使用 Boost-Spirit 解析类似 SQL 的语句

转载 作者:搜寻专家 更新时间:2023-10-31 00:43:39 26 4
gpt4 key购买 nike

我是 boost::spirit 的新手。我编写了程序来解析 SQL 语句,例如“select * from table where conditions”。它编译失败。报告了大量模板错误。那么,有人会帮助我吗?

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

struct db_select {
void exec() {}

std::string filed;
std::string table;
std::string condition;
};

std::ostream& operator<<(std::ostream& os, const db_select& se) {
return os << "filed: " << se.filed << " table: " << se.table << " condition: " << se.condition;
}

template <class Iterator>
struct selecter : qi::grammar<Iterator, db_select (), ascii::space_type> {
selecter() : selecter::base_type(se) {
se %= "select" >> +qi::char_ << "from" << +qi::char_ << "where" << +qi::char_;
}

qi::rule<Iterator, db_select (), ascii::space_type> se;
};

int main(int argc, char* argv[]) {
if (argc < 2)
return -1;

std::string str(argv[1]);
const char* first = str.c_str();
const char* last = &str[str.size()];
selecter<const char*> se;
db_select rst;

bool r = qi::phrase_parse(first, last, se, ascii::space, rst);
if (!r || first != last) {
std::cout << "parse failed, at: " << std::string(first, last) << std::endl;
return -1;
} else
std::cout << "success, " << rst << std::endl;

return 0;
}

最佳答案

编辑 终于在电脑后面,修改答案:

注意三点

1。语法错误

解析器表达式包含错误(<< 而不是预期的 >>)。这导致了很多编译错误。注意 ******* 的外观在编译器错误中:

/.../qi/nonterminal/rule.hpp|176 col 13| error: no matching function for call to ‘assertion_failed(mpl_::failed************ 

旨在将您引导至源代码中的相应注释:

// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);

容易修复。一个下来,两个去!

2。调整结构

为了作为规则属性分配给您的数据类型,您需要使其融合兼容。最方便的方式:

 BOOST_FUSION_ADAPT_STRUCT(db_select,
(std::string,field)(std::string,table)(std::string,condition));

现在代码编译。但是解析失败。还有一个要走:

3。词位

此外,您还需要采取措施避免使用 +qi::char_ 表达式“吃掉”您的查询关键字。

作为基础,考虑写成类似的东西

   lexeme [  (!lit("where")  >> +qi::graph) % +qi::space ]
  • lexeme抑制封闭表达式的船长
  • !断言指定的关键字必须匹配

最后,查看 qi::no_case 的文档进行不区分大小写的匹配。

完整代码

#include <iostream>
#include <string>
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

struct db_select {
void exec() {}

std::string field;
std::string table;
std::string condition;
};

BOOST_FUSION_ADAPT_STRUCT(db_select,(std::string,field)(std::string,table)(std::string,condition));

std::ostream& operator<<(std::ostream& os, const db_select& se) {
return os << "field: " << se.field << " table: " << se.table << " condition: " << se.condition;
}

template <class Iterator>
struct selecter : qi::grammar<Iterator, db_select (), qi::space_type> {
selecter() : selecter::base_type(se) {
using namespace qi;
se %= "select"
>> lexeme [ (!lit("from") >> +graph) % +space ] >> "from"
>> lexeme [ (!lit("where") >> +graph) % +space ] >> "where"
>> +qi::char_;
}

qi::rule<Iterator, db_select (), qi::space_type> se;
};

int main(int argc, char* argv[]) {
if (argc < 2)
return -1;

std::string str(argv[1]);
const char* first = str.c_str();
const char* last = &str[str.size()];
selecter<const char*> se;
db_select rst;

bool r = qi::phrase_parse(first, last, se, qi::space, rst);
if (!r || first != last) {
std::cout << "parse failed, at: " << std::string(first, last) << std::endl;
return -1;
} else
std::cout << "success, " << rst << std::endl;

return 0;
}

测试:

g++ test.cpp -o test
./test "select aap, noot, mies from table where field = 'value'"

输出:

success, field: aap,noot,mies table: table condition: field='value'

关于c++ - 尝试使用 Boost-Spirit 解析类似 SQL 的语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10331264/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com