1. UNIVERSIDADE DO ESTADO DO RIO GRANDE DO NORTE
CAMPUS DE NATAL
Compiladores
Analisador léxico
Natal/Dezembro/2011
2. UNIVERSIDADE DO ESTADO DO RIO GRANDE DO NORTE - UERN
Campus de Natal
2011
Construção de um analisador Léxico da linguagem C++
Componentes: Acássio dos Anjos
Helder Fabrício
Rafael Jullian
Thaise Regina
Natal/Dezembro/2012
3. UNIVERSIDADE DO ESTADO DO RIO GRANDE DO NORTE - UERN
Campus de Natal
2011
SUMÁRIO
1. Linguagem ....................................................................................................................4
2. Palavras-Chave da linguagem.....................................................................................7
3. AFN’s e AFD’s ..............................................................................................................8
3. Implementação.............................................................................................................13
4. 1. Linguagem
A linguagem de programação é um conjunto de instruções e uma série de convenções
lexical projetado especificamente para orientar computadores o que fazer.
Ao escolher uma linguagem de programação para fazer um projeto, muitas
considerações diferentes podem ser tomadas. Primeiro, é preciso decidir o que é conhecido
como o nível da linguagem de programação. O nível determina o quão perto do hardware a
linguagem de programação é. Nas línguas de nível inferior, as instruções são escritas
pensando-se diretamente na interface de interação com hardware, enquanto que em
linguagens de "alto nível" um código mais abstrato (ou conceitual) é escrito.
Geralmente, o código de alto nível é mais portátil, o que significa que pode trabalhar
em mais máquinas diferentes, com um menor número de modificações, e um maior número
de reutilizações, enquanto que uma linguagem de baixo nível essa portabilidade é limitada
pelas peculiaridades do hardware que foi escrito para. No entanto, a vantagem de código de
baixo nível é que é geralmente mais rápido devido ao fato de que ele é realmente escrito
aproveitando as possibilidades de uma máquina específica.
A maior ou menor grau de programação deve ser escolhido para um projeto específico,
dependendo do tipo de programa que está sendo desenvolvido. Por exemplo, quando um
driver de hardware é desenvolvido para um sistema operacional, obviamente, um nível muito
baixo é usado para a programação. Enquanto que quando grandes aplicações são
desenvolvidas geralmente um nível mais elevado é escolhido, ou uma combinação de peças
críticas escritas em linguagens de baixo nível e outros nas mais altas.
Apesar de existirem línguas que são claramente pensadas para serem de baixo nível,
como ASSEMBLY, cujos conjuntos de instruções são adaptados para cada máquina o código
é feito para e outros idiomas são inerentemente as linguagens de nível alto, como o Java, que
5. é projetado para ser totalmente independente de a plataforma onde vai correr. A linguagem
C++ está em uma posição intermediária, uma vez que pode interagir diretamente com o
hardware quase sem limitações, e pode usá-la de maneira bem abstrata pelas camadas mais
baixas e funciona como uma das mais poderosas linguagens de alto nível.
A linguagem C++ apresenta algumas características de linguagem de alto nível que
podem ser bastante atraentes para os usuários:
• Programação orientada a objeto
A possibilidade de orientar a programação de objetos permite ao programador criar
aplicações a partir de um ponto de vista mais como uma comunicação entre objetos em vez de
uma seqüência estruturada de código. Além disso, permite uma maior reutilização de código
de uma maneira mais lógica e produtiva.
• Portabilidade
Você pode praticamente compilar o mesmo código C++ em quase qualquer tipo de
sistema de computador e do funcionamento sem fazer qualquer alteração. C++ é o mais
utilizado e a linguagem de programação mais portátil no mundo.
• Brevidade
Um código escrito em C++ é muito curto em comparação com outras línguas, desde o
uso de caracteres especiais é preferível às palavras-chave, poupando algum esforço para o
programador (e prolongar a vida de nossos teclados!).
• Programação modular
Corpo de um aplicativo em C++ pode ser composto de vários arquivos fontes de
código que são compilados separadamente e depois interligados. Economizando tempo, uma
vez que não é necessário recompilar a aplicação completa ao fazer uma única alteração, mas
6. apenas o arquivo que a contém. Além disso, esta característica permite linkar código C++
com código produzido em outras línguas, como o Assembler ou C.
• Compatibilidade com C
C++ é compatível com a linguagem C. Qualquer código escrito em C pode ser
facilmente incluído em um programa C++, sem fazer qualquer alteração.
• Velocidade
O código resultante de uma compilação C++ é muito eficiente, devido certamente à
sua dualidade como linguagem de alto nível e de baixo nível e ao tamanho reduzido da
própria linguagem.
7. 2. Palavras-chave da linguagem
São palavras padrão da linguagem que são utilizadas para a estruturação do código,
referente às suas operações, sejam elas rotinas cíclicas da linguagem (como imprimir valores)
ou rotinas matemáticas e booleanas.
• Booleanas: diz respeito a palavras usadas em operações booleanas.
ERbooleanas = (and + or + xor + not)
• Tipos de dados: diz respeito aos tipos de dados que são reconhecidos pela linguagem e
que são utilizados para resolver os problemas algorítmicos.
ERtiposdedados = (char + int + bool + float + double + string + mystring)
• Operadores: diz respeito ao conjunto dos operadores aritméticos, incremento,
decremento, aritmético e atribuição, relacional.
ERoperadores = (+ - + = + * + / + %)
• Entrada e saída: diz respeito ao conjunto de palavras chaves que orientam o código a
ler ou imprimir dados (fornecidos pelo usuário)
ERinput/output = (int + cin + cout + getline + stringstream)
• Controle: diz respeito ao conjunto de palavras-chave usadas para orientar no controle
de certos trechos do código e limitar a fazer operações obedecendo à alguns critérios.
ERcontrol= (if + eles + eles if + while + do + for + continue + break + goto + exit + switch +
case +default + catch + )
• Caracteres especiais: diz respeito aos caracteres especiais utilizados para diferentes
situações rotineiras da linguagem, como comentários, incluir parágrafo, incluir quebra
de linha, incluir espaço, declaração de bibliotecas, etc.
ERcaracteres-especiais = ( / + * + // + ; + , + : + ( + ) + [ + ] + { + } + # + n + “ + ” +
a + t + ' + ” + v + r + f + b)
• Funções: diz respeito as palavras usadas para dividir o código em tarefas menores,
viabilizando a reutilização das operações.
ERfunções = (include + void + system + pause + main + getch + puts + return + cout +
cin)
8. 3. AFN’s e AFD’s
AFN: Um autômato finito não determinístico é uma
onde Q e Σ são conjuntos não
• Q é o conjunto de estados
• Σ é o alfabeto;
• q0 é o estado inicial;
• F é o conjunto de estados válidos (ou de aceitação)
• 2Q
significa o conjunto das partes de Q
AFD: Um autômato finito não determinístico é uma
M = (S, Σ, T, s, A
• um conjunto finito de estados (
• um conjunto finito de símbolos chamado de al
• uma função de transição (
• um estado inicial (s
• um conjunto de estados f
Um autômato finito não determinístico é uma quíntupla:
são conjuntos não-vazios, , e
é o conjunto de estados;
;
é o conjunto de estados válidos (ou de aceitação);
nifica o conjunto das partes de Q.
Um autômato finito não determinístico é uma quíntupla:
A)
um conjunto finito de estados (S)
um conjunto finito de símbolos chamado de alfabeto (Σ)
uma função de transição (T : S × Σ → S)
∈ S)
um conjunto de estados finais(A ⊆ S)
13. 4. Implementação
Main: onde está especificada a localização do arquivo e é feita a leitura de cada palavra para
a futura comparação dentro das classes. Caso o arquivo não esteja no local especificado é
retornada uma mensagem de erro.
package compilador;
import java.io.*;
public class Compilador {
public static void main(String[] args) {
palavras_chaves p_c = new palavras_chaves();
caracteres_especiais c_e = new caracteres_especiais();
tipos_de_dados t_d_d = new tipos_de_dados();
operadores op = new operadores();
funcoes fc = new funcoes();
forma_identificador f_i = new forma_identificador();
tokens valido = new tokens();
tokens invalido = new tokens();
int linhas = 0;
String[] vetorlinha;
try
{
BufferedReader entrada = new BufferedReader(new
FileReader("C:UsersAcássioDocumentsNetBeansProjectsCompila
dorsrccompiladorarquivo.txt"));
while(entrada.ready())
{
vetorlinha = entrada.readLine().split(" ");
linhas++;
for(int x=0;x<vetorlinha.length;x++){
if(p_c.lexico(vetorlinha[x]))
{
valido.token.add(vetorlinha[x]);
valido.linha.add(String.valueOf(linhas));
}else if(c_e.lexico(vetorlinha[x]))
{
valido.token.add(vetorlinha[x]);
valido.linha.add(String.valueOf(linhas));
}else if(t_d_d.lexico(vetorlinha[x]))
{
valido.token.add(vetorlinha[x]);
valido.linha.add(String.valueOf(linhas));
}else if(op.lexico(vetorlinha[x]))
{
valido.token.add(vetorlinha[x]);
valido.linha.add(String.valueOf(linhas));
16. Classe funções: é feita a comparação com cada um dos operadores determinados pelas nossas
expressões regulares.
package compilador;
import java.util.ArrayList;
public class operadores {
ArrayList<String> operador = new ArrayList();
public operadores()
{
operador.add("::");
operador.add("++");
operador.add("--");
operador.add(".");
operador.add("->");
operador.add("+");
operador.add("-");
operador.add("!");
operador.add("~");
operador.add("&");
operador.add(".*");
operador.add("*");
operador.add("->*");
operador.add("/");
operador.add("%");
operador.add("<<");
operador.add(">>");
operador.add("<");
operador.add("<=");
operador.add(">");
operador.add(">=");
operador.add("==");
operador.add("!=");
operador.add("^");
operador.add("&&");
operador.add("=");
operador.add("+=");
operador.add("-=");
operador.add("<<=");
operador.add(">>=");
operador.add("&=");
operador.add("^=");
}
public boolean lexico(String token)
{
return operador.contains(token);
}
}
17. Classe funções: é feita a comparação com cada um das palavras-chave determinados pelas
nossas expressões regulares.
package compilador;
import java.util.ArrayList;
public class palavras_chaves {
ArrayList<String> palavra = new ArrayList();
public palavras_chaves()
{
palavra.add("and");
palavra.add("default");
palavra.add("template");
palavra.add("and_eq");
palavra.add("delete");
palavra.add("not");
palavra.add("this");
palavra.add("else");
palavra.add("operator");
palavra.add("true");
palavra.add("bitand");
palavra.add("enum");
palavra.add("or");
palavra.add("try");
palavra.add("typedef");
palavra.add("export");
palavra.add("private");
palavra.add("typeid");
palavra.add("break");
palavra.add("extern");
palavra.add("case");
palavra.add("catch");
palavra.add("false");
palavra.add("public");
palavra.add("union");
palavra.add("for");
palavra.add("goto");
palavra.add("class");
palavra.add("if");
palavra.add("sizeof");
palavra.add("while");
palavra.add("continue");
palavra.add("struct");
palavra.add("new");
palavra.add("switch");
palavra.add("include");
palavra.add("stdio");
}
public boolean lexico(String token)
{
return palavra.contains(token);
}
}
18. Classe funções: é feita a comparação com cada um das palavras-chave dos tipos de dados
determinados pelas nossas expressões regulares.
package compilador;
import java.util.ArrayList;
public class tipos_de_dados {
ArrayList<String> dados = new ArrayList();
public tipos_de_dados()
{
dados.add("int");
dados.add("void");
dados.add("float");
dados.add("double");
dados.add("char");
dados.add("bool");
dados.add("wchar_t");
dados.add("short");
dados.add("signed");
dados.add("unsigned");
dados.add("long");
}
public boolean lexico(String token)
{
return dados.contains(token);
}
}
package compilador;
import java.util.ArrayList;
public class tokens {
ArrayList<String> token = new ArrayList();
ArrayList<String> linha = new ArrayList();
}
package compilador;
public class forma_identificador {
char[] maiusculas =
{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q'
,'r','s','t','u','v','w','x','y','z'};
char[] minusculas =
{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q'
,'R','S','T','U','V','W','X','Y','Z'};
char[] numeros = {'0','1','2','3','4','5','6','7','8','9'};
char[] tokene;
int valido=0;
public boolean lexico(String token)
{