2012-02-07 110 views
5

我正在閱讀Boost Spirit(和Boost Fusion)教程(版本1.48.0)。我一直在玩玩具員工的例子。到源鏈接是在這裏:Boost :: Spirit簡單文法示例

http://www.boost.org/doc/libs/1_48_0/libs/spirit/example/qi/employee.cpp

這裏是例子的語法:

employee_parser() : employee_parser::base_type(start) 
    { 
     using qi::int_; 
     using qi::lit; 
     using qi::double_; 
     using qi::lexeme; 
     using ascii::char_; 

     quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; 

     start %= 
      lit("employee") 
      >> '{' 
      >> int_ >> ',' 
      >> quoted_string >> ',' 
      >> quoted_string >> ',' 
      >> double_ 
      >> '}' 
      ; 
    } 

    qi::rule<Iterator, std::string(), ascii::space_type> quoted_string; 
    qi::rule<Iterator, employee(), ascii::space_type> start; 

而且我修改刪除引號的處理,只是解析分隔符之間的任何字符,並賦給到解析器映射到的結構。

 //quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; 
     start %= 
      lit("employee") 
      >> '{' 
      >> int_ >> ',' 
      >> +(char_) >> ',' 
      >> +(char_) >> ',' 
      >> double_ 
      >> '}' 
      ; 

我的假設是,char_包括所有字符,直到達到逗號。但是,編譯並使用以下字符串運行會返回解析失敗。

./employee 
employee{10,my,name,20.0} 
------------------------- 
Parsing failed 
------------------------- 

我也嘗試寫一個類似解析器自動轉換爲相應的類型我的結構類型。我確定我錯過了一些根本錯誤,就像上面定義輸入字符串的正確語法一樣,所以任何幫助都非常感謝!

謝謝!

回答

10

+(char_)消耗一個或多個字符,所以它也會消耗逗號,並且永遠不會移動到>> ','。它很貪婪。

你應該寫+(char_ - ','),採用差分算-

//... 
>> int_ >> ','  
>> +(char_ - ',') >> ','  
>> +(char_ - ',') >> ','  
>> double_ 
//... 

分析器+(char_ - ',')達到逗號,直到將消耗每字符。之後,它將移動到>> ',',消耗它,然後繼續下一行+(char_ - ','),直到逗號等。

更多關於這家運營商,你可以在這裏找到:http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/difference.html

OR

如果要分析其中只包含字母的名字,你也可以考慮寫解析器只接受字母:

//... 
>> int_ >> ','  
>> +(char_("a-zA-Z")) >> ','  
>> +(char_("a-zA-Z")) >> ','  
>> double_ 
//... 
+2

......那將只是ASCII字母,然後......何塞不開心。 ;-) – DevSolar 2014-12-12 09:53:35