Скачиваний:
273
Добавлен:
15.06.2014
Размер:
3.05 Mб
Скачать

Конечные автоматы

Конечные автоматы. Детерминированные и недетерминированные КА. Диаграмма состояний КА. Связь КА и синтаксических диаграмм. Построение КА на основе леволинейной и праволинейной грамматик. Построение леволинейной и праволинейной грамматик на основе КА. Преобразование КА к детерминированному виду. Минимизация КА. Устранение недостижимых и эквивалентных состояний КА. Автоматизация построения лексических анализаторов. Программа LEX

Конечные автоматы.

Конечным автоматом называется пятерка следующего вида: M (Q, V, δ, q0, F), где Q – конечное множество состояний автомата, V – конечное множество допустимых входных символов (алфавит автомата), δ - функция переходов, отображающая декартово произведение множеств V×Q во множество подмножеств Q: δ(a,q)=R, a V, q Q, R Q; q0 – начальное состояние автомата, q0 Q; F – непустое множество конечных состояний автомата, F Q, F.

КА полностью определен, если в каждом его состоянии существует функция перехода для всех возможных входных симво-

лов: a V, q Q δ(a,q)=R, R Q.

В начале работы автомат всегда находится в состоянии q0. На каждом такте он под воздействием очередного символа входной цепочки либо переходит в новое состояние либо остается в текущем. Если функция перехода допускает несколько возможных состояний, то КА может перейти в любое из них. Работа КА продолжается до тех пор, пока на его вход поступают символы из входной цепочки.

КА M (Q, V, δ, q0, F) принимает цепочку символов ω V+, если получив на вход эту цепочку, он из начального состояния может перейти в одно из конечных состояний f F. Язык L(M), заданный КА – это множество всех цепочек символов, которые принимаются этим автоматом. Два КА эквивалентны, если они задают один и тот же язык. Все КА являются распознавателями для регулярных языков.

Граф переходов КА – это ориентированный граф, в котором состояния КА соответствуют вершинам, а переходам δ(p,a)=q, a V, p,q Q - дугам (p,q), помеченным символом а. Вершины, соответствующие начальному и конечным состояниям, выделяются, обычно двойной границей. На рисунке представлен КА: M({H,A,B,S},{a,b},δ,H,{S}). δ:

δ(H,b)=B, δ(B,a)=A, δ(A,b)={B,S}. Чтобы исключить ситуации, из которых нет переходов по входным символам, в КА добавляют еще одно состояние, на которое замыкают все неопределенные переходы, преобразуя автомат к полностью определенному виду. Это дополнительное состояние соответствует состоянию ошибки.

КА M (Q, V, δ, q0, F) называется детерминированным КА, если a V,q Q: δ(q,a)={r}, r Q либо δ(q,a)= , т.е. в каждом из его состояний для любого входного символа функция перехода содержит не более одного состояния. Иначе КА недетерминированный.

Связь КА и синтаксических диаграмм.

Построение КА по леволинейной грамматике. Имеется леволинейная грамматика G(T,N,P,S), задающая язык L(G). Необходимо построить эквивалентный ей КА M(Q,V,δ,q0,F), задающий тот же язык L(M)=L(G). Задача решается в 2 этапа. 1. Исходная леволинейная грамматика G приводится к автоматному виду G’. 2. Искомый автомат M(Q,V,δ,q0,F) строится на основе полученной автоматной грамматики G’(T’,N’,P’,S’). Алгоритм построения КА:

1)Q=N {H}. Множество состояний соответствует нетерминальным символам грамматики, к которым добавляется еще один символ H.

2)V=T. Входной алфавит соответствует множеству терминальных символов.

3)pi P: At, A N, t T δ(H,t)= δ(H,t) {A}. В функцию переходов для состояния H добавляется состояние А.

4)pi P: ABt, A,B N, t T δ(B,t)= δ(B,t) {A}. В функцию переходов для состояния B добавляется состояние А.

5)q0=H. Начальное состояние соответствует добавленному на первом шаге состоянию Н.

6)F={S}. Множество конечных состояний соответствует аксиоме S.

Пример.

G=({/,*,a,,}, {S,C,K,A,B,D,E}, P, S)

Р= { S A/ | B; C C/ | C* | Ca | D| E*; K K/ | K* | Ka | E/; A C*; B K; D C; E / }

1.Q={S,C,K,A,B,D,E,H}

2.V={/,*,a,,}

3.E / δ(H,/)= δ(H,/) {E}.

4.1.S A/ δ(A,/)= δ(A,/) {S}; S B← δ(B, )= δ(B, ) {S}

4.2.δ(C,/)= δ(C,/) {C}; δ(C,*)= δ(C,*) {C}; δ(C,a)= δ(C,a) {C}; δ(D, )= δ(D, ) {C}; δ(E,*)= δ(E*,) {C}

