如何在提升精神中正确解析保留字

Cth*_*utu 6 parsing boost boost-spirit boost-spirit-qi

我正在尝试解析一系列语法:<direction> <type> <name>.例如:

in float foo
Run Code Online (Sandbox Code Playgroud)

方向可以是in,outin_out.我已成功通过使用qi :: symbols类将方向关键字转换为枚举来解析正确的文本.

但是,问题显示我没有正确的文本.举个例子:

int foo
Run Code Online (Sandbox Code Playgroud)

符号表解析器将除'int'类型的'in'部分,因此结果将是:

direction: in
type: t
name: foo
Run Code Online (Sandbox Code Playgroud)

并且未检测到错误.能够解析in,out和in_out保留字并确保它们后跟非标识符字符以便前一文本的"int"部分失败的最佳方法是什么?

谢谢

seh*_*ehe 5

除了迈克建议的"手动"方法,你可以

  1. 使用便利包装规则
  2. 使用distinctSpirit Repository中的解析器direetive

1.使用便利包装

我记得,我曾经想出过这个快速而又肮脏的帮手:

static const qi::rule<It, qi::unused_type(const char*)> kw 
      = qi::lit(qi::_r1) >> !qi::alnum;
Run Code Online (Sandbox Code Playgroud)

你可以使用哪个(+"lit"用于衰减数组-ref const char*):

stmt = 
         kw(+"if") >> '(' >> expr >> ')' >> block
     >> -(kw(+"else") >> block)
     ;
Run Code Online (Sandbox Code Playgroud)

你可以使它更方便

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;
}
Run Code Online (Sandbox Code Playgroud)

所以你可以

kw_if   = kw("if");
kw_then = kw("then");
kw_else = kw("else");
kw_and  = kw("and");
kw_or   = kw("or");
kw_not  = kw("not");
Run Code Online (Sandbox Code Playgroud)

2.使用distinctSpirit Repository中的指令

除了Mike建议的"手动"方法之外,您还可以使用distinctSpirit 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();
}
Run Code Online (Sandbox Code Playgroud)