Herramientas de usuario

Herramientas del sitio


otros:compilers

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
otros:compilers [2009/11/07 17:40]
alfred
otros:compilers [2020/05/09 09:25] (actual)
Línea 1: Línea 1:
 ====== Compiladores ====== ====== Compiladores ======
 Para crear un compilador necesitamos un analizador léxico (o //​scanner//​) analiza el texto, y un analizador sintáctico (o //parser//) el que analiza la estructura del texto y realiza las acciones necesarias según esta. El analizador léxico recorre el texto y va pasando las porciones útiles (//​tokens//​) al parser, este actuará según la estructura en la que estén colocados los tokens. Para crear un compilador necesitamos un analizador léxico (o //​scanner//​) analiza el texto, y un analizador sintáctico (o //parser//) el que analiza la estructura del texto y realiza las acciones necesarias según esta. El analizador léxico recorre el texto y va pasando las porciones útiles (//​tokens//​) al parser, este actuará según la estructura en la que estén colocados los tokens.
-   * Para Java el creador de analizadores léxicos se llama [[#​jflex|JFlex]] y el creador de parsers [[#​cup|CUP]]. Estas son herramientas a las que se les pasa código y, a partir de este, generan el analizador o el parser.+  ​* Para Java el creador de analizadores léxicos se llama [[#​jflex|JFlex]] y el creador de parsers [[#​cup|CUP]]. Estas son herramientas a las que se les pasa código y, a partir de este, generan el analizador o el parser
 +  * Los nombrados anteriormente son versiones de los primeros creadores Lex y Yacc. 
 +  * Actualmente existen otros generadores de parsers como son [[http://​www.gnu.org/​software/​bison/​|Bison]],​ [[http://​www.antlr.org/​|ANTLR]]...
  
 ===== JFlex ===== ===== JFlex =====
Línea 171: Línea 173:
  
 ===== CUP ===== ===== CUP =====
 +
 +
  
  
Línea 220: Línea 224:
           ;           ;
 </​code>​ </​code>​
-Donde las correspondencias son...+Donde los elementos que aparecen son denominados **símbolos** y sus correspondencias son...
   * PROGRAMA: El programa en sí.    * PROGRAMA: El programa en sí. 
   * VARBLOCK: Al bloque de definición de variables.   * VARBLOCK: Al bloque de definición de variables.
Línea 249: Línea 253:
 } }
 </​code>​ </​code>​
-El árbol sería el siguiente:+El árbol sería el siguiente: ​\\ \\ \\  
 +{{otros:​compilers:​arbol.png?​500|}} \\ \\  
 +Siendo los **símbolos terminales** los elementos que están en las ramas del árbol (paréntesis,​ números, signos...) y los símbolos** no terminales** los elementos que están en el tronco (código, igualdad, operación...). 
 + 
 + 
 + 
 + 
 + 
  
 ==== Instalación,​ uso y combinación con JFlex ==== ==== Instalación,​ uso y combinación con JFlex ====
 +  * [[http://​www2.cs.tum.edu/​projects/​cup/​]]
 +  * {{otros:​compilers:​java_cup_v10k.zip|CUP}}
 +Descomprimimos el archivo del CUP, nos aparecerá una carpeta denominada java_cup_v10k,​ esa es la carpeta que deberemos agregar como ''​external class folder''​ en eclipse (desde la misma ventana desde donde agregamos el jar del JFlex) y desde esa carpeta será desde donde ejecutemos el comando: ''​java java_cup.Main nuestro_fichero.cup''​. Donde nuestro fichero es el código CUP que programemos. Este comando generará dos ficheros\clases que tendremos que agregar a nuestro proyecto:
 +  * ''​parser.java''​ donde estará el código del parser.
 +  * ''​sym.java''​ donde se definirán todos los símbolos.
 +Para que JFlex sea compatible con CUP debemos agregar a las instrucciones de generación el parámetro ''​%cup''​. \\ 
 +Cuando combinamos los códigos generados por JFlex y CUP el que lanza el analizador léxico ahora es la misma clase parser. El siguiente código sería un ejemplo de inicio de parseo:
 +<code java>
 +parser p = null;
 +Yylex lex = null;
 +try {
 + if (args.length == 0) {
 + System.out.println("​Llegint des de l' stream d'​entrada:​ ");
 + lex = new Yylex(System.in);​
 + } else {
 + System.out.println("​Llegint des del fitxer: " + new java.io.File(args[0]).getAbsolutePath());​
 + lex = new Yylex(new java.io.FileReader(args[0]));​
 + }
 + p = new parser(lex);​
 + p.parse();
 +catch ...
 +</​code>​
 +Dentro del código JFlex tendremos que retornar objetos ''​Symbol'',​ el constructor de estos, entre otras cosas, recibe un tipo de simbolos (de la lista de símbolos en el archivo ''​sym.java''​ generado), dos objetos (el left y el right) que luego podremos recoger y el valor. En el siguiente ejemplo cuando se encuentra una definción "​.code"​ se envia que es un símbolo del tipo ''​STARTCODE'',​ el número de línea (como objeto left), nada (como objeto right), y el texto (por si se necesita):
 +<​code>​
 +"​.code"​ { return new Symbol(sym.STARTCODE,​ yyline + 1, 0, yytext()); }
 +</​code>​
 +{{otros:​compilers:​flex_and_cup.tar.gz|Aquí}} un par de ejemplos.
 +
 +
 +
  
 ==== Código ==== ==== Código ====
-==== Ejemplos ​====+El código CUP se estructura de la siguiente forma: 
 +  - Código Java de fuera de la clase (tipo imports...). 
 +  - Código interno de la clase parser y que podrá ser accedido desde el código generado entre: ''​parser code {: :​}''​ 
 +  - El action code, entre: ''​action code {: :​}''​ 
 +  - El código que define la gramática. 
 +El código que define la gramática comienza con la definición de los nombres de símbolos terminales y no terminales:​ 
 +<​code>​ 
 +terminal WORD, COMA, NUMBER, DOSPUNTOS, CORCHIZQ, CORCHDER; 
 +terminal STARTPROGRAM,​ ENDPROGRAM, STARTCODE, ENDCODE, STARTDECVAR,​ ENDDECVAR, STARTMACRO, ENDMACRO, STARTDECMACRO,​ ENDDECMACRO;​ 
 +terminal COMANDO, REGISTRO, TIPO; 
 +nonterminal programa, name, bloccodi, codi, liniacodi, blocvariables,​ blocmacros, decvars, valor, macro, decmacros, etiqueta; 
 +nonterminal memaddr, operando1, operando2;​ 
 +</​code>​ 
 +Luego la creación de la gramática se haría con la estructura explicada anteriormente,​ pero con la siguiente sintaxis: 
 +<​code>​ 
 +PROGRAMA ​ ::VARBLOCK FUNCBLOCK CODEBLOCK 
 +          | VARBLOCK CODEBLOCK 
 +          ; 
 +</​code>​ 
 +Además podemos incluir código y leer los tokens pasados por el analizador léxico, por ejemplo podemos leer el contenido de cada token (agregando '':​nombre_variable''​ tras su definición) o acceder a los objetos left y right con ''​nleft''​ y ''​nright''​. 
 +<​code>​ 
 +DEF_FUNC ​ ::NOMFUNC ID:w PAR_IZQ PAR_DER CORCH_IZQ CODE_BODY CORCH_DER 
 +              {: 
 +                    System.out.println("​Se ha definido una función llamada: " + w.toString() + " en linea:"​ + nleft); 
 +              :} 
 +          | ... 
 +</​code>​ 
 + 
 +En el ejemplo de la documentación encontramos la definición de la gramática siguiente:​ 
 +<​code>​ 
 +expr_list ::expr_list expr_part  
 +       | expr_part 
 +       ; 
 + 
 +expr_part ::expr:e  
 +       {: System.out.println("​" + e); :}  
 +       ; 
 + 
 +expr      ::expr:e1 PLUS expr:​e2 ​    
 +       {: RESULT ​new Integer(e1.intValue() + e2.intValue());​ :}  
 +       | expr:e1 MINUS expr:​e2 ​    
 +              {: RESULT ​new Integer(e1.intValue() - e2.intValue());​ :}  
 +       | expr:e1 TIMES expr:e2  
 +       {: RESULT = new Integer(e1.intValue() * e2.intValue());​ :}  
 +       | expr:e1 DIVIDE expr:e2  
 +       {: RESULT = new Integer(e1.intValue() / e2.intValue());​ :}  
 +       | expr:e1 MOD expr:e2  
 +       {: RESULT = new Integer(e1.intValue() % e2.intValue());​ :}  
 +       | NUMBER:​n ​                 
 +       {: RESULT = n; :}  
 +       | MINUS expr:​e ​             
 +       {: RESULT = new Integer(0 - e.intValue());​ :}  
 +       | LPAREN expr:e RPAREN ​     
 +       {: RESULT = e; :}  
 +       ; 
 +</​code>​ 
 + 
 + 
 + 
 + 
 + 
 +===== Notas ===== 
 +  * La herramienta de Python para generar analizadores léxicos y sintácticos es la denominada PLY (que se encuentra [[http://​www.dabeaz.com/​ply/​index.html|aquí]]),​ su nombre viene de //Python Lex Yacc//. 
  
-===== Compiladores con Python ===== 
-===== Compiladores con .NET ===== 
  
otros/compilers.1257615647.txt.gz · Última modificación: 2020/05/09 09:25 (editor externo)