如何以提升精神正确解析保留字 [英] How to parse reserved words correctly in boost spirit
问题描述
我正在尝试解析以下语法序列:<方向 > <类型 > <名称 >.例如:
I'm trying to parse a sequence of the syntax: < direction > < type > < name >. For example:
in float foo
方向可以是in、out或in_out.通过使用 qi::symbols 类将方向关键字转换为枚举,我成功地解析了正确的文本.
where the direction can be either in, out, or in_out. I've succeeded in parsing correct text by using a qi::symbols class to convert the direction keywords to an enum.
但是,当我没有正确的文本时会出现问题.举个例子:
However, the problem shows when I don't have correct text. Take the example:
int foo
符号表解析器将排除 'int' 类型的 'in' 部分,因此结果将是:
The symbol table parser will except the 'in' part of the 'int' type and so the results will be:
direction: in
type: t
name: foo
并且没有检测到错误.能够解析 in、out 和 in_out 保留字并确保它们后跟一个非标识符字符从而使前一个文本的int"部分失败的最佳方法是什么?
And the error is not detected. What's the best way to be able to parse the in, out and in_out reserved words and ensure that they are followed by a non-identifier character so that the 'int' part of the previous text fails?
谢谢
推荐答案
除了 Mike 建议的手动"方法外,您还可以
In addition to the "manual" approach suggested by Mike you can
- 使用便利包装规则
- 使用来自 Spirit Repository 的
distinct
解析器指令
- use a convenience wrapper rule
- use the
distinct
parser direetive from the Spirit Repository
1.使用方便的包装器
我才想起来,我曾经想过这个又快又脏的帮手:
1. Use a convenience wrapper
I just remembered, I once came up with this quick and dirty helper:
static const qi::rule<It, qi::unused_type(const char*)> kw
= qi::lit(qi::_r1) >> !qi::alnum;
你可以使用like(使用+"lit"
将数组引用衰减为const char*
):
Which you could use like (using +"lit"
to decay the array-ref into 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.使用 Spirit Repository 中的 distinct
指令
除了 Mike 建议的手动"方法之外,您还可以使用 Spirit Repository 中的 distinct
解析器指令:
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();
}
这篇关于如何以提升精神正确解析保留字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!