...

Cosa è un linguaggio?

by user

on
Category: Documents
22

views

Report

Comments

Transcript

Cosa è un linguaggio?
Teoria dei linguaggi
Cosa è un linguaggio?
„ Alfabeto = insieme di simboli (caratteri ascii)
„ Stringa
„ insieme finito di simboli di un alfabeto
„ ε e la stringa vuota (talvolta denotata da λ)
„ |s| rappresenta la lunghezza di una stringa.
„ Linguaggio un insieme di stringhe
„ ∅, l’insieme vuoto è un linguaggio
„ {ε} è il linguaggio contenente la sola stringa vuota
„ L’insieme di tutti I possibile ptogrammi C è un
linguaggio
„ L’insieme di tutti I possibili identificatori in un linguaggio
è un linguaggio
1
Terminologia
„ Dato un alfabeto
T = {a, b}
su di esso si possono definire infiniti linguaggi
L1 = {a, aa, ab, aab}
L2 = {a,b}
L3 = linguaggio contenente lo stesso numero
di a e di b
Definizioni
„ Cardinalità di un linguaggio = numero di
stringhe appartenenti al linguaggio
„ Frase = stringa appartenente al linguaggio
„ Linguaggio infinito = linguaggio con
cardinalità infinita
„ Linguaggio finito = linguaggio con
cardinalità finita
„ Linguaggio vuoto Φ = linguaggio con
cardinalità 0
„ stringa vuota = ε oppure λ
2
Operazioni su stringhe
„ Concatenamento
x=a
y = bc
x ·y = abc
sε =s
εs=s
„ Sottostringhe
x = bc
„ Riflessione
x = ab
y = ba
„ Potenza m-esima
sn = s s s .. s ( n times)
s0 = ε
x=a
x4 = aaaa
y = ab
y3 = ababab
Operazioni su i linguaggi
„ Concatenamento
L1 = {a, b}
L2 = {c, d}
L = L1 ·L2 =
= {xy | x ∈ L1, y ∈ L2} =
= {ac, ad, bc, bd}
„ Unione
L1 = {a, b}
L2 = {c, d}
L = L1 ∪ L2=
= {x ∈ L1 ∪ L2} =
= {a, b, c, d}
„ Potenza m-esima
Lm = Lm-1 ·L
L0 = Φ
Esempio
L = {a, b}
L3 = L2 ·L
= {aa, ab, ba, bb} ·{a, b} =
= {aaa, aba, baa, bba, aab,
abb,
bab, bbb}
3
Linguaggio universale
„ Definiamo linguaggio universale (monoide libero)
su un alfabeto T l’insieme di tutte le stringhe di tale
alfabeto
„ Il linguaggio universale si può definire come limite
dell’elevamento a potenza
L* = stella di Kleene =
∪n=0Ln = L0 ∪ L1 ∪ L2 ∪….
∝
„ Positive Closure
L+ = ∪n=1Ln = L1 ∪ L2 ∪….
Esempi di Linguaggi
„ L1 = {a,b,c,d}
L2 = {1,2}
„ L1L2 = {a1,a2,b1,b2,c1,c2,d1,d2}
„ L1 ∪ L2 = {a,b,c,d,1,2}
„ L13 = tutte le stringhe di lunghezza 3 (con a,b,c,d}
„ L1* = tutte le stringhe con a,b,c,d e la stringa vuota
„ L1+ = non include la stringa vuota
4
Grammatiche
„ Per descrivere un linguaggio sia esso un linguaggio
naturale o un linguaggio di programmazione è
necessario definire un insieme di regole a cui deve
sottostare ogni frase del linguaggio per essere corretta.
„ Tali regole devono specificare tutte o solo le stringhe
appartenenti al linguaggio
„ Per fare ciò è necessario quindi introdurre:
„
una grammatica: cioè una specifica formale di tutte le
strutture di frase (o frasi) consentite
„ un algoritmo di riconoscimento: cioè un metodo per
analizzare le frasi e determinare la loro struttura
Grammatiche generative
„ Una Grammatica generativa può essere
pensata come un insieme di regole che
generano tutte e sole le frasi del linguaggio
„ Noam Chomsky ha definito quattro classi di
“complessità” per le grammatiche generative
Chomsky Hierarchy.
5
The Chomsky Hierarchy
Tipo 0 - Grammatiche generali - Macchina di Turing
Tipo1 - Grammatiche Dipendenti dal Contesto
Tipo 2 - Grammatiche non contestuali - Automi a Pila
Tipo 3 - Grammatiche regolari - Automi a stati finiti
Tipo 0
Tipo 1
Tipo 2
Tipo 3
Grammatiche generative
„ Una grammatica generativa G è espressa come una quadrupla
G=(V, Σ, P, S),
„ dove:
V è l’insieme dei non terminali o variabile (nel seguito
utilizzeremo le lettere maiscule)
„ Σ è l’insieme finito di terminali (utilizzaremo le lettere minuscole)
„ P è l’insieme finito delle produzioni o regole nella forma
α→β
„ S è un simbolo speciale appartenente all’insieme dei non
terminali V chiamato assioma
„ Normalmente V ∩ Σ = ∅.
„ Ogni simbolo della grammatica è un elemento di V ∪ Σ.
„
6
Grammatiche regolare (tipo 3)
„ Una grammatica regolare (RG) è denotata da G = (V, Σ,
P,S), dove V è l’ insieme dei non terminali, Σ è l’insieme
dei terminali, S è un non-terminale chiamato assioma, P
è un insieme finito di produzioni, con ogni produzione
nella forma
A →β,
con: A ∈ V e β ∈ (V ∪ Σ)*.
∀ produzione in una grammatica regolare regolare le produzioni
possono consistere in produzioni come le seguenti
A → aB, B → b (grammatiche lineari destre)
oppure
B → Ab, A → a (grammatiche lineari sinistre)
„ Generalmenre, le lettere greche minuscole denotano
stringhe in (V ∪ Σ)*.
„ Esempio di grammatica
V = {S}
Σ = {a, b}
P = {S → ε (stringa vuota)
S → abS
S = {S}
Stringhe appartenenti al linguaggio:
S → abS → ab
S → abS → ababS → abab
7
„ Nelle grammatiche di tipo 3, il solo non
terminale nella parte destra (RHS) della
produzione sempre si trova alla fine della
regola (o alternativamente all’inizio)
„ Le grammatiche di tipo 3 sono molto
restrittive (non si possono utilizzare per la
sintassi dei linguaggi di programmazione) ma
i loro riconoscitori sono molto efficenti.
Cosa è un linguaggio regolare?
„ Sono tutti e soli i linguaggi che si possono
generare con grammatiche generative di tipo
3
„ Un linguaggio che può essere espresso
mediante le operazioni di concatenamento,
unione e stella di Kleene applicate un numero
finito di volte a linguaggi unitari e al
linguaggio vuoto
„ Ogni linguaggio finito è regolare
8
Automi a stati finiti
„ Un riconoscitore per un linguaggio è un programma
che prende iuna stringa x e risponde “si” se x è una
frase del linguaggio, “no” altrimenti.
„ Chiameremo Automa a stati finiti il riconoscitore per il
linguaggi regolari
„ Un automa a stati finiti può essere deterministico
(DFA o DFSA) o non deterministico (NFA o NFSA)
„ Sia DFA che NFA riconoscono I linguaggi regolari
„
„
deterministico – piu’ veloce, ma talvonta poco
compatto
non-deterministico – piu’ lento, ma piu compatto
„ Per la costruzione degli analizzatori lessicali si
utilizzano automi deterministici.
Finite state automata (FSA)
„ Un FSA ha:
un insieme finito di stati
„ un insieme di transizioni (o mosse) da uno
stato ad un altro stato etichettato da caratteri
di Σ
„ uno stato speciale chiamato stato iniziale S0
„ un insieme di stati finali o di accettazione
(stringa valida)
„
9
„ Gli automi a stati finiti sono rappresentati
graficamente da un digramma di transizioni.
„ Iniziamo dallo stato iniziale
„ Il carattere di input a genera una transizione dallo
stato corrente ad uno altro stato se esiste una
mossa dallo stato corrente etichettata con il
carattere di input
„ Se non esiste una mossa etichetata con il
carattere di unput la stringa è valida se lo stato è
di accettazione (stato finale)
„ Esempio
(a b (c)+ )+.
Non-Deterministic Finite
Automaton (NFA)
„ Un automa a stati finiti non-deterministico (NFA) è un modelllo
matematico che consiste di:
„
„
„
S – un insieme di stati
Σ - un insieme di simboli di input (alfabeto)
mosse – una funzione che data una coppia stato-simbolo
restituisce uno stato, cioè
Mossa : S x Σ → S
„
„
s0 - uno stato iniziale, s0 ∈ S
F – un insieme di stati finali F ⊆ S
„ In un NFA sono consentite
„
„
ε-mosse. In altre parole, esistono transizioni che non consumano
simboli
due mosse che da uno stato per effetto dello stesso simbolo
portano a due stati diversi
„ Un NFA accetta una stringa x, se e solo se esiste un cammino
dallo stato iniziale ad uno stato finale tale ogni arco sia etichettato
coni simboli in x
10
Costruzione del riconoscitore di
un FSA
„ lettera = a .. z, A..Z
„ cifra = 0..9
„ Del è un qualsiasi carattere diverso da a..z e
0..9
lettera | cifra
0
lettera | _ 1
2
Del
a..z
0..9
-
del
FINALI
0
1
Error
1
Error
NO
1
1
1
Error
2
NO
2
Error Error Error Error
SI
11
NFA (Esempio)
0 rappresenta lo stato iniziale s0
{2} è l’insieme degli stati finali F
Σ = {a,b}
S = {0,1,2}
a
La funzione di transizione e descritta
a
b
dalla tabella
0
1
2
start
a
b
b
0 {0,1} {0}
Grafo di transizione di un NFA
1
_
{2}
2
_
_
Il linguaggio riconosciuto da questo NFA è
(a | b) * a b
Esempio: commenti C++
12
Espressioni regolari
„ Una espressione regolare puo essere:
„
„
„
„
„
„
„
ε (la stringa vuota) e denota il linguaggio {ε}
∀ simbolo terminale a, a è una espressione regolare
se R è una espressione regolare R* è una espressione regolare (R*
è chiamate stella di kleene o chiusura di R). Per esempio: (ab)*
genera: ε, ab, abab, etc.
se R è una espressione regolare R+ è una espressione regolare. Per
esempio: (ab)+ genera: ab, abab, etc.
se R e S sono espressioni regolari, R ∪ S (oppure R|S) è una
espressione regolare che si comporta come R o S
se R e S sono espressioni regolari, R · S (oppure RS) è una
espressione regolare che descrive la concatenazione di R seguito
da S
[a-z] è una abbreviazione per denotes a|b|c|..|z
Espressioni regolare
Espressioni regolai sopra un alfabeto Σ
Espressione reg.
Linguaggio
ε
{ε}
a∈ Σ
{a}
L(r1) ∪ L(r2)
(r1) | (r2)
(r1) (r2)
L(r1) L(r2)
(L(r))*
(r)*
(r)
L(r)
„ (r)+ = (r)(r)*
„ (r)? = (r) | ε
13
Esempi
„ (c|d|e)(a|b)
„
rappresenta il linguaggio
„
L = {ca, cb, da, db, ea, eb}
„ (a|b)*c(a|b)*
„
rappresenta l’insieme di stringhe con zero o
piu “a” seguite da “c”, seguite da zero o piu “b”
„ (a b (c)+
)+
14
Espressioni regolari
„ Le parentesi possono essere omesse nelle
espressioni regolare utilizzando le regole di
precedenza
*
concatenation
|
„ ab*|c
means
highest
next
lowest
(a(b)*)|(c)
„ Esempi
Σ = {0,1}
0|1 => {0,1}
(0|1)(0|1) => {00,01,10,11}
0* => {ε ,0,00,000,0000,....}
(0|1)* => tutte le stringhe con 0 e 1, compresa la stringa
vuota
Definizioni Regolari
„ LA scrittura di espressioni regolari per alcuni linguaggi può
essere complessa perche le espressioni regolari che lo
descrivono possono essere complesse, In questo caso si usano
le definizioni regolari”.
„ Noi possiamo attribuire dei nomi come simboli per la definizione
di altre espressioni regolari.
„ Una definizione regolare è una sequenza di definizioni nella
forma:
d1 → r 1
d2 → r 2
.
dn → r n
dove di è un nome
e
ri è una espressione regolare sui simboli
Σ∪{d1,d2,...,di-1}
15
Definizioni regolari
„ Esempio: Identificatori in C
lettera → A | B | ... | Z | a | b | ... | z
cifra → 0 | 1 | ... | 9
identificatore → lettera (lettera | cifra ) *
„ SE noi scriviamo direttamente l’espressione regolare
avremo
(A|...|Z|a|...|z) ( (A|...|Z|a|...|z) | (0|...|9) ) *
„ Esempio: Numeri interi senza segno
cifra → 0 | 1 | ... | 9
cifra → cifra +
opt-fraction → ( . cifra ) ?
opt-exponent → ( E (+|-)? cifra ) ?
unsigned-num → cifra opt-fraction opt-exponent
Proprieta’ algebriche
Assioma
Descrizione
r |s = s|r
| e’ commutativo
r |(s|t) = r |(s|t)
| è associativo
(rs)t = r (st)
La concatenazione è
associativa
La concatenazione gode della
prorprietà distributiva su |
ε è l’elemento neutro per la
concatenazione
r (s|t) = rs|rt
(s|t)r = sr |tr
εr = r
rε = r
r* = ( r |ε)*
r** = r*
* è idenpotente
16
Grammatiche regolari - Automi a
stati finiti (FSA)
„ Esiste una corrispondenza biunivoca tra
grammatiche regolari ed FSA
„ Esempio
Espressione regolare : a*·b·c*
„ Grammatica regolare:
„
V = {S, A, C}
T = {a, b, c}
P={
S→A
A → aA
A → bC
C → cC
C → ε}
S = {S}
a
c
P0
b
P1
17
Esempio
V = {S}
T = {a, b}
P = {S → ε
S → abS
S = {S}
a
P0
P1
b
Esempio
„ Grammatica per il linguaggio dei numeri interi
V = {S,D}
0,1,2,3,…9
T = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
P = {S → D
P0
P1
0,1,2,3…9
S →DS
D →0|1|2|3|4|5|6|7|8|9}
S = {S}
„ Grammatica per il linguaggio dei numeri interi (non sono accettati numeri
come 04)
V = {S,D}
1,2,3,…9
T = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
P = {S → D
P0
P1
S →0
0,1,2,3…9
S →DS
D →1|2|3|4|5|6|7|8|9}
P2
0
S = {S}
18
Esempio
„ Esempio
V = {S}
T = {a, b}
P = {S → ε
S → abS
S = {S}
Il seguente FSA riconosce a*b*
a
non anbn
b
P0
b
P1
La ricorsione è necessaria per modellare anbn (Cioè non
è un FSA
„ Le grammatiche regolari sono troppo
restrittive per i linguaggi di programmazione e
pertanto non sono sufficienti per la
costruzione dei compilatori
„ Per esempio, le grammatiche regolari non
possono generare il linguaggio anbn con n ≥
1 (Nota che tale linguaggio corrisponde al
Begin e End dei linguaggi di a
programmazione)
„ Esistono altri tipi di grammatiche generative
che possono generare tale linguaggio.
„
19
Espressioni regolari - Grammatica
regolare
„ Esiste una corrispondenza biunivoca tra
linguaggio regolare ed espressione regolare
„ Esempio
Espressione regolare : a*·b·c*
„ Regular Grammar:
„
V = {S, A, C}
T = {a, b, c}
P={
S→A
A → aA
A → bC
C → cC
C → ε}
S = {S}
Grammatiche regolari - Automi a
stati finiti (FSA)
„ FSA(Q, T, δ, q0, F)
Dove Q = insieme degli stati
T insieme di simboli terminali
δ insieme delle transizioni,
q0 = stato iniziali,
F = insieme stati finali
„ G(V, T, P, S)
„ Algoritmo di costruzione
V=Q
S = q0
∀ q ∈ Q, ∀ a ∈ T se ∃ una transizione etichettata con a da q a r ∈ Q
allora esiste in P la produzione q → a r
∀ q ∈ F, ∃ una produzione q → ε
20
Esempio
Q = {A, B, C}
a
T = {a, b, c, d}
F = {B, C}
A
q0 = A
A = δ(A,a), B = δ(A,b), C = δ(B,c),
C = δ(C,d), A = δ(C,b)
d
c
b
B
C
b
V = {A, B, C}
T = {a, b, c, d}
B → ε, C → ε
A → a A, A → a B, B → c C, C → d C, C → b A
S=A
Esempio
„ Linea di commento che inizia
con “//” a termina con “eol”
V = {S, A, C}
T = {/, c, e}
P={
S → // A
A→ cA
A → e}
E = // c* e
P2
P1
c
e
e = eol
c = qualsiasi carattere
P0
P1
21
Conversione di una espressione
regolare in un Automa a stati finiti
„ La conversione di una espressione regolare
in un NFA produce un NFA tale che ogni
stato ho solo uno o due successori ed ha un
unico stato finale
„ Un espressione regolare può essere
convertito in un NFA automaticamente
utilizzando le regole di Thomson’s.
Queste regole sono semplici e sistematiche
„ Non è detto che sia uil metodo più efficente per
effettuare la conversione
„ Garantisceh che il risultante NFA abbia uno stato
iniziale e uno stato finale.
„
Forme base
„ Per ε, si costruisce il seguente NFA
start
ε
i
f
„ Per a in T, si costruisce il seguente NFA
start
i
a
f
22
Recursive Rules
„ Detti N(s) e N(t) gli NFA for s and t.
NFA N(s|t):
N(s)
ε
ε
start
i
f
ε
ε
N(t)
Recursive Rules
„
NFA N(st):
start
i
N(s)
N(t)
f
23
Recursive Rules
„
NFA N(s*)
ε
start
„
ε
i
ε
N(s)
f
ε
NFA N((s)) = N(s)
Thomson’s Construction (Example
- (a|b) * a )
a:
b:
a
a
ε
(a | b)
b
ε
ε
ε
b
ε
(a|b)
*
ε
ε
a
ε
ε
ε
b
ε
ε
(a|b)
*a
ε
ε
ε
a
ε
ε
ε
b
a
ε
ε
24
Chiusura
„ La ε chiusura di uno stato è l’insieme degli stati che
include:
Lo stato stesso,
„ Gli stati che possono essere raggiunti dallo stato
attraverso una serie di ε mosse
„
„ Per calcolare la ε -chiusura di un insieme s:
Aggiungere s alla ε -chiusura
„ Se t appartiene alla ε-chiusura(s) e esiste una ε
mossa da t a u, aggiungere u alla chiusura e
continuare fino a quando possibile
„
Funzione chiusura
void close(NFASet S) {
while (x in S and x →λy and y notin S) {
S = S U {y}
}
}
25
Costruzione di un DSA da un NFA
Eliminazione delle epsilon mosse
N (Q, T, δ, q0, F)
automa con epsilon mosse
N’ (Q, T, δ’, q0, F’) automa senza epsilon mosse
con F’ = F ∪ q0 se ε-chiusura(q0) contiene uno stato di F
F’ = F altrimenti
per ogni a in T esiste δ’(q,a) se esiste δ(q,a) oppure esiste
uno stato p tale che
δ(p,a), p= δ(q, ε)
Costruzione di un DSA da un NFA
„ Eliminazione delle transizioni non deterministiche
N (Q, T, δ, q0, F)
automa non deterministico
senza epsilon mosse
M (Q’, T, δ’, q’0, F’) automa deterministico
dove
Q’ = 2Q
F’ = {p ∈ Q’ | p contiene uno stato appartenente a F}
q’0 = [q0 ]
∀ p ∈ Q’ e ∀ a ∈ T
δ’(p,a) = {s | s ∈ δ(q,a) ∩ F ≠ ∅}
26
Esempio
a
ε
a
2
1
5
a
a
b
3
4
b
Esempio
a
a
a
2
1
a
5
a
a
b
3
b
4
27
Esempio
a
a
a
2
1
a
5
a
a
b
3
4
b
Esempio
[2,3,4]
a
a
[2]
[1]
[5]
a
b
a
[4,5]
b
[2,4]
a
b
28
Uno stato S è finale (o accettante) nel DS se contiene uno stato
finale in NFA
Lo stato iniziale e ε-closure({s0}
Conversione di un NFA in un DFA
Inserire ε-closure({s0}) come stato non marcato in DS
while (c’è uno stato non marcato S1 in DS) do {
marcare S1
per ogni simbolo di ingresso a do {
S2 Í ε-closure(move(S1,a))
if (S2 ∉ DS)
aggiungere S2 in DS come stato non marcato
transfunc[S1,a] Í S2
}
}
DFA MakeDeterministic(NFA N) {
DFA D; NFASet T
D.StartState = { N.StartState }
close(D.StartState)
D.States = { D.StartState }
while (è possibile aggiungere stati/transizioni){
∀ S in D.States and c in Σ
T = {y in N.States : x→c y per qualche x in S}
close(T);
if (T notin D.States) {
D.States = D.States U {T}
D.Trans = D.Trans U {S →c T}
}}
D.AcceptingStates = { S in D.States : uno stato di
accettazione di N in S}
}
29
Esempio di conversione di un NFA
in un DFA
2
ε
0
ε
a
3
ε
1
6
ε
ε
7
a
8
ε
4
b
5
ε
Esempio di conversione di un NFA
in un DFA
S0 = ε-closure({0}) = {0,1,2,4,7} S0 in DS come stato non marcato
⇓ marcare S0
ε-closure(move(S0,a)) = ε-closure({3,8}) = {1,2,3,4,6,7,8} = S1
ε-closure(move(S0,b)) = ε-closure({5}) = {1,2,4,5,6,7} = S2
transfunc[S0,b] Í S2
transfunc[S0,a] Í S1
⇓ marcare S1
ε-closure(move(S1,a)) = ε-closure({3,8}) = {1,2,3,4,6,7,8} = S1
ε-closure(move(S1,b)) = ε-closure({5}) = {1,2,4,5,6,7} = S2
transfunc[S1,a] Í S1
transfunc[S1,b] Í S2
⇓ marcare S2
ε-closure(move(S2,a)) = ε-closure({3,8}) = {1,2,3,4,6,7,8} = S1
ε-closure(move(S2,b)) = ε-closure({5}) = {1,2,4,5,6,7} = S2
transfunc[S2,a] Í S1
transfunc[S2,b] Í S2
S1 in DS
S2 in DS
30
Esempio di conversione di un NFA
in un DFA
S0 è lo stato iniziale dato che 0 membro di S0={0,1,2,4,7}
S1 è lo stato di accettazione (stato finale) del DFA dato che 8 appartiene a S1 = {1,2,3,4,6,7,8}
a
S1
a
S0
a
b
b
S2
b
Esempio
31
Conversione di una Espressione
Regolare direttamente in un DFAs
„ E’ possibile convertire direttamente una espressione
1.
2.
3.
4.
regolare in un DFA (senza creare prima un NFA).
Concatenare l’espressione con un simbolo speciale #.
r Î (r)#
“espressione regolare aumentata”
Creare un albero sintattico della “espressione regolare
aumentata”
In tale albero sintattico tutti gli elementi del vocabolario
(più # e ε) sono delle foglie dell’albero
Numerare con “position number” tutti gli elementi del
vocabolario (più # e ε)
Regular Expression Î DFA
(cont.)
(a|b) * a Î (a|b) * a #
•
•
|
a
1
b
2
Albero sintattico di (a|b) * a #
#
4
a
3
*
“espressione regolare aumentata”
• Ogni simbolo e numerato (positions)
• Ogni simbolo è una foglia
• inner nodes sono operatori
32
followpos
Definiamo la funzione followpos
followpos(i) -- è l’insime di posizioni che seguono una
posizione I nella stringa generata dall’espressione regolare
aumentata
Esempio,
( a | b) * a #
1 2
3 4
followpos(1) = {1,2,3}
followpos(2) = {1,2,3}
followpos(3) = {4}
followpos(4) = {}
firstpos, lastpos, nullable
„ Per valutare followpos, noi abbiamo bisogno
di tre funzioni che sono definite per I nodi
dell’albero
„ firstpos(n) -- l’insieme di posizioni del first
simbolo della stringa generata dalla subexpression di radice n.
„ lastpos(n) -- l’insieme di posizioni del last
simbolo della stringa generata dalla subexpression di radice n. nullable(n) -- true
se la stringa vuota appartine alla subexpression di radice n, false altrimenti
33
Come valutare firstpos, lastpos,
nullable
n
nullable(
n)
firstpos(n)
lastpos(n)
foglia ε
true
Φ
Φ
Foglia i
false
{i}
{i}
c2
nullable(c1)
or
nullable(c2)
firstpos(c1) ∪
firstpos(c2)
lastpos(c1) ∪
lastpos(c2)
c2
nullable(c1)
and
nullable(c2)
if (nullable(c1))
firstpos(c1)∪firstpos(c
2)
else firstpos(c1)
if (nullable(c2))
lastpos(c1) ∪
lastpos(c2)
else lastpos(c2)
firstpos(c1)
lastpos(c1)
|
c1
•
c1
*
c
true
Come valutare followpos
„ Due regole per calcolare la funzione followpos:
1. Se n un concatenation-node (•)con figlio sinistro c1 e
figlio destro c2, e i ∈ lastpos(c1), allora firstpos(c2)
⊆ followpos(i).
2. Se n è un star-node (*), e i ∈ lastpos(n), allora
firstpos(n) ⊆ followpos(i).
„ Se firstpos e lastpos sono stati calcolati per ogni
nodo, followpos può essere calcolato con una visita
depth-first dell’albero sintattico.
34
Example -- ( a | b) * a #
green – firstpos
blue – lastpos
{1,2,3} • {4}
{1,2,3}• {3} {4}# {4}
4
{1,2}*{1,2}{3}a{3}
3
{1,2} {1,2}
|
{1} a {1} {2}b {2}
2
1
followpos(1) = {1,2,3}
followpos(2) = {1,2,3}
followpos(3) = {4}
followpos(4) = {}
• Dopo aver calcolato followpos possiamo creare il DFA
per l’espressione regolare.
Algoritmo (RE Î DFA)
Creare l’albero sintattico di (r) #
Calcolare le funzioni followpos, firstpos, lastpos, nullable
Porre firstpos(root) in S (S è l’insieme degli stati del DFA) come stato non
marcato.
while (∃ s ∈ S non marcato) {
s
for each simbolo a {
s’ Í followpos(s1) ∪ ... ∪ followpos(sn)
let s1,...,sn posizioni in s e simboli per quelle posizioni sono a
move(s,a) Í s’
if (s’ non e vuoto e non in S
put s’ into S come stato non marcato.
„ the start state of DFA is firstpos(root)
„ the accepting states of DFA are all states containing the position of #
35
Esempio -- ( a | b) * a #
followpos(1)={1,2,3}
followpos(3)={4}
followpos(2)={1,2,3}
followpos(4)={}
S1=firstpos(root)={1,2,3}
⇓ marcare S1
a: followpos(1) ∪ followpos(3)={1,2,3,4}=S2
b: followpos(2)={1,2,3}=S1
⇓ marcare S2
a: followpos(1) ∪ followpos(3)={1,2,3,4}=S2
b: followpos(2)={1,2,3}=S1
move(S1,a)=S2
move(S1,b)=S1
move(S2,a)=S2
move(S2,b)=S1
b
S1
start state: S1
accepting states: {S2}
a
a
S2
b
Example -- ( a | ε) b c* #
followpos(1)={2}
followpos(2)={3,4}
followpos(3)={3,4}
followpos(4)={}
S1=firstpos(root)={1,2}
⇓ marcare S1
a: followpos(1)={2}=S2
move(S1,a)=S2
b: followpos(2)={3,4}=S3
move(S1,b)=S3
⇓ marcare S2
b: followpos(2)={3,4}=S3
⇓ marcare S3
c: followpos(3)={3,4}=S3
S2
move(S2,b)=S3
a
b
S1
move(S3,c)=S3
b
S3
c
start state: S1
accepting states: {S3}
36
Minimizzare il numero di stati per
un DFA
„ Dividere gli stati in due insiemi:
„ G1 : insiemi di stati finali
„ G2 : insieme di stati non finali states
„ Per ogni nuovo gruppo G
„ Partizionare G in sottogruppo take che gli stati s1 e s2 sono
nello stesso gruppo iff
per tutti I simboli di input a, gli stati s1 e s2 hanno transizioni a
stati nello stesso gruppo.
„ Lo stato iniziale del DFA minimizzato è il gruppo
contenente lo stato inziale del DFA originale.
„ GLi stati finiale del DFA minimizzato sono I gruppi
contenente gli stati finiali del DFA originale.
Esempio si minimizzazione
a
1
G1 = {2}
G2 = {1,3}
2
a
b
b
a
G2 cannot be partitioned because
3
move(1,a)=2
move(3,a)=2
b
move(1,b)=3
move(2,b)=3
So, the minimized DFA (with minimum states)
b
{1,3}
a
a
{2}
b
37
Minimizing DFA – Esempio
a
a
1
2
a
Groups:
4
b
a
b
3
{1,2,3}
{1,2}
b
{4}
{3}
no more partitioning
b
So, the minimized DFA
a
b
1->2
2->2
3->4
1->3
2->3
3->3
b
a
{3}
b
a
{1,2}
a
b
{4}
Esempi di espressioni regolari
1. letter(letter|digit)*
2. digits = digit digit*
opt_frac = . digits | ε
opt_exp = (E(+|-| ε) digits | ε
num = digits opt_frac opt_exp
38
Fly UP