AYUDA CON UN ANALIZADOR SEMANTICO
HOLA PRIMERO QUE NADA AGRADEZCO EL TIEMPO QUE SE TOMAN PARA LEER ESTE POST Y ESPERO ME PUEDAN DAR UNA PEQUEÑA ORIENTACIÓN DE COMO SOLUCIONAR MI PROBLEMA. EL DETALLE ES QUE ESTOY CURSANDO LA MATERIA DE LENGUAJES Y AUTÓMATAS 2 DONDE SE ME PIDE DESARROLLAR UN COMPILADOR QUE LLEVE ACABO LAS TAREAS DE ANÁLISIS LÉXICO SINTÁCTICO Y SEMÁNTICO ESTE ULTIMO ES QUE ME A REPRESENTADO UN PROBLEMA YA QUE NO LOGRO COMPRENDER COMO HACERLO Y ME MANTIENE ATORADO. PARA REALIZAR DICHOS ANÁLISIS ME SERVÍ DE UTILIZAR LAS HERRAMIENTAS JCUP J LEX LAS CUALES SE ME HICIERON LA FORMA MAS SENCILLAS PARA REALIZAR A CONTINUACIÓN LES PRESENTO LOS DOS ARCHIVOS CON EL FIN DE QUE ALGUIEN ME PUEDA AYUDAR DE ANTE MANO MUCHAS GRACIAS
/*------------------------------ARCHIVO .FELX--------------------------------------*/
import java_cup.runtime.Symbol;
%%
/* segunda parte: declaramos las directivas y los macros */
%class AnalizadorLexico
%public
%full
%unicode
%line
%column
%char
%cup
LineTerminator = \r|\n|\r\n|\n\r
WhiteSpace = {LineTerminator} | [ \t\f]
ValorEntero = 0|[1-9][0-9]*
Comentario = [//] [a-z][a-z]*[0-9]*
Mensaje = [a-z_]*[A-Z_]*
%%
/* OPERADORES Y SIGNOS */
";" {return new Symbol(sym.PCOMA, new token(yycolumn, yyline, yytext()));}
"," {return new Symbol(sym.COMA, new token(yycolumn, yyline, yytext()));}
"(" {return new Symbol(sym.ABRIRPAR, new token(yycolumn, yyline, yytext()));}
")" {return new Symbol(sym.CERRARPAR, new token(yycolumn, yyline, yytext()));}
/* PALABRAS RESERVADAS */
"inicio" {return new Symbol(sym.INICIO, new token(yycolumn, yyline, yytext()));}
"fin" {return new Symbol(sym.FIN, new token(yycolumn, yyline, yytext()));}
"comando" {return new Symbol(sym.COMANDO, new token(yycolumn, yyline, yytext()));}
"hombre" {return new Symbol(sym.HOMBRE, new token(yycolumn, yyline, yytext()));}
"secuestro" {return new Symbol(sym.SECUESTRO, new token(yycolumn, yyline, yytext()));}
"armas" {return new Symbol(sym.ARMAS, new token(yycolumn, yyline, yytext()));}
"codigo" {return new Symbol(sym.CODIGO, new token(yycolumn, yyline, yytext()));}
/* EXPRESIONES */
{ValorEntero} {return new Symbol(sym.VALINT, new token(yycolumn, yyline, yytext()));}
{Comentario} {return new Symbol(sym.COMENT, new token(yycolumn, yyline, yytext()));}
{LineTerminator} {return new Symbol(sym.ENTER, new token(yycolumn, yyline, yytext()));}
{Mensaje} {return new Symbol(sym.MENSAJE, new token(yycolumn, yyline, yytext()));}
{WhiteSpace} {/* ignorar */}
/*-----------------------------------ARCHIVO.CUP-----------------------------------------------*/
import java_cup.runtime.*;
import java.util.ArrayList;
action code {:
ArrayList<Instruccion> instrucciones = new ArrayList();
:}
parser code {:
//esta es la manera en que se puede acceder a un objeto que se genera durante la etapa del parsing
public ArrayList<Instruccion> getInstrucciones(){
return action_obj.instrucciones;
}
@Override
public void syntax_error(Symbol sy) {
token t=(token)sy.value;
done_parsing();
report_error("Error sintáctico cerca de \""+ t.getCadena()+"\" : ["+t.getRow()+" : "+t.getCol()+"]",null);
}
:}
/*---------------------------------TERMINALES------------------------------*/
/*-----------------------------PALABRAS RESERVADAS-------------------------*/
terminal PCOMA,ABRIRPAR,CERRARPAR,INICIO,FIN,HOMBRE,COMANDO,SECUESTRO,ARMAS,CODIGO,ENTER,COMENT, COMA, VALINT;
terminal token MENSAJE;
/*-------------------------------NO TERMINALES----------------------------*/
non terminal instrucciones, programa;
non terminal Instruccion instruccion,hombre,comando,secuestro,armas,codigo;
/*-------------------------------GRAMATICAS-------------------------------*/
start with programa;
/*-----------------------ESTRUCTURA DE PROGRAMA---------------------------*/
programa ::= INICIO ENTER instrucciones ENTER FIN;
/*---------------------DEFINICION DE INSTRUCCIONES--------------------------*/
instrucciones ::= instrucciones ENTER instruccion| instruccion;
instruccion ::= codigo|hombre|secuestro|armas|comando;
codigo ::= CODIGO MENSAJE PCOMA;
hombre ::= HOMBRE MENSAJE PCOMA;
secuestro ::= SECUESTRO MENSAJE PCOMA;
armas ::= ARMAS MENSAJE PCOMA;
comando ::= COMANDO MENSAJE PCOMA;
NOTA EL COMPILADOR EN SU ETAPA FINAL DEBERÍA DE PERMITIR CREAR UNA ORACIÓN COMÚN COMO POR EJEMPLO "HOMBRES ARMADOS CERDA DE LA ESCUELA TAL" Y CAMBIARLO A UN LENGUAJE QUE SOLO UN CIERTO GRUPO PUDIERA DESCIFRARLO
SI ALGUIEN TIENE ALGÚN LINK DONDE EXPLIQUE COMO HACER DICHOS ANÁLISIS SIN LAS HERRAMIENTAS MENCIONADAS TAMBIÉN LO AGRADECERÍA YA QUE QUISIERA VER SI LO PUEDO HACER DESDE 0 Y COMPRENDER MEJOR COMO FUNCIONA UN COMPILADOR.
- Inicie sesión o regístrese para enviar comentarios
Darle seguimientos a Herramientas o has algo nuevo
Segun veo te generan codigo ese codigo tendrias que modificarlo para sacarle la siguiente etapa de tu proyecto. Tienes que investigar con que metodologia o proceso estan haciendo el codigo para que le entiendas mejor.
No conozco bien esas herramientas pero segun veo te hacen el trabajo duro de la programacion, yo te recomendaria de que si quieres entender bien como funciona todo el rollo de hacer un compilador para tu proyecto, lo programes con el Metodo de compiladores de "una sola pasada". cuando haces el lexico y sintactico practicamente el semantico se da solo. y es muy facil cuando le entiendes a la mecanica.
saludos.
LA VERDAD ES QUE QUISIERA
LA VERDAD ES QUE QUISIERA HACERLO TODO YO PERO EL TIEMPO EN LA ESCUELA ME LO IMPIDE, UN QUE SI AGRADECERÍA ALGÚN LINK DONDE PUEDA CHECAR EL MÉTODO DE PROGRAMACIÓN MENCIONADO Y ALGUNOS OTROS AL RESPECTO DE LOS ANALIZADORES EN CUESTIÓN MUCHÍSIMAS GRACIAS DE ANTEMANO
POR QUE ESCRIBES TODO EN
POR QUE ESCRIBES TODO EN MAYUSCULAS? ( parece que estas gritando )
solo es una costumbre que
solo es una costumbre que tengo lo mismo hago con mi escritura cotidiana
Todo en minúsculas?
Oscar es incorrecto, hhle12 no escribe todo en mayúsculas en su código existen minúsculas :P (coscorron)
La idea la tome de un libro.
Aqui hay un enlace del libro que te salvara la vida.
Compiladores del Dragón Rojo
Es el mas usado y en los promeros capitulos habla de lo que requieres.
Lo tengo en mi casa como recuerdo de que algun dia realice por lo menos dos compiladores con dos tecnicas diferentes, tomadas de ese libro.
Hay otro pero no me acuerdo del nombre lo preste y nunca me lo regresaron :). es uno pequeño de portada verde.
Saludos.
Jajaj @avefenix_x Y que tal
Jajaj @avefenix_x Y que tal está? Porque segun lei estaba muy denso, que opinas?
hhle12 Se puede hacer un analizador lexico y sintactico a mano si el lenguaje es bastante sencillo.
El analizador léxico consiste en partir la entrada en tokens, tengan o no sentido.
El analizador semántico consiste en ver si esos tokens tienen sentido o no de acuerdo a las reglas del lenguaje
En el ejemplo que pones: "hombres armados cerca de la escuela tal" el analizador léxico debería de generar los tokens:
[hombres, armados, cerca, de, la, escuela , tal]
suponiendo que único tipo de token que tienes es una palabraString [] tokens;
void tokenize( String input ) {
tokens = input.split("\\s");
}
}
Para el semántico, lo que tiene que hacer es validarlo, por ejemplo tu regla puede ser que el primer token sea "hombres" y el último "tal" en cuyo caso estaría correcta la sentencia. Dependiendo del lenguaje se agregan más o menos reglas o mas o menos tipos de tokens.
void parse( String [] tokens ) throws ParseException {
// la regla es que empieze con "hombres" y termine con "tal"
if ( tokens == null
|| tokens.length == 0
|| !tokens[0].equals("hombres")
|| !tokens[tokens.length-1].equals("tal") ) {
throw new ParseException("<hombres> expected at the beginning or <tal> at the end.", 0);
}
/// todo ok
}
}
Para la salida, una vez que tienes tu tokens y son válidos, se puede hacer una sustitución directa, por otra palabra, por otra cosa, un símbolo, lo que tu quieras.
String [] transform( String [] tokens ) {
String [] output = new String[tokens.length];
int i = 0;
StringBuilder sb = new StringBuilder();
for ( String token : tokens ) {
output[i++] = sb.append(token).reverse().toString();
sb.setLength(0);
}
return output;
}
}
Y listo, ahora tu lenguaje está transformado en algo que solo cierto grupo puede descifrar.
Exception in thread "main" java.text.ParseException: <hombres> expected at the beginning or <tal> at the end.tala
at Parser.parse(Ejemplo.java:15)
at Main.main(Ejemplo.java:38)
$java Main "hombres armados cerca de la escuela tal"
serbmoh sodamra acrec ed al aleucse lat
Aqui esta el ejemplo completo:
https://gist.github.com/OscarRyz/6687505
Esto es obviamente a grandes rasgos. Te preguntaras: Por que existen entonces herramientas para hacer el analizador lexico y sintactico y tanta tecnología alrededor de los compiladores? Porque los lenguajes que tienen que procesar son mucho mucho más complejos que esto, pero todos tienen los mismos principios, partir en tokens, validarlos y hacer algo con ellos.Estas herramientas ayudan a escribir a identificar los tokens y a hacer la validación y a las transformaciones.
En mi ejemplo partí en tokens usando String.split('\\s") que simplemente divide usando espacios, pero los tokens pueden ser mucho mas complejos, por ejemplo en un lenguaje de programación como Java esto:
String a = 1+-1;
podia dar 7 tokens:['String', 'a', '=', '1', '+' '-1', ';']
y hay que saber diferenciar entre letras, números, símbolos etc. La regla que dice que no le puedes asignar un entero a un string esta en la siguiente fase, y la salida ( en vez de simplemente voltear los tokens ) cuando es valida ( ieint a = 1 +-1;
) seria algo como:putfield // asignarlo a la variable 'a'
Espero que esto te sirva de ayuda para empezar. No se si este de mas decirlo pero obviamente mi implementación es bastante básica, mi conocimiento de estas herramientas también es muy básico, pero puede servir de base para ir aprendiendo más. Cualquier corrección es bienvenida.
Esta algo confuso, pero .....
Esta algo confuso @OscarRyz, pero si tu maestro te hace leerlo a la fuerza le entiendes :)
La verdad el metodo que te recomende es el mas facil, el resto del libro si esta algo conplejo y de confusion multiple.
debes de enterder muchas cosas, para saber que es lo que realmente vas a programar :).
El Metodo de compiladores de una sola pasada no son ni 10 Hojas del libro y esta mul facil de entender cuando le agarras la onda vas a ver que no es nada complejo.
y la idea que te da @OscarRyz es parte de la solucion.
Saludos.
GRACIAS
GRACIAS A LOS DOS POR HABERME AYUDADO YA COMPRENDÍ MEJOR LA PARTE DE LOS COMPILADORES Y HASTA ME ESTOY ANIMANDO A HACERLO PROGRAMADO ESPERO NO TENER PROBLEMAS