我正在尝试解析语法序列:<方向> <类型> <名称>。例如:
in float foo
其中方向可以是 在 , 出 , 或 进出 .通过使用 qi::symbols 类将方向关键字转换为枚举,我成功地解析了正确的文本。
但是,当我没有正确的文本时会出现问题。举个例子:
int foo
符号表解析器将排除“int”类型的“in”部分,因此结果将是:
direction: in
type: t
name: foo
并且未检测到错误。能够解析 in、out 和 in_out 保留字并确保它们后跟一个非标识符字符以便前一个文本的“int”部分失败的最佳方法是什么?
谢谢
最佳答案
除了迈克建议的“手动”方法之外,您还可以
distinct
来自 Spirit Repository 的解析器指令 1. 使用方便的包装器
我只记得,我曾经想出了这个又快又脏的 helper :
static const qi::rule<It, qi::unused_type(const char*)> kw
= qi::lit(qi::_r1) >> !qi::alnum;
您可以像这样使用(使用
+"lit"
将数组引用衰减为 const char*
):stmt =
kw(+"if") >> '(' >> expr >> ')' >> block
>> -(kw(+"else") >> block)
;
你可以让它更方便
template <std::size_t N>
static auto kw(char const (&keyword)[N]) -> qi::rule<Iterator> {
// qi::lit has problems with char arrays, use pointer instead.
return qi::lit(+keyword) >> !qi::alnum;
}
这样你就可以
kw_if = kw("if");
kw_then = kw("then");
kw_else = kw("else");
kw_and = kw("and");
kw_or = kw("or");
kw_not = kw("not");
2. 使用
distinct
来自 Spirit Repository 的指令除了 Mike 建议的“手动”方法之外,您还可以使用
distinct
来自 Spirit Repository 的解析器指令:int main()
{
using namespace spirit_test;
using namespace boost::spirit;
{
using namespace boost::spirit::ascii;
qi::rule<char const*, space_type> r;
r = distinct::keyword["description"] >> -lit(':') >> distinct::keyword["ident"];
BOOST_TEST(test("description ident", r, space));
BOOST_TEST(test("description:ident", r, space));
BOOST_TEST(test("description: ident", r, space));
BOOST_TEST(!test("descriptionident", r, space));
}
return boost::report_errors();
}
关于parsing - 如何以 boost spirit 正确解析保留字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20131162/