4.3.δ(K,/)= δ(K,/) {K}; δ(K,*)= δ(K,*) {K}; δ(K,a)= δ(K,a) {K}; δ(E,/)= δ(E,/) {K}

4.4. δ(C,*)= δ(C,*) {A}; δ(K,)= δ(K,) {B}; δ(C,)= δ(C,) {D}

5.q0=H

6.F={S}

δ

S C

K

A

B

D

E

H

/

C

K

S

 

 

K

E

*

C,A

K

 

 

 

C

 

a

C

K

 

 

 

 

 

D

B

 

 

 

 

 

 

 

 

S

C

 

 

Видно, что автомат недетерминированный, т.к. δ(С,*)={C,A}. Колонки, соответствующие конечному состоянию в общем случае могут и не быть пустыми. Автомат не полностью определен. Построим граф.

Построение КА по праволинейной грамматике. Имеется праволинейная грамматика G(T,N,P,S), задающая язык L(G). Необходимо построить эквивалентный ей КА M(Q,V,δ,q0,F), задающий тот же язык L(M)=L(G). Аналогично предыдущему случаю, исходная грамматика приводится к автоматному виду, после чего строится автомат. Алгоритм построения КА:

1)Q=N {H}. Множество состояний соответствует нетерминальным символам грамматики, к которым добавляется еще один символ H.

2)V=T. Входной алфавит соответствует множеству терминальных символов.

3)pi P: At, A N, t T δ(A,t)= δ(A,t) {H}. В функцию переходов для состояния A добавляется состояние H.

4)pi P: AtB, A,B N, t T δ(A,t)= δ(A,t) {B}. В функцию переходов для состояния A добавляется состояние B.

5)q0=S. Начальное состояние соответствует аксиоме S.

6)F={H}. Множество конечных состояний соответствует добавленному на первом шаге состоянию Н.

Построение леволинейной грамматики по КА. Имеется КА M(Q,V,δ,q0,F), определяющий язык L(M). Необходимо построить эквивалентную ему леволинейную грамматику G(T,N,P,S), задающую тот же язык L(G)=L(M). Алгоритм построения леволинейной грамматики:

1)T=V. Множество терминальных символов строится из входного алфавита автомата.

2)N=Q\{q0}. Множество нетерминалов грамматики соответствует множеству состояний автомата за исключением начального.

3)Ai = q0 | δ(Ai,t)={B1, B2,…, Bn}, n>0, Bk Q, k=1,2,..,n, t V P=P {Bkt}. Пополняется множество правил.

4)Ai q0 , Ai Q| δ(Ai,t)={B1, B2,…, Bn}, n>0, Bk Q, k=1,2,..,n, t V P=P {BkAit}. Пополняется множество правил.

5)Если F={F0} S={F0}. Если у автомата одно конечное состояние, оно становится аксиомой грамматики.

6)Если F={F1, F2,…, Fn}, n>1 N=N {S}, P=P {SF1 | F2 |…| Fn}. Если у автомата несколько конечных состояний, то добавляется новый нетерминал S, и пополняется множество правил.

Построение праволинейной грамматики по КА. Имеется КА M(Q,V,δ,q0,F), определяющий язык L(M). Необходимо по-

строить эквивалентную ему праволинейную грамматику G(T,N,P,S), задающую тот же язык L(G)=L(M). Алгоритм:

1)T=V. Множество терминальных символов строится из входного алфавита автомата.

2)N=Q. Множество нетерминалов грамматики соответствует множеству состояний автомата.

3)Ai Q: δ(Ai,t)={B1, B2,…, Bn}, n>0, Bk Q, Bk F, k=1,2,..,n, t V P=P {AitBk}. Пополняется множество правил.

4)Ai Q: δ(Ai,t)={B1, B2,…, Bn}, n>0, Bk Q, Bk F, k=1,2,..,n, t V P=P {Ait}. Пополняется множество правил.

5)Ai Q: δ(Ai,t)={B1, B2,…, Bn}, n>0, Bk Q, Bk F, k=1,2,..,n, t V, δ(Bk,t’)={C1, C2,…, Cm} Cj Q, q=1,2,..,m, t’ V P=P {AitBk}. Пополняется множество правил, если есть переходы из конечных состояний.

6)S={q0}

Пример.

M({S,C,K,A,B,D,E,H},{/,*,a,,},δ,H,{S})

δ

S C

K

A

B

D

E

H

/

C

K

S

 

 

K

E

*

C,A

K

 

 

 

C

 

a

C

K

 

 

 

 

 

D

B

 

 

 

 

 

 

 

 

S

C

 

 

1.T={/,*,a,,}

2.N={S,C,K,A,B,D,E,H}

3.1.δ(C,/)={C} P=P {C/C}; δ(C,*)={C,A} P=P {C*C | *A}; P=P {CaC}; P=P {C→↓D};

3.2.P=P {K/K | *K | aK | B};

3.3.P=P {D→←С};

