用 boost spirit x3 解析 SQL 类查询
Parse SQL like query with boost spirit x3
我正在尝试使用 boost spirit x3 解析一个简单的 SQL 类查询。
之前的精灵版本有similar post。但是有了spirit x3,我们就不需要文法了
所以这是我的尝试:
// SELECT chr, pos FROM table
// Select chr, pos FROM table WHERE a=5 and b = 6
// SELECT chr, pos FROM table WHERE a =5 and b=6 INSIDE region
// I would like to extract :
// vector<string> fields = {chr, pos}
// string tablename = "table"
// string where = "a=5 and b=6"
// string region = "region"
string source ="SELECT chr,pos FROM table WHERE a=5 AND b=6 INSIDE region";
// varname = chr, pos, table, region
auto varname = x3::rule<class varname, string>()
= x3::lexeme[(x3::alpha >> *(x3::alnum|'_'|'.'))];
// any character except "INSIDE"
auto condition = x3::rule<class condition, string>()
= x3::lexeme[*x3::char_]-"INSIDE";
// fields selection
auto selectRule = x3::rule<class fields, vector<string>> ()
= "SELECT" >> varname % ",";
// table name
auto fromRule = x3::rule<class fromRule, string>()
= "FROM" >> varname;
// where clause
auto whereRule = x3::rule<class whereRule, vector<string>>()
= "WHERE" >> condition ;
// inside clause
auto insideRule = x3::rule<class insideRule, string>()
= "INSIDE" >> varname;
auto begin = source.begin();
auto end = source.end();
vector<string> results;
x3::phrase_parse(begin,end,
selectRule >> fromRule >> -(whereRule >>-insideRule),
x3::space, results);
if (begin != end)
cout<<"COULD NOT PARSE"<<endl;
else
cout<<"parse succes"<<endl;
for (auto i : results)
cout<<i<<endl;
它returns:
chr
pos
table
a=5 AND b=6 INSIDE region
results 包含提取的所有属性数据,除了保留在条件字符串中的 insideRule 属性数据。
有什么线索可以让我的解析器正常工作吗?
这正在工作:
struct VqlResult {
std::vector<std::string> selectData;
std::string fromData;
std::string whereData;
std::string insideData;
};
BOOST_FUSION_ADAPT_STRUCT
(
VqlResult,
selectData,
fromData,
whereData,
insideData
);
// Pseudo Sql parser
// e.g : SELECT chr,pos FROM table WHERE a=5 AND b=6 INSIDE region
bool parseSql(const std::string& sql)
{
auto varnameRule = x3::rule<class varname, string>()
= x3::lexeme[(x3::alpha >> *(x3::alnum|'_'|'.'))];
auto columnsRule = x3::rule<class varname, string>()
= x3::lexeme[*(x3::char_ - '"' - "FROM")];
auto conditionRule = x3::lexeme[*(x3::char_ - "INSIDE")];
auto selectRule = x3::rule<class fields, vector<string>> ()
= "SELECT" >> columnsRule % ",";
auto fromRule = "FROM" >> varnameRule;
auto whereRule = "WHERE" >> conditionRule;
auto insideRule = "INSIDE" >> varnameRule;
auto begin = sql.begin();
auto end = sql.end();
VqlResult results;
x3::phrase_parse(begin,end,
selectRule >> fromRule >> -whereRule >> -insideRule,
x3::space, results);
// parse all
if (begin != end){
cout<<"cannot parse "<<endl;
return false;
}
return true;
}
我正在尝试使用 boost spirit x3 解析一个简单的 SQL 类查询。
之前的精灵版本有similar post。但是有了spirit x3,我们就不需要文法了
所以这是我的尝试:
// SELECT chr, pos FROM table
// Select chr, pos FROM table WHERE a=5 and b = 6
// SELECT chr, pos FROM table WHERE a =5 and b=6 INSIDE region
// I would like to extract :
// vector<string> fields = {chr, pos}
// string tablename = "table"
// string where = "a=5 and b=6"
// string region = "region"
string source ="SELECT chr,pos FROM table WHERE a=5 AND b=6 INSIDE region";
// varname = chr, pos, table, region
auto varname = x3::rule<class varname, string>()
= x3::lexeme[(x3::alpha >> *(x3::alnum|'_'|'.'))];
// any character except "INSIDE"
auto condition = x3::rule<class condition, string>()
= x3::lexeme[*x3::char_]-"INSIDE";
// fields selection
auto selectRule = x3::rule<class fields, vector<string>> ()
= "SELECT" >> varname % ",";
// table name
auto fromRule = x3::rule<class fromRule, string>()
= "FROM" >> varname;
// where clause
auto whereRule = x3::rule<class whereRule, vector<string>>()
= "WHERE" >> condition ;
// inside clause
auto insideRule = x3::rule<class insideRule, string>()
= "INSIDE" >> varname;
auto begin = source.begin();
auto end = source.end();
vector<string> results;
x3::phrase_parse(begin,end,
selectRule >> fromRule >> -(whereRule >>-insideRule),
x3::space, results);
if (begin != end)
cout<<"COULD NOT PARSE"<<endl;
else
cout<<"parse succes"<<endl;
for (auto i : results)
cout<<i<<endl;
它returns:
chr
pos
table
a=5 AND b=6 INSIDE region
results 包含提取的所有属性数据,除了保留在条件字符串中的 insideRule 属性数据。 有什么线索可以让我的解析器正常工作吗?
这正在工作:
struct VqlResult {
std::vector<std::string> selectData;
std::string fromData;
std::string whereData;
std::string insideData;
};
BOOST_FUSION_ADAPT_STRUCT
(
VqlResult,
selectData,
fromData,
whereData,
insideData
);
// Pseudo Sql parser
// e.g : SELECT chr,pos FROM table WHERE a=5 AND b=6 INSIDE region
bool parseSql(const std::string& sql)
{
auto varnameRule = x3::rule<class varname, string>()
= x3::lexeme[(x3::alpha >> *(x3::alnum|'_'|'.'))];
auto columnsRule = x3::rule<class varname, string>()
= x3::lexeme[*(x3::char_ - '"' - "FROM")];
auto conditionRule = x3::lexeme[*(x3::char_ - "INSIDE")];
auto selectRule = x3::rule<class fields, vector<string>> ()
= "SELECT" >> columnsRule % ",";
auto fromRule = "FROM" >> varnameRule;
auto whereRule = "WHERE" >> conditionRule;
auto insideRule = "INSIDE" >> varnameRule;
auto begin = sql.begin();
auto end = sql.end();
VqlResult results;
x3::phrase_parse(begin,end,
selectRule >> fromRule >> -whereRule >> -insideRule,
x3::space, results);
// parse all
if (begin != end){
cout<<"cannot parse "<<endl;
return false;
}
return true;
}