compiladores: análisis léxico - laboratorio de sistemaslsub.org/comp/slides/s02.lex.pdf · un...

90
1/25/16, 2:47 PM Compiladores: Análisis léxico - (c)2014 LSUB Page 1 of 90 http://127.0.0.1:3999/s02.lex.slide#1 Compiladores: Análisis léxico Francisco J Ballesteros LSUB, URJC

Upload: phungdung

Post on 29-Sep-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 1 of 90http://127.0.0.1:3999/s02.lex.slide#1

Compiladores: Análisis léxicoFrancisco J BallesterosLSUB, URJC

Page 2: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 2 of 90http://127.0.0.1:3999/s02.lex.slide#1

Analizador léxico

Identificar tokens en la cadena de entrada

procesar los ficheros de entrada

generar la entrada para el parser

Ignorar comentarios

Mantener la idea de fichero-número de línea para mensajes de error

Page 3: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 3 of 90http://127.0.0.1:3999/s02.lex.slide#1

Analizador léxico

Al definir el lenguaje

tendremos que definir una gramática para el mismo

Los elementos básicos de la gramática son los tokens

Page 4: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 4 of 90http://127.0.0.1:3999/s02.lex.slide#1

Analizador léxico

Token

palabras reservadas

identificadores

números

signos de puntuación

El conjunto de tokens depende del lenguaje en cuestión

Usaremos palabras reservadas en el análisis sintáctico

Normalmente ignoramos el espacio en blanco

El valor de un token o lexema es el string para el mismo

Page 5: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 5 of 90http://127.0.0.1:3999/s02.lex.slide#1

Tokens

Para C, por ejemplo

LPAREN (RPAREN )IF ifIDENT mainSCOL ;PLUS +PLUSEQ +=...

Page 6: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 6 of 90http://127.0.0.1:3999/s02.lex.slide#1

Tokens

Para printf

FMT %DECARG dSTRARG sPCENT %%CHARS ...

Por ejemplo

%d, %%d

Nos da

FMT DECARG CHARS(", ") PCENT CHARS("d")

Entre paréntesis van los lexemas

Page 7: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 7 of 90http://127.0.0.1:3999/s02.lex.slide#1

Tokens

Otro ejemplo

x*2+3

Nos podría dar

VAR("x") MULT NUM(2) ADD NUM(3)

Page 8: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 8 of 90http://127.0.0.1:3999/s02.lex.slide#1

Tokens

Otro ejemplo

pi*2+3

Nos podría dar

PI MULT NUM(2) ADD NUM(3)

Esta vez pi no es una variable, está reservado.

Page 9: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 9 of 90http://127.0.0.1:3999/s02.lex.slide#1

Tokens

Otro ejemplo, expresiones regulares:

[ab]+.*\.c$

Podríamos tener los tokens

LBRA CHR('a') CHR('b') RBRA PLUS DOT STAR CHR('.') CHR('c') ETEXT

O tal vez

LBRA STR("ab") RBRA PLUS DOT STAR STR(".c") ETEXT

O tal vez

SET("ab") PLUS DOT STAR CHR('.') CHR('c') ETEXT

Todo depende de cómo hagamos el lenguaje

Page 10: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 10 of 90http://127.0.0.1:3999/s02.lex.slide#1

Tokens

Un token tiene

identificador único (ID, LBRA, RBRA, ...)

lexema o valor (3.5, main, ...)

Muchas veces fichero y número de línea (para errores)

Page 11: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 11 of 90http://127.0.0.1:3999/s02.lex.slide#1

Tokens

Podemos meter la pata al definirlos

Por ej, en C++

Vector<Number>cin >> xVector<Vector<Number>>

Es el último?

>>

o?

> >

C++ no lo sabe y por eso no compila

Page 12: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 12 of 90http://127.0.0.1:3999/s02.lex.slide#1

Una calculadora

Expresiones sencillas y no ambiguas tales como...

# esto es un comentario3 + 4( 5 * 3 ) + 434 / 5 / 72 * piabs ( 2 * pi )

Por ahora sólo pi y abs como predefinidos.

Page 13: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 13 of 90http://127.0.0.1:3999/s02.lex.slide#1

Una calculadora

Ya hay dudas:

-32 * -32 - 3

No hay cambio de signo.

- 2*1 // no válido.

Page 14: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 14 of 90http://127.0.0.1:3999/s02.lex.slide#1

