(→Solution) |
(→Problem (in Portuguese)) |
||
Line 3: | Line 3: | ||
<table border="0" cellpadding="3"> | <table border="0" cellpadding="3"> | ||
<tr> | <tr> | ||
− | <td align="left" style="padding-left: 100px;">S | + | <td align="left" style="padding-left: 100px;">S → E</td> |
</tr> | </tr> | ||
<tr> | <tr> | ||
− | <td align="left" style="padding-left: 100px;">E | + | <td align="left" style="padding-left: 100px;">E → E '''+''' E | E ''':=''' E | '''(''' E ''')''' | '''id'''</td> |
</tr> | </tr> | ||
</table> | </table> |
A gramática seguinte admite atribuições dentro de expressões.
S → E |
E → E + E | E := E | ( E ) | id |
Quando uma expressão está a ser analisada é necessário diferenciar os casos onde a expressão está à direita, daqueles onde a expressão está à esquerda, do sinal de atribuição. Note que não é possível atribuir um valor a uma expressão. Por exemplo a expressão id + id := id é ilegal. No entanto, as expressões id := ( id + id ), quer id := ( id := id ), ou ainda ( id ) := ( id := ( id + id ) ) são autorizadas.
Considere que o operador := é menos prioritário que o operador +, além de associativo à direita, enquanto o operador '+' é associativo à esquerda.
Escreva um esquema de tradução que usa um atributo herdado (e nenhum sintetizado) chamado lado associado ao símbolo E, e que determina se a expressão corrente está à direita ou à esquerda da atribuição. O código associado à gramática emitirá uma mensagem de erro caso a expressão seja ilegal.
S -> E { E.lado = 'D'; } E1 -> E2 + E3 { if (E1.lado == 'E') error(); else { E2.lado = 'D'; E3.lado = 'D'; } } E1 -> E2 := E3 { if (E1.lado == 'E') error(); else { E2.lado = 'E'; E3.lado = 'D'; } } E1 -> ( E2 ) { E2.lado = E1.lado; } E -> id { /* nothing to do */ }