Análise Léxica - · PDF fileSimplicidade do projeto. Programa Analisador...

download Análise Léxica - · PDF fileSimplicidade do projeto. Programa Analisador léxico sintático para análise semântica token obter token Tabela de símbolos . Expressões Regulares

If you can't read please download the document

Transcript of Análise Léxica - · PDF fileSimplicidade do projeto. Programa Analisador...

  • Compiladores 1

    http://erinaldosn.wordpress.com

    Anlise Lxica

    A varredura, ou anlise lxica, a fase de um compilador que l o programa-

    fonte como um arquivo de caracteres e o separa em marcas. Essas marcas so como

    palavras em uma linguagem natural.

    Exemplos de smbolos lxicos so as palavras reservadas, os identificadores, a

    constantes e os operadores da linguagem. Durante o processo de anlise lxica, so

    desprezados caracteres no significativos como espaos em branco e comentrios.

    Alm de reconhecer os smbolos lxicos, o analisador tambm realiza outras

    funes, como armazenar alguns desses smbolos (identificadores e constantes) em

    tabelas internas e indicar a ocorrncia de erros lxicos.

    Para implementar um analisador lxico mo, importante comear com um

    diagrama ou outra descrio para os lexemas de cada token. Podemos escrever cdigo

    para identificar a cada ocorrncia de cada lexema na entrada e retoranr informaes

    sobre o token identificado.

    A tarefa efetuada pelo sistema de varredura um caso especial de casamento de

    padres. Os mtodos de especificao e reconhecimento de padres que se aplicam no

    processo de varredura so basicamente os de expresses regulares e autmatos finitos.

    Podemos produzir um analisador lxico automaticamente especificando os

    padres dos lexemas para um gerador de analisador lxico e compilando esses padres

    em cdigo que funciona como um analisador lxico.

    O papel do analisador lxico A tarefa principal do analisador lxico ler os caracteres da entrada do programa

    fonte, agrup-los em lexemas e produzir como sada uma sequncia de tokens para cada

    lexema no programa fonte.

    Token: um par consistindo em um nome e um valor de atributo opcional.

    Padro: uma descrio da forma que os lexemas de um token podem assumir

    Lexema: uma sequncia de caracteres no programa fonte que casa com o padro para um token e identificado pelo analisador lxico como uma instncia desse

    token.

    O fluxo de tokens enviado ao analisador sinttico para que a anlise seja

    efetuada

    Interaes entre o analisador lxico e o analisador sinttico:

    O analisador lxico a parte do compilador que l o texto fonte, ele pode

    realizar outras tarefas, como remover comentrios e o espao em branco. Outra tarefa

    correlacionar as mensagens de erro geradas pelo compilador com o programa fonte.

    Os motivos que separam as fases de anlise lxica e anlise sinttica so:

    1. Simplicidade do projeto.

    Programa

    fonte

    Analisador

    lxico

    Analisador

    sinttico

    para anlise

    semntica

    token

    obter

    token

    Tabela de

    smbolos

  • Expresses Regulares

    http://erinaldosn.wordpress.com

    2. A eficincia do compilador melhorada. 3. A portabilidade do compilador melhorada.

    Os analisadores lxicos so divididos em uma cascata de dois processos:

    1. O escandimento consiste no processo simples de varredura da entrada sem se preocupar com a remoo de comentrios e a compactao de espaos em branco

    consecutivos em apenas um caractere.

    2. A anlise lxica, onde o analisador lxico produz a sequncia de tokens como sada.

    Atributos de tokens Quando mais de um lexema casar com um padro, o analisador lxico precisa

    oferecer s fases subsequentes do compilador informaes adicionais sobre qual foi o

    lexema em particular casado.

    Exemplo: o padro para o token number casa com 0 e 1.

    Assim, em muitos casos, o analisador lxico retorna ao analisador sinttico o

    nome do token e um valor de atributo que descreve o lexema representado pelo token. O

    nome do token influencia as decises durante a anlise sinttica, enquanto o valor do

    atributo influencia a traduo dos tokens aps o reconhecimento sinttico.

    Normalmente as informaes sobre um identificador (associa muitas

    informaes ao token) so mantidas na tabela de smbolos. Assim, o valor de atributos

    apropriado para um identificador um apontador para a sua entrada na tabela de

    smbolos.

    Em certos pares (operadores, pontuao e palavras chave) no h necessidade de

    um valor de atributo.

    Um compilador tpico armazena uma cadeia de caracteres representando uma

    constante e como valor de atributo um apontador para essa cadeia.

    Erros lxicos difcil para um analisador lxico saber, sem o auxlio de outros componentes,

    que existe um erro no cdigo fonte.

    Por exemplo, um analisador lxico no tem como saber se fi a palavra-chave

    if escrita errada ou um identificador de funo no declarada. Como fi um lexema

    vlido para o token id, o analisador lxico precisa retornar o token id ao analisador

    sinttico e deixar que alguma outra fase do compilador trate o erro devido

    transposio das letras.

    O processo de varredura As unidades lgicas geradas pela varredura so denominadas marcas (tokens).

    As marcas so entidades lgicas, usualmente definidas como um tipo enumerado. typedef enum {

    if, then, else, plus, minus, num, id,...

    } TokenType;

    Em uma linguagem sem tipos enumerados, como em C, temos que definir as

    marcas diretamente como valores numricos simblicos. # define IF 256

    # define THEN 257

    # define ELSE 258

    Esses nmeros comeam em 256 para evitar confuso com valores numricos da

    tabela ASCII.

  • Compiladores 3

    http://erinaldosn.wordpress.com

    Um sistema de varredura deve computar pelo menos tantos atributos de uma

    marca quanto necessrio para possibilitar a continuidade do processamento. Como o

    sistema de varredura precisar possivelmente computar diversos atributos para cada

    marca, frequentemente til coletar todos os atributos em um nico tipo de dado

    estruturado, denominado registro marca (TokenRecord).

    Esse registro poderia ser declarado em C como: typedef struct {

    TokenType tokenval;

    char * stringval;

    int numval;

    } TokenRecord;

    Um arranjo mais comum o sistema de varredura retornar apenas o valor da

    marca e colocar os outros atributos em variveis que possam ser acessadas por outras

    partes do compilador.

    A varredura no converte todo o programa fonte em uma sequncia de tokens de

    uma vez. A varredura ocorrer sob o controle de uma analisador sinttico, retornando a

    marca seguinte demandada por meio de uma funo com a seguinte declarao em C: TokenType getNextToken(void);

    A funo getNextToken retornara a prxima marca fornecida, bem como

    computadr aributos adicionais, como o valor em caracteres da marca. A cadeia de

    caracteres de entrada geralmente armazenada em um repositrio ou fornecida pelos

    recursos de entrada do sistema.

    Exemplo: considere a seguinte linha de cdigo fonte em C: a[index] = 4 + 2;

    Suponha que essa linha de cdigo seja armazenada em um repositrio de

    entrada, com o prximo caractere de entrada indicado pela seta:

    a [ i n d e x ] = 4 + 2

    A ativao de getNextToken precisar saltar o quatro brancos seguintes,

    reconhecer a cadeia de caracteres a como a prxima marca, e retornar o valor de marca

    ID como prxima marca.

    a [ i n d e x ] = 4 + 2

    Uma chamada subsequente de getNextToken iniciar o reconhecimento a partir

    do caractere de colchete esquerda.

    Bufferes de entrada Devido quantidade de tempo necessria para processar caracteres e o grande

    nmero de caracteres que precisam ser processados durante a compilao de um

    programa fonte grande, foram desenvolvidas tcnicas especializadas de buffering para

    reduzir o custo exigido no processamento em um nico caractere de entrada.

    Um esquema importante envolve dois bufferes que so recarregados

    alternadamente.

    E = M * C * * 2 EOF

    forward

    lexemeBegin

  • Expresses Regulares

    http://erinaldosn.wordpress.com

    Cada buffer possui o mesmo tamanho N, e N normalmente corresponde ao

    tamanho de um bloco de disco (4096 bytes).

    Usando um sistema de leitura do sistema, podemos ler N caracteres para um

    buffer. Se restarem menos de N caracteres no arquivo de entrada, ento um caractere

    especial, representado por eof, marca o fim do arquivo fonte.

    So mantidos dois apontadores para a entrada:

    lexemeBegin marca o incio do lexema corrente;

    forward l adiante, at que haja casamento de padro

    Uma vez que o prximo lexema determinado, forward configurado para

    apontar para o seu ltimo caractere direita, e lexemeBegin configurado para apontar

    para o caractere imediatamente aps o lexema recm-encontrado.

    Sentinelas Se usarmos o esquema de pares de buffer precisaremos verificar, sempre que

    avanarmos o apontador forward, se o movemos para fora de um dos buffers; nesse

    caso tambm precisaremos recarregar o outro buffer.

    Para cada caractere lido fazemos dois testes: um para o fim do buffer e o outro

    para determinar qual caractere foi lido.

    Sentinela um caractere especial que no pode fazer parte do programa fonte, e

    uma escolha natural o caractere de fim de arquivo, eof.

    E = M * EOF C * * 2 EOF EOF

    forward

    lexemeBegin switch (* forward++) {

    case eof:

    if (forward est no fim do primeiro buffer){

    recarrega segundo buffer;

    forward = incio do segundo buffer;

    }

    else if (forward est no fim do segundo buffer){

    recarrega primeiro buffer;

    forward = incio do primeiro