3.4.P=P {E/K | *C};

3.5.P=P {H/E}

4.δ(A,/)={S} P=P {A/}; δ(B,)={S} P=P {B→←}.

5.Если бы из состояния S были переходы, то добавились бы A/S; B→←S.

6.S={H}

P: {A/; B→←; C/C | *C | *A | aC | D; K/K | *K | aK | B; D→←С; E/K | *C; H/E;}

Преобразование КА к детерминированному виду. Для любого КА можно построить эквивалентный ему ДКА. Алгоритм преобразования КА M(Q,V,δ,q0,F) в эквивалентный ему ДКА M’(Q’,V’,δ’,q0’,F’):

1)V’=V;

2)q0’= q0;

3)Q’={q0}; Начинаем с начального состояния

4)qi’ Q’ δ(qi’, vj’)= {δ(qk,vj)}=qij’, qk qi’, j=1,2,..,|V|; Q’=Q’ qij’; Итерационно формируем новые состояния и пере-

ходы;

5)qi’ Q’, qk F, qk qi’ F’=F’ {qi’}; Множество конечных состояний.

Пример. ИД см выше.

1.V’={/,*,a,,};

2.q0’={H};

3-4.

δ

H

E

K

C

B

C,A

D

S

C,S

/

E

K

K

C

 

C,S

 

 

C

*

 

C

K

C,A

 

C,A

 

 

C,A

a

 

 

K

C

 

C

 

 

C

 

 

B

D

 

D

 

 

D

 

 

 

 

S

 

C

 

 

5. F’={{S},{CS}};

δ

H

E

K

C

B

A

D

S

G

/

E

K

K

C

 

G

 

 

C

*

 

C

K

A

 

A

 

 

A

a

 

 

K

C

 

C

 

 

C

 

 

B

D

 

D

 

 

D

 

 

 

 

S

 

C

 

 

F’={S,G};

Минимизация КА. Минимизация заключается в построении эквивалентного КА с меньшим числом состояний. Рассмотрим два алгоритма: устранение недостижимых состояний и объединение эквивалентных состояний. Состояние q Q КА M(Q,V,δ,q0,F) недостижимое, если при ωV+ невозможен переход КА из начального состояния в состояние q. Алгоритм устранения недостижимых состояний:

1)Q’={q0};

2)qi Q’: δ(qi, vk)=qj, k=1,2,..,|V|; Q’=Q’ qj Т.е. итерационно включаются все состояния, в которые можно попасть из начального;

3)δ’=δδ(qi,vk), qi Q’; т.е. остаются только соответствующие им переходы;

4)F’=FQ’.

Состояния q, q’ Q называются n-эквивалентными, n0, если, находясь в одном из этих состояний и получив на вход произвольную цепочку ωV*, |ω|n, КА может перейти в одно и то же множество конечных состояний. 0-эквивалентными состояниями КА будут F и Q\F. Множества эквивалентных состояний называются классами эквивалентности, а их совокупность – множеством классов эквивалентности R(n), и R(0)={F, Q\F}. Алгоритм построения эквивалентных состояний:

1)n=0, Строится R(n)

2)n=n+1. Строится R(n): R(n)={ri(n): {qi Q: a V, δ(qi,a) rj(n-1)}}. Т.е. в новые классы входят те состояния,, которые для одних и тех же входных символов переходят в одно и то же n-1 эквивалентные состояния.

3)Если R(n)R(n-1), то повторить шаг 2.

Далее каждый класс эквивалентности становится состоянием минимизированного КА, функции переходов в котором строятся очевидным образом.

Пример. М({A,B,C,D,E,F,G}, {0,1}, δ, A ,{D, E})

δ

A

B

C

D

E

F

G

0

B

 

 

C

B

D

F

1

C

D

E

E

D

G

F

1. Q’={A};

2.1.Q’=Q’ {B,C}

2.2.Q’=Q’ {D,E}

2.3.Q’=Q’ {B,C,D,E}

4. F’={DE}{A,B,C,D,E}={D,E}

1.R(0)={{A,B,C},{D,E}}

2.R(1)={0:{A},{BC},{D,E}; 1:{A},{BC},{D,E}};

3.R(2)={0:{A},{BC},{D,E}; 1:{A},{BC},{D,E}}.

Лексический анализ используется не только при построении компиляторов, но и в различных других областях, связанных с обработкой текста. Например, подсветка синтаксиса ЯП в текстовом редакторе, командные процессоры. Поскольку задачи лексического анализа четко формализуются, имеется возможность автоматизировать процесс разработки ЛА. Самой известной программой подобного рода является LEX. Входной язык содержит описания лексем в терминах регулярных выражений. Результатом является программа на каком-либо ЯП, которая позволяет читать входной файл (или стандартный поток ввода) и выделять из него лексемы, соответствующие заданным регулярным выражениям. Полученный код сканера можно дополнять необходимыми функциями по усмотрению разработчика.