【问题标题】:How do I parse an expression with nested parenthesis with boost.Spirit?如何使用 boost.Spirit 解析带有嵌套括号的表达式?
【发布时间】:2011-04-14 10:58:38
【问题描述】:

我需要解析包含键/值对和键/子表达式对的 1 行表达式,例如:

123=a 456=b 789=(a b c) 111=((1=a 2=b 3=c) (1=x 2=y 3=z) (123=(x y z))) 666=evil

为了使解析器更简单,我愿意分几个步骤进行解析,将第一级标签(这里是 123、456、789、111 和 666)分开,然后在另一个步骤中解析它们的内容。 这里 789 的值为"a b c",111 的值为(1=a 2=b 3=c) (1=x 2=y 3=z) (123=(x y z))

但是语法在这一点上打败了我,所以我可以想出一种方法来获取匹配括号之间的表达式。我得到的 111 是 (1=a 2=b 3=c,它以第一个右括号结束。

我找到了这个方便的示例并尝试使用它,但没有成功:

#include <map>
#include <string>
#include <boost/spirit/include/classic.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace qi = boost::spirit::qi;

void main()
{
    auto                                                                   value = +qi::char_("a-zA-Z_0-9");
    auto                                                                   key   =  qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9");
    qi::rule<std::string::iterator, std::pair<std::string, std::string>()> pair  =  key >> -('=' >> value);
    qi::rule<std::string::iterator, std::map<std::string, std::string>()>  query =  pair >> *((qi::lit(';') | '&') >> pair);

    std::string input("key1=value1;key2;key3=value3");  // input to parse
    std::string::iterator begin = input.begin();
    std::string::iterator end = input.end();

    std::map<std::string, std::string> m;        // map to receive results
    bool result = qi::parse(begin, end, query, m);   // returns true if successful
}

我该怎么做?

编辑:我在http://boost-spirit.com/home/articles/qi-example/parsing-a-list-of-key-value-pairs-using-spirit-qi/找到了这个例子

【问题讨论】:

    标签: c++ grammar boost-spirit boost-spirit-qi


    【解决方案1】:

    你可以这样写:

    qi::rule<std::string::iterator, std::pair<std::string, std::string>()> pair = 
            key >> -(
               '=' >> ( '(' >> raw[query] >> ')' | value )
            )
        ;
    

    它将所有嵌入式查询存储为与键关联的值(字符串)。不过,这将从存储的值中删除括号。如果您仍希望将括号存储在返回的属性中,请使用:

    qi::rule<std::string::iterator, std::pair<std::string, std::string>()> pair = 
            key >> -(
               '=' >> ( raw['(' >> query >> ')'] | value )
            )
        ;
    

    【讨论】:

    • 为了编译我必须在定义pair之前声明(不定义)query。无论如何,这行得通吗?
    • 是的,您可以在实际使用之前或之后声明、定义和/或初始化规则。最好是使用语法,其中规则是成员,它们在语法的构造函数中初始化。
    • @hkaiser 您的示例中的“原始”是什么?我在这篇文章中找不到任何对它的引用。
    • @ForeverLearning:请参阅此处以获取相应的文档:boost.org/doc/libs/1_63_0/libs/spirit/doc/html/spirit/qi/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    相关资源
    最近更新 更多