2012-02-07 9 views
5

Estoy repasando los tutoriales de Boost Spirit (y Boost Fusion) (versión 1.48.0). He estado jugando con el ejemplo del empleado de juguete. El enlace a la fuente está aquí:Boost :: Ejemplo de gramática simple de Spirit

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

Aquí es del ejemplo de gramática:

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; 

Y mis modificaciones quitar el tratamiento de las cotizaciones y simplemente analiza cualquier carácter entre el delimitador y asigna esa a la estructura al que se asigna el analizador.

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

Mi hipótesis es que char_ incluye todos los caracteres hasta que se alcanza una coma. Sin embargo, compilar y ejecutar con la siguiente cadena devuelve un error al analizar.

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

También estoy intentando escribir un analizador similar para convertir automáticamente a los tipos apropiados de mi tipo de estructura. ¡Estoy seguro de que me falta algo fundamentalmente erróneo en cuanto a definir la gramática correcta para una cadena de entrada como la anterior, por lo que cualquier ayuda es muy apreciada!

Gracias!

Respuesta

10

+(char_) consume uno o más caracteres, por lo que también consumirá comas y nunca se moverá a >> ','. Es codicioso

Usted debe escribir +(char_ - ','), utilizando operador de diferencia -:

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

Analizador +(char_ - ',') consumiría cada carbón hasta que se alcanza por comas. Después de eso, se moverá al >> ',', cómprelo y luego continúe con la siguiente línea +(char_ - ',') hasta la coma y así sucesivamente.

Más información este operador se puede encontrar aquí: http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/difference.html

O

Si desea analizar los nombres de los cuales contiene sólo letras, también puede que no escribe analizador que aceptan sólo letras:

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

... eso serían solo letras ASCII, entonces ... José no se divierte. ;-) – DevSolar

Cuestiones relacionadas