compiladores: yacc - (c)2014 lsublsub.org/comp/slides/s07.yacc.pdf · compiladores: yacc - (c)2014...
TRANSCRIPT
![Page 1: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/1.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 1 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Compiladores: YaccFrancisco J BallesterosLSUB, URJC
![Page 2: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/2.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 2 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Yacc
Es un compilador de compiladores
yet another compiler compiler
Genera parsers LALR para gramáticas adecuadas
Disponible en casi todos los sistemas
En C, en Limbo, en Go, etc.
Ver Yacc: A parser generator Stephen C. Johnson y Ravi Sethi
Ver tambien
Yacc: Yet Another Compiler-Compiler (http://dinosaur.compilertools.net/yacc/)
![Page 3: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/3.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 3 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Yacc en Go
Basta ejecutar:
term% go tool yaccusage: yacc [-o output] [-v parsetable] inputterm%
O, haciendo un script...
term% gaccusage: yacc [-o output] [-v parsetable] inputterm%
![Page 4: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/4.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 4 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Yacc
El fuente para yacc es un fichero xxx.y con formato
/* declaraciones para yacc */%{ ... declaraciones en Go ...%}... mas declaraciones para yacc ...%%expr : expr '+' expr | expr '-' expr
term : id | '(' expr ')'
... mas reglas en BNF ...
%%
... codigo en Go ...
![Page 5: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/5.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 5 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Yacc
...declaraciones...%%...reglas BNF de la gramática...%%...código para el compilador...
Las declaraciones definen tokens, etc.
Las que van entre %{ y %} son declaraciones en Go
La gramática son reglas en BNF (formateadas a gusto del autor)
El código se escribe en Go.
En el yacc para C se genera C y se usa C, no Go.
![Page 6: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/6.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 6 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Yacc
A partir del fich.y yacc genera un fichero fuente en Go
Como Go permite definir items después de usarlos, el orden da un poco igual.
Pero no ocurre así en C.
![Page 7: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/7.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 7 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Declaraciones
Normalmente incluyen declaraciones iniciales para el fuente...
/* Evaluador de expresiones simples */
%{
// +build ignore
package main
import ( "io" "os" "strconv" "fmt" "unicode" "bufio")
%}
![Page 8: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/8.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 8 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Declaraciones
y definiciones de tokens, lexemas y atributos
/* tipo de datos para atributos de simbolos de la gramatica */%union { num float64 name string}
/* tokens */%token '('%token ')'%token '\n'%token <num> NUM PI /* su valor es float64 */%token <name> FN /* su valor es string */
/* tokens para operadores, de menor a mayor precedencia * y con asociatividad indicada (left, right, unary) */%left '+' '-'%left '*' '/'
%%
![Page 9: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/9.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 9 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Tokens
Un token es un int
Si definimos
%token '('
El (identificador del) token vale '('
Si definimos
%token NUM
Yacc crea una constante NUM para el id del token.
Si definimos
%token <num> NUM
Decimos que el lexema vale yySymVal.num, esto es, float64
![Page 10: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/10.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 10 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Tokens
%union { num float64 name string}
%token '('%token ')'%token '\n'%token <num> NUM PI%token <name> FN
¿Más claro ahora?
![Page 11: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/11.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 11 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Tokens
Cuando los tokens son operadores y queremos definir su precedencia podemos utilizar
%left '+'
para un operador binario asociado a la izquierda
%right ARROW
para un operador binario asociado a la derecha
%unary UMINUS
para un operador unario
Su precedencia es menor si se declaran antes
%left '+' '-'%left '*' '/'
![Page 12: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/12.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 12 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Atributos y símbolos
Cada símbolo tiene un valor definido en la unión
%union { num float64 name string}
Según la declaración de token o la declaración de tipo para el no-terminal que hagamos:
%type <num> expr call
indica que los no-terminales expr y call son yySymVal.num
![Page 13: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/13.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 13 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Símbolo inicial
La definición
%start prog
indica que prog es el símbolo inicial de la gramática
Si no la indicamos, es el primero en la gramática
![Page 14: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/14.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 14 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Gramática
La gramática se define en BNF.
Para
A ::= B | C | <empty>
podemos escribir
A : B | C | /* empty */ ;
![Page 15: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/15.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 15 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Ejemplo de gramática
lines : line | lines line ;
line : expr '\n' | '\n' ;
expr : expr '+' expr | expr '-' expr | expr '*' expr | expr '/' expr | '(' expr ')' | NUM | PI | FN '(' expr ')' ;
![Page 16: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/16.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 16 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Ejemplo de gramática
Mejor que no sea recursiva por la derecha!
lines : line | lines line ;
line : expr '\n' | '\n' ;
La entrada tiene en este caso líneas con una expresión por línea (o líneas vacías).
Nuestro lex tendrá que darnos el token '\n' en este ejemplo
![Page 17: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/17.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 17 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Ejemplo de gramática
expr : expr '+' expr | expr '-' expr | expr '*' expr | expr '/' expr | '(' expr ')' | NUM | PI | FN '(' expr ')' ;
La gramática para expresiones es ambigua, pero las declaraciones de precedencia lo resuelven.
%left '+' '-'%left '*' '/'
![Page 18: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/18.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 18 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Acciones
Para, por ejemplo, pasar de notación infija a postfija:
%%lines : line | lines line ;
line : expr '\n' { fmt.Printf("\n") } | '\n' ;
expr : expr '+' expr { fmt.Printf(" +") } | expr '-' expr { fmt.Printf(" -") } | expr '*' expr { fmt.Printf(" *") } | expr '/' expr { fmt.Printf(" /") } | '(' expr ')' { } | NUM { fmt.Printf(" %v", $1) } | PI { fmt.Printf(" pi") } | FN '(' expr ')' { fmt.Printf(" %s\n", $1) } ;%%
![Page 19: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/19.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 19 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Acciones
Y con esta gramática:
term% gacc -p Expr expr.yterm% go run y.go3 + 4 * pi 3 4 pi * +2 2
La opción -p Expr hace que se use ExprSymVal en lugar de yySymVal
![Page 20: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/20.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 20 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Código
Tras el último %% escribimos normalmente el programa principal y a menudo el código del scanner.
Por ejemplo, este es el que hemos utilizado en el traductor a postfija:
func main() { debuglex = false txt := &bufsrc{in: bufio.NewReader(os.Stdin)} l := NewLex(txt, "stdin")
ExprParse(l) os.Exit(nerrors);}
![Page 21: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/21.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 21 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Código
La llamada
yyParse(l)
ejecuta el parser
El argumento ha de implementar
type yyLex interface { Lex(lval *yySymType) int Error(e string)}
y es el scanner.
Con el flag -p Expr usamos ExprParse, ExprLex y ExprSymType
![Page 22: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/22.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 22 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
func main() { debuglex = false txt := &bufsrc{in: bufio.NewReader(os.Stdin)} l := NewLex(txt, "stdin")
ExprParse(l) os.Exit(nerrors);}
![Page 23: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/23.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 23 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
type Text interface { Get() (rune, error) Unget() error}
type bufsrc struct { in io.RuneScanner}
func (s *bufsrc) Get() (rune, error) { r, _, err := s.in.ReadRune() return r, err}
func (s *bufsrc) Unget() error { return s.in.UnreadRune()}
![Page 24: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/24.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 24 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
type builtin struct { tok int num float64}var builtins = map[string]builtin{ "pi": builtin{tok: PI, num: 3.1415926}, "abs": builtin{tok: FN},}
var file stringvar line intvar debuglex boolvar nerrors int
![Page 25: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/25.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 25 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
type ExprLex interface { Lex(lval *ExprSymType) int Error(e string)}
type lex struct { in Text val []rune}
func NewLex(t Text, fname string) *lex { file = fname line = 1 return &lex{in: t}}
![Page 26: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/26.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 26 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
func (l *lex) got(r rune) { l.val = append(l.val, r)}
func (l *lex) getval() string { return string(l.val)}
![Page 27: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/27.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 27 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
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' { line++ } } if c == '\n' { line++ } if c != ' ' && c != '\t' { l.in.Unget() return nil } }}
![Page 28: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/28.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 28 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
func Errorf(s string, v ...interface{}) { fmt.Printf("%s:%d: ", file, line) fmt.Printf(s, v...) fmt.Printf("\n")
nerrors++ if nerrors > 5 { fmt.Printf("too many errors\n") os.Exit(1) }}
func (l *lex) Error(s string) { Errorf("%s near '%s'", s, l.getval())}
![Page 29: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/29.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 29 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
func (l *lex) Lex(lval *ExprSymType) (tid int) { if debuglex { defer func() { fmt.Printf("tok %s\n", tname(tid, lval)) }() } l.val = nil if err := l.skipBlanks(); err != nil { if err != io.EOF { Errorf("%s", err) } return 0 } c, err := l.in.Get() if err != nil { Errorf("%s", err) return 0 } l.got(c) switch {
...
![Page 30: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/30.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 30 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
func (l *lex) Lex(lval *ExprSymType) (tid int) {
...
switch { case c == '\n' || c == '+' || c == '*' || c == '/' || c == '(' || c == ')': lval.name = l.getval() return int(c) case c == '-': n, _ := l.in.Get() l.in.Unget() if n < '0' || n > '9' { return '-' } fallthrough
...
![Page 31: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/31.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 31 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
case c >= '0' && c <= '9': for { c, err := l.in.Get() if err != nil { Errorf("%s", err) return 0 } if c != '-' && c != 'e' && c != '+' && c != '.' && !unicode.IsNumber(c) { l.in.Unget() break } l.got(c) } // id,kw lval.name = l.getval() n, err := strconv.ParseFloat(lval.name, 64) if err != nil { Errorf("%s", err) return 0 } lval.num = n return NUM
![Page 32: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/32.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 32 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
case unicode.IsLetter(c): for { c, err := l.in.Get() if err != nil { Errorf("%s", err) return 0 } if !unicode.IsLetter(c) && !unicode.IsNumber(c) { l.in.Unget() break } l.got(c) } // id,kw lval.name = l.getval() b, ok := builtins[lval.name] if !ok { Errorf("unknown name '%s'", lval.name) return 0 } lval.num = b.num return b.tok } Errorf("wrong input at char %c", c) return 0}
![Page 33: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/33.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 33 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Lex para yacc
func main() { debuglex = false txt := &bufsrc{in: bufio.NewReader(os.Stdin)} l := NewLex(txt, "stdin")
ExprParse(l) os.Exit(nerrors);}
![Page 34: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/34.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 34 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Normalmente se usa una global nerrors
Y la usaremos para abortar tras varios errores
El parser llama al método Error del scanner en errores sintácticos:
func (l *lex) Error(s string) { Errorf("%s near '%s'", s, l.getval())}
Y luego hace lo que puede por recuperarse...
En C llama a yyerror y yacc mantiene yynerrs.
![Page 35: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/35.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 35 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Salida de Yacc
La salida es
El fuente en Go para el parser
Un fichero y.output con información del parser
![Page 36: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/36.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 36 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Salida de Yacc
Para
%token num%left '+'%left '*'
%%
expr : expr '+' expr | expr '*' expr | num
%%
![Page 37: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/37.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 37 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Salida de Yacc
Tenemos un y.output como sigue
state 0 $accept: .expr $end
num shift 2 . error
expr goto 1
state 1 $accept: expr.$end expr: expr.+ expr expr: expr.* expr
$end accept + shift 3 * shift 4 . error
![Page 38: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/38.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 38 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Salida de Yacc
state 2 expr: num. (3)
. reduce 3 (src line 8)
state 3 expr: expr +.expr
num shift 2 . error
expr goto 5
![Page 39: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/39.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 39 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Salida de Yacc
state 4 expr: expr *.expr
num shift 2 . error
expr goto 6
state 5 expr: expr.+ expr expr: expr + expr. (1) expr: expr.* expr
* shift 4 . reduce 1 (src line 8)
![Page 40: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/40.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 40 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Salida de Yacc
state 6 expr: expr.+ expr expr: expr.* expr expr: expr * expr. (2)
. reduce 2 (src line 8)
6 terminals, 2 nonterminals4 grammar rules, 7/2000 states0 shift/reduce, 0 reduce/reduce conflicts reported51 working sets usedmemory: parser 2/300000 extra closures6 shift entries, 1 exceptions3 goto entries0 entries saved by goto defaultOptimizer space used: output 9/300009 table entries, 2 zeromaximum spread: 6, maximum offset: 6
![Page 41: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/41.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 41 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Conflictos
Shift/reduce
A veces los buscamos (se hará un shift)
Reduce/reduce
La hemos liado (normalmente)
Pero se usa la primera encontrada en el estado
Hay que ver y.output
![Page 42: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/42.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 42 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Atributos
Cada símbolo tiene un valor
definido por la declaración dada a Yacc
En una regla de la forma
A: B C { ....} X Y
Podemos utilizar en la acción
$$: Valor de A
$1: Valor de B
$2: Valor de C
$4: Valor de X
$5: Valor de Y
![Page 43: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/43.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 43 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Calcular expresiones
Si incluimos las definiciones
%union { num float64 name string}
%token '('%token ')'%token '\n'%token <num> NUM PI%token <name> FN
%left '+' '-'%left '*' '/'
%type <num> expr
![Page 44: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/44.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 44 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Calcular expresiones
lines : line | lines line ;
line : expr '\n' { fmt.Printf("%v\n", $1) } | '\n' ;
expr : expr '+' expr { $$ = $1 + $3 } | expr '-' expr { $$ = $1 - $3 } | expr '*' expr { $$ = $1 * $3 } | expr '/' expr { $$ = $1 / $3 } | '(' expr ')' { $$ = $2 } | NUM | PI /* by default: {$$ = $1} */ ;
![Page 45: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/45.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 45 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Calcular expresiones
term% gacc -p Expr expr2.yterm% go run y.go1 + 2 * pi7.2831852
![Page 46: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/46.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 46 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Atributos
Como definimos los valores a partir de los hijos
los denominamos atributos sintetizados
![Page 47: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/47.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 47 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Acciones y gramática
La introducción de acciones equivale a introducir nuevos símbolos
Y modifica la gramática
A: B {...} C
No es lo mismo que
A: B C {...}
![Page 48: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/48.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 48 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Acciones y gramática
A: B {...} C
Equivale a
A: B TEMP CTEMP: /* empty */ { ... }
![Page 49: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/49.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 49 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Acciones y gramática
A: B { $$ = 1 } C { $$ = $2 + 2 }
Hace que el valor de A sea 3.
A: B TEMP C { $$ = $2 + 2 }TEMP: /* empty */ { $$ = 1 }
![Page 50: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/50.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 50 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Debug
Podemos darle un valor a la global yyDebug
O ExprDebug si usamos el flag de yacc -p Expr
term% go run y.go3 + 253 +reduce 10 in: state-6stdin:2: syntax error near ''state-10saw
error recovery pops state 10error recovery pops state 3error recovery pops state 0exit status 1
Esto es para su valor 2
![Page 51: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/51.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 51 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Debug
ExprDebug = 3
nos da
term% go run y.go3 + 3lex U+E002 NUMreduce 10 in: state-6lex U+002B +lex U+E002 NUMreduce 10 in: state-6lex U+000A
reduce 5 in: state-15reduce 3 in: state-96reduce 1 in: state-2lex U+0000 tok-1
![Page 52: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/52.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 52 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Tomemos de nuevo
lines : line | lines line ;
line : expr '\n' { fmt.Printf("%v\n", $1) } | '\n' ;
expr : expr '+' expr { $$ = $1 + $3 } | expr '-' expr { $$ = $1 - $3 } | expr '*' expr { $$ = $1 * $3 } | expr '/' expr { $$ = $1 / $3 } | '(' expr ')' { $$ = $2 } | NUM | PI /* by default: {$$ = $1} */ ;
![Page 53: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/53.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 53 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Y con esta entrada...
term% gacc -p Expr expr3.yterm% go run y.go3 + 2 *stdin:1: syntax error near '\n'exit status 1term%
en la primera línea con error dejamos de compilar!
![Page 54: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/54.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 54 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Pero podemos modificar la gramática usando:
lines : line | lines line ;
line : expr '\n' { fmt.Printf("%v\n", $1) } | error \n | '\n' ;
Y ahora tenemos:
term% go run y.go3 + 2 *stdin:1: syntax error near '\n'2 + 24
![Page 55: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/55.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 55 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
El símbolo error
está predefinido en la gramática
equivale a un error sintáctico
yacc puede reducir el error a error si tiene problemas
Con la producción hemos
dado la línea por zanjada
y la gramática sigue evaluando las líneas siguientes
![Page 56: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/56.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 56 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Veámoslo con yyDebug=2 (o ExprDebug)
term% go run y.go3 +reduce 11 in: state-7stdin:1: syntax error near '\n'state-11saw
error recovery pops state 11error recovery pops state 3reduce 4 in: state-15reduce 1 in: state-2
![Page 57: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/57.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 57 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
stdin:1: syntax error near '\n'state-11saw
error recovery pops state 11
Y de y.output:
state 11 expr: expr +.expr
( shift 6 NUM shift 7 PI shift 8 . error
expr goto 17
No había expresión tras el +
![Page 58: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/58.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 58 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Y sigue con...
error recovery pops state 3
Y de y.output:
state 3 line: expr.\n expr: expr.+ expr expr: expr.- expr expr: expr.* expr expr: expr./ expr
\n shift 10 + shift 11 - shift 12 * shift 13 / shift 14 . error
![Page 59: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/59.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 59 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Y sigue con...
reduce 4 in: state-15
Y de y.output:
state 15 line: error \n. (4)
. reduce 4 (src line 48)
El error ha podido reducirse por la nueva producción, y el análisis sigue...
![Page 60: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/60.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 60 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Veamos con esta otra...
lines : line | lines line ;
line : expr '\n' { if nerrors == 0 { fmt.Printf("%v\n", $1) } } | error '\n' { Errorf("wrong expression") } | '\n' ;
expr : expr '+' expr { $$ = $1 + $3 } | expr '+' error { Errorf("operand expected after '+'") } | expr '-' expr { $$ = $1 - $3 } | expr '*' expr { $$ = $1 * $3 } | expr '/' expr { $$ = $1 / $3 } | '(' expr ')' { $$ = $2 } | NUM | PI /* by default: {$$ = $1} */ ;
![Page 61: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/61.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 61 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Ahora tenemos...
term% go run y.go3 +stdin:1: syntax error near '\n'stdin:1: operand expected after '+'
Con yacc es muy difícil dar buenos errores.
aumentamos la gramática con errores sintácticos
Y nos sincronizamos en algún signo de puntuación
Pero habrá errores en cascada
Al final hay que evitar producir salida si hay errores
![Page 62: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/62.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 62 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Cuándo acaba un error y empieza otro?
Otro error:
term% go run y.go3 + +stdin:1: syntax error near '+'stdin:1: operand expected after '+'stdin:2: operand expected after '+'
![Page 63: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/63.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 63 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Cuándo acaba un error y empieza otro?
Ahora con...
lines : line | lines line ;
line : expr '\n' { if nerrors == 0 { fmt.Printf("%v\n", $1) } } | error '\n' { Errorf("wrong expression"); Errflag = 0 } | '\n' ;
expr : expr '+' expr { $$ = $1 + $3 } | expr '+' error { Errorf("operand expected after '+'"); Errflag = 0 } | expr '-' expr { $$ = $1 - $3 } | expr '*' expr { $$ = $1 * $3 } | expr '/' expr { $$ = $1 / $3 } | '(' expr ')' { $$ = $2 } | NUM | PI /* by default: {$$ = $1} */ ;
![Page 64: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/64.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 64 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Cuándo acaba un error y empieza otro?
Errflag = 0
le dice a Yacc que considere el error por zanjado.
En lugar de recuperarse llamará de nuevo a yyError
En este caso es peor usarlo, otras veces no
term% go run y.go3 + +stdin:1: syntax error near '+'stdin:1: operand expected after '+'stdin:2: syntax error near '\n'stdin:2: operand expected after '+'too many errors
![Page 65: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/65.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 65 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
A veces no son sintácticos...
expr : expr '+' expr { $$ = $1 + $3 } | expr '-' expr { $$ = $1 - $3 } | expr '*' expr { $$ = $1 * $3 } | expr '/' expr { if $3 == 0.0 { Errorf("divide by 0") $$ = 0 } else { $$ = $1 / $3 } } | '(' expr ')' { $$ = $2 } | NUM | PI /* by default: {$$ = $1} */ ;
![Page 66: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/66.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 66 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Errores
Con lo que tenemos...
term% go run y.go3 / 0stdin:0: divide by 0
![Page 67: Compiladores: Yacc - (c)2014 LSUBlsub.org/comp/slides/s07.yacc.pdf · Compiladores: Yacc - (c)2014 LSUB 1/25/16, 2:49 PM Page 18 of 67 Acciones Para, por ejemplo, pasar de notación](https://reader036.vdocuments.com.br/reader036/viewer/2022081523/5fcdfcfd7db2981f43088d07/html5/thumbnails/67.jpg)
1/25/16, 2:49 PMCompiladores: Yacc - (c)2014 LSUB
Page 67 of 67http://127.0.0.1:3999/s07.yacc.slide#1
Questions?
Francisco J BallesterosLSUB, URJChttp://lsub.org (http://lsub.org)