Baixe Compiladores - Apostilas - Informática Part3 e outras Notas de estudo em PDF para Informática, somente na Docsity!
S ::= ASB | BSA | SS | aS | ε
A ::= ABS | B
B ::= BSSA | A
Neste momento SP = {a, S}. Agora Q := ∅, e assim a repetição do algoritmo termina com SP = {a,
S}, os únicos símbolos produtivos.
Para simplificar a gramática, os símbolos improdutivos podem ser removidos, bem como todas as
produções de P que contenham estes símbolos. Assim, a gramática simplificada para o exemplo
seria:
S ::= SS | aS | ε
Dicas para a eliminação de símbolos inúteis :
1º Todo T (terminal) é produtivo;
2º Marcar todos os T (terminais);
3º Marcar todos os NT (não-terminais) que possuem produções totalmente marcadas;
4º Marcar nas outras produções os NT que já foram marcados;
5º Eliminar os estados e as produções não marcadas.
Obs : Se o inicial for inútil, a linguagem (L) é vazia.
Obs II : Quando inútil, o símbolo não encaminha a finalização de uma sentença.
O segundo tipo de símbolos inúteis são aqueles que jamais são gerados a partir de S. Estes
símbolos, chamados de inalcançáveis, são eliminados pelo seguinte algoritmo:
Algoritmo: Eliminação de Símbolos Inalcançáveis
Entrada : Uma GLC G=(N,T,P,S)
Saída : Uma GLC G’=(N’,T,P’,S), sem símbolos inalcançáveis.
SA := {S}
M := {S} “o conjunto de símbolos marcados”.
Repita
M := {X | X ∈ N∪T e X ∉ SA e existe uma produção Y ::= αXβ e Y ∈ SA};
SA := SA ∪ M;
Até M = ∅;
N’= SA ∩ N;
T’= SA ∩ T;
P’:= {p | p∈P e todos os símbolos de p pertencem a SA};
Para exemplificar, seja G :
S ::= aS | SB | SS | ε
A ::= ASB | c
B ::= b
Inicialmente, SA = {S} e M = {S}. Assim, se obtém :
S ::= aS | SB | SS | ε
e a e B são os únicos símbolos recém marcados que não estão em SA. Assim, a M é atribuído o
conjunto {a, B} e a SA é atribuído {S, a, B}. Em seguida se obtém :
B ::= b
e assim M passa a ser igual a {b} e SA igual a {S, a, B, b}. Já que M não contém não-terminais, a
execução do laço deixará M = ∅ e SA não será alterado. Assim, S, a, B e b são alcançáveis e A e
c são inalcançáveis e suas produções podem ser eliminadas da gramática, resultando :
S ::= aS | SB | SS | ε
B ::= b
Dicas para a eliminação de símbolos inalcançáveis :
Os símbolos inalcançáveis são aqueles que partindo do inicial S, não são alcançados por n
transições.
5.6.2 εεεε - Produções
Conforme foi dito anteriormente, uma GLC pode ter produções do tipo A ::= εεεε. Mas toda GLC
pode ser transformada em uma GLC equivalente sem este tipo de produções (chamadas
εεεε -produções ), com exceção da produção S ::= εε εε, se esta existir (ou seja, a cadeia vazia pertence
à linguagem). Assim procedendo, é possível mostrar que toda GLC pode obedecer à restrição
das GSC (tipo 1). É o método da eliminação de εεεε -produções , da qual se tratará agora.
A exclusão de εεεε -produções pode determinar modificações diversas nas produções da gramática.
O algoritmo é dividido em três etapas, como segue :
a) Variáveis que constituem produções vazias. Considera, inicialmente, todas as variáveis que
geram diretamente ε (ex: A →→→→ εεεε). A seguir, sucessivamente são determinadas as variáveis que
indiretamente geram ε (ex: B →→→→ A );
b) Exclusão de produções vazias. Inicialmente, são consideradas todas as produções não-
vazias. A seguir, cada produção cujo lado direito possui uma variável que gera a palavra vazia,
determina uma produção adicional, sem esta variável;
c) Inclusão de geração da palavra vazia, se necessário. Se a palavra vazia pertence à
linguagem, então é incluída uma produção para gerar a palavra vazia.
O método consiste em determinar, para cada variável A em N , se A →→→→ * εεεε. Se isto for verdade, se
diz que a variável A é anulável. Pode-se assim substituir cada produção da forma
B ::= X 1 X 2 ...Xn por todas as produções formadas pela retirada de uma ou mais variáveis Xi
anuláveis.
Inicialmente temos E = { εεεε }.
Quando o laço é executado pela primeira vez, Q = {C} , e se obtém :
S ::= aS|SS|bA A::=BC B::=CC|ab|aAbC C::= ε
Como Q não é vazio, temos E = {ε, C} e uma segunda iteração, que deixa Q = {B}, e obtém-se :
S::=aS|SS|bA A::=BC B::=CC|ab|aAbC C::= ε
Novamente Q não é vazio, temos E = {ε, B, C}, e numa nova iteração, que faz Q = {A}
S::=aS|SS|bA A::=BC B::=CC|ab|aAbC C::= ε
O símbolo A é acrescentado a E , que passa a ser E = { εεεε , A, B, C}. Na próxima iteração não são
acrescentados símbolos a Q , terminando assim o algoritmo, e temos que os ε-não-terminais em G
são A , B e C.
Para eliminar os ε-não-terminais de uma GLC , pode-se usar o seguinte algoritmo, que elimina ε-
não-terminais sem introduzir novos. A estratégia é baseada na seguinte idéia: Seja A um ε-não-
terminal em G. Então ele é dividido conceitualmente em dois não-terminais A’ e A”, tal que A’
gera todas as cadeias não-vazias e A ” gera apenasεε εε. Agora, do lado direito de cada produção
onde A aparece uma vez, por exemplo B ::= αααα A ββββ, é trocado por duas produções B ::= αααα A’ ββββ e
B ::= αα αα A” ββββ. Já que A” só gera εεεε, ele pode ser trocado por εεεε (ou seja, eliminado), deixando
B ::= ααααββββ. Depois disso, pode-se usar A em lugar de A’. A produção final fica: B ::= ααααββββ | αααα A ββββ,
onde A não é mais um ε-não-terminal. Se B ::= αα αα A ββ ββ A γγγγ, então são obtidas quatro combinações
possíveis pelas trocas de A por εεεε ( α A β A γ , α A βγ , αβ A γ , αβγ ) e assim por diante.
Algoritmo: Eliminar Todos os εεεε -não-terminais
Entrada : Uma GLC G=(N,T,P,S)
Saída : Uma GLC G=(N’,T,P’,S’) ε-livre.
Construa o conjunto E
P’ := {p | p ∈ P e p não é ε-produção }
Repita
Se P’ tem uma produção da forma A ::= αBβ, tal que B ∈ E, αβ (N∪T)*^ e αβ ≠ ε, então
inclua a produção A ::= αβ em P’;
Até que nenhuma nova produção possa ser adicionada a P’;
Se S ∈ E, então
Adicione a P’as produções S’ ::= S | ε;
N’ := N ∪ {S’};
Senão
S’ := S;
N’ := N;
Fim Se
Dica : Como eliminar as εεεε -produções.
1º Se o símbolo inicial S possui ε-produção, cria a seguinte regra : S’::= S / ε
2º Riscar as ε-produções de todas as regras
3º marcar os NT (não-terminais) que possuem ε-produções indiretas, ou seja, muda para um
estado onde tenha ε-produções.
4º Onde houver NT marcados, fazer novas combinações, criando novas produções.
5.6.3 Produções Unitárias
Uma produção na forma A →→→→ B não adiciona informação alguma em termos de geração de
palavras, a não ser que a variável A pode ser substituída por B. Neste caso, se B →→→→ αααα, então a
produção A →→→→ B pode ser substituída por A →→→→ αααα.
Uma produção da forma A ::= αα αα em uma GLC G=(N,T,P,S) é chamada de produção unitária se α
é um não-terminal. Um caso especial de produção unitária é a produção A ::= A , também
chamada produção circular. Tal produção pode ser removida imediatamente sem afetar a
capacidade de geração da gramática. O algoritmo para eliminar produções unitárias assume que
as produções circulares já tenham sido eliminadas anteriormente. Essa eliminação é trivial, pois a
identificação de produções circulares é bastante simples.
Algoritmo: Eliminar Produções Unitárias
Entrada : Uma GLC G=(N,T,P,S) sem produções circulares.
Saída : Uma GLC G=(N,T,P’,S) sem produções unitárias.
Para toda A ∈ N faça:
NA := {B | A →* B, com B ∈ N};
Fim Para
P’ := ∅;
Para toda produção B ::= α ∈ P faça:
Se B ::= α não é uma produção unitária, então:
P’ := P’ ∪ {A ::= α | B ∈ NA};
Fim Se
Fim Para
Podem surgir símbolos inalcançáveis depois da aplicação deste algoritmo. Isso se deve ao fato de
que o símbolo é substituído por suas produções, e se o mesmo aparecer somente em produções
unitárias, o mesmo irá desaparecer do lado direito das produções. Para exemplificar, aplique o
algoritmo na seguinte gramática:
S ::= aB | aA | A // substitui A pelas suas produções
B ::= aA | B | A // idem com A e B
A ::= C | aaa // idem com C
C ::= ε | cBc
Observação : Depois de eliminar produções unitárias deve-se eliminar produções inalcançáveis,
e transformar a GLC em GLC ε -livre se necessário.
5.6.4 Fatoração
Uma GLC está fatorada se ela é determinística, ou seja, se ela não possui produções para um
mesmo não-terminal no lado esquerdo cujo lado direito inicie com a mesma cadeia de símbolos
ou com símbolos que derivam seqüências que iniciem com a mesma cadeia de símbolos. De
acordo com esta definição, a seguinte gramática é não-determinística:
S ::= aSB | aSA
A ::= a
B ::= b
fonte do
não-determinismo
5.6.5 Eliminação de Recursão à Esquerda
Um não-terminal A , em uma GLC G=(N,T,P,S) é recursivo se A →→→→αααα A ββββ, para
αααα e ββββ ∈∈∈∈ (N ∪∪∪∪ T)*.
Se α = ε, então A é recursivo à esquerda ; se β = ε, então A é recursivo à direita. Esta
recursividade pode ser direta ou indireta.
Uma gramática com pelo menos um não-terminal recursivo à esquerda ou à direita é uma
gramática recursiva à esquerda ou à direita , respectivamente.
Uma GLC G=(N,T,P,S) possui recursão à esquerda direta se P contém pelo menos uma
produção da forma A ::= A αααα.
Uma GLC G=(N,T,P,S) possui recursão à esquerda indireta se existe em G uma derivação da
forma A →→→→ n^ A ββββ, para algum n ≥≥≥≥ 2.
Para eliminar as recursões diretas à esquerda nas produções :
A::=Aα 1 |Aα 2 |...|Aαn|...|β 1 |β 2 |...|βm
onde nenhum ββββ i começa com A , deve-se substituir estas produções pelas seguintes :
A ::= β 1 A’|β 2 A’|...|βmA’
A’::= α 1 A’|α 2 A’|...|αnA’|ε
onde A’ é um novo não-terminal.
A seguir é apresentado um algoritmo para eliminar recursões diretas e indiretas à esquerda :
Algoritmo: Eliminar Recursões à Esquerda
Entrada : Uma GLC G=(N,T,P,S).
Saída : Uma GLC G=(N’,T,P’,S) sem recursão à esquerda.
N’ := N;
P’ := P;
Ordene os não-terminais de N’ em uma ordem qualquer (por exemplo, A 1 , A 2 , A 3 , ..., An);
Para i de 1 até n, faça:
Para j de 1 até i-1 faça
Substitua as produções de P’ da forma Ai ::= Ajγ por produções da forma
Ai ::= δ 1 γ | δ 2 γ | ... | δkγ, onde δ 1 , δ 2 , ... δk são os lados direitos das produções
com lado esquerdo Aj, ou seja, Aj ::= δ 1 | δ 2 | ... | δk.
Fim Para;
Elimine as recursões diretas das produções de P’com lado esquerdo Ai;
Fim Para;
Note que este algoritmo já elimina as recursões à esquerda diretas e indiretas.
Dica : Eliminação de recursão à esquerda.
1º Detectar recursão à esquerda
2º Eliminar a recursão, mantendo as não recursivas na mesma regra com X’ no final de cada
produção
3º Criar um estado ‘X’ com produções formadas pelas produções recursivas mais ‘X’ no final de
cada produção. Adicionar no final a produção ε
4º Verificar se não existem recursões indiretas
5.7 TIPOS ESPECIAIS DE GLC
- A seguir serão identificados alguns tipos especiais de GLC :
a) Gramática Própria: Uma GLC é própria se :
a.1) Não possui produções cíclicas (ver definição seguinte);
a.2) É ε-livre;
a.3) Não possui símbolos inúteis.
b) Gramática Sem Ciclos: G = (N,T,P,S) é uma GLC sem ciclos (ou livre de ciclos) se não existe
em G nenhuma derivação da forma A →
A, para todo A ∈ N.
c) Gramática Reduzida: Uma GLC G=(N,T,P,S) é uma GLC reduzida se :
c.1) L(G) não é vazia;
c.2) Se A ::= α ∈ P então A ≠ α
c.3) G não possui símbolos inúteis
d) Gramática de Operadores: Uma GLC G=(N,T,P,S) é de operadores se ela não possui
produções cujo lado direito contenha não-terminais consecutivos.
e) Gramática Unicamente Inversível: Uma GLC reduzida é unicamente inversível se ela não
possui produções com lados direitos iguais.
f) Gramática Linear: Uma GLC G=(N,T,P,S) é linear se todas as suas produções forem da forma
A ::= xBw | x, onde A e B pertencem a N, e x e w pertencem a T
g) Forma Normal de Chomsky: Uma GLC está na forma normal de Chomsky se ela é ε-livre, e
todas as suas produções (exceto, possivelmente, S ::= ε) são da forma:
g.1) A ::= BC, com A, B e C ∈ N, ou
g.2) A ::= a; com A ∈ N e a ∈ T.
h) Forma Normal de Greinbach: Uma GLC está na forma normal de Greinbach se ela é ε-livre e
todas as suas produções (exceto, possivelmente, S ::= ε) são da forma A ::= aα tal que
a ∈ T, α ∈ N*^ e A ∈ N.
O algoritmo genérico do cálculo do conjunto FIRST para uma cadeia qualquer é recursivo e utiliza
as definições para os casos especiais acima.
Algoritmo: Cálculo do Conjunto First de uma Cadeia
Entrada: Uma cadeia de símbolos X ∈∈∈∈ (N ∪∪∪∪ T)* de uma gramática G=(N,T,P,S).
Uma tabela TABFIRST com o conjunto FIRST de cada não-terminal de G.
Saída: O conjunto FIRST(X), denotado por F.
Se X = εεεε então:
F := {εεεε}.
Senão se X ∈∈∈∈ T então:
F = {X}
Senão se X ∈∈∈∈ N então:
Sejam X ::= αααα 1 | αααα 2 | ... | ααααn as produções com lado esquerdo X, então
F := FIRST(αααα 1 ) ∪∪∪∪ FIRST(αααα 2 ) ∪∪∪∪...∪∪∪∪ FIRST(ααααn);
Senão
i := 0;
F := ∅;
Repita:
i := i+1;
Xi := o i-ésimo símbolo da cadeia X;
F := F ∪∪∪∪ TABFIRST(Xi) - {εεεε};
Se X = εεεε então:
F := F ∪∪∪∪ {εεεε};
Fim Se
Até X ∈∈∈∈ T ou X = εεεε ou (X ∈∈∈∈ N e εεεε ∉∉∉∉ TABFIRST(X))
Fim Se
Para determinar o conjunto FIRST de cada um dos não-terminais de uma gramática, procede-se
como segue:
Crie uma tabela TABFIRST cujas linhas são rotuladas com os não-terminais da gramática e com
uma coluna rotulada como “FIRST”, que irá conter os símbolos pertencentes ao FIRST de cada não-
terminal. Inicialize cada uma das posições desta tabela com ∅ (conjunto vazio).
Para cada um dos não-terminais, calcule o seu conjunto FIRST utilizando o algoritmo acima. Repita
o passo 2 até que não ocorra mais nenhuma modificação na tabela.
Para exemplificar, considere a gramática:
S ::= ABS|aA
A ::= ε|a
B ::= Bb|cd
Inicialmente constrói-se a tabela:
N FIRST
S ∅
A ∅
B ∅
Calculando o FIRST de S pelo algoritmo acima, faz-se FIRST(S) = FIRST(ABS) ∪∪∪∪ FIRST(aA).
Como FIRST(A) = ∅∅∅∅, na tabela, então FIRST(S) inicialmente é ∅∅∅∅ ∪∪∪∪ {a}. A tabela fica:
N FIRST
S {a}
A ∅
B ∅
Calculando o FIRST(A) temos {εεεε, a}. Então a tabela fica:
N FIRST
S {a}
A {ε, a}
B ∅
Calculando o FIRST(B) temos FIRST(B) = FIRST(Bb) ∪ FIRST(cd) = ∅ ∪ {c}. A tabela fica:
N FIRST
S {a}
A {ε, a}
B {c}
Como a tabela foi modificada, o passo 2 deve ser repetido. Desta vez, ao calcular o FIRST de S
teremos: FIRST(S) = FIRST(ABS) ∪∪∪∪ FIRST(aA) = {a} ∪∪∪∪ FIRST(BS) ∪∪∪∪ {a} = {a}∪∪∪∪{c}∪∪∪∪{a} = {a,
c}. Logo a tabela fica:
N FIRST
S {a, c}
A {ε, a}
B {c}
O cálculo do FIRST de A e B não modifica a tabela. Mas como houve uma modificação no cálculo
do FIRST de S, o passo 2 deve ser novamente executado. Como desta vez não haverá
modificações, a última tabela será de fato a definitiva.
5.9.2 Conjunto Follow
FOLLOW(A) é definido para todo A ∈∈∈∈ N como sendo o conjunto de símbolos terminais que
podem aparecer imediatamente após A em alguma forma sentencial de G. A seguir, é definido um
algoritmo que constrói o FOLLOW de todos os não-terminais simultaneamente.
O tabela FOLLOW dos não-terminais da gramática é inicializada como:
N FOLLOW
S {$}
A ∅
B ∅
Para o primeiro passo, temos as ocorrências de Y ::= XXX em S ::= ABS e B ::= Bb, assim:
FOLLOW(A) = FOLLOW(A) ∪∪∪∪ FIRST(BS) = ∅∅∅∅ ∪∪∪∪ {c} = {c}
FOLLOW(B) = FOLLOW(B) ∪∪∪∪ FIRST(S) = ∅∅∅∅ ∪∪∪∪ {a, c} = {a, c}
FOLLOW(B) = FOLLOW(B) ∪∪∪∪ FIRST(b) = {a, c} ∪∪∪∪ {b} = {a, b, c}
Temos então a tabela FOLLOW intermediária:
N FOLLOW
S {$}
A {c}
B {a, b, c}
No segundo passo, as produções são analisadas da esquerda para a direita. A produção S ::= ABS
faz com que:
FOLLOW(S) = FOLLOW(S) ∪∪∪∪ FOLLOW(S) = {$}
Como εεεε ∉∉∉∉ FIRST(S), a segunda regra termina para esta produção. Para a produção
S ::= aA, temos:
FOLLOW(A) ::= FOLLOW(A) ∪∪∪∪ FOLLOW(S) = {c, $}
Como εεεε ∈∈∈∈ FIRST(A), o símbolo a esquerda de A é analisado. Como é um terminal (a), o algoritmo
pára. Já que não há mais produções que tenham não-terminais a direita, o cálculo da tabela
FOLLOW termina. A tabela final fica:
N FOLLOW
S {$}
A {c, $}
B {a, b, c}
Lista de Exercícios de Simplificação de GLC’s
1 – Eliminação de símbolos inúteis ou improdutivos :
a)
S ::= ASB | BSA | SS | aS | ε A ::= ABS | B B ::= BSSA | A
b) A ::= aBa | cB | cC | aD B ::= aCb | aD | ab | ε C ::= ab | cBd | aA D ::= aD | dE | aD E ::= Ead | aD | ED
c) S ::= aA A ::= a | bB B ::= b | dD C ::= cC | c D ::= dD
d) S ::= aCD | ab | bB | aaS B ::= bbB | Daa | a C ::= aCa | BCb | Ecab E ::= ab | Ea | Ba D ::= abB | ab | DD
e) S ::= Abc | aBc A ::= aAb | AB | Abc | CD B ::= bBc | bC | Bc C ::= cCc | cC | CD D ::= bbD | Dbc | DD E ::= bEc | EC | cc
f) S ::= 0A1 | 1B0 | C A ::= 1A0 | AC B ::= 0D1 | 01 C ::= 1A | 0C D ::= 1B0 | 10
g) S ::= EE | E + E | (E) A ::= id | id * E | id + E | (id) E ::= BS | A+E | AE | A B ::= id + B | id*E
h) S ::= aAc | aBc | ac A ::= aEd | aAb | ab B ::= BaD | aBb | a C ::= aCd | af D ::= aDd | aD E ::= aEa | af
i) S ::= aAb | aCd | ab A ::= aAb | aA B ::= ad | aBC C ::= aSa | aa
i) P ::= KL | bKLe K ::= cK | TV T ::= tT | ε
V ::= vV | ε L ::= LC | C C ::= P | com | ε
4 – Produções Unitárias :
a) S ::= bS | A A ::= aA | a
b) S ::= aSb | A A ::= aA | B B ::= bBc | bc
c) S ::= 1S0 | 0A00 | A | B A ::= 0 | BC | C | S B ::= A | 01 | 0S0 | 1 C ::= 1 | 01 | 0S D ::= D | 01 | ab
d) S ::= 1A0 | 0B1 | B A ::= 1B0 | C | 01 B ::= 10B | 01C | D C ::= 10 | 01 | 0C D ::= 1D0 | 10 | C
e) S ::= aA | aB | A A ::= bC | Bd | B B ::= aCd | aC | A C ::= aC | S
f) S ::= aSa | FbD A ::= aA | CA | ε B ::= bB | FE C ::= cCb | AcA D ::= Dd | fF | c E ::= BC | eE | EB F ::= fF | Dd
5 – Fatoração :
a) c ::= V = exp | id (E) V ::= id [E] | id E ::= exp + E | exp
b) S ::= bcD | Bcd B ::= bB | b D ::= dD |d
c) S ::= aA | aB A ::= aA | a B ::= b
d) S ::= Ab | ab | baA A ::= aab | b
e) S ::= Abc | bBC | bCD A ::= aBC | aDC B ::= dCc | dc C ::= Acd | cd D ::= aBC | abc | aC
f) S ::= 1A0 | 1B A ::= 1A0 | 100 B ::= C10 | C C ::= 11C | 11D D ::= 10 | 11
g) S ::= 10D | 11C | 0B B ::= 1CD | 101B | 01 C ::= 101C | 1B0 | 00 D ::= 00B | 011D | 110
h) S ::= aBd | acD | bC B ::= bDc | bCd | ad D ::= cdD | caB C ::= cbB | adD
i) S ::= bcD | Bcd B ::= bB | b D ::= dD | d
j) C ::= V=exp | id(E) V ::= id[E] | id E ::= exp,E | exp
6 – Eliminação de recursão à esquerda :
a) A ::= Abc | Acd | cdB | c B ::= Bc | dd
b) S ::= Aab | Bc | ScAb A ::= Sac | BaA | ab B ::= Ac | aBb | ab
c) A ::= Ac | bd | cd B ::= ac | Bd | Ac
d) S ::= Aa | Bb | Sac A ::= Sab | ab B ::= a | Ba
e) S ::= A0 | 0B1 | 11C
BIBLIOGRAFIA
AHO, A.V.; SETHI, R.; ULLMAN, J.D. Compiladores: princípios, técnicas e ferramentas. Rio
de Janeiro/RJ: LTC, 1995. 344 p.
FURTADO, O.J.V. Linguagens formais e compiladores: notas de aula. Florianópolis/SC: INE-
UFSC, 1992. 77 p.
HOPCROFT, J. E.; ULLMAN, J. D. Introduction to automata theory, languages and
computation. Reading: Addison-Wesley, 1979. 418 p.
JOSÉ NETO, J. Introdução à compilação. Rio de Janeiro/RJ: LTC, 1987. 222 p.
MARTINS, Joyce. Linguagens Formais e Compiladores. Universidade do Vale do Itajaí – Notas
de Aula. São José/SC.
MENEZES, P. F. B. Linguagens Formais e Autômatos. Porto Alegre/RS: II-UFRGS, Sagra
Luzzatto, 1997. 168 p.
PRICE, A.M.A.; EDELWEISS, N. Introdução às linguagens formais. Porto Alegre/RS: II-
UFRGS, 1989. 60 p.
WAZLAWICK, R.S. Linguagens formais e compiladores: notas de aula. Florianópolis/SC: INE-
UFSC, 1992. 83 p.
ZILLER, R.M. Aplicação de autômatos finitos. In: SEMANA TECNOLÓGICA, 1., Florianópolis,
1997. Anais. Biguaçu, UNIVALI, 1997. p.51-71.