Una calculadora: Tokens

NUMLPARENRPARENADDSUBMULDIVPIABS

Page 15: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 15 of 90http://127.0.0.1:3999/s02.lex.slide#1

Una calculadora: Tokens

Valor de los tokens:

NUM -> valor como float con signo

Y el resto nada

LPARENRPARENADDSUBMULDIVPIABS

El comentario lo eliminamos y no es un token

Page 16: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 16 of 90http://127.0.0.1:3999/s02.lex.slide#1

Ejemplo:

# esto es un comentario3 + 4( 5 * 3 ) + 434 / 5 / 72 * piabs ( 2 * pi )

nos da

NUM(3) ADD NUM(4)LPAREN NUM(5) MUL NUM(3) RPAREN ADD NUM(43)NUM(4) DIV NUM(5) DIV NUM(7)NUM(2) MUL PIABS LPAREN NUM(2) MUL PI RPAREN

Page 17: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 17 of 90http://127.0.0.1:3999/s02.lex.slide#1

Un trozo de un lenguaje

Sentencias sencillas

{ print x; print y; print z; }x = "texto";if x == "texto" { ... }for x in "a" "b" "c" { print x; }

Page 18: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 18 of 90http://127.0.0.1:3999/s02.lex.slide#1

Un trozo de un lenguaje

{ print x; print y; print z; }x = "texto";if x == "texto" { ... }for x in "a" "b" "c" { print x; }

Tokens:

LBRARBRASCOLEQEQEQPRINTFORIFNAMESTR

Page 19: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 19 of 90http://127.0.0.1:3999/s02.lex.slide#1

Un trozo de un lenguaje

Valores de los tokens:

NAME -> xSTR -> "texto"

El resto ninguno

Page 20: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 20 of 90http://127.0.0.1:3999/s02.lex.slide#1

Expresiones regulares

Sólo expresiones sencillas

abca|b|c.[0-9]([0-9]|[a-z])*

Page 21: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 21 of 90http://127.0.0.1:3999/s02.lex.slide#1

Expresiones regulares

abca|b|c.[0-9]([0-9]|[a-z])*

Tokens

CHRORANYRANGELPARENRPARENSTAR

Page 22: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 22 of 90http://127.0.0.1:3999/s02.lex.slide#1

Expresiones regulares

Valor de los tokens

CHR -> aRANGE -> 0-9

Y el resto ninguno

Page 23: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 23 of 90http://127.0.0.1:3999/s02.lex.slide#1

Construcción de un scanner

Tenemos que pasar de texto a tokens

leyendo de izquierda a derecha

normalmente se permite mirar un char adelante

cada token corresponde a un string

hay que ver hasta dónde llega cada uno

Page 24: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 24 of 90http://127.0.0.1:3999/s02.lex.slide#1

Construcción de un scanner

Podríamos describir cada token con una expresión regular

teniendo cuidado de evitar ambigüedad

probar en cada punto de la entrada cada expresión

devolver el token que encaja con la expresión

En esto se basa lex(1), pero es más fácil.

Page 25: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 25 of 90http://127.0.0.1:3999/s02.lex.slide#1

Lenguajes y alfabetos

Un lenguaje es un conjunto de strings (los válidos en el lenguaje)

Los strings son secuencias de símbolos de un alfabeto

No todos los strings pertenecen al lenguaje

A = {símbolos válidos en el lenguaje}

L(A) = {strings de A válidos}

Page 26: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 26 of 90http://127.0.0.1:3999/s02.lex.slide#1

Tokens, lenguajes y alfabetos

Para tener un scanner podemos definir un lenguaje para los lexemas

lexema: "valor" de los tokens

Por ejemplo

NUM -?[0-9]+(\.[0-9]+) // 3 -4 -2.3LPAREN \( // (RPAREN \) // )ADD \+ // +SUB - // -MUL \* // *DIV / // /PI pi // piABS abs // abs

Nos da

(-?[0-9]+(\.[0-9]+))|\(|\)|\+|-|\*|/|pi|abs

Page 27: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 27 of 90http://127.0.0.1:3999/s02.lex.slide#1

Tokens, lenguajes y alfabetos

En este lenguaje podemos reconocer las cadenas

sin depender del contexto en que están

empleando expresiones regulares

Es un lenguaje regular

Page 28: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 28 of 90http://127.0.0.1:3999/s02.lex.slide#1

