explorer escribiste:Una expresión en Perl5 que es capaz de localizar esas cadenas:
¡Bien! Yo había intentado algo similar (también embebiendo código Perl dentro de la expresión regular). Por eso hice la aclaración:
pierrot escribiste:(esto podría no ser cierto en el caso de Perl 5, pues la expresividad de las regexps de Perl 5 excede a la de las regexps concebidas como objeto matemático).
Otra
feature o característica de las
regexps de Perl que no es precisamente regular, es el de las
backreferences. Por ejemplo, el lenguaje
{ w w | w en { 0, 1 }* } es claramente NO regular, y sin embargo la regexp de Perl 5,
Using perl Syntax Highlighting
/\A ([01]*)\1 \z/x
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
es capaz de "localizar" estas cadenas.
Sin embargo, en el caso de otros lenguajes no regulares que son igualmente simples, por ejemplo,
{a^n b^m : n, m >= 1, m > n}, empiezan a notarse las limitaciones de las expresiones regulares. Si pensamos utilizar (??{...}) como en tu solución:
Using perl Syntax Highlighting
/^ (a+) (??{ "b" x length $1 }) $/x
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
en este caso no sabemos exactamente cuántas letras 'b' van después de las 'a' (sabemos que son una cantidad mayor a la de las 'a', pero desconocemos el número exacto). Con una gramática sigue siendo natural:
Using perl Syntax Highlighting
grammar G {
regex TOP { a<TOP>b | abb+ }
}
for <abb aaa abbb aaaabbbbb aabb> -> $cadena {
say ((so G.parse($cadena)) ?? "SI" !! "NO") ~ ": $cadena";
}
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
La gramática formal para este lenguaje sería la dada por las reglas:
S -> aSb | abB, B -> bB | b. Como sabemos que la regla de B genera cadenas de la forma
b+, podemos (en Perl 6) escribir directamente
S -> aSb | abb+ y ahorrarnos la definición de la regla para B. No he leído mucho sobre las gramáticas en Perl 6, pero son como unas gramáticas libres de contexto (o sea, solo una variable del lado izquierdo de las reglas) y del lado derecho se aceptan nombres de variables y ¡expresiones regulares en vez de terminales!