Escolar Documentos
Profissional Documentos
Cultura Documentos
Programa fonte
parse tree
grafo de dependncia
Tipos de atributos
Atributos sintetizados: computados a partir dos atributos dos ns-filhos (abaixo do prprio n). Atributos herdados: computados a partir de ns-pais ou ns-irmos (acima ou ao lado do prprio n).
Exemplo em yacc
line
: ; expr : | ; term : | ; factor : | ; expr '\n'{ printf("%d\n", $1); } expr '+' term term { $$ = $1 + $3; }
term '*' factor { $$ = $1 * $3; } factor '(' expr ')' DIGIT { $$ = $2; }
Atributos Sintetizados
Muito usados na prtica. Uma definio que usa apenas atributos sintetizados chamada de S-attributed definition. Definies S-attributed podem sempre ser anotadas atravs da avaliao das regras semnticas em cada n, atravessando a parse tree bottom-up, a partir das folhas.
T.val = 15
T.val = 3 F.val = 3 digit.lexval = 3 digit.lexval = 5 F.val = 5 *
T.val = 4 F.val = 4
digit.lexval = 4
Atributos Herdados
Definidos a partir dos ns-pai e/ou dos nsirmos. teis para especificar dependncia do contexto, por exemplo se um identificador aparece esquerda ou direita de uma atribuio. sempre possvel trabalhar apenas com atributos sintetizados.
Regra semntica L.in = T.type T.type = integer T.type = real L1.in = L.in addtype(id.entry, L.in) addtype(id.entry, L.in)
Grafos de dependncia
teis para determinar a ordem de avaliao dos atributos:
1. Gerar grafo de dependncia 2. fazer sort topolgico ordenao dos ns de um grafo acclico dirigido em que todas as arestas vo de um n anterior para ns posteriores.
S1 +
S2
while
*
B S1 3 5
Semelhante traduo para notao ps-fixa: criar sub-rvores criando um n para cada operando e operador. Cada n pode ser representado por um registro com vrios campos. Operador: um campo identifica o tipo do operador, e os outros campos so apontadores para os ns dos operandos. Podem existir campos adicionais para guardar atributos.
Contruir a rvore para a expresso: a4*c p1 = mkleaf(id, entry_a); p2 = mkleaf(num, 4); p3 = mknode(-,p1,p2); p4 = mkleaf(id, entry_c); p5 = mknode(+, p3, p4);
Regra semntica E.nptr = mknode(+, E1.nptr, T.nptr) E.nptr = T.nptr T.nptr = E.nptr T.nptr = mkleaf(id,id.entry) T.nptr = mkleaf(num,num.val)