2013-02-19 85 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