2013-02-19 36 views
0

我试图解析与升压::精神这个简单consise XML的头脑结构,的boost ::精神和语法

One{ 
    Two{ 
     Three{ 
     } 
    } 
} 

和代码的组织结构如下:

的结构定义保持精神-东西:

struct config; 
typedef boost::variant< boost::recursive_wrapper<config> , std::string > config_node; 

struct config 
{ 
    std::string name; 
    std::vector<config_node> children; 
}; 


BOOST_FUSION_ADAPT_STRUCT(
    config, 
    (std::string, name) 
    (std::vector<config_node>, children) 
) 

宣言(无耻从XML介绍抄截) (在解析器类上)

qi::rule<Iterator, config(), qi::locals<std::string>, ascii::space_type> cfg; 
qi::rule<Iterator, config_node(), ascii::space_type> node; 
qi::rule<Iterator, std::string(), ascii::space_type> start_tag; 
qi::rule<Iterator, void(std::string), ascii::space_type> end_tag; 

在解析器'parse'方法中定义规则。

node = cfg; 
    start_tag = +(char_ -'{') >> '{'; 
    end_tag = char_('}'); 

    cfg %= start_tag[_a = _1] 
     >> *node 
     >> end_tag(_a); 

_a和_1是boost :: phoenix变量。

此规则上面粘贴的小文档片断的作品,但如果我把它改为:

One{ 
    Two{ 
    } 
    Three{ 
    } 
} 

(两个组在同一范围内,而不是其他组的组内)解析器失败。 我不知道为什么。

回答

2

为了将来的参考,你的代码看起来像Boost教程中的mini_xml2.cpp(简称“无耻窃取者”)的简化版本。

为了使您的工作例如,你必须更改线路:

start_tag = +(char_ -'{') >> '{'; 

start_tag = +(char_ -'{' - '}') >> '{';

这是不言自明现在:)每当分析器分析start_tag ,它开始寻找node s(因为>> *node部分)。由于}是合法的start_tag,因此可能会将其识别为一个,而不应该这样做。


btw在代码中有一些冗余可能会考虑修复。例如:

在最初的mini_xml2.cpp示例中,end_tag用作检查您是否关闭与打开的标记相同的标记(因此标记为void(std::string))的函数。你会更好用

cfg %= start_tag[_a = _1] 
>> *node 
>> "}"; 

在mini_xml2.cpp例子多态的,所以boost::variant与游客一起使用的节点。在你的例子中,这也是多余的。说实话,这让我不知道怎么行

node = cfg 

编译过程中没有造成任何问题,因为nodeboost::variant类型。仅供参考,在原来的示例中,这是行:

node %= xml | text; 

%=操作者正确地“猜测”的RHS的类型中,由于操作者|读取结果作为boost::variant

+0

谢谢。提升是一个巨大的怪物,我仍然试图“驯服”它。 =) – 2013-02-22 16:07:40