Lenguajes y autómatas

Un atómata finito es una máquina que acepta cadenas

Un lenguaje regular es reconocible por un atómata finito

Un lenguaje regular es describible con una expresión regular

Una expresión regular es implementable con un autómata finito

Page 29: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 29 of 90http://127.0.0.1:3999/s02.lex.slide#1

Expresión regular

Definida recursivamente

Siendo x un char y a y b expresiones regulares:

L(x) = { x }, siendo x cualquier char salvo \, (, ), ., |, *, ?

L(\x) = { x }

L((a)) = L(a)

L(.) = { cualquier char }

L(ab) = { la de L(a) concatenado con lb de L(b) }

L(a|b) = L(a) U L(b)

L(a*) = { "" } U L(a) U L(aa) U L(aaa) U ...

Page 30: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 30 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata finito

En este lenguaje podemos reconocer las cadenas utilizando un autómata finito

Para reconocerlo:

partimos de un estado inicial

en cada carácter de la entrada transitamos a otro estado

algunos de los estados son finales

si terminamos y no hay estado final, tenemos un error

Un error es una cadena no reconocida

Page 31: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 31 of 90http://127.0.0.1:3999/s02.lex.slide#1

Lenguaje para tokens de calculadora

Ejemplo, el lenguaje que describe los tokens de

# esto es un comentario3 + 4.4( 5 * 3 ) + -434 / 5 / 72 * piabs ( 2 * pi )

que son

NUMLPARENRPARENADDSUBMULDIVPIABS

puesto que ignoramos comentarios y espacio y en blanco!

Page 32: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 32 of 90http://127.0.0.1:3999/s02.lex.slide#1

Lenguaje para tokens de calculadora

Podríamos describirlo como la expresión regular

LTC = (-?[0-9]+(\.[0-9]+))|\(|\)|\+|-|\*|/|pi|abs

que reconoce entre otros...

3+4.4(5*3)+-43abspi

Page 33: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 33 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

Para definir un atómata finito

partimos de un estado inicial

para cada estado y símbolo en la entrada transitamos a otro estado

indicamos qué estados son finales

Si no está definida una transición, no reconocemos ese caso. El automáta es:

alfabeto de entrada

conjunto de estados (con inicial y finales)

conjunto de transiciones

Page 34: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 34 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

Por ejemplo, para

abs

Podríamos definir

Page 35: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 35 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

O lo que es lo mismo

Page 36: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 36 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

Y para pi|abs

Page 37: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 37 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

Por ejemplo, para nuestros números

4 54

Podríamos definir

Page 38: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 38 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

Y con decimales...

4 54 43.23

Podríamos definir

Page 39: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 39 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

Y con decimales y signo opcional...

4 54 43.23 -32 -2.3

Podríamos definir

Page 40: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 40 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

Todo junto

Page 41: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 41 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

¿Está todo?

No

Nos falta (, ), +, -, * y /

Y tenemos problemas

-3

- 3

Hay algo de ambigüedad.

Page 42: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 42 of 90http://127.0.0.1:3999/s02.lex.slide#1

Ambigüedad

-3

- 3

Podemos decidir entre signo y resta mirando si sigue un dígito o no.

Page 43: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 43 of 90http://127.0.0.1:3999/s02.lex.slide#1

Ambigüedad

En general podemos

Utilizar la cadena más larga que encaja

Utilizar la primera de las subexpresiones si hay varias

En nuestro ejemplo en realidad no hay ambigüedad: hay no determinismo

Page 44: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 44 of 90http://127.0.0.1:3999/s02.lex.slide#1

No determinismo

Necitamos un atómata finito no determinista

Hay dos transiciones válidas para -

Page 45: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 45 of 90http://127.0.0.1:3999/s02.lex.slide#1

Atómata finito no determinista

Podemos tener transiciones en la cadena vacía para el signo

Page 46: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 46 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómata para LTC

Page 47: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 47 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scan de nombres

En lugar de utilizar estados para reconocer todos los nombres

Podemos reconocer un nombre en general

Y buscar el nombre en una tabla para ver si está reservado

Esto se hace si hay muchas palabras reservadas (keywords)

O si son varias pero son largas

Page 48: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 48 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómatas

Finitos Deterministas (AFD, o DFA)

una única transición por estado y entrada

Finitos no deterministas (AFND, o NFA)

varias transiciones posibles

