AULA Nº 3

(Download da Aula)

<< anterior próxima >>
menu de aulas dúvidas
 

TP Lex e Yacc - As ferramentas para construção de compiladores do Turbo Pascal

Tp Lex e Yacc são adaptações para o Turbo Pascal das conhecidas ferramentas Lex e Yacc do UNIX. Seu objetivo é auxiliar a construção de compiladores e programas similares, como interpretadores de linguagem de comando, com a linguagem Turbo Pascal. Este texto é um pequeno manual para o uso dessas ferramentas extraído do manual original.

As ferramentas geradoras de compiladores TP Lex e Yacc rodam sobre o MS-DOS (versão 3.0 ou posteriores) e compilador Turbo Pascal (versão 4.0 ou posteriores) e são licenciadas para uso gratuito. As units de biblioteca LEXLIB.TPU e YACCLIB.TPU são distribuídas  compiladas com o Turbo Pascal 6.0, para usá-las com outra versão de Turbo Pascal provavelmente elas deverão ser recompiladas ( os códigos fonte são LEXLIB.PAS e YACCLIB.PAS)
 

Onde encontrar os arquivos de distribuição do TP Lex e Yacc

    Dê uma olhada na seção de downloads do site.  

Instalando o TP Lex e Yacc

Copie os arquivos de distribuição para um diretório apropriado de seu disco. Coloque esse diretório no 'path' do DOS e do Turbo Pascal para que o compilador do mesmo possa encontrar as units de biblioteca do TP Lex e Yacc.

Pronto! Tendo feito isso já é possível compilar programas TP Lex e Yacc.

Extensões 'default' são usadas para a nomeação dos arquivos:

Essa extensões podem ser sobrescritas especificando-se os sufixos.
 

Exemplo Inicial

Como exemplo inicial tente compilar o programa EXPR que vem junto com os arquivos de instalação. Esse programa simula uma calculadora simples. O arquivo  exprlex.l é o analisador léxico e o arquivo expr.y é o analisador sintático. Para compilá-los execute os seguintes comandos:

As saídas serão os arquivos exprlex.pas e expr.pas, respectivamente. Para compilar esses programas no Pascal, entre com o comando: A saída será o arquivo executável expr.exe.
 

Como escrever os arquivos de entrada para o TP Lex 

Programas TPLex são formados por três partes separadas por delimitadores %%. São elas:

1. Definições
2. Regras
3. Procedimentos auxiliares
1. A seção de definições pode conter os seguintes elementos:
1.1 Definições regulares na forma:
        nome  substituição
        Ex.: D   [0-9]
Abrevia  subexpressões comuns. O nome deve iniciar com uma letra (letras maiúsculas e minúsculas são distintas), seguida por uma sequência de letras e dígitos;
1.2 Definições de estado inicial na forma:
        % start nome ...
 
Especifica condições iniciais sobre as regras. Será melhor descrito posteriormente.
        1.3 Declarações Turbo Pascal fechadas entre %{ e %}.
Elas serão inseridas no arquivo de saída em um escopo global. Também as linhas que não        se parecem com  uma definição Lex, como por exemplo, linhas que começam com espaço em branco ou tabulação, serão tratadas como código turbo Pascal. Isso permite a inclusão de comentários do Turbo Pascal no programa Lex.
2. A seção de regras contém as especificações da rotina do analisador léxico. Cada regra consiste de uma expressão regular que descreve a string para ser combinada com a entrada e a ação correspondente ( sentença TURBO PASCAL para ser executada ). Seu formato é o seguinte:
         expressão  sentença;
         Ex.: D    writeln("Isso é um número");
Note  que a sentença deve terminar com ';'  (deve-se usar begin e end para sentenças compostas). A sentença pode estender-se por várias linhas se as linhas sucessoras forem dentadas com espaços em branco ou tabulação. A ação pode ser substituída pelo caracter '|' indicando que a ação para esta regra é a mesma da próxima regra.

A unit de biblioteca TPLEX provê várias variáveis e rotinas usuais na programação de ações. Entre elas a string yytext que armazena o texto da string combinada.

O formato das expressões regulares usadas para descrever as regras é descrito na próxima seção.

3. A seção de procedimentos auxiliares pode conter qualquer código Turbo Pascal. Esses  procedimentos serão adicionados ao arquivo de saída. Essa seção é opcional.
 

Expressões  Regulares

A tabela a seguir sumariza o formato das expressões regulares reconhecidas pelo TP Lex.
 
 
 
expressão combinação exemplo
c algum caracter c a
\c caracter c literalmente \*
"s" string s literalmente "**"
. algum caracter e nova linha a .*b
^ começo de linha ^abc
$ final de linha abc$
[s] algum caracter em s [abc]
[^s] algum caracter que não está em s [^abc]
r* zero ou mais r's a*
r+ um ou mais r's a+
r? zero ou um r a?
r{m,n} m para n ocorrências de r a{1,5}
r{m} m ocorrências de r a{5}
r1r2 r1 então r2 ab
r1|r2 r1 ou r2 a | b
(r) r (a | b)
r1/r2 r1 quando seguido de r2 a/b
<xr r quando condição de início é x <xabc
 

Como escrever os arquivos de entrada para o TP Yacc 

Programas TPYacc são formados por três partes separadas por delimitadores %%. São elas:

1.Definições
2.Regras
3.Procedimentos auxiliares
 
1. A seção de definições pode conter os seguintes elementos:
1.1 Definição do símbolos inicial na forma:
%start símbolo
   
Declara o não terminal inicial da gramática ( se esta definição é omitida, TP Yacc assume o primeiro não terminal mais a esquerda da primeira regra gramatical como o símbolo inicial).
1.2. Definições de terminais na forma:
        % token símbolo
Declara os símbolos terminais da linguagem. Pode-se declarar aqui o tipo de cada token.
        Ex.: % token  DIGITO
1.3. Definições de precedência na forma:
        % left símbolo ...
        % right símbolo ...
        % nonassoc símbolo ...
Declara os símbolos operadores que podem ser associados com uma precedência. Esses símbolos podem, mas não precisam aparecer na seção de definição de terminais. Cada definição de precedência introduz um novo nível de precedência, as mais baixas são declaradas primeiro.
        Ex.: %left '+'  '-'      /* operadores adicionais */
                %left '*'  '/ '     /* operadores de multiplicação */
1.4. Definições de tipos na forma:
        % type <nome>  símbolo ...
Pode-se associar um tipo de dado aos símbolos terminais e não-terminais;

Para os símbolos não-terminais: %type <nome_tipo> símbolo...

     Ex.: % token <Real > DIGITO (para símbolos terminais)
1.5. Declarações Turbo Pascal fechadas entre %{  e %}.
Pode-se incluir código Turbo Pascal nessa seção. Esse código será inserido como declaração global no arquivo de saída.
 
2. Na seção de regras temos:

            nome: símbolo...;

          Ex.: expr: expr ´+´ expr
                         | expr ´-´ expr
                         ;
Ex.: expr: expr ´+´ expr {$$ := $1 + $3;}             %{ type YYSType = Real; %}, na seção de definições.   Ex.: expr: NUM{$$:= 2*$1;} expr ($$ := $2 + $3;}

 
3. Procedimentos Auxiliares

    São procedimentos que serão copiados para o arquivo pascal gerado. É opcional.

 

Análise Léxica