Você está na página 1de 6

Nome: Luciano Antunes de Farias RA 2008033591

Codificação

#include<stdlib.h>
#include<stdio.h>

struct Reg{
char nome[80];
char sobreNome[80];
int idade;
float salario;
}cad;

struct Reg mat[4];


void QuickSort(struct Reg *vet, int inicio, int fim){
int x=0;
struct Reg aux;
struct Reg pivo= vet[inicio]; /*recebe o primeiro elemento do vetor*/
int ps= inicio; /*recebe a indexação do inicio do vetor*/
int pi= fim; /*recebe a indexação do fim do vetor*/
while(ps < pi){
while(strcmp(vet[pi].sobreNome,pivo.sobreNome) < 0 && pi > 0){
pi--;
}

while((strcmp(vet[ps].sobreNome,pivo.sobreNome) > 0 ||
strcmp(vet[ps].sobreNome,pivo.sobreNome) == 0) && (ps < pi)){
ps++;
}

if(ps == pi){
aux = vet[inicio];
vet[inicio]= vet[ps];
vet[ps]= aux;
QuickSort(vet, inicio, ps-1);
QuickSort(vet, ps+1, fim);
}
else{
aux = vet[pi];
vet[pi] = vet[ps];
vet[ps] = aux;
}
}
}

main(){

struct Reg tmp;//matriz que recebe os dados

FILE *out;// variavel pra fazer a leitura


out = fopen("bd.txt","r");

char n[80],s[80];// n = nome, s = sobrenome


int i,con = 0;//i = idade, con = contador
float sala;//sala = salario

printf("Antes...\n\n");
while(fscanf(out,"%s %s %d %f",n,s,&i,&sala) != EOF){// pega os dados do arquivo e
carrega em mat[]
printf("%s",n);
printf("\t%s",s);
printf(" \t%d",i);
printf("\t%f",sala);
printf("\n");

strcpy(mat[con].nome,n);
strcpy(mat[con].sobreNome,s);
mat[con].idade = i;
mat[con].salario = sala;
con++;

printf("\n");
fclose(out);

printf("Depois...\n\n");
//--------------------------------------------------------------ordena

FILE *file;// variavel para gravar


file = fopen("bd.txt","w");

int t = 0;

QuickSort(mat,0,10);

//imprime na tela resultado


t = 0;
while(t < con){
printf("%s",mat[t].nome);
printf("\t%s",mat[t].sobreNome);
printf(" \t%d",mat[t].idade);
printf("\t%f\n",mat[t].salario);
t++;
}

printf("\n\n");
t = 0;
while(t < con){
fprintf(file,"%s\t%s \t%d\t
%f\n",mat[t].nome,mat[t].sobreNome,mat[t].idade,mat[t].salario);
t++;
}

fclose(file);

system("pause");
}
Definição de Analise Léxica

Análise léxica é o processo de analisar a entrada de linhas de caracteres (tal como o código-
fonte de um programa de computador) e produzir uma seqüência de símbolos chamado
"símbolos léxicos" (lexical tokens), ou somente "símbolos" (tokens), que podem ser
manipulados mais facilmente por um parser (leitor de saída). O componente do compilador
responsável pela execução desse processo é conhecido como Analisador léxico.

A análise léxica é a forma de verificar determinado alfabeto. Quando analisamos uma palavra,
podemos definir através da análise léxica se existe ou não algum caracter que não faz parte do
nosso alfabeto, ou um alfabeto inventado por nós.

É a primeira etapa do processo de compilação e seu objetivo é dividir o código fonte em


símbolos, preparado-o para a Análise Sintática. Neste processo pode-se destacar três
atividades como fundamentais:

 Extração e classificação dos tokens;


 Eliminação de delimitadores e comentários;
 Recuperação de Erros.

O analisador léxico funciona de duas maneiras:

 Primeiro estado da análise: A primeira etapa lê a entrada de caracteres, um de cada


vez, mudando o estado em que os caracteres se encontram. Quando o analisador encontra
um caracter que ele não identifica como correto, ele o chama de "estado morto" então, ele
volta à última análise que foi aceita e assim tem o tipo e comprimento do léxico válido.

Um léxico, entretanto, é uma única lista de caracteres conhecidas de ser um tipo correto. Para
construir um símbolo, o analisador léxico necessita de um segundo estado.

 Segundo estado da análise: Nesta etapa são repassados os caracteres do léxico para
produzir um valor. O tipo do léxico combinado com seu valor é o que adequadamente
constitui um símbolo, que pode ser dado a um parser. (Alguns símbolos tais como
parênteses não têm valores, e então a função da análise não pode retornar nada).

A análise léxica escreve um parser muito mais fácil. Em vez de ter que acumular, renomeia
seus caracteres individualmente. O parser não mais se preocupa com símbolos e passa a
preocupar-se só com questões de sintática. Isto leva a eficiência de programação, e não
eficiência de execução. Entretanto, desde que o analisador léxico é o subsistema que deve
examinar cada caracter único de entrada, podem ser passos intensivos e o desempenhos se
torna crítico, pode estar usando um compilador.

As desvantagens da Análise Léxica são o tratamento de dados em branco, formato fixo de


entrada e a inexistência de palavras reservadas, em determinadas linguagens.

Construção do autómato (algoritmo) A = (Q, T, M, q0, H):

q ¬ estado_inicial
Repetir
q ¬ delta (q, c)
Se (q Ï H) { H = conj. estados finais do autómato }
Então
guardar (c)
ler (c)
Até (q Î H)
Código_símbolo ¬ f (q)

Erros

mensagem_erro (tipo, classe, código, símbolo, posição)


caso tipo seja
1 : escrever (‘ERRO FATAL ’);
2 : escrever (‘ERRO GRAVE ’);
3 : escrever (‘AVISO ’);
caso classe seja
1 : escrever (‘NA ANÁLISE LÉXICA ‘);
2 : escrever (‘NA ANÁLISE SINTÁCTICA ‘);
3 : escrever (‘NA ANÁLISE SEMÂNTICA ‘);
Escrever (‘NO SÍMBOLO ‘, símbolo, ‘NA POSIÇÃO ‘, posição.linha, posição.coluna);
caso código seja
1:…
2:…

Fim

 Consiste em um conjunto de procedimentos, um para cada não terminal da


gramática

1. void A(){
2. escolheProdução-A(); // A:: X1,X2,...Xk
3. for (i=1 até k){
4. if (Xi é um não terminal)
5. executa Xi();
6. else if (Xi igual a símbolo de entrada a)
7. avança na entrada para o próximo símbolo;
8. else /*ocorre um erro*/
9. }
10. }

Análise Semântica
Assegura que um programa fonte segue as convenções semânticas da linguagem.
A verificação pode ser estática ou dinâmica, se realizada durante a compilação ou
execução.
Exemplos de verificação estática:
- Verificação de tipos
- Verificação de fluxo de controle. Ex: break fora de um laço
- Verificação de unicidade de identificadores (identificadores redeclarados).
Sistema de Tipos
A definição de uma linguagem de tipos inclui:
- Quais os tipos válidos
- Regras para atribuir tipos às construções
- Regras para comparar tipos
Normalmente,
- Cada expressão tem um tipo
- O tipo depende das expressões elementares
Ex: E → ^E (E designa o tipo X e ^E designa um apontador para X)
Expressões de tipo
Um tipo é representado por uma expressão de tipo que é uma sentença de uma
sublinguagem de tipos. Uma expressão de tipo é um tipo básico ou é formada aplicando
um
operador chamado construtor de tipo a outras expressões de tipo.
Uma Sublinguagem de Tipos
1) Tipos básicos : boolean, char, integer, real. Tipos básicos especiais: tipo error (erro
de
tipo) e void (ausência de valor)
2) Construtores de tipos:
Arrays ⇒ array(intervalo, tipo)
ex: Array[1..10] of integer ⇒ array([1..10],integer)Produto ⇒ T1 * T2 onde T1 e T2
são expressões de tipo (p.ex. lista de argumentos
em funções). Ex: int X (int, float) ⇒ int * float
Record ⇒ reg(E1*E2*E3*...*En) onde
Ei = (nome * tipo)
ex: Record
nome:array[1..20] of char;
fone:integer;
end;
Reg ( ( nome * array([1..20],char))*(fone*integer))
Apontadores : apont (tipo apontado)
ex: p = ^nodo; ⇒ apont(nodo)
Identificadores : podem ser dados nomes a tipos.
ex: type nodo = record
id:string[10];
info: Tinfo;
end;
type Tinfo : integer;
Escreva expressões de tipos para os seguintes tipos:
a) Um array de ponteiros para reais, onde os índices vão de 1 a 100.
b) Um array bidimensional de inteiros (i.e. um array de arrays) com linhas
de 0 a 9 e colunas de -10 a 10
a) array([1..100],apont(real))
b) array([0..9],array([-10..10],integer))
Funções e Procedimentos
Function X(a:char; b:real):real; ⇒ char*real → real
Procedure Y(a:real; b:char; c:integer) ⇒ real * char * integer
Escreva uma expressão de tipos para uma função cujo domínio sejam funções de
inteiros para pointers para inteiros e cujo tipo sejam records consistindo de um inteiro e
de
um caracter.
(integer → apont(integer)) → reg((campo1*integer)*(campo2*char))
O tipo pode ser representado na forma de uma árvore (como as construções da
linguagem)

Você também pode gostar