如何以提升精神正确解析保留字 [英] How to parse reserved words correctly in boost spirit

查看:18
本文介绍了如何以提升精神正确解析保留字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解析以下语法序列:<方向 > <类型 > <名称 >.例如:

I'm trying to parse a sequence of the syntax: < direction > < type > < name >. For example:

in float foo

方向可以是inoutin_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

  1. 使用便利包装规则
  2. 使用来自 Spirit Repository 的 distinct 解析器指令
  1. use a convenience wrapper rule
  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