Las reglas de Raku son las expresiones regulares , la coincidencia de cadenas y la función de análisis de propósito general del lenguaje de programación Raku , y son una parte fundamental del lenguaje. Dado que las construcciones de coincidencia de patrones de Perl han excedido las capacidades de las expresiones regulares formales durante algún tiempo, la documentación de Raku se refiere a ellas exclusivamente como regexes , distanciando el término de la definición formal.
Raku proporciona un superconjunto de características de Perl 5 con respecto a las expresiones regulares, incorporándolas en un marco más amplio llamado reglas , que proporcionan las capacidades de una gramática de expresión de análisis , además de actuar como un cierre con respecto a su alcance léxico. [1] Las reglas se introducen con la rulepalabra clave, que tiene un uso bastante similar a las definiciones de subrutinas. Las reglas anónimas se pueden introducir con la palabra clave regex(o rx), o simplemente se pueden utilizar en línea como las expresiones regulares en Perl 5 a través de los operadores m(coincidencia) o s(sustitución).
Historia
En Apocalypse 5 , un documento que describe las decisiones preliminares de diseño para la coincidencia de patrones de Raku, Larry Wall enumeró 20 problemas con la "cultura actual de expresiones regulares". Entre ellos, que las expresiones regulares de Perl eran "demasiado compactas y 'lindas'", tenían "demasiado apoyo en muy pocos metacaracteres", "poco soporte para capturas con nombre", "poco soporte para gramáticas" y "mala integración con el lenguaje 'real'". [2]
Entre finales de 2004 y mediados de 2005, se desarrolló un compilador para reglas de estilo Raku para la máquina virtual Parrot llamado Parrot Grammar Engine (PGE), que luego fue renombrado como Parser Grammar Engine, un término más genérico . PGE es una combinación de entorno de ejecución y compilador para gramáticas de estilo Raku que permite que cualquier compilador basado en Parrot utilice estas herramientas para analizar y también para proporcionar reglas a sus entornos de ejecución.
Entre otras características de Raku, en 2007 se agregó soporte para capturas con nombre a Perl 5.10. [3]
En mayo de 2012, la implementación de referencia de Raku, Rakudo , envió su instantánea mensual Rakudo Star con un analizador JSON funcional construido completamente con reglas de Raku. [4]
Cambios respecto a Perl 5
Sólo hay seis características sin cambios con respecto a las expresiones regulares de Perl 5:
- Literales: caracteres de palabras (letras, números y guiones bajos ) que coinciden literalmente
- Capturando:
(...) - Alternativas:
| - Escape de barra invertida:
\ - Cuantificadores de repetición:
*,+, y?, pero no{m,n} - Sufijo de coincidencia mínima:
*?,+?,??
Algunas de las incorporaciones más potentes incluyen:
- La capacidad de hacer referencia a reglas
<rulename>para construir gramáticas completas. - Un puñado de operadores de confirmación que permiten al programador controlar el retroceso durante la coincidencia.
Los siguientes cambios mejoran enormemente la legibilidad de las expresiones regulares:
- Grupos simplificados que no capturan:
[...], que son los mismos que los de Perl 5:(?:...) - Afirmaciones de código simplificadas:
<?{...}> - Permite incluir espacios en blanco sin que coincidan, lo que permite expresiones regulares de varias líneas. Utilice
\o' 'para expresar espacios en blanco. - El formato regex extendido (de Perl 5
/x) ahora es el predeterminado.
Cambios implícitos
Algunas de las características de las expresiones regulares de Perl 5 son más potentes en Raku debido a su capacidad de encapsular las características ampliadas de las reglas de Raku. Por ejemplo, en Perl 5, había operadores de anticipación positivos y negativos (?=...)y (?!...). En Raku existen estas mismas características, pero se denominan <before ...>y <!before ...>.
Sin embargo, debido a que beforepuede encapsular reglas arbitrarias, se puede utilizar para expresar la búsqueda anticipada como un predicado sintáctico para una gramática. Por ejemplo, la siguiente gramática de expresión de análisis describe el lenguaje clásico no independiente del contexto :
S ← & ( A ! b ) a + B
A ← a A ? b
B ← b B ? c
En Raku las reglas serían:
regla S { <antes de <A> <!antes de b>> a+ <B> }
regla A { a <A>? b }
regla B { b <B>? c }
Por supuesto, dada la posibilidad de mezclar reglas y código normal, esto se puede simplificar aún más:
regla S { (a+) (b+) (c+) < { $0 . elems == $1 . elems == $2 . elems } > }
Sin embargo, esto hace uso de afirmaciones , que es un concepto sutilmente diferente en las reglas de Raku, pero sustancialmente diferente en la teoría del análisis, lo que hace que este sea un predicado semántico en lugar de sintáctico. La diferencia más importante en la práctica es el rendimiento. No hay forma de que el motor de reglas sepa qué condiciones puede cumplir la afirmación, por lo que no se puede realizar ninguna optimización de este proceso.
Integración con Perl
En muchos lenguajes, las expresiones regulares se introducen como cadenas, que luego se pasan a rutinas de biblioteca que las analizan y compilan en un estado interno. En Perl 5, las expresiones regulares compartían parte del análisis léxico con el escáner de Perl. Esto simplificó muchos aspectos del uso de expresiones regulares, aunque agregó una gran cantidad de complejidad al escáner. En Raku, las reglas son parte de la gramática del lenguaje. No existe un analizador independiente para reglas, como sucedía en Perl 5. Esto significa que el código, incrustado en reglas, se analiza al mismo tiempo que la regla misma y su código circundante. Por ejemplo, es posible anidar reglas y código sin volver a invocar el analizador:
regla ab {
(a.) # coincide con "a" seguido de cualquier carácter
# Luego verifica si ese carácter era "b" # Si es así, imprime un mensaje. { $0 ~~ /b {diga "encontró la b"}/ }
}
Lo anterior es un solo bloque de código Raku que contiene una definición de regla externa, un bloque interno de código de afirmación y, dentro de este, una expresión regular que contiene un nivel más de afirmación.
Implementación
Palabras clave
Hay varias palabras clave que se utilizan junto con las reglas de Raku:
- expresión regular
- Una expresión regular con nombre o anónima que ignora los espacios en blanco dentro de la expresión regular de forma predeterminada.
- simbólico
- Una expresión regular con nombre o anónima que implica el
:ratchetmodificador. - regla
- Una expresión regular con nombre o anónima que implica los modificadores
:ratchety:sigspace. - receta
- Una expresión regular anónima que acepta delimitadores arbitrarios, como
//donde regex solo acepta llaves. - metro
- Una forma de operador de expresión regular anónima que realiza coincidencias con delimitadores arbitrarios.
- mm
- Abreviatura de m con el
:sigspacemodificador. - s
- Una forma de operador de expresión regular anónima que realiza sustitución con delimitadores arbitrarios.
- es
- Abreviatura de s con el
:sigspacemodificador. /.../- Simplemente colocar una expresión regular entre barras es una forma abreviada de
rx/.../.
A continuación se muestra un ejemplo de uso típico:
palabra token { \w+ }
frase de regla { <palabra> [ \, <palabra> ]* \. }
si $string ~~ / <frase> \n / {
...
}
Modificadores
Los modificadores se pueden colocar después de cualquiera de las palabras clave de la expresión regular y antes del delimitador. Si se nombra una expresión regular, el modificador se coloca después del nombre. Los modificadores controlan la forma en que se analizan las expresiones regulares y cómo se comportan. Siempre se introducen con un :carácter inicial.
Algunos de los modificadores más importantes incluyen:
:io:ignorecase– Realizar la correspondencia sin tener en cuenta mayúsculas y minúsculas.:mo:ignoremark– Realizar la coincidencia sin tener en cuenta los caracteres que se combinan.:go:global– Realizar la coincidencia más de una vez en una cadena de destino determinada.:so:sigspace– Reemplace los espacios en blanco en la expresión regular con una regla de coincidencia de espacios en blanco, en lugar de simplemente ignorarla.:Perl5– Trate la expresión regular como una expresión regular de Perl 5.:ratchet– Nunca realice retroceso en la regla.
Por ejemplo:
suma de expresiones regulares { :ratchet :sigspace <término> \+ <expr> }
Gramáticas
Una gramática se puede definir mediante el grammaroperador . Una gramática es, en esencia, un espacio de nombres para reglas:
gramática Str::SprintfFormat {
expresión regular formato_token { \%: <índice>? <precisión>? <modificador>? <directiva> }
índice token { \d+ \$ }
precisión token { <indicadores>? <vector>? <conteo_precisión> }
indicadores token { <[\ +0\#\-]>+ }
conteo_precisión token { [ <[1-9]>\d* | \* ]? [ \. [ \d* | \* ] ]? }
vector token { \*? v }
modificador token { ll | <[lhmVqL]> }
directiva token { <[\%csduoxefgXEGbpniDUOF]> }
}
Esta es la gramática utilizada para definir la notación de formato de cadena de Perl sprintf.
Fuera de este espacio de nombres, puedes utilizar estas reglas de la siguiente manera:
si / <Str::SprintfFormat::format_token> / { ... }
Una regla utilizada de esta manera es en realidad idéntica a la invocación de una subrutina con la semántica adicional y los efectos secundarios de la coincidencia de patrones (por ejemplo, las invocaciones de reglas se pueden retroceder).
Ejemplos
A continuación se muestran algunos ejemplos de reglas en Raku:
rx { a [ b | c ] ( d | e ) f : g } rx { ( ab * ) < { $1 . tamaño % 2 == 0 } > }
Esto último es idéntico a:
rx { ( ab [ bb ] * ) }
Referencias
- ^ Wall, Larry (24 de junio de 2002). "Sinopsis 5: expresiones regulares y reglas".
- ^ Wall, Larry (4 de junio de 2002). "Apocalipsis 5: Coincidencia de patrones".
- ^ Perl 5.10 ya está disponible - Perl Buzz Archivado el 9 de enero de 2008 en Wayback Machine
- ^ moritz (5 de mayo de 2012). "Lanzamiento de Rakudo Star 2012.05".
Enlaces externos
- Raku Grammars - La página del manual de referencia para gramáticas.
- Tutorial de gramática: un tutorial de gramática en Raku
- Sinopsis 05 - El documento de estándares que cubre las reglas y expresiones regulares de Perl 6.
- Introducción a las expresiones regulares de Perl 6: introducción sencilla a las expresiones regulares de Perl 6.