Come dice il titolo, ho trascorso un paio d'ore lo scorso fine settimana cercando di concludere la classe di linguaggi corrispondenti alle espressioni regolari compatibili con Perl, escludendo qualsiasi operatore di corrispondenza che consenta di eseguire codice arbitrario all'interno del modello .
Se non sai cosa sono i PCRE, leggi questo e questo .
Il problema è che le risorse disponibili su Internet si fermano praticamente in lingue senza contesto e i PCRE possono corrispondere a più di quelli (vedi sotto); ma non so davvero dove trovare altri teoremi o documenti su questo tipo di cose.
In particolare: i PCRE sono ovviamente un superset di lingue regolari (poiché la sintassi PCRE ha tutti gli operatori linguistici regolari).
Qualsiasi CFG può essere messo nella forma normale di Greibach, che rimuove la ricorsione sinistra. Penso che questo possa essere usato per mezzo di (?(DEFINE)...)
gruppi per "tradurre" la grammatica in corrispondenti subroutine, evitando di soffocare sulla ricorsione sinistra, traducendo:
- il non terminale alla testa di ogni produzione diventa una subroutine
(?<HEAD>...)
- il corpo di ogni produzione viene inserito nella subroutine; i terminali sono lasciati così come sono, i non terminali diventano invocazioni di procedure (cioè
(?&NONTERMINAL)
); - tutte le produzioni con lo stesso non-terminale della testa sono OR insieme per mezzo
|
dell'operatore (più un ulteriore raggruppamento con(?:...)
, se necessario) - il modello diventa quindi un
(?(DEFINE)...)
gruppo contenente tutte le produzioni "tradotte" e un richiamo per la procedura del simbolo iniziale, per abbinare l'intera stringa, ovvero^(?(DEFINE)...)(?&START)$
Questo dovrebbe riguardare qualsiasi CFG. Pertanto, i PCRE dovrebbero essere in grado di abbinare qualsiasi CFL.
C'è di più: prendiamo il linguaggio semplice ovvero la lingua delle stringhe ripetuta due volte. Questo linguaggio non è un CFL - il lemma di pompaggio per i CFL fallisce. (Prestare particolare attenzione a che | v x w | ≤ p deve essere mantenuto, quindi non si può semplicemente pompare l'inizio o la fine delle due stringhe ripetute.)
Tuttavia, questo linguaggio è facilmente accompagnata da un PCRE: ^(.*)\1$
. Pertanto, siamo rigorosamente al di sopra dei CFL.
Quanto sopra? Bene, come ho detto, non ne ho idea. Non sono riuscito a trovare risorse sulle CSL o su tutte le altre classi intermedie per prendere una decisione. Qualche esperto disposto a discuterne?
Addendum: mi è stato chiesto di specificare esattamente quale sottoinsieme della sintassi PCRE deve essere consentito. Come ho scritto all'inizio del post, volevo escludere qualsiasi operatore che consentisse di eseguire codice arbitrario all'interno del modello, come ad esempio ??{}
.
Per amor dell'argomento, penso che possiamo attenerci alla sintassi definita dalla pagina man pcresyntax (3) , che è un sottoinsieme ragionevole di ciò che offre Perl 5.10-5.12, meno i callout (poiché non sono all'interno del modello). Non sono sicuro che l'aggiunta o la rimozione di verbi di controllo di backtracking cambi la lingua che possiamo riconoscere; in tal caso, sarebbe bello capire quali classi prenderemo con e senza quelle.