Il linguaggio delle espressioni regolari ha bisogno di un push down degli automi per analizzarlo?


12

Voglio convertire un utente inserito espressione regolare in un NFA in modo da poter quindi eseguire l'NFA contro una stringa per scopi corrispondenti. Qual è la macchina minima che può essere utilizzata per analizzare le espressioni regolari?

Presumo che debba essere un automa push down perché la presenza di parentesi indica la necessità di contare e un DFA / NFA non può eseguire un conteggio arbitrario. Questo assunto è corretto? Ad esempio, l'espressione a (bc *) d richiederebbe un PDA in modo che l'espressione secondaria tra parentesi sia gestita correttamente.


1
Cosa intendi esattamente con "analisi"? Intendi verificare se l'ingresso è davvero un'espressione regolare o hai in mente qualcosa di più complicato, ad esempio una macchina che emette una descrizione dell'NFA corrispondente? (se non sei sicuro che l'input sia davvero un'espressione regolare e devi verificarlo, allora devi essere in grado di verificare che la parentesi sia corretta e che normalmente significhi usare uno stack.)
Kaveh

Per una risposta pratica, si poteva guardare il Plan 9 fonte Grep per grep.y .
Bruce Ediger,

Risposte:


8

Hai ragione. È facile dimostrare che la sintassi delle espressioni regolari non è regolare usando tecniche standard .

REG(p)p

Detto questo, probabilmente non vuoi codificare un PDA a mano. Prendi in considerazione l'utilizzo di un generatore di parser come ANTLR o byacc . Se, d'altra parte, vuoi studiare l'analisi delle lingue programmando tu stesso i parser, dovresti continuare con altri algoritmi di analisi di base come CYK , Earley , discesa ricorsiva e LR .


Grazie. la scrittura di codice per questi compiti crea una migliore comprensione e non è pensata per essere efficiente come utilità esistenti come lex, yacc, bison ecc.
Phil Wright,

@PhilWright: Capisco, bello! Ho modificato in ulteriori suggerimenti per questo caso.
Raffaello

Preferirei un parser di discesa ricorsivo codificato a mano per questo.
Dave Clarke,

Se si scrive a mano un parser per questo, una delle discese ricorsive (dopo il factoring e il massaggio) è un'opzione, il parser LCC per C < sites.google.com/site/lccretargetablecompiler > ha un'interpretazione interessante per la gestione di molti operatori. Ma forse il modo più semplice per costruire la mano è l'analisi della precedenza.
vonbrand,

3

Ti suggerisco di leggere la bella risposta di Jukka alla domanda " Abbinare espressioni regolari usando espressioni regolari " anche su cstheory. Un estratto:

Ad esempio, possiamo modificare la notazione standard come segue per ottenere espressioni regolari "compresse" :

  • Puoi rimuovere qualsiasi prefisso che consiste in una sequenza di ('s
  • Puoi rimuovere qualsiasi suffisso che consiste in una sequenza di)

Cioè, ((a|b)*c)de(f|g)può essere espresso nella notazione "compressa" usando, ad esempio, una delle seguenti forme: a|b)*c)de(f|go ((a|b)*c)de(f|goppure (a|b)*c)de(f|g).

[...]

La notazione "compressa" (di un'espressione regolare) è un linguaggio regolare.

Questo è solo un collegamento a una "diversa visione" interessante (secondo me) sul linguaggio delle espressioni regolari; come sottolineato nei commenti seguenti, non è utile per creare un albero di sintassi. Se vuoi scrivere a mano il tuo parser, ti suggerirò questo semplice articolo su codeproject " Writing-own-regular-expression-parser ".


Jukka rimuove essenzialmente il requisito di bilanciamento delle parentesi. Non conosco alcun caso in cui ciò sia effettivamente fatto, ma vale la pena notare che cambiando la semantica, è possibile "semplificare" la sintassi.
Raffaello

4
Tu (e Jukka) non state analizzando le regexps, ma solo riconoscendole. "Sì, è una regexp (compressa)."
Gilles 'SO- smetti di essere malvagio'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.