Difference between revisions of "Semantic Analysis/Exercise 01"

From Wiki**3

< Semantic Analysis
(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 ==

Revision as of 18:45, 2 June 2012

The Problem (in Portuguese)

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>

Solution