L'algoritmo Maximal Munch è implementata aggiungendo una piccola quantità di stato mutabile all'esecutore DFA, e aggiungendo la capacità dell'esecutore DFA per "riavvolgere" l'ingresso: in effetti, dotandolo di funzioni come tell()
e seek()
.
Vale anche la pena notare che il DFA non è completo, nel senso che la funzione di transizione non è completa. Alcune coppie {state, input}
non hanno un risultato definito. [Nota 2]
Con questo in mente, l'algoritmo è il seguente:
Set Accepted NFA State to ⊥
Set Accepted Position to Tell(Input Stream)
Set State to Starting State
Repeat:
If State ∈ Accepting:
Set Accepted NFA State to Accepting NFA State for State [Note 1]
Set Accepted Position to Tell(Input Stream)
Read one symbol from Input Stream into Next Symbol
If there is a transition from {State, Next Symbol} to New State:
Set State to New State
Continue the loop
Otherwise:
Rewind Input Stream to Accepted Position
Return Accepted NFA State
Se l'algoritmo ritorna e inferiore ;, quindi senza gettone è stato riconosciuto e il flusso di input saranno stati riavvolto nella posizione iniziale .
Note:
La NFA ha in genere un omomorfismo univoca tra gli stati e le azioni di accettare, ma l'algoritmo di costruzione DFA può combinare due accettare stati NFA con diverse azioni. In questo caso, l'algoritmo flex deve dare priorità alla prima azione nel file di input. Nell'algoritmo sopra riportato, rappresentiamo questo mappando ogni stato DFA accettante al componente che accetta lo stato NFA che ha la priorità.
È facile completare il DFA aggiungendo uno stato aggiuntivo (e unico) sink
che non accetta e che ha solo transizioni su se stesso. Quindi possiamo aggiungere lo stato sink
come transizione per qualsiasi transizione altrimenti non specificata. Se chiamiamo lo stato sink
e il fondo; allora sarà chiaro come modificare l'algoritmo fornito; in pratica, questo non è affatto necessario perché nella pratica non ci interessa che il DFA sia incompleto. Tuttavia, ha un qualche impatto sugli algoritmi di minimizzazione dello stato.
Penso che si intendesse taggare questo con flex-lexer che viene utilizzato per l'analizzatore lessicale; non Flex che viene utilizzato per Adobe/Apache UI Framework. Ho cambiato il tagging. – JeffryHouser
Immagino che in un DFA sia semplice quanto prendere tanti caratteri quante sono le transizioni ricordando l'ultimo stato accettabile. –
@JoSo: buona risposta di base. È un po 'più facile pensare che il DFA abbia stati in cui transita mentre corre. Ogni stato è contrassegnato come "accetta" o "non accettato" (ad es. Stati verdi e rossi); può attraversare più stati verdi e rossi durante l'esecuzione. Alla fine arriva ad uno stato che non ha uscite valide per il prossimo carattere di input; se quello stato è verde, accetta, altrimenti si lamenta. Quindi non deve davvero ricordare l'ultimo stato accettato; è o in uno, o no, quando termina. –