Generación de código Generación de código para sentencias condicionales (I) Marina de la Cruz Alfonso Ortega Índice • Generación de código para sentencias condicionales • Generación de código para bucles while cond_stm : TOK_IF exp TOK_THEN stm_train TOK_FI exp ; ; exp ; pop eax mov eax, [eax] PILA cmp eax, 0 je near fin_then# ; ; ; ; si nºrefs de exp>0 stm_train fin_then#: • Las ideas básicas son: • modificar ligeramente la gramática. • asegurar que el número de etiqueta(#) sea el mismo en las dos veces que aparece fin_then# . Para ello se añade un nuevo atributo semántico, etiqueta. 1 Prácticas de compiladores 2004-2005 Generación de código para sentencias condicionales (II) cond_stm : TOK_IF exp TOK_THEN Generación de código para sentencias condicionales (III) cond_stm:TOK_IF exp TOK_THEN stm_train TOK_FI MODIFICACIÓN DE LA GRAMÁTICA cond_stm ; ; ; : if_exp_then stm_train TOK_FI if_exp_then : TOK_IF exp TOK_THEN Comprobaciones semánticas comprobar que $2.tipo == TIPO_BOOL comprobar $2.nrefs<2 stm_train1 pop eax mov eax, [eax] PILA cmp eax, 0 je near fin_then# Generación de código ; ; ; fin_then#: ; # = $1.etiqueta TOK_ELSE stm_train2 TOK_FI exp exp Reserva de etiqueta (#) ; si nºrefs de exp>0 stm_train1 jmp near fin_ifelse# $$.etiqueta=etiqueta++ fin_then#: Generación de código pop eax mov eax, [eax] ; si nºrefs de exp>0 cmp eax, 0 je near fin_then# ; # = $$.etiqueta Prácticas de compiladores 2004-2005 2 Prácticas de compiladores 2004-2005 ; ; ; stm_train2 fin_ifelse#: 3 Prácticas de compiladores 2004-2005 4 Generación de código para sentencias condicionales (IV) cond_stm:TOK_IF exp TOK_THEN stm_train1 Generación de código para bucles while (I) TOK_ELSE stm_train2 TOK_FI loop_stm : TOK_WHILE exp TOK_DO stm_train TOK_END MODIFICACIÓN DE LA GRAMÁTICA cond_stm if_exp_then_stm_train1 if_exp_then : if_exp_then_stm_train1 TOK_ELSE stm train2 TOK_FI : if_exp_then stm_train1 : TOK_IF exp TOK_THEN inicio_while#: ; ; exp ; Propagación de atributos Comprobaciones semánticas $$.etiqueta = $1.etiqueta comprobar que $2.tipo == TIPO_BOOL comprobar $2.nrefs<2 jmp near inicio_while# Generación de código fin_ifelse#: fin_while#: ; # = $1.etiqueta 5 Generación de código para bucles while (II) TOK_WHILE exp TOK_DO stm_train TOK_END MODIFICACIÓN DE LA GRAMÁTICA loop_stm : while_exp_do stm_train TOK_END while_exp_do : token_while exp TOK_DO token_while : TOK_WHILE Reserva de etiqueta (#) ; # = $$.etiqueta Comprobaciones semánticas comprobar que $2.tipo == TIPO_BOOL comprobar $2.nrefs<2 Propagación de atributos Generación de código jmp near inicio_while# fin_while#: ; # = $1.etiqueta $$.etiqueta = $1.etiqueta Generación de código pop eax mov eax, [eax] ; si nºrefs de exp>0 cmp eax, 0 je near fin_while# ; # = $$.etiqueta Prácticas de compiladores 2004-2005 ; si nºrefs de exp>0 ; ; <stm train> ; ; # = $1.etiqueta Prácticas de compiladores 2004-2005 inicio_while#: cmp eax, 0 je near fin_while# fin_then#: Generación de código pop eax mov eax, [eax] ; si nºrefs de exp>0 cmp eax, 0 je near fin_then# ; # = $$.etiqueta Generación de código PILA jmp near fin_ifelse# Reserva de etiqueta (#) $$.etiqueta=etiqueta++ pop eax mov eax, [eax] Generación de código $$.etiqueta=etiqueta++ loop_stm : exp 7 Prácticas de compiladores 2004-2005 6