Semantic Analysis/Exercise 01: Difference between revisions
From Wiki**3
< Semantic Analysis
Line 1: | Line 1: | ||
{{TOCright}} | {{TOCright}} | ||
== The Problem (in Portuguese) == | == 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 (tID ou tASSIGN) depois de declaradas (tLET); que variáveis com o mesmo nome não podem ser declaradas no mesmo bloco; e que os tokens tINT e tSTRING correspondem a literais, respectivamente, dos tipos inteiro e cadeia de caracteres. | Considere o analisador sintáctico da linguagem Simple (abaixo). Considere que as variáveis só podem ser utilizadas em expressões ('''tID''' ou '''tASSIGN''') depois de declaradas ('''tLET'''); que variáveis com o mesmo nome não podem ser declaradas no mesmo bloco; e que os tokens '''tINT''' e '''tSTRING''' correspondem a literais, respectivamente, dos tipos inteiro e cadeia de caracteres. | ||
Traduza para C (visitor em C++: '''c_writer''') e valide semanticamente (visitor em C++: '''type_checker''') a árvore sintáctica abstracta, emitindo mensagens se forem detectados erros de validação semântica. Utilize as classes da CDK ('''cdk::symbol_table''', 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(). | Traduza para C (visitor em C++: '''c_writer''') e valide semanticamente (visitor em C++: '''type_checker''') a árvore sintáctica abstracta, emitindo mensagens se forem detectados erros de validação semântica. Utilize as classes da CDK ('''cdk::symbol_table''', 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> | <text> | ||
Line 13: | Line 13: | ||
%right tASSIGN | %right tASSIGN | ||
%left '-' | %left '-' | ||
%nonassoc | %nonassoc tUNARY | ||
%% | %% | ||
program : tSTART block { _compiler->ast(new | program : tSTART block { _compiler->ast(new program_node(LINE, $2)); } | ||
; | ; | ||
block : tBLOCK decls instrs tEND { $$ = new | block : tBLOCK decls instrs tEND { $$ = new block_node(LINE, $2, $3); } | ||
; | ; | ||
decls : decl | decls : decl { $$ = new cdk::sequence_node(LINE, $1); } | ||
| decls decl | | decls decl { $$ = new cdk::sequence_node(LINE, $2, $1); } | ||
; | ; | ||
decl : tLET tID | decl : tLET tID { $$ = new declaration_node(LINE, $2); } | ||
; | ; | ||
instrs : instr | instrs : instr { $$ = new cdk::sequence_node(LINE, $1); } | ||
| instrs instr | | instrs instr { $$ = new cdk::sequence_node(LINE, $2, $1); } | ||
; | ; | ||
instr : ';' | instr : ';' { $$ = new cdk::nil_node(LINE); } | ||
| block ';' | | block ';' { $$ = $1; } | ||
| tPRINT expr ';' | | tPRINT expr ';' { $$ = new print_exp_node(LINE, $2); } | ||
| tPRINT tSTRING ';' | | tPRINT tSTRING ';' { $$ = new print_str_node(LINE, $2); } | ||
; | ; | ||
expr : tID | expr : tID { $$ = new cdk::identifier_node(LINE, $1); } | ||
| tINT | | tINT { $$ = new cdk::integer_node(LINE, $1); } | ||
| | | expr '-' expr { $$ = new cdk::sub_node(LINE, $1, $3); } | ||
| | | '-' expr %prec tUNARY { $$ = new cdk::neg_node(LINE, $2); } | ||
| | | tID tASSIGN expr { $$ = new assignment_node(LINE, $1, $3); } | ||
; | ; | ||
%% | %% |
Revision as of 19:24, 5 May 2014
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 (tID ou tASSIGN) depois de declaradas (tLET); que variáveis com o mesmo nome não podem ser declaradas no mesmo bloco; e que os tokens tINT e tSTRING correspondem a literais, respectivamente, dos tipos inteiro e cadeia de caracteres.
Traduza para C (visitor em C++: c_writer) e valide semanticamente (visitor em C++: type_checker) a árvore sintáctica abstracta, emitindo mensagens se forem detectados erros de validação semântica. Utilize as classes da CDK (cdk::symbol_table, 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 tUNARY
%% program : tSTART block { _compiler->ast(new program_node(LINE, $2)); }
;
block : tBLOCK decls instrs tEND { $$ = new block_node(LINE, $2, $3); }
;
decls : decl { $$ = new cdk::sequence_node(LINE, $1); }
| decls decl { $$ = new cdk::sequence_node(LINE, $2, $1); } ;
decl : tLET tID { $$ = new declaration_node(LINE, $2); }
;
instrs : instr { $$ = new cdk::sequence_node(LINE, $1); }
| instrs instr { $$ = new cdk::sequence_node(LINE, $2, $1); } ;
instr : ';' { $$ = new cdk::nil_node(LINE); }
| block ';' { $$ = $1; } | tPRINT expr ';' { $$ = new print_exp_node(LINE, $2); } | tPRINT tSTRING ';' { $$ = new print_str_node(LINE, $2); } ;
expr : tID { $$ = new cdk::identifier_node(LINE, $1); }
| tINT { $$ = new cdk::integer_node(LINE, $1); } | expr '-' expr { $$ = new cdk::sub_node(LINE, $1, $3); } | '-' expr %prec tUNARY { $$ = new cdk::neg_node(LINE, $2); } | tID tASSIGN expr { $$ = new assignment_node(LINE, $1, $3); } ;
%% </text>
Solution
The solution is straightforward and very similar to that obtained for the the Tiny language.