2010-10-24 15 views
6

Solo he estado trabajando con Boost.Spirit (de Boost 1.44) durante tres días, tratando de analizar mensajes crudos de correo electrónico mediante la gramática exacta en RFC2822. Pensé que estaba empezando a entenderlo y llegar a alguna parte, pero luego me encontré con un problema:Boost.Spirit error al mezclar "alterna" con "opcionales"?

#include <iostream> 
#include <boost/spirit/include/qi.hpp> 

namespace qi = boost::spirit::qi; 
using qi::omit; 
using qi::repeat; 
using std::cout; 
using std::endl; 

typedef qi::rule<std::string::const_iterator, std::string()> strrule_t; 

void test(const std::string input, strrule_t rule) { 
    std::string target; 
    std::string::const_iterator i = input.begin(), ie = input.end(); 

    if (qi::parse(i, ie, rule, target)) { 
     cout << "Success: '" << target << "'" << endl; 
    } else { 
     cout << "Failed to match." << endl; 
    } 
} 

int main() { 
    strrule_t obsolete_year = omit[-qi::char_(" \t")] >> repeat(2)[qi::digit] >> 
     omit[-qi::char_(" \t")]; 
    strrule_t correct_year = repeat(4)[qi::digit]; 

    test("1776", correct_year | repeat(2)[qi::digit]); // 1: Works, reports 1776. 
    test("76", obsolete_year);      // 2: Works, reports 76. 
    test("76", obsolete_year | correct_year);  // 3: Works, reports 76. 
    test(" 76", correct_year | obsolete_year);  // 4: Works, reports 76. 
    test("76", correct_year | obsolete_year);  // 5: Fails. 
    test("76", correct_year | repeat(2)[qi::digit]); // 6: Also fails. 
} 

Si la prueba # 3 obras, entonces ¿por qué la prueba # 5 - la misma prueba exacta con las dos alternativas invertidas -- ¿fallar?

De la misma manera, si perdona la expresión: si la prueba # 4 funciona, y el espacio al principio está marcado como opcional, entonces ¿por qué la prueba # 5 (la misma prueba con la misma entrada exacta? , excepto que no hay espacio en la entrada) ¿fallan?

Y, por último, si esto es un error en Boost.Spirit (como sospecho que debe ser), ¿cómo puedo solucionarlo?

Respuesta

7

Esto se debe a que ha encontrado un error en la directiva de Spirit repeat[]. Gracias por el informe, arreglé este problema en SVN (rev. [66167]) y estará disponible en Boost V1.45. Al mismo tiempo, me gustaría agregar su pequeña prueba como una prueba de regresión al conjunto de pruebas de Spirit. Espero que no te importe que lo haga.

+0

¡Gracias! Sí, puede usar ese código como una prueba de regresión. –

Cuestiones relacionadas