Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用boost.Spirit解析带有嵌套括号的表达式?_C++_Grammar_Boost Spirit_Boost Spirit Qi - Fatal编程技术网

C++ 如何使用boost.Spirit解析带有嵌套括号的表达式?

C++ 如何使用boost.Spirit解析带有嵌套括号的表达式?,c++,grammar,boost-spirit,boost-spirit-qi,C++,Grammar,Boost Spirit,Boost Spirit Qi,我需要解析包含键/值对和键/子表达式对的单行表达式,如: 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的值是“abc”,111的值是(1=a2=b3=c)(1=x2=y3=z)(123=(xyz)) 但是语法在这一点上击败了我,

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

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的值是
“abc”
,111的值是
(1=a2=b3=c)(1=x2=y3=z)(123=(xyz))

但是语法在这一点上击败了我,所以我无法找到一种方法来获得匹配括号之间的表达式。对于111,我得到的是
(1=a2=b3=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
}
#包括
#包括
#包括
#包括
#包括
名称空间qi=boost::spirit::qi;
void main()
{
自动值=+qi::char_uu(“a-zA-Z_u0-9”);
自动关键点=qi::char_u(“a-zA-Z”)>>*qi::char_u(“a-zA-Z_u0-9”);
qi::规则对=键>>-('='>>值);
qi::rule query=pair>>*((qi::lit(“;”)|'&')>>pair);
字符串输入(“key1=value1;key2;key3=value3”);//要分析的输入
std::string::iterator begin=input.begin();
std::string::iterator end=input.end();
std::map m;//用于接收结果的映射
bool result=qi::parse(begin、end、query、m);//如果成功,则返回true
}
我怎么能做到

编辑:我在

找到了这个例子,你可以这样写:

qi::rule<std::string::iterator, std::pair<std::string, std::string>()> pair = 
        key >> -(
           '=' >> ( '(' >> raw[query] >> ')' | value )
        )
    ;
qi::规则对=
键>>-(
“=”>>(“(“>>原始[查询]>>”)”|值)
)
;
它将所有嵌入的查询存储为与键关联的值(字符串)。但这将从存储的值中删除括号。如果仍要将括号存储在返回的属性中,请使用以下方法:

qi::rule<std::string::iterator, std::pair<std::string, std::string>()> pair = 
        key >> -(
           '=' >> ( raw['(' >> query >> ')'] | value )
        )
    ;
qi::规则对=
键>>-(
“=”>>(原始[”(“>>查询>>”)”]|值)
)
;

为了编译,我必须声明(而不是定义)
query
在我定义
pair
之前。这样做行吗?是的,你可以在规则实际使用之前或之后声明、定义和/或初始化规则。最好是使用语法,其中规则是成员,它们在语法的构造函数中初始化。@hkaiser在你的示例中“原始”是什么?我找不到任何对它的引用在这篇文章中。@ForeverLearning:有关相应的文档,请参见此处: