style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

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--------------------------------------*/

/* primera parte: no hace falta poner nada */

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.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de avefenix_x

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.

Imagen de hhle12

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 )

Imagen de hhle12

solo es una costumbre que

solo es una costumbre que tengo lo mismo hago con mi escritura cotidiana

Imagen de rodrigo salado anaya

Todo en minúsculas?

Oscar es incorrecto, hhle12 no escribe todo en mayúsculas en su código existen minúsculas :P (coscorron)

Imagen de avefenix_x

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 palabra

class Lexer {
    String [] 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.

class Parser {
   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.

class CodeGenerator {
     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.

$java Main "yada yada yada yada"
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 ( ie int a = 1 +-1; ) seria algo como:

iconst_0  // el 0, porque el compilador ya sabe que 1+-1 da 0 ( una optimización )
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.

Imagen de avefenix_x

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.

Imagen de hhle12

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

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">