2012-02-07 23 views
5

Boost Spirit (ve Boost Fusion) eğiticilerini (sürüm 1.48.0) geçiyorum. Oyuncak çalışan örneğiyle oynuyordum. İşte Boost :: Ruh basit dilbilgisi örneği

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

Örnekteki dilbilgisi geçerli:: kaynağına bağlantı burada

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; 

Ve modifikasyonlar tırnak tedavisi çıkarıp sadece sınırlayıcı arasında herhangi bir karakter ayrıştırır ve bu atar ayrıştırıcının yapısına eşlenir.

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

Benim varsayımım, char_'ın bir virgül olana kadar tüm karakterleri içermesidir. Ancak, aşağıdaki dize ile derleme ve yürütme ayrıştırılamıyor. Ben de benzer bir ayrıştırıcı yazmaya çalışılıyor

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

otomatik benim yapı tipi uygun türleri yayın yapmak için. Yukarıdaki gibi bir giriş dizesi için doğru dilbilgisi tanımlamak kadar temelde yanlış bir şey eksik eminim, bu yüzden herhangi bir yardım büyük takdir!

Teşekkürler!

cevap

10

+(char_), bir veya daha fazla karakter tüketir, bu nedenle virgül tüketir ve hiçbir zaman >> ',''a gitmez. Bu açgözlü.

Sen fark operatörünü - kullanarak, +(char_ - ',') yazmalıdır:

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

Ayrıştırıcı +(char_ - ',') virgül ulaşılana kadar her kömürü tüketmek olacaktır. Bundan sonra >> ',''a hareket edecek, tüketecek ve daha sonra +(char_ - ',') ile virgül ve benzeri olana kadar devam edecektir. Burada bulabilirsiniz bu operatör hakkında

Daha: Ayrıca ayrıştırıcı yazma düşünebilirsiniz http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/difference.html

VEYA

yalnızca harfleri içeren isimleri ayrıştırmak istiyorsanız, hangi yalnızca harf kabul ediyoruz:

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

... bu sadece ASCII harfleri olurdu, o zaman ... José eğlendirilmedi. ;-) – DevSolar