Análise Léxica

Num compilador, a análise linear é chamada de análise léxica ou esquadrinhamento (scanning). Por exemplo, na análise léxica, os caracteres no enunciado de atribuição:

montante := depósito_inicial + taxa_de_juros * 60

Poderiam ser agrupados nos seguintes tokens:

1. O identificador montante

2. O símbolo de atribuição :=

3. O identificador depósito_inicial

4. O sinal de adição

5. O identificador taxa_de_juros

6. O sinal de multiplicação

7. O número 60

Os espaços que separam os caracteres desses tokens seriam normalmente eliminados durante a análise léxica.

Análise Sintática

A análise hierárquica é chamada de análise gramatical ou análise sintática. Envolve o agrupamento dos tokens do programa fonte em frase gramaticais, que são usadas pelo compilador, a fim de sintetizar a saída.

Usualmente, as frases gramaticais do programa fonte são representadas por uma árvore gramatical, tala como a mostrada na Fig. 1.4.

Na expressão depósito_inicial + taxa_de_juros * 60, a frase taxa_de_juros * 60 é uma unidade lógica, porque as convenções usuais das expressões aritméticas nos dizem que a multiplicação é realizada antes da adição.

Como a expressão depósito_inicial + taxa_de_juros é seguida por um * não é agrupada numa única frase, na Fig. 1.4.

A estrutura hierárquica de um programa é usualmente expressa por regras recursivas. Por exemplo, poderíamos ter as seguintes regras como parte da definição de expressões:

1. Qualquer identificador é uma expressão.

2. Qualquer número é uma expressão.

3. Se expressão1 e expressão2 são expressões, então também o são:

expressão1 + expressão2

expressão1 * expressão2

(expressão1)

As regras 1 e 2 são as regras base (não recursivas), enquanto 3 define expressões em termos dos operadores aplicados às demais expressões.

Então, pela regra 1 depósito_inicial e taxa_de_juros são expressões. Pela regra 2, 60 é uma expressão, enquanto que, pela regra 3, podemos primeiro inferir que taxa_de_juros * 60 é uma expressão e, finalmente, que depósito_inicial + taxa_de_juros * 60 também o é.

Similarmente, muitas linguagens definem recursivamente enunciados tais como:

1. Se identificador, é um identificador e expressão2 uma expressão então:

identificador1 := expressão2

é um enunciado.

2. Se expressão1, é uma expressão e comando2 é um enunciado, então:

while(expressão1) do comando2

if(expressão1) then comando2

são enunciados.

A divisão entre a análise léxica e a sintática é um tanto arbitrária. Usualmente, escolhemos uma que simplifique a tarefa global de análise.

Um fator determinante na divisão é o de uma construção da linguagem fonte ser inerente recursiva ou não.

As construções léxicas não requerem recursão, enquanto as sintáticas frequentemente a exigem.

As gramáticas livres de contexto são uma formalização das regras recursivas que podem ser usadas para guiar a análise sintática.

Por exemplo, a recursão não é requerida para reconhecer identificadores, que são tipicamente cadeias de letras e dígitos, começando por uma letra.

Reconheceríamos normalmente os identificadores por um simples esquadrinhamento do fluxo de entrada, aguardando até que um caractere, que não uma letra ou um dígito, fosse encontrado, e agrupado, num token tipo identificador, todas as letras e dígitos coletados até aquele ponto.

Os caracteres, dessa forma agrupados, seriam registrados numa tabela, chamada tabela de símbolos, e removidos da entrada, de tal forma que o processamento do próximo token pudesse se iniciar.

Por outro lado, esse tipo de esquadrinhamento linear não é poderoso o suficiente para analisar expressões ou enunciados.

Por exemplo, não podemos fazer corresponder apropriadamente os parênteses nas expressões, ou o begin e o end nos enunciados, sem criar algum tipo de estrutura hierárquica ou aninhamento na entrada.

A árvore gramatical da Fig. 1.4 descreve a estrutura sintática da entrada. Uma representação interna mais comum dessa estrutura sintática é dada pela árvore sintática na Fig. 15(a).

Uma árvore sintática é uma representação condensada da árvore gramatical, na qual os operadores figuram como nós interiores e os operandos de um operador são os filhos do nó daquele operador.

Livro fonte: https://github.com/germanoa/compiladores/blob/master/doc/ebook/Compiladores%20Principios%2C%20Tecnicas%20e%20Ferramentas%20-%20Alfred%20V.%20Aho.pdf

Para enviar seu comentário, preencha os campos abaixo:

Deixe um comentário

*

Seja o primeiro a comentar!