III – Análise sintáctica Geradores de parsers Bibliografia aconselhada: –Aho, Sethi e Ullman – secção 4.9 LFA 1999/ Jorge Morais
Yacc – gerador de parsers YACC – Yet Another Compiler-Compiler Tradução para um programa em C usando o método LALR fich.y compilador yacc y.tab.c y.tab.c compilador C a.out entrada a.out saída LFA 1999/ Jorge Morais
Programa em yacc Declarações % Regras de tradução % Rotinas em C LFA 1999/ Jorge Morais
Declarações Declarações em C entre %{ e %} – tradução directa para C: enum{FALSE,TRUE}; Declaração de tokens: %token INTEIRO REAL Precedência e associatividade de operadores LFA 1999/ Jorge Morais
Regras de tradução X Y 1 | Y 2 |... | Y n X:Y 1 { acção semântica 1 } |Y 2 { acção semântica 2 }... |Y n { acção semântica n } ; LFA 1999/ Jorge Morais
Terminais e não terminais Strings de letras e dígitos declarados como tokens são terminais Caracteres na forma c são terminais (correspondem a um token representado apenas pelo próprio carácter) Todas as outras strings são não terminais LFA 1999/ Jorge Morais
Valores de atributos $$ – valor de atributo do lado esquerdo da regra $i – valor de atributo do elemento de ordem i do lado direito Exemplo: Expr : expr + term { $$ = $1 + $3 } | term ; LFA 1999/ Jorge Morais
Interface com o analisador léxico O yacc comunica com o analisador léxico chamando a função yylex Os atributos são passados a partir da variável global yylval Usando o lex/flex podemos gerar o analisador léxico, que poderá ser usado fazendo #include lex.yy.c Compilação: gcc y.tab.c -ly -ll LFA 1999/ Jorge Morais
Resolução de conflitos Conflitos reduce/reduce – é usado o primeiro a ser listado na especificação do yacc Conflitos shift/reduce – é resolvido escolhendo o shift LFA 1999/ Jorge Morais
Associatividade e precedência Associatividade: %left + - %right ^ %noassoc < Precedência: %prec terminal LFA 1999/ Jorge Morais