用Boost Spirit Classic解析SQL INSERT
问题描述:
我正在努力学习Boost Spirit并作为练习,我试着用Boost Spirit Classic解析SQL INSERT statement
。用Boost Spirit Classic解析SQL INSERT
这是我试图解析字符串:
INSERT INTO example_tab (cola, colb, colc, cold) VALUES (vala, valb, valc, vald);
从这个SELECT example我创建了这个小语法:
struct microsql_grammar : public grammar<microsql_grammar>
{
template <typename ScannerT>
struct definition
{
definition(microsql_grammar const& self)
{
keywords = "insert", "into", "values";
chlit<> LPAREN('(');
chlit<> RPAREN(')');
chlit<> SEMI(';');
chlit<> COMMA(',');
typedef inhibit_case<strlit<> > token_t;
token_t INSERT = as_lower_d["insert"];
token_t INTO = as_lower_d["into"];
token_t VALUES = as_lower_d["values"];
identifier =
nocase_d
[
lexeme_d
[
(alpha_p >> *(alnum_p | '_'))
]
];
string_literal =
lexeme_d
[
ch_p('\'') >> +(anychar_p - ch_p('\''))
>> ch_p('\'')
];
program = +(query);
query = insert_into_clause >> SEMI;
insert_into_clause = insert_clause >> into_clause;
insert_clause = INSERT >> INTO >> identifier >> LPAREN >> var_list_clause >> RPAREN;
into_clause = VALUES >> LPAREN >> var_list_clause >> RPAREN;
var_list_clause = list_p(identifier, COMMA);
}
rule<ScannerT> const& start() const { return program; }
symbols<> keywords;
rule<ScannerT> identifier, string_literal, program, query, insert_into_clause, insert_clause,
into_clause, var_list_clause;
};
};
使用最小的测试它:
void test_it(const string& my_example)
{
microsql_grammar g;
if (!parse(example.c_str(), g, space_p).full)
{
// point a - FAIL
throw new exception();
}
// point b - OK
}
不幸的是,它总是进入A点并抛出异常。由于我是新手,我不知道我的错误在哪里。我有两个问题:
- 使用Boost Spirit时,调试解析错误的正确方法是什么?
- 为什么解析在这个例子中失败?
答
为了得到知名度到什么是无法解析,解析的结果赋值给一个parse_info <>,然后登录/检查parse_info <> ::停止字段,在这种情况下应该是一个const char *指向你输入的与你的语法相匹配的字符串的最后一个字节。
microsql_grammar g;
parse_info<std::string::const_iterator> result = parse(example.begin(), example.end(), g, space_p)
if (!result.full)
{
std::string parsed(example.begin(), result.stop);
std::cout << parsed << std::endl;
// point a - FAIL
}
// point b - OK
道歉,如果这不能编译,但应该是一个起点。
+0
谢谢!我从文件中读取字符串,但没有注意到字符串上附加了一个换行符,因此它没有完全匹配字符串。 – 2011-05-26 14:29:58
我试过你的语法,它解析上面的输入。如果您提供的输入具有任何尾随空格或换行符,它们将阻止parse_info :: full标志被设置,但parse_info :: hit标志将被设置。 – equackenbush 2011-05-24 20:45:49