(New page: <p><span lang="pt">A gramática seguinte admite atribuições dentro de expressões.</span></p> <table border="0" cellpadding="3"> <tr> <td align="right">S</td> <td...) |
(→Problem (in Portuguese)) |
||
(7 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | == Problem (in Portuguese) == | ||
<p><span lang="pt">A gramática seguinte admite atribuições dentro de expressões.</span></p> | <p><span lang="pt">A gramática seguinte admite atribuições dentro de expressões.</span></p> | ||
− | + | 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. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Solution == | == Solution == | ||
− | [[category: | + | S -> E { E.lado = 'D'; } |
− | [[category: | + | E<sub>1</sub> -> E<sub>2</sub> + E<sub>3</sub> { if (E<sub>1</sub>.lado == 'E') error(); else { E<sub>2</sub>.lado = 'D'; E<sub>3</sub>.lado = 'D'; } } |
+ | E<sub>1</sub> -> E<sub>2</sub> := E<sub>3</sub> { if (E<sub>1</sub>.lado == 'E') error(); else { E<sub>2</sub>.lado = 'E'; E<sub>3</sub>.lado = 'D'; } } | ||
+ | E<sub>1</sub> -> ( E<sub>2</sub> ) { E<sub>2</sub>.lado = E<sub>1</sub>.lado; } | ||
+ | E -> id { /* nothing to do */ } | ||
+ | |||
+ | [[category:Compiladores]] | ||
+ | [[category:Ensino]] |
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 */ }