es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

fparsec – limitar número de caracteres a los que se aplica un analizador

Tengo un problema en el cual, durante el análisis de un flujo, llego a un punto donde los siguientes N caracteres deben ser analizados aplicando un analizador específico varias veces (en secuencia).

(Ejemplo de juguete simplificado):
“`hx
17<tag><anothertag><a42…
^
|- Estoy aquí
““
Digamos que el número 17 indica que los siguientes N=17 caracteres forman etiquetas, por lo tanto, necesito aplicar repetidamente mi “tagParser”, pero detenerme después de 17 caracteres y no consumir el resto, incluso si parece una etiqueta porque esto tiene un significado diferente y será analizado por otro analizador.

No puedo usar many o many1 porque eso comería el flujo más allá de esos N caracteres. Tampoco puedo usar parray porque no sé cuántas aplicaciones exitosas de ese analizador hay dentro de los N caracteres.

Estaba investigando manyMinMaxSatisfy, pero no pude entender cómo utilizarlo en este caso.

¿Existe alguna forma de cortar N caracteres de un flujo y alimentarlos a algún analizador? ¿O hay alguna forma de invocar muchas aplicaciones, pero hasta N caracteres?

Gracias.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para resolver este problema, puedes usar el analizador parray en combinación con el analizador uptoNChars para consumir solo los próximos N caracteres y luego aplicar repetidamente el analizador tagParser a esa entrada limitada.

    Aquí tienes un ejemplo de código para ilustrar este enfoque:

    let firstNParsers (n:int, p:Parser<'a, 'b>) =
        let rec inner i acc =
            if i = n then acc
            else p .>>. inner (i+1) (acc @ [x])
        inner 0 []
    
    let tagParser = // tu analizador de etiquetas
    let fullParser = 
        (integer .>>. uptoNChars n) >>= fun (_, input) ->
        parray (firstNParsers (n, tagParser)) input
    

    En este fragmento de código, primero consumimos el entero que especifica la longitud de la sección de etiquetas, y luego usamos uptoNChars para consumir solo los siguientes N caracteres. Luego usamos parray en combinación con una función auxiliar firstNParsers (que aplica el tagParser N veces) para analizar esos N caracteres.

    Ten en cuenta que parray fallará si encuentra un carácter que no es una etiqueta válida, por lo que es posible que debas manejar ese caso por separado.

Comments are closed.