¿Cómo analizo esto correctamente con espíritu?
-
19-08-2019 - |
Pregunta
Mi situación: soy nuevo en Spirit, tengo que usar VC6 y, por lo tanto, estoy usando Spirit 1.6.4.
Tengo una línea que se ve así:
//The Description;DESCRIPTION;;
Quiero poner el texto DESCRIPTION
en una cadena si la línea comienza con // The Description;
.
Tengo algo que funciona pero que no me parece tan elegante:
vector<char> vDescription; // std::string doesn't work due to missing ::clear() in VC6's STL implementation
if(parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+~ch_p(';'))[assign(vDescription)]
),
// End grammar
space_p).hit)
{
const string desc(vDescription.begin(), vDescription.end());
}
Me gustaría mucho más asignar todos los caracteres imprimibles hasta el siguiente ';'
pero lo siguiente no funcionará porque analizar (...). hit == false
parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+print_p)[assign(vDescription)]
>> ';'
),
// End grammar
space_p).hit)
¿Cómo hago que golpee?
Solución
Puede intentar usar confix_p
:
confix_p(as_lower_d["//the description;"],
(+print_p)[assign(vDescription)],
ch_p(';')
)
Debería ser equivalente a Respuesta de Fred .
La razón por la cual su código falla es porque print_p
es codicioso . El analizador + print_p
consumirá caracteres hasta que encuentre el final de la entrada o un carácter no imprimible. Semicolon es imprimible, por lo que print_p
lo reclama. Su entrada se agota, la variable se asigna y la coincidencia falla & # 8212; no queda nada para que coincida el último punto y coma de su analizador.
La respuesta de Fred construye un nuevo analizador, (print_p - ';')
, que coincide con todo lo que print_p
hace, excepto los punto y coma. " Coincide con todo excepto X , y luego con X " es un patrón común, por lo que confix_p
se proporciona como un acceso directo para construir ese tipo de analizador. La documentación sugiere su uso para analizar comentarios de estilo C o Pascal, pero eso no es obligatorio.
Para que su código funcione, Spirit necesitaría reconocer que el codicioso print_p
coincidía demasiado y luego retroceder para permitir una coincidencia menor. Pero aunque Spirit retrocederá, no retrocederá al '' medio '' de lo que un analizador secundario de otra manera igualaría con avidez. Retrocederá al siguiente '' punto de elección ''. pero tu gramática no tiene ninguna. Consulte Retroceso exhaustivo y codicioso RD en la documentación de Spirit.
Otros consejos
No estás recibiendo un golpe porque ';' coincide con print_p. Prueba esto:
parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+(print_p-';'))[assign(vDescription)]
>> ';'
),
// End grammar
space_p).hit)