1 / 112

Linguagens Formais, Lex & Yacc Vladimir Oliveira Di Iorio

Linguagens Formais, Lex & Yacc Vladimir Oliveira Di Iorio. Introdução. Linguagens Formais. Linguagens formais são linguagens cuja sintaxe (e geralmente semântica) é precisamente definida, sem ambigüidades. São diferentes de linguagens naturais, recheadas de imprecisões e ambigüidades.

giles
Download Presentation

Linguagens Formais, Lex & Yacc Vladimir Oliveira Di Iorio

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linguagens Formais, Lex & Yacc Vladimir Oliveira Di Iorio

  2. Introdução

  3. Linguagens Formais • Linguagens formais são linguagens cuja sintaxe (e geralmente semântica) é precisamente definida, sem ambigüidades. • São diferentes de linguagens naturais, recheadas de imprecisões e ambigüidades. • Exemplos de linguagens formais: linguagens de programação como C, C++, Pascal, Java, linguagens de consulta como SQL.

  4. Exemplo • Uma definição para o comando UPDATE da linguagem SQL, usando estilo BNF: UPDATE [TRANSACTION transaction] {table | view}SET col = <val> [, col = <val> …][WHERE <search_condition> | WHERE CURRENT OF cursor]; • Exemplo de um comando válido: UPDATE CLIENTE SET DATA_INCLUSAO = CURRENT DATE;

  5. Objetivos do Curso • Estudar fundamentos teóricos de linguagens formais: • alfabetos, palavras e linguagens; • expressões regulares; • gramáticas regulares e livres de contexto. • Apresentar ferramentas no estilo Lex, para processamento de entradas usando linguagens regulares. • Apresentar ferramentas no estilo Yacc, para processamento de entradas usando linguagens livres de contexo. • Dar exemplos de utilização de ferramentas Lex e Yacc, na construção de filtros, pequenos interpretadores e compiladores.

  6. Visão Geral - Expressões Regulares • Expressões regulares são um formalismo usado para definir o formato correto de uma cadeia de caracteres. • São usados símbolos de um alfabeto qualquer, juntamente com operadores especiais, como '*' e '+'. • Um exemplo: a+ b c* Essa expressão define que as cadeias válidas são aquelas que iniciam com uma seqüência não vazia de símbolos 'a', seguidos de exatamente um símbolo 'b', seguido de uma seqüência possivelmente vazia de símbolos 'c'.

  7. Estado final Estado inicial Visão Geral - Autômatos • Autômatos finitos são um formalismo equivalente às expressões regulares, que usa representação em forma de grafo. • Autômato finito equivalente à expressão a+ b c* : a b c a

  8. Visão Geral - Gramáticas • Gramáticas são mais um formalismo usado para definir o formato correto de uma cadeia de caracteres. • Os símbolos são classificados como terminais e não terminais, e são usadas regras de reescrita para os símbolos não terminais. • Gramática equivalente à expressão a+ b c* : <S> -> a<A> <A> -> a<A> | b<B> | b <B> -> c<B> | c

  9. Visão Geral - Lex • Ferramentas no estilo Lex utilizam uma especificação baseada em expressões regulares. • A partir dessa definição, Lex gera automaticamente um programa que simula o comportamento de autômatos equivalentes às expressões fornecidas. • O programa lê uma entrada e verifica se essa entrada está no formato especificado. • Enquanto verifica a entrada, pode executar algumas ações (trechos de programa) desejadas.

  10. Visão Geral - Yacc • Ferramentas no estilo Yacc funcionam de maneira parecida com Lex - mas utilizam uma especificação baseada em gramáticas. • O formalismo de gramáticas é mais poderoso que o de expressões regulares e autômatos, assim é possível gerar programas que processam entradas mais complexas. • Da mesma forma que Lex, Yacc pode associar ações (trechos de programa) a cada regra da gramática. À medida que a entrada é processada, ações adequadas são executadas. Essas ações podem ser, por exemplo, a interpretação ou compilação da entrada.

  11. Visão Geral - Lex & Yacc • Um compilador ou interpretador pode ser gerado rapidamente usando Lex e Yacc em conjunto. • Lex é geralmente usado para separar uma entrada em unidades léxicas. No caso de uma linguagem de programação, por exemplo, pode identificar um número real como "1.23" ou uma palavra-chave como "begin". • Yacc pode usar as unidades léxicas produzidas por Lex e verificar se essas unidades formam uma entrada válida. Enquanto isso pode, por exemplo, compilar a entrada.

  12. Visão Geral - Lex & Yacc regras léxicas regras sintáticas entrada saída Lex Yacc Analisador Léxico Analisador Sintático

  13. História • O primeiro compilador para uma linguagem de programação de alto nível foi desenvolvido para a linguagem FORTRAN, na década de 50. • Na época, a teoria de linguagens formais ainda não estava estabelecida (Chomsky, 1959). • Foi necessário um esforço gigantesco, e a utilização de um grande número de programadores.

  14. História • Atualmente, com a utilização de ferramentas como Lex e Yacc, é possível construir rapidamente um compilador. • O processo de geração automática utilizado por essas ferramentas, em geral, produz analisadores quase tão rápidos quanto os escritos totalmente à mão.

  15. Linguagens Formais

  16. Alfabetos e Palavras • Um alfabeto é um conjunto finito de símbolos distintos. • Exemplo: Σ = {a,b,c} é um alfabeto formado pelos símbolos a, b e c. • Uma palavra sobre um alfabeto Σ é uma seqüência de comprimento finito formada com símbolos desse alfabeto. • Algumas palavras sobre o alfabeto Σ = {a,b,c} : abc , bcaabbac , b • A palavra de comprimento zero é representada por λ .

  17. Linguagens • Seja Σ um alfabeto qualquer. O conjunto de todas as palavras sobre Σ é denotado por Σ* . • Por exemplo, se Σ = {a,b,c} , então Σ* = {λ, a, b, c, aa, ab, ac, ba, bb, bc, ca, cb, cc, aaa, ...} • Uma linguagem sobre um alfabeto Σ é qualquer subconjunto de Σ* . • Linguagens sobre Σ = {a,b,c} : {a, ab, bbc} {aa, ab, ac, ba, bb, bc, ca, cb, cc} todas as palavras que começam com a

  18. Linguagens • Outras linguagens sobre Σ = {a,b,c} : todas as palavras de comprimento par {λ, a, b, c} {λ} { } Σ* • A concatenação de 2 palavras será representada por sua justaposição. Por exemplo, sejam uma palavra x = abc e uma palavra y = bb . A concatenação de x com y é representada por xy = abcbb .

  19. Concatenação de linguagens • Se X e Y são duas linguagens, a concatenação de X com Y, denotada por XY, é a seguinte linguagem: XY = { palavras xy tais que x  X e y  Y } Ou seja, são as palavras formadas pela concatenação de uma palavra qualquer de X com uma palavra qualquer de Y (prefixo pertence a X, sufixo pertence a Y).

  20. Concatenação de linguagens • Por exemplo, sejam X = {a,b,c} e Y = {abb,ba} . Então XY = {aabb,aba,babb,bba,cabb,cba} • A concatenação de X consigo mesma n vezes é Xn : Xn = X X X ... X X (n vezes) • Por definição, X0 é o conjunto {λ}: X0 = {λ}

  21. Concatenação de linguagens • Outros exemplos, com X = {a,b,c} e Y = {abb,ba} : X0 = {λ} X1 = X = {a,b,c} X2 = XX = {aa,ab,ac,ba,bb,bc,ca,cb,cc} X3 = X2X = {aaa,aab,aac,aba,abb,abc,aca,acb,acc, baa,bab,bac,bba,bbb,bbc,bca,bcb,bcc, caa,cab,cac,cba,cbb,cbc,cca,ccb,ccc} Y2 = YY = {abbabb,abbba,baabb,baba}

  22. Exercícios Considere o alfabeto Σ = {a,b,c}. Seja L1 a linguagem das palavras que começam com o símbolo 'a', e L2 a linguagem das palavras que terminam com o símbolo 'b'. • O conjunto {a,b,c} é uma linguagem sobre Σ? • Qual a menor linguagem que pode ser criada com esse alfabeto (menor número de palavras) ? • Qual é o resultado da concatenação de L1 com L2 ? • Qual é o resultado da união de L1 com L2 ? • A união de 2 linguagens pode resultar em uma linguagem menor que as outras duas? • A concatenção de 2 linguagens pode resultar em uma linguagem menor que as outras duas?

  23. Fecho de Kleene • A operação X*, denominada Fecho de Kleene de X, é definida como a união de Xi , com i variando de 0 a infinito: X*= X0X1 X2 X3... Ou seja, X* consiste de todas as palavras que se pode construir a partir dos elementos de X. • Por exemplo, se X = {a,b,c} e Y = {abb,ba} : X*= {λ,a,b,c,aa,ab,ac,ba,bb,bc,ca,cb,cc,aaa,...} Y* = {λ,abb,ba,abbabb,abbba,baabb,baba,abbabbabb,...}

  24. Expressões Regulares

  25. Expressões Regulares - Definição • Para definir expressões regulares, vamos usar as seguintes abreviações: • o conjunto {a} será representado simplesmente por a ; • {a,b,c,...} será representado por a  b  c ... • O conjunto de expressões regulares sobre um alfabeto Σqualquer é definido como: • os conjuntos { } e λ são expressões regulares; • para todo símbolo a de Σ, a é uma expressão regular; • se x e y são expressões regulares sobre Σ, então também são expressões regulares: x  y , xy e x* .

  26. Expressões Regulares - exemplos • a b linguagem formada apenas pelas palavras a e b • abb aa  ac linguagem formada exatamente pelas palavras abb, aa e ac, ou seja, {abb,aa,ac} • a* linguagem (infinita) de todas as palavras formadas apenas com o símbolo a

  27. Expressões Regulares - exemplos • (a  b) (ab  bb) denota a linguagem {aab,abb,bab,bbb} • (a  b)* a linguagem {λ,a,b,aa,ab,ba,bb,aaa,...} : • (aa)* palavras só com a, e com comprimento par (inclui a palavra nula)

  28. Expressões Regulares - exemplos • Outras abreviações: • x+ é usado para abreviar xx* ; • x2 é usado para abreviar xx ; • x3 para abreviar x2x etc. • (a2)+ palavras só com a, e com comprimento par maior que zero (não inclui a palavra nula) • a (a  b  c)* Linguagem sobre {a,b,c} das palavras que começam com o símbolo a

  29. Expressões Regulares - exemplos • a (a  b  c)* b Linguagem sobre {a,b,c} das palavras que começam com o símbolo a e terminam com b • (b  c) (a  b  c)* λ Linguagem das palavras sobre {a,b,c} que não começam com o símbolo a

  30. Expressões Regulares - exercícios • Que linguagens são essas? • (a  b)* b (a  b)* • (a  b)* a (a  b)* a (a  b)* • (a  b  c) (a  b  c) (a  b  c) • (b* a b* a b*) *

  31. Expressões Regulares - exercícios • Construa expressões regulares para: • Linguagem das palavras de comprimento par sobre o alfabeto {a,b,c}. • Linguagem das palavras sobre o alfabeto {a,b,c} que contenham exatamente um símbolo c .

  32. Expressões Regulares - restrições • As linguagens que podem ser especificadas por expressões regulares são chamadas de linguagens regulares. • Mas expressões regulares não podem ser usadas para especificar qualquer linguagem desejada. • Muitas linguagens não conseguem ser especificadas com expressões regulares, necessitando de formalismos mais poderosos.

  33. Expressões Regulares - restrições • Exemplos de linguagens que não são regulares: • Linguagem cujas palavras têm o formato anbn, para qualquer n. Ou seja: { λ, ab, aabb, aaabbb, ... } • Linguagem sobre alfabeto { a, b, (, ) } com aninhamento correto de parêntesis abrindo e fechando.

  34. Lex - Gerador de Analisadores Léxicos

  35. Lex - Gerador de Analisadores Léxicos • Ajuda a escrever programas cuja entrada pode ser descrita por meio de expressões regulares. • Principais utilizações: • transformações simples e extração de padrões em textos; • separação da entrada em unidades léxicas, como preparação para um analisador sintático. • Os exemplos utilizados nesta apresentação seguirão o formato do programa JFlex, um clone de Lex que gera código em Java.

  36. Lex - fonte • Um texto fonte para LEX é composto de: • lista de expressões regulares; • fragmentos de programa associados a cada expressão. • Quando o fonte é submetido ao LEX, um programa é automaticamente gerado. Esse programa: • lê um arquivo de entrada; • particiona a entrada em cadeias que "casam" com as expressões regulares definidas; • executa os fragmentos de programa associados às expressões "casadas"; • escreve no arquivo de saída.

  37. Lex - esquema de funcionamento Yylex (programa gerado) fonte Lex entrada saída Yylex

  38. 1. 2 . 3 . 4 . %% %standalone %% \t { System.out.print("TAB"); } Lex - exemplo com JFlex • Um exemplo, usando o gerador JFlex: • Como na maioria dos clones de Lex, o fonte é dividido em 3 seções, separadas por "%%". • No JFlex, as seções são: • código do usuário a ser incluído; • opções e declarações; • regras e ações associadas.

  39. Uma regra 1. 2 . 3 . 4 . %% %standalone %% \t { System.out.print("TAB"); } Essa opção indica que o programa gerado poderá ser executado diretamente (não será usado dentro de um analisador sintático). Ação (fragmento de programa) associada à expressão Expressão regular Lex - exemplo com JFlex

  40. 1. 2 . 3 . 4 . %% %standalone %% \t { System.out.print("TAB"); } Lex - exemplo com JFlex • Essa regra "casa" com um caractere "\t" (tabulação) da entrada. Se isso acontecer, o código entre chaves é executado. • Se a entrada não casa com nenhuma regra, a ação default é executada: escrever o caractere diretamente na saída. • Ou seja, esse "programa" Lex serve para ler uma entrada e trocar as tabulações por "TAB".

  41. 1. 2 . 3 . 4 . %% %standalone %% \t { System.out.print("TAB"); } Lex - usando o JFlex • Supondo que o fonte abaixo esteja no arquivo ex1.flex: Executa jflex, gerando Yylex.java > jflex ex1.flex Reading "ex1.flex" Constructing NFA : 6 states in NFA Converting NFA to DFA : .. 4 states before minimization, 3 states in minimized DFA Writing code to "Yylex.java" > javac Yylex.java gera Yylex.class

  42. Lex - executando analisador gerado teste... Esta linha comeca com tab Esta com 2 tabs fim. • Supondo que o texto abaixo esteja no arquivo teste.txt: > java Yylex teste.txt teste... TABEsta linha comeca com tab TABTABEsta com 2 tabs • Para gerar a saída no arquivo saida.txt: > java Yylex teste.txt > saida.txt

  43. Lex - expressões regulares • Expressões regulares usadas em regras: • caracteres de texto: letras, dígitos, caracteres especiais como '\t', '\n' etc. • operadores: usados como funções especiais das expressões regulares. • Na maioria das versões de Lex, os operadores são: " \ [ ] ˆ - ? . * + | ( ) $ / { } % < > • Os operadores podem ser utilizados como caracteres de texto, se vierem precedidos de um caractere de escape ('\') ou se estiverem entre aspas duplas. • Nas slides seguintes, veremos o funcionamento de alguns operadores.

  44. Lex - expressões regulares • Classes de caracteres: [abc]casa com um dos caracteres a, b ou c [a-zA-Z]casa com uma letra minúscula ou maiúscula [^a-zA-Z]casa com qualquer coisa, exceto letras • Caractere arbitrário: .casa com qualquer caractere, exceto newline • Exclusivos de JFlex: [:letter:]isLetter( ) [:digit:]isDigit( ) [: lowercase:]isLowerCase( ) [:uppercase:]isUpperCase( )

  45. Lex - expressões regulares • Expressões repetidas (* e +): a*casa com qualquer número consecutivo de a's (incluindo zero repetições) a+casa com uma ou mais ocorrências de a [A-Za-z][A-Za-z0-9]* definição usual de "identificador" • Alternação e agrupamento ( | ): (ab|cd)casa com ab ou cd

  46. Lex - expressões regulares • Expressão opcional (?): ab?ccasa com ac ou abc; (ab|cd+)?(ef)* casa comabefef , efefef , cdef, ou cddd mas não com abc , abcd , ou abcdef • Macros e repetições: {digit}casa com a definição da expressão regular digit (seção de definições) a{n} casa comn vezes a concatenação de a

  47. Lex - escolha de regras • Como ocorre a escolha das regras para casamento? • À medida que a entrada é lida, o analisador procura a regra que possibilita o casamento com a mais longa possível seqüência de caracteres da entrada. • Se mais de uma regra possibilita o casamento com a seqüência mais longa, a escolha é feita pela ordem em que as regras aparecem na fonte.

  48. 1. 2 . 3 . 4 . 5. 6 . %% %standalone Identifier = [a-zA-Z][a-zA-Z0-9]* %% abc { System.out.println("-----\"abc\""); } {Identifier} { System.out.println("-----id"); } Lex - escolha de regras • Supondo que o fonte abaixo esteja no arquivo ex2.flex: > jflex ex2.flex Reading "ex2.flex" Constructing NFA : 16 states in NFA Converting NFA to DFA : ...... 8 states before minimization, 6 states in minimized DFA Writing code to "Yylex.java" > javac yylex.java

  49. Lex - escolha de regras abcde abc abc123 123abcd 123abc • Supondo que o texto abaixo esteja no arquivo teste.txt: > java Yylex teste.txt • O que será impresso???

  50. 1. 2 . 3 . 4 . 5. 6 . %% %standalone Identifier = [a-zA-Z][a-zA-Z0-9]* %% abc { System.out.println("-----abc"); } {Identifier} { System.out.println("-----id"); } Lex - escolha de regras Saída: Entrada: -----id -----abc -----id 123-----id 123-----abc abcde abc abc123 123abcd 123abc

More Related