transiciones con la cadena vacía (se puede transitar o no)

Page 49: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 49 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómatas para expresiones regulares

NFA para

x

Page 50: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 50 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómatas para expresiones regulares

NFA para

re1 re2

Page 51: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 51 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómatas para expresiones regulares

NFA para

re1 | re2

Page 52: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 52 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómatas para expresiones regulares

NFA para

re1 ?

Page 53: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 53 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómatas para expresiones regulares

NFA para

re1 *

Page 54: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 54 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómatas para expresiones regulares

NFA para

c(a|b)*

Page 55: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 55 of 90http://127.0.0.1:3999/s02.lex.slide#1

Autómatas para expresiones regulares

NFA para

c(a|b)*

Y podemos simplificarlo

Page 56: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 56 of 90http://127.0.0.1:3999/s02.lex.slide#1

Construir un DFA desde un NFA

Es fácil pero tedioso:

los estados del DFA son los conjuntos de estados alcanzados en el NFA

empezar en el estado inicial del NFA

para cada posible transición NFA: transitar al estado del DFA para el cjto de estadosNFA alcanzado

si tenemos un estado final del NFA, el estado es final.

Page 57: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 57 of 90http://127.0.0.1:3999/s02.lex.slide#1

Implementar un DFA

Podemos utilizar una tabla

Columnas para los estados

Filas para la entradas

Nuevos estados como valores

La función de estado toma una entrada y devuelve el nuevo estado

Hasta que la entrada se acepta

Page 58: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 58 of 90http://127.0.0.1:3999/s02.lex.slide#1

¿Dónde estábamos?

Queríamos un scanner para la calculadora

Y para eso hicimos un NFA para el lenguaje de sus tokens

(que a su vez son tokens de otro lenguaje!)

Page 59: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 59 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Page 60: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 60 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Podemos implementar directamente el autómata

Usando lex(1) y dándole las expresiones regulares

o mejor

escribiendo en Go el código para el autómata

si hay muchos nombres usaríamos una tabla.

va a quedar pequeño y rápido

Page 61: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 61 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Primero la entrada...

var text = `3 + (4.3 * abs(-1 * pi))`

func main() { fmt.Printf("scanning %s\n", text) txt := NewStrText(text) for { r, err := txt.Get() if err != nil { fmt.Printf("got err %s\n", err) break } fmt.Printf("got %c\n", r) }} Run

Page 62: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 62 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

¿Qué es la entrada para nosotros?

type Text interface { Get() (rune, error) Unget() error}

Utilizaremos Unget para look-ahead

De hecho, go tiene un interface (io.RuneScanner) definido para esto.

Page 63: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 63 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Tokens

type TokId inttype Tok struct { Id TokId Num float64}

// token id valuesconst ( None TokId = iota Num Lparen Rparen Add Sub Mul Div Pi Abs)

Page 64: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 64 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Lexer

