(Created page with "{{TOCright}} == The Problem (in Portuguese) == Considere o analisador sintáctico da linguagem Simple (abaixo). Considere que as variáveis só podem ser utilizadas em expressõe...") |
(→The Problem (in Portuguese)) |
||
Line 41: | Line 41: | ||
%% | %% | ||
</text> | </text> | ||
+ | |||
+ | A interface pública da tabela de símbolos é a seguinte: | ||
+ | |||
+ | <cpp> | ||
+ | template <typename Symbol> | ||
+ | class SymbolTable { | ||
+ | public: | ||
+ | // inicia a tabela com um contexto (global) | ||
+ | SymbolTable(); | ||
+ | |||
+ | // destrói contextos e símbolos (atenção a este aspecto) | ||
+ | ~SymbolTable(); | ||
+ | |||
+ | // criação de um novo contexto | ||
+ | void push(); | ||
+ | |||
+ | // destruição do contexto actual | ||
+ | void pop(); | ||
+ | |||
+ | // definição de um símbolo no contexto actual | ||
+ | bool insert(const char *name, Symbol *symbol); | ||
+ | |||
+ | // substituição de dados relativos a um símbolo (contexto actual) | ||
+ | bool replaceLocal(const char *name, Symbol *symbol); | ||
+ | |||
+ | // substituição de dados relativos a um símbolo (primeiro contexto onde ocorra) | ||
+ | bool replace(const char *name, Symbol *symbol); | ||
+ | |||
+ | // procura um símbolo (contexto actual) | ||
+ | bool findLocal(const char *name, Symbol *symbol); | ||
+ | |||
+ | // procura um símbolo (a partir do contexto indicado por from, relativo ao actual) | ||
+ | Symbol *find(const char *name, int from = 0) const; | ||
+ | }; | ||
+ | </cpp> | ||
== Solution == | == Solution == |
Contents |
Considere o analisador sintáctico da linguagem Simple (abaixo). Considere que as variáveis só podem ser utilizadas em expressões (ID ou ASSIGN) depois de declaradas (LET); que variáveis com o mesmo nome não podem ser declaradas no mesmo bloco; e que os tokens INT e STRING correspondem a literais, respectivamente, dos tipos inteiro e cadeia de caracteres.
Traduza para C (visitor em C++) e valide semanticamente (visitor em C++) a árvore sintáctica abstracta, emitindo mensagens se forem detectados erros de validação semântica. Utilize as classes da CDK (cdk::SymbolTable, nós, etc.) na resolução do problema. Pode ser útil definir outras classes auxiliares de validação de tipos (Symbol, etc.). Nos visitors, implemente apenas os métodos process. O acesso às sub-árvores de nós binários faz-se através dos métodos left() e right() e às sub-árvores de nós unários através do método argument().
<text> %token tSTART tBLOCK tEND tLET tPRINT tASSIGN %token <str> tID tSTRING %token tINT %type <node> program block decl instr %type <sequence> decls instrs %right tASSIGN %left '-' %nonassoc tUMINUS
%% program : tSTART block { _compiler->ast(new ProgramNode(LINE, $2)); }
;
block : tBLOCK decls instrs tEND { $$ = new BlockNode(LINE, $2, $3); }
;
decls : decl { $$ = new Sequence(LINE, $1); }
| decls decl { $$ = new Sequence(LINE, $2, $1); } ;
decl : tLET tID { $$ = new DeclNode(LINE, $2); }
;
instrs : instr { $$ = new Sequence(LINE, $1); }
| instrs instr { $$ = new Sequence(LINE, $2, $1); } ;
instr : ';' { $$ = new Nil(LINE); }
| block ';' { $$ = $1; } | tPRINT expr ';' { $$ = new PrintExpNode(LINE, $2); } | tPRINT tSTRING ';' { $$ = new PrintStrNode(LINE, $2); } ;
expr : tID { $$ = new Identifier(LINE, $1); }
| tINT { $$ = new Integer(LINE, $1); } | tID tASSIGN expr { $$ = new AssignmentNode(LINE, $1, $3); } | expr '-' expr { $$ = new SUB(LINE, $1, $3); } | '-' expr %prec tUMINUS { $$ = new NEG(LINE, $2); } ;
%% </text>
A interface pública da tabela de símbolos é a seguinte:
<cpp> template <typename Symbol> class SymbolTable { public:
// inicia a tabela com um contexto (global) SymbolTable();
// destrói contextos e símbolos (atenção a este aspecto) ~SymbolTable();
// criação de um novo contexto void push();
// destruição do contexto actual void pop();
// definição de um símbolo no contexto actual bool insert(const char *name, Symbol *symbol);
// substituição de dados relativos a um símbolo (contexto actual) bool replaceLocal(const char *name, Symbol *symbol);
// substituição de dados relativos a um símbolo (primeiro contexto onde ocorra) bool replace(const char *name, Symbol *symbol);
// procura um símbolo (contexto actual) bool findLocal(const char *name, Symbol *symbol);
// procura um símbolo (a partir do contexto indicado por from, relativo ao actual) Symbol *find(const char *name, int from = 0) const;
}; </cpp>