Un analizador sintáctico (en inglés parser) es una de las partes de un compilador que transforma su entrada en un árbol de derivación.
El análisis sintáctico convierte el texto de entrada en otras estructuras (comúnmente árboles), que son más útiles para el posterior análisis y capturan la jerarquía implícita de la entrada. Un analizador léxico crea tokens de una secuencia de caracteres de entrada y son estos tokens los que son procesados por el analizador sintáctico para construir la estructura de datos, por ejemplo un árbol de análisis o árboles de sintaxis abstracta.
Archivo .txt
lado1=5; lado2=86; base=105; color2=200; calculo=lado1+lado2-base+300-100/color2-4;
Salida :: Q-Compiler ::
lado1=5; lado2=86; base=105; color2=200; calculo=-3.07;
q-compiler.cpp
/**
*
* Desarrollador: Guillermo Quezada de Pedro
* Sem: 6 Grupo "F"
* Profesor: M.C. Benjamin Iglesias Cortes
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sstream>
#include <iostream>
#define MEM_LINES 128
#define MEM_VARIABLES 128
#define MEM_OPERATIONS 128
using namespace std;
class Compilation
{
FILE *_file;
long lSize;
char *buffer;
int char_count;
size_t result;
char *q_buffer;
int q_count;
int _line;
int n_digit;
struct lines
{
char line_data[MEM_VARIABLES];
int len;
}line[MEM_LINES];
struct asignations
{
char variable[MEM_VARIABLES];
float value;
int len;
int n_operators;
}asignation[MEM_LINES];
struct operations
{
char variable[MEM_VARIABLES];
char _operator;
float value;
int line;
}operation[MEM_OPERATIONS];
public:
void file_read(char file_name[])
{
_file = fopen(file_name,"rb");
if (_file==NULL) {fputs ("File error",stderr); exit (1);}
fseek(_file,0,SEEK_END);
lSize = ftell(_file);
rewind(_file);
buffer = (char*)malloc(sizeof(char)*lSize);
result = fread(buffer,1,lSize,_file);
fclose (_file);
}
void file_compress()
{
q_count = 0;
q_buffer = (char*)malloc(sizeof(char)*lSize);
for(char_count = 0;char_count < lSize;char_count++)
{
if(buffer[char_count] != ' ' )
{
q_buffer[q_count] = buffer[char_count];
q_count +=1;
}
}
free(buffer);
}
void compile_lines()
{
memset( &line, 0, sizeof(line) );
int _char;
int _data;
_line = 0;
_data = 0;
for(_char = 0; _char < q_count; _char++)
{
line[_line].line_data[_data] = q_buffer[_char];
_data +=1;
if( q_buffer[_char] == ';' )
{
line[_line].len = strlen(line[_line].line_data);
_line +=1;
_data = 0;
}
}
free(q_buffer);
}
void compile_variables_assignation()
{
memset( &asignation, 0, sizeof(asignation) );
int _char;
int i;
_char = 0;
for(i=0;i < _line;i++)
{
while(line[i].line_data[_char] != '=')
{
asignation[i].variable[_char] = line[i].line_data[_char];
_char +=1;
};
asignation[i].len = strlen(asignation[i].variable);
_char = 0;
}
}
void compile_variables_operation()
{
memset( &operation, 0, sizeof(operation) );
int i; //Numero de Linea
int len; //Longitud de linea
int k; //Lector de caracteres en la linea
int _digit; //Posicion de nuevo valor en la linea digit
int _char;
int count_as; //Variables asignacion indirectas
len = 0;
n_digit = 0;
_digit = 0;
count_as = 0;
for(i=0;i < _line; i++)
{
_char = asignation[i].len+1;
len = line[i].len;
for(k=0; k < len; k++)
{
if (isdigit(line[i].line_data[_char]))
{
operation[n_digit].variable[_digit] = line[i].line_data[_char];
operation[n_digit].line = i;
_digit +=1;
_char+=1;
}
else if(isalpha(line[i].line_data[_char]))
{
operation[n_digit].variable[_digit] = line[i].line_data[_char];
operation[n_digit].line = i;
_digit +=1;
_char+=1;
}
else
{
if(line[i].line_data[_char] != ';')
{
operation[n_digit+1]._operator = line[i].line_data[_char];
}
n_digit +=1;
_digit = 0;
_char +=1;
}
if(_char == len) k = len;
}
}
//ASCII TO INTEGER
for(i = 0; i < n_digit; i++)
{
operation[i].value = atoi(operation[i].variable);
}
//Operaciones Algebraicas Basicas(Lineal)
float total;
int n_operator;
total = 0;
n_operator = 0;
for(i = 0; i < _line+1; i++)
{
for(k = 0; k < n_digit; k++)
{
if(operation[k].line == i)
{
if(isalpha(operation[k].variable[0]))
{
if(strcmp(operation[k].variable,asignation[k].variable))
{
operation[k].value = asignation[count_as].value;
count_as += 1;
}
}
n_operator +=1;
asignation[i].n_operators = n_operator;
if(operation[k]._operator == '\0')
{
total += operation[k].value;
asignation[i].value = total;
}
if(operation[k]._operator == '+')
{
total += operation[k].value;
asignation[i].value = total;
}
if(operation[k]._operator == '-')
{
total -= operation[k].value;
asignation[i].value = total;
}
if(operation[k]._operator == '*')
{
total *= operation[k].value;
asignation[i].value = total;
}
if(operation[k]._operator == '/')
{
total /= operation[k].value;
asignation[i].value = total;
}
}
else
{
total = 0;
n_operator = 0;
}
}
}
}
void q_file_make(char file_name[])
{
//Errores de visualizacion de SyntaxHighlighter
//Funcion completa ->
//https://github.com/torukMnk/Q-parser
}
};
int main(void)
{
Compilation com;
char option;
char name[16];
do{
//system("cls"); //Windows
system("clear"); //Linux
cout<<":: Q Compiler ::"<<"\n";
cout<<"Nombre del archivo: ";
cin>>name;
cout<<'\n';
com.file_read(name);
com.file_compress();
com.compile_lines();
com.compile_variables_assignation();
com.compile_variables_operation();
com.q_file_make(name);
cout<<"Desea compilar otro archivo: (Y/N): ";
cin>>option;
option = toupper(option);
}while(option != 'N');
}
No hay comentarios:
Publicar un comentario