parsing - 如何以 boost spirit 正确解析保留字

标签 parsing boost boost-spirit boost-spirit-qi

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

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 的解析器指令:
  • http://www.boost.org/doc/libs/1_55_0/libs/spirit/repository/test/qi/distinct.cpp

  • 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/

    相关文章:

    c++ - 我可以将 BOOST_FUSION_ADAPT_STRUCT 与继承的东西一起使用吗?

    php - 解析错误 : syntax error, 意外的 T_PRIVATE

    c++ - 使用 boost::spirit 在解析为结构时将解析值默认为较早的值

    c - Bison 语法/解析器的多个起点

    c++ - 没有 Boost 的现代 C++ 中的 bimap 实现

    c++ - 绑定(bind)并连接的 Boost.Asio 数据报 (UDP) 套接字

    c++ - 用于解析 C++ 中重复日期描述的库?

    boost::spirit::karma 生成器规则中的语义 Action

    java - 从 Web 服务响应中解析单个 XML 节点

    algorithm - 自由格式文本的通用地址解析器