type Lexer interface { // return next token Scan() (Tok, error) // Look ahead one token Peek() (Tok, error)}

Page 65: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 65 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Lex

type lex struct { in Text saved Tok}

func NewLex(t Text) Lexer { return &lex{in: t}}

Page 66: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 66 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Lex

func (l *lex) Peek() (Tok, error) { tok, err := l.Scan() l.saved = tok return tok, err}

func (l *lex) Scan() (Tok, error) { if l.saved.Id != None { x := l.saved l.saved = Tok{} return x, nil } if err := l.skipBlanks(); err != nil { return Tok{}, err } return l.nextTok()}

Page 67: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 67 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Lex

func (l *lex) skipBlanks() error { for { c, err := l.in.Get() if err != nil { return err } if c != ' ' && c != '\t' && c != '\n' { l.in.Unget() return nil } }}

Page 68: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 68 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Lex

func (l *lex) nextTok() (Tok, error) { c, err := l.in.Get() if err != nil { return Tok{}, err } switch { case c == '+': return Tok{Id:Add}, nil case c == '-': return Tok{Id:Sub}, nil case c == '*': return Tok{Id:Mul}, nil case c == '/': return Tok{Id:Div}, nil case c >= '0' && c <= '9': l.in.Unget() return l.scanNum() case c == 'p': l.in.Unget() return l.scanPi() case c == 'a': l.in.Unget() return l.scanAbs() } return Tok{}, fmt.Errorf("wrong input at char %c", c)}

Page 69: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 69 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Lex, números

func (l *lex) scanNum() (Tok, error) { n, err := l.scanInt() if err != nil { return Tok{}, err } c, err := l.in.Get() if err != nil { return Tok{Id: Num, Num: n}, nil } if c != '.' { l.in.Unget() return Tok{Id: Num, Num: n}, nil } dec, err := l.scanDec() if err != nil { return Tok{}, err } return Tok{Id: Num, Num: n+dec}, nil}

Page 70: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 70 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Lex, números

func (l *lex) scanInt() (float64, error) { r := 0.0 some := false for { c, err := l.in.Get() if some && err == io.EOF { return r, nil } if err != nil { return r, err } if c <= '0' || c >= '9' { l.in.Unget() return r, nil } r *= 10 r += float64(int(c) - int('0')) some = true }}

Page 71: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 71 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Lex, números

func (l *lex) scanDec() (float64, error) { r := 0.0 d := 1.0 some := false for { c, err := l.in.Get() if some && err == io.EOF { return r, nil } if err != nil { return r, err } if c <= '0' || c >= '9' { l.in.Unget() return r, nil } n := int(c) - int('0') r += float64(n) / d d *= 10.0 some = true }}

Page 72: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 72 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora

Listo

Ojo a bug en SUB!

func main() { text := `3 + (41.32 * abs(-1 * pi))` fmt.Printf("scanning %s\n", text) txt := NewStrText(text) l := NewLex(txt) for { t, err := l.Scan() if err != nil { fmt.Printf("got err %s\n", err) break } fmt.Printf("got tok %s\tnum %v\n", t.Id, t.Num) }} Run

Page 73: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 73 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora: fixed

func (l *lex) nextTok() (Tok, error) { c, err := l.in.Get() if err != nil { return Tok{}, err } switch { case c == '+': return Tok{Id:Add}, nil case c == '-': n, _ := l.in.Get() l.in.Unget() if n >= '0' && n <= '9' { t, err := l.scanNum() t.Num *= -1 return t, err } return Tok{Id:Sub}, nil case c == '*': return Tok{Id:Mul}, nil case c == '/': return Tok{Id:Div}, nil case c == '(': return Tok{Id:Lparen}, nil case c == ')': return Tok{Id:Rparen}, nil case c >= '0' && c <= '9': l.in.Unget() return l.scanNum() case c == 'p': l.in.Unget()

Page 74: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 74 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para la calculadora: fixed

Y ahora

func main() { text := `3 - (41.32 * abs(-1 * pi))` fmt.Printf("scanning %s\n", text) txt := NewStrText(text) l := NewLex(txt) for { t, err := l.Scan() if err != nil { fmt.Printf("got err %s\n", err) break } fmt.Printf("got tok %s\tnum %v\n", t.Id, t.Num) }} Run

Page 75: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 75 of 90http://127.0.0.1:3999/s02.lex.slide#1

Comentarios

func (l *lex) skipBlanks() error { for { c, err := l.in.Get() if err != nil { return err } if c == '#' { for c != '\n' { if c, err = l.in.Get(); err != nil { return err } } } if c != ' ' && c != '\t' && c != '\n' { l.in.Unget() return nil } }}

Page 76: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 76 of 90http://127.0.0.1:3999/s02.lex.slide#1

Comentarios

func main() { text := `# comentario3 - (41.32 * abs(-1 * pi))`

fmt.Printf("scanning %s\n", text) txt := NewStrText(text) l := NewLex(txt) for { t, err := l.Scan() if err != nil { fmt.Printf("got err %s\n", err) break } fmt.Printf("got tok %s\tnum %v\n", t.Id, t.Num) }} Run

Page 77: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 77 of 90http://127.0.0.1:3999/s02.lex.slide#1

Comentarios

La parte delicada es reconocerlos

sin que sea ambiguo si es otro token.

a / b

vs

a // b

Se hace que el autómata se coma todo desde el token de principio de comentario hasta el de fin de comentario

Page 78: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 78 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

# comentario{ print x; print y; print z; }x = "texto";if x == "texto" { ... }for x in "a" "b" "c" { print x; }

Esta vez mantendremos nombre de fichero y número de línea

Y guardaremos el lexema

Page 79: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 79 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

Tokens

type TokId inttype Tok struct { Id TokId Val string Ln int}

// token id valuesconst ( None TokId = iota Str Lbra Rbra Eq Cmp Id Scol Print If For In)

Page 80: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 80 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

Nuevo lex

type lex struct { in Text saved Tok ln int val []rune}

func NewLex(t Text) Lexer { return &lex{in: t, ln: 1}}

Page 81: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 81 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

SkipBlanks cuenta líneas ahora

func (l *lex) skipBlanks() error { for { c, err := l.in.Get() if err != nil { return err } if c == '#' { for c != '\n' { if c, err = l.in.Get(); err != nil { return err } } if c == '\n' { l.ln++ } } if c != ' ' && c != '\t' && c != '\n' { l.in.Unget() return nil } if c == '\n' { l.ln++ } }}

Page 82: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 82 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

Scan y peek como antes

func (l *lex) Peek() (Tok, error) { tok, err := l.Scan() l.saved = tok return tok, err}

func (l *lex) Scan() (Tok, error) { if l.saved.Id != None { x := l.saved l.saved = Tok{} return x, nil } if err := l.skipBlanks(); err != nil { return Tok{}, err } return l.nextTok()}

Page 83: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 83 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

NextTok es nuestro scanner utilizando got para acumular caracteres que nos gustan y tambien gotTok para terminar con el token actual

func (l *lex) got(r rune) { l.val = append(l.val, r)}

func (l *lex) gotTok(id TokId) Tok { t := Tok{ Id: id, Val: string(l.val), Ln: l.ln, } l.val = nil return t}

Page 84: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 84 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

La parte fácil

func (l *lex) nextTok() (Tok, error) { c, err := l.in.Get() if err != nil { return Tok{}, err } switch { case c == '{': l.got('{'); return l.gotTok(Lbra), nil case c == '}': l.got('}'); return l.gotTok(Rbra), nil case c == ';': l.got(';'); return l.gotTok(Scol), nil

Page 85: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 85 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

Los strings...

func (l *lex) nextTok() (Tok, error) { c, err := l.in.Get() if err != nil { return Tok{}, err } switch {

case c == '"': for { c, err := l.in.Get() if err != nil { return Tok{}, err } if c == '"' { return l.gotTok(Str), nil } l.got(c) } //str

Page 86: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 86 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

Asignación y comparación

func (l *lex) nextTok() (Tok, error) { c, err := l.in.Get() if err != nil { return Tok{}, err } switch {

case c == '=': l.got('=') n, _ := l.in.Get() if n == '=' { l.got('=') return l.gotTok(Cmp), nil } l.in.Unget() return l.gotTok(Eq), nil

Page 87: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 87 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

Identificadores y keywords

Vamos a usar una tabla de keywords

var keywords = map[string]TokId { "print": Print, "if": If, "for": For, "in": In,}

Page 88: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 88 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

Identificadores y keywords

func (l *lex) nextTok() (Tok, error) { c, err := l.in.Get() if err != nil { return Tok{}, err } switch {

case unicode.IsLetter(c): l.got(c) for { c, err := l.in.Get() if err != nil { return Tok{}, err } if !unicode.IsLetter(c) && !unicode.IsNumber(c) { l.in.Unget() t := l.gotTok(Id) if id, ok := keywords[t.Val]; ok { t.Id = id } return t, nil } l.got(c)

Page 89: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 89 of 90http://127.0.0.1:3999/s02.lex.slide#1

Scanner para sentencias sencillas

Y listo:

var keywords = map[string]TokId { "print": Print, "if": If, "for": For, "in": In,}var text = `{ print x; print y; print z; } x = "texto";if x == "texto" { print xxx; }for x in "a" "b" "c" { print x; }`func main() {

fmt.Printf("scanning %s\n", text) txt := NewStrText(text) l := NewLex(txt) for { t, err := l.Scan() if err != nil { fmt.Printf("got err %s\n", err) break } fmt.Printf("ln %d tok %s\t '%v'\n", t.Ln, t.Id, t.Val) }} Run

Page 90: Compiladores: Análisis léxico - Laboratorio de Sistemaslsub.org/comp/slides/s02.lex.pdf · Un lenguaje es un conjunto de strings (los válidos en el lenguaje) Los strings son secuencias

1/25/16, 2:47 PMCompiladores: Análisis léxico - (c)2014 LSUB

Page 90 of 90http://127.0.0.1:3999/s02.lex.slide#1

Questions?

Francisco J BallesterosLSUB, URJChttp://lsub.org (http://lsub.org)