Análise sintáctica

A Fase 2 do trabalho consiste na implementação de um analisador sintáctico. Esta implementação pode ser feita em C/C++ ou usando a ferramenta yacc/bison. O programa deverá usar o analisador léxico anterior e reconhecer sintacticamente qualquer programa escrito em LEI. Uma boa estratégia de diagnóstico e recuperação de erros será valorizada. 

A gramática que reconhece um programa em LEI pode ser definida da seguinte forma:


Programa → Decls Funcs
Decls → DefClasses DeclVars DeclFuncs
DefClasses → DefClasses DefClass | DefClass
DefClass → classe Classe { CompClasses }
                 | subclasse Classe { ListaClasses } { CompClasses }
                 | ε
Classe → ID
CompClasses → CompClasses CompClass | CompClass
CompClass → DeclFunc | DeclVar
                       | construtor DeclFunc
                       | destrutor DeclFunc
ListaClasses → ListaClasses , Classe | Classe
DeclVars → DeclVars DeclVar | DeclVar
DeclVar → TipoSimples ListaVars | TipoVector ListaVect | ε
Tipo → TipoSimples | TipoVector
TipoSimples → inteiro | real | Classe
ListaVars → ListaVars , ID | ID
TipoVector → vector inteiro | vector real | vector Classe
ListaVect → ListaVect , ID [ INT ] | ID [ INT ]
DeclFuncs → DeclFuncs DeclFunc | DeclFunc
DeclFunc → funcao Tipo ID ( ListaTipos ) | funcao Tipo ID ( )
ListaTipos → ListaTipos , Tipo | Tipo
Funcs → Funcs Func | Func
Func → Cabeca { Corpo }
Cabeca → Tipo ClasseID ( ListaArgs ) | Tipo ClasseID ( )
ListaArgs → ListaArgs , Tipo ID | Tipo ID
Corpo → VarLocais Instrucoes
VarLocais → DeclVars
Instrucoes → Instrucoes Inst | Inst
Inst → ε | quebra | continua | Atrib | ChamaFuncao | ChamaFuncaoPreDef | CicloSeSenao | CicloPara | CicloEnquanto | CicloFazerEnquanto
Atrib → ClasseID <- Expr
ChamaFuncao → ClasseID ( ListaExpr) | ClasseID ( )
ChamaFuncaoPreDef → ler ( ArgLE ) | escrever ( ArgLE ) | ler_caracter ( ) | escrever_caracter ( Expr )
CicloSeSenao → se ( Cond ) { Instrucoes } senao { Instrucoes }
                         | se ( Cond ) { Instrucoes }
CicloPara → para ( Atrib ate Cond passo Atrib ) { Instrucoes}
CicloEnquanto → enquanto ( Cond ) { Instrucoes }
ClicoFazerEnquanto → fazer { Instrucoes } enquanto ( Cond )
ListaExpr → ListaExpr , Expr | Expr
ArgLE → ArgLE , INT , ClasseID | ArgLE , ClasseID | INT , ClasseID | ClasseID
ClasseID → ClasseID . ID | ID | ClasseID . ID [ Expr ] | ID [ Expr ]
Expr → Expr OpExpr Expr | OpExprUn  Expr | ( Expr ) | ClasseID | Numero | ChamaFuncao | ChamaFuncaoPreDef | STRING
Numero → INT | REAL
OpExpr → OpAritemetico | OpBits
OpAritmetico → * | / | + | - | /q | /r
OpBits → e | ou | oux | dir | esq
OpExprUn → + | - | nao
Cond → Cond OpCond Cond | OpCondUn Cond | ( Cond ) | Expr
OpCond → OpRelacional | OpLogico
OpRelacional → < | <= | > | >= | = | !=
OpLogico → _e | _ou | _oux
OpCondUn → _nao


Como é fácil de verificar, esta gramática é ambígua. Antes de ser usada, convirá eliminar qualquer ambiguidade (tratando a precedência habitual de operadores), factorizar e eliminar recursividade à esquerda.

De referir ainda que as classes definem novos tipos. Será necessário guardar os nomes das variáveis para os poder usar na declaração de variáveis.

A entregar

Código em C/C++ ou yacc/bison.


Voltar

Ultima alteração: sexta-feira, 24 de Novembro de 2000 às 20:58