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?
¡Gracias! Sí, puede usar ese código como una prueba de regresión. –