Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
otros:compilers [2009/11/07 19:09] 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 254: | Línea 256: | ||
| {{otros:compilers:arbol.png?500|}} \\ \\ | {{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...). | 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...). | ||
| + | |||
| Línea 270: | Línea 273: | ||
| <code java> | <code java> | ||
| parser p = null; | parser p = null; | ||
| - | |||
| Yylex lex = null; | Yylex lex = null; | ||
| - | |||
| try { | try { | ||
| - | |||
| if (args.length == 0) { | if (args.length == 0) { | ||
| - | |||
| System.out.println("Llegint des de l' stream d'entrada: "); | System.out.println("Llegint des de l' stream d'entrada: "); | ||
| - | |||
| lex = new Yylex(System.in); | lex = new Yylex(System.in); | ||
| - | |||
| } else { | } else { | ||
| - | |||
| System.out.println("Llegint des del fitxer: " + new java.io.File(args[0]).getAbsolutePath()); | System.out.println("Llegint des del fitxer: " + new java.io.File(args[0]).getAbsolutePath()); | ||
| - | |||
| lex = new Yylex(new java.io.FileReader(args[0])); | lex = new Yylex(new java.io.FileReader(args[0])); | ||
| - | |||
| } | } | ||
| - | |||
| p = new parser(lex); | p = new parser(lex); | ||
| - | |||
| p.parse(); | p.parse(); | ||
| catch ... | catch ... | ||
| Línea 299: | Línea 291: | ||
| </code> | </code> | ||
| {{otros:compilers:flex_and_cup.tar.gz|Aquí}} un par de ejemplos. | {{otros:compilers:flex_and_cup.tar.gz|Aquí}} un par de ejemplos. | ||
| + | |||
| + | |||
| ==== Código ==== | ==== Código ==== | ||
| + | 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: | En el ejemplo de la documentación encontramos la definición de la gramática siguiente: | ||
| <code> | <code> | ||
| Línea 330: | Línea 352: | ||
| ; | ; | ||
| </code> | </code> | ||
| - | Corresponde a una lista de expresiones donde | ||
| - | ===== Compiladores con Python ===== | + | |
| - | ===== Compiladores con .NET ===== | + | |
| + | |||
| + | |||
| + | ===== 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//. | ||
| + | |||