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.

expresiones regulares en competencia (condición de carrera)

Estoy intentando usar PLY (lex/yacc) en Python para analizar un lenguaje llamado ‘GRBL’.
GRBL se ve algo así:

Los códigos ‘G’ indican a una máquina que se ‘mueva’ y las coordenadas indican hacia dónde.

LEX nos exige especificar una expresión regular única para cada posible ‘token’.

Así que en este caso necesito una expresión regular que defina claramente ‘G00’ y otra que defina claramente ‘G01’, etc.

Obviamente, el primer pensamiento sería ‘r’G00’ etc.
Sin embargo, el código G es impreciso. Puede estar en mayúscula o minúscula, puede haber ceros anteriores, etc.

(g0, G00, g001, etc.)

Entonces algo para G00 podría ser tan simple como:

‘r'[Gg]{1}0*’

Y para G01 podríamos tener

‘r'[Gg]{1}0*1’

Pero esto no funciona. G00 se analiza correctamente, pero G01 muestra lo siguiente:

LexToken(G00, ‘G0’, 3,21)
Carácter no válido ‘1’

Es decir, lex piensa que G01 es un token G0 y no sabe qué hacer con el ‘1’.
Claramente, este es algún tipo de problema de coincidencia ambiciosa.

Desafortunadamente, no puedo usar el terminador “$” para especificar que la cadena debe ‘terminar’ con un “1”.

Me doy cuenta de que esto puede parecer sencillo para algunos, ¡pero llevo 3 horas intentando hacerlo funcionar! ¿Alguien sabe cómo solucionar este problema?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución utilizando lookahead

    Para resolver este problema, podemos utilizar lookahead (?=) para asegurarnos de que el token termine con 0 o 1, dependiendo del código G que se esté analizando.

    Para G00, la expresión regular se vería así:

    r'[Gg]0(?=[\\sXYZ]|$)'
    

    Esto coincidirá con cualquier cadena que comience con G o g, seguido de un 0, y termine con un carácter de espacio en blanco o las coordenadas X, Y, Z, o el final de la cadena.

    Para G01, la expresión regular se vería así:

    r'[Gg]0*1(?=[\\sXYZ]|$)'
    

    Esto coincidirá con cualquier cadena que comience con G o g, seguido de uno o más 0s, luego un 1, y termine con un carácter de espacio en blanco o las coordenadas X, Y, Z, o el final de la cadena.

    Utilizando estas expresiones regulares, deberías poder analizar con precisión los códigos G en GRBL.

Comments are closed.