Como construir um compilador utilizando ferramentas...

Post on 21-Jul-2020

8 views 1 download

Transcript of Como construir um compilador utilizando ferramentas...

Como construir um compilador utilizandoferramentas Java

Aula 12 – Análise Semântica

Prof. Marcio Delamarodelamaro@icmc.usp.br

Como construir um compilador utilizando ferramentas Java – p. 1/86

O que é

Preocupa com o significado de cada construção.

Como construir um compilador utilizando ferramentas Java – p. 2/86

O que é

Preocupa com o significado de cada construção.

Depende da linguagem.

Como construir um compilador utilizando ferramentas Java – p. 2/86

O que é

Preocupa com o significado de cada construção.

Depende da linguagem.

Passeio(s) na árvore sintática

Como construir um compilador utilizando ferramentas Java – p. 2/86

O que é

Preocupa com o significado de cada construção.

Depende da linguagem.

Passeio(s) na árvore sintática

Realizada em diversas fases, cada um relativa adiferentes aspectos.

Como construir um compilador utilizando ferramentas Java – p. 2/86

Por que em fases?

class A {B varB;

}

class B {}

(1)ListNode

(2)ClassDeclNode (8)ListNode

Token: A (3)ClassBodyNode (9)ClassDeclNode

(4)ListNode Token: B (10)ClassBodyNode

(5)VarDeclNode

Token: B (6)ListNode

(7)VarNode

Token: varB

Como construir um compilador utilizando ferramentas Java – p. 3/86

Por que em fases?a. visita ao nó 1

b. visita ao nó 2, insere aclasse A

c. visita ao nó 3

d. visita ao nó 4

e. visita ao nó 5 e veri-fica declaração

f. visita ao nó 8

g. visita ao nó 9 e insereclasse B

h. visita ao nó 10

(1)ListNode

(2)ClassDeclNode (8)ListNode

Token: A (3)ClassBodyNode (9)ClassDeclNode

(4)ListNode Token: B (10)ClassBodyNode

(5)VarDeclNode

Token: B (6)ListNode

(7)VarNode

Token: varB

Como construir um compilador utilizando ferramentas Java – p. 4/86

Por que em fases?Fase 1:

a. visita ao nó 1

b. visita ao nó 2, insere aclasse A

c. visita ao nó 3

d. visita ao nó 4

e. visita ao nó 5

f. visita ao nó 8

g. visita ao nó 9 e inserreclasse B

h. visita ao nó 10.

(1)ListNode

(2)ClassDeclNode (8)ListNode

Token: A (3)ClassBodyNode (9)ClassDeclNode

(4)ListNode Token: B (10)ClassBodyNode

(5)VarDeclNode

Token: B (6)ListNode

(7)VarNode

Token: varB

Como construir um compilador utilizando ferramentas Java – p. 5/86

Por que em fases?Fase 2:

a. visita ao nó 1

b. visita ao nó 2

c. visita ao nó 3

d. visita ao nó 4

e. visita ao nó 5 e veri-fica declaração

f. visita ao nó 8

g. visita ao nó 9

h. visita ao nó 10

(1)ListNode

(2)ClassDeclNode (8)ListNode

Token: A (3)ClassBodyNode (9)ClassDeclNode

(4)ListNode Token: B (10)ClassBodyNode

(5)VarDeclNode

Token: B (6)ListNode

(7)VarNode

Token: varB

Como construir um compilador utilizando ferramentas Java – p. 6/86

analisador semântico: parte 1

Analisa a declaração de classes.

Como construir um compilador utilizando ferramentas Java – p. 7/86

analisador semântico: parte 1

Analisa a declaração de classes.

Constrói tabela de símbolos.

Como construir um compilador utilizando ferramentas Java – p. 7/86

analisador semântico: parte 1

Analisa a declaração de classes.

Constrói tabela de símbolos.

Ao encontrar um nó ClassDeclNode, o analisadorsemântico deve incluir a classe correspondente natabela de símbolos.

Como construir um compilador utilizando ferramentas Java – p. 7/86

analisador semântico: parte 1

Analisa a declaração de classes.

Constrói tabela de símbolos.

Ao encontrar um nó ClassDeclNode, o analisadorsemântico deve incluir a classe correspondente natabela de símbolos.

A árvore sintática não precisa ser completamentepercorrida, somente os seus níveis mais altos.

Como construir um compilador utilizando ferramentas Java – p. 7/86

analisador semântico: parte 1

Analisa a declaração de classes.

Constrói tabela de símbolos.

Ao encontrar um nó ClassDeclNode, o analisadorsemântico deve incluir a classe correspondente natabela de símbolos.

A árvore sintática não precisa ser completamentepercorrida, somente os seus níveis mais altos.

Tratamento de classes aninhadas.

Como construir um compilador utilizando ferramentas Java – p. 7/86

Tratamento das classes

ListNode

ClassDeclNode

class1

ListNode

ClassDeclNodeClassBodyNode

ClassBodyNodeclass2

Symtable

class1

class2

class class1 {}class class2 {}

Como construir um compilador utilizando ferramentas Java – p. 8/86

Tratamento das classes aninhadas

ListNode

ClassDeclNode

class1

ListNode

ClassDeclNode

ListNode

ClassDeclNode

aninhada

ListNode

ClassDeclNodeClassBodyNode

ClassBodyNodeclass2

ClassBodyNode

ClassBodyNode

Symtable

class1

class2

aninhada

aninhada

aninhada

Symtable

Symtable

class class1 { class aninhada{ }}

class class2 { class aninhada { }}

Como construir um compilador utilizando ferramentas Java – p. 9/86

Erros semânticos...

Nessa fase da análise semântica, somente um tipo de errosemântico pode ser detectado: quando uma classe que jáfoi definida num determinado escopo é redefinida.

class class1{

class class1 {}

}

Como construir um compilador utilizando ferramentas Java – p. 10/86

Implementação:mainif ( parser.token_source.foundLexError()

+ parser.contParseError == 0)

{

if (print_tree) // exibir a arvore

{

PrintTree prt = new PrintTree();

prt.printRoot(root);

}

ClassCheck tc = new ClassCheck();

try {

tc.ClassCheckRoot(root);

System.out.println("0 Semantic error found");

}

catch (SemanticException e)

{

System.out.println(e.getMessage());

}

}

Como construir um compilador utilizando ferramentas Java – p. 11/86

ClassCheckpackage semanalysis;

import symtable. * ;

import syntacticTree. * ;

public class ClassCheck {

Symtable Maintable; // tabela de mais alto n ıvel

protected Symtable Curtable; // apontador para a tb corrent e

int foundSemanticError;

public ClassCheck()

{

EntrySimple k;

foundSemanticError = 0;

Maintable = new Symtable(); // cria tabela principal

k = new EntrySimple("int"); // insere tipos b asicos

Maintable.add(k);

k = new EntrySimple("string");

Maintable.add(k);

}

Como construir um compilador utilizando ferramentas Java – p. 12/86

Tratando da raizpublic void ClassCheckRoot(ListNode x) throws SemanticEx ception

{

Curtable = Maintable; // tabela corrente = principal

// chama an alise para raiz da arvore

ClassCheckClassDeclListNode(x);

// se houve erro, lanca excec ao

if (foundSemanticError != 0)

throw new SemanticException(foundSemanticError +

" Semantic Errors found (phase 1)");

}

Como construir um compilador utilizando ferramentas Java – p. 13/86

Tratando lista de classespublic void ClassCheckClassDeclListNode(ListNode x)

{

if (x == null) return;

try {

ClassCheckClassDeclNode( (ClassDeclNode) x.node);

}

catch (SemanticException e)

{ // se um erro ocorreu na an alise da classe,

// d a a mensagem, mas faz a an alise para pr oxima classe

System.out.println(e.getMessage());

foundSemanticError++;

}

ClassCheckClassDeclListNode(x.next);

}

Como construir um compilador utilizando ferramentas Java – p. 14/86

Tratando declaração de uma classepublic void ClassCheckClassDeclNode(ClassDeclNode x)

throws SemanticException {

// salva apontador p/ tabela corrente

Symtable temphold = Curtable;

EntryClass nc;

if (x == null) return;

// procura classe na tabela

nc = (EntryClass) Curtable.classFindUp(x.name.image);

if (nc != null) // j a declarada, ERRO

{

throw new SemanticException(x.name,

"Class "+ x.name.image + " already declared");

}

// inclui classe na tabela corrente

Curtable.add(nc = new EntryClass(x.name.image, Curtable ));

Curtable = nc.nested; // tabela corrente = tabela da classe

ClassCheckClassBodyNode(x.body);

Curtable = temphold; // recupera apontador p/ tabela corren te

}

Como construir um compilador utilizando ferramentas Java – p. 15/86

Errata

O erro reportado no slide anterior deveria ser verificadotambém na fase 2 apenas. No exemplo abaixo, B ainda nãoestaria na tabela de símbolos, mas o erro deveria serapontado. Na fase i verifica-se a partir da tabela corrente.Na fase 2 a partir da tabela do nível anterior.

class A {class B{}

}class B {}

Como construir um compilador utilizando ferramentas Java – p. 16/86

Como fica a tabela de símbolos

int

1

0

string

int

1

0

string

int

1

0

string

Maintable Curtable

APróx. livre

Maintable

Curtable

Próx. livre

A

Maintable

Próx. livre

Curtable

(a) (b)

(c)

2 2

2

3

Como construir um compilador utilizando ferramentas Java – p. 17/86

Regras de escopo

Verifica-se se no escopo corrente já existe uma classecom o mesmo nome da classe sendo declarada.

Como construir um compilador utilizando ferramentas Java – p. 18/86

Regras de escopo

Verifica-se se no escopo corrente já existe uma classecom o mesmo nome da classe sendo declarada.

Essa procura é feita por meio do métodoSymtable.classFindUp

Como construir um compilador utilizando ferramentas Java – p. 18/86

Regras de escopo

Verifica-se se no escopo corrente já existe uma classecom o mesmo nome da classe sendo declarada.

Essa procura é feita por meio do métodoSymtable.classFindUp

Procura a classe na tabela corrente.

Como construir um compilador utilizando ferramentas Java – p. 18/86

Regras de escopo

Verifica-se se no escopo corrente já existe uma classecom o mesmo nome da classe sendo declarada.

Essa procura é feita por meio do métodoSymtable.classFindUp

Procura a classe na tabela corrente.

Caso não tenha encontrado, chama recursivamente apesquisa utilizando a tabela de nível superior.

Como construir um compilador utilizando ferramentas Java – p. 18/86

classFindUppublic EntryTable classFindUp(String x)

{

EntryTable p = top;

// para cada elemento da tabela corrente

while (p != null)

{

// verifica se e uma entrada de classe ou tipo simples

// e ent ao compara o nome

if ( ((p instanceof EntryClass) || (p instanceof EntrySimpl e))

&& p.name.equals(x))

return p;

p = p.next; // pr oxima entrada

}

if (levelup == null) // se n ao achou e e o n ıvel mais externo

return null; // retorna null

// procura no n ıvel mais externo

return levelup.mytable.classFindUp(x);

}

Como construir um compilador utilizando ferramentas Java – p. 19/86

Tratando o corpo da classe

Só interessa o corpo da classe se dentro dele houverdeclaração de classe aninhada.

Como construir um compilador utilizando ferramentas Java – p. 20/86

Tratando o corpo da classe

Só interessa o corpo da classe se dentro dele houverdeclaração de classe aninhada.

Então somente a lista de classes é que interessa.

Como construir um compilador utilizando ferramentas Java – p. 20/86

Tratando o corpo da classe

Só interessa o corpo da classe se dentro dele houverdeclaração de classe aninhada.

Então somente a lista de classes é que interessa.

Dentro da declaração de variáveis, métodos ouconstrutores, não existem declarações de classes.

Como construir um compilador utilizando ferramentas Java – p. 20/86

Tratando o corpo da classepublic void ClassCheckClassBodyNode(

ClassBodyNode x)

{

if (x == null) return;

ClassCheckClassDeclListNode(x.clist);

}

Como construir um compilador utilizando ferramentas Java – p. 21/86

ExercíciosDiga como ficaria a tabela de símbolos após a primeira fase daanalisador semântico ser concluída. Mostre também qual oprograma fonte que gerou cada árvore.

Como construir um compilador utilizando ferramentas Java – p. 22/86

Exercícios

Como construir um compilador utilizando ferramentas Java – p. 23/86

Exercícios

Como construir um compilador utilizando ferramentas Java – p. 24/86

Exercícios

Como construir um compilador utilizando ferramentas Java – p. 25/86

Exercícios

Como construir um compilador utilizando ferramentas Java – p. 26/86

Exercícios

Como construir um compilador utilizando ferramentas Java – p. 27/86

Análise semântica: parte 2

Nova classe VarCheck

Como construir um compilador utilizando ferramentas Java – p. 28/86

Análise semântica: parte 2

Nova classe VarCheck

Usa a estrutura montada na parte 1

Como construir um compilador utilizando ferramentas Java – p. 28/86

Análise semântica: parte 2

Nova classe VarCheck

Usa a estrutura montada na parte 1

Faz outras verificações em relação a classes edeclaraçoes de variáveis.

Como construir um compilador utilizando ferramentas Java – p. 28/86

Análise semântica: parte 2

Nova classe VarCheck

Usa a estrutura montada na parte 1

Faz outras verificações em relação a classes edeclaraçoes de variáveis.

Não requer a análise de toda a árvore sintática.

Como construir um compilador utilizando ferramentas Java – p. 28/86

Método mainif ( parser.token_source.foundLexError()

+ parser.contParseError == 0)

{

if (print_tree) // exibir a arvore

{

PrintTree prt = new PrintTree();

prt.printRoot(root); // chama m etodo para imprimir arvore

}

VarCheck tc = new VarCheck();

try {

tc.VarCheckRoot(root);

System.out.println("0 Semantic Errors found");

}

catch (SemanticException e)

{

System.out.println(e.getMessage());

}

}

Como construir um compilador utilizando ferramentas Java – p. 29/86

VarCheckpackage semanalysis;

import symtable. * ;

import syntacticTree. * ;

public class VarCheck extends ClassCheck {

public VarCheck()

{

super();

}

public void VarCheckRoot(ListNode x) throws SemanticExce ption

{

ClassCheckRoot(x); // faz an alise das classes

VarCheckClassDeclListNode(x);

if (foundSemanticError != 0) // se houve erro, lanca excec ao

throw new SemanticException(foundSemanticError +

" Semantic Errors found (phase 2)");

}

Como construir um compilador utilizando ferramentas Java – p. 30/86

VarCheck: observações

É subclasse de ClassCheck

Como construir um compilador utilizando ferramentas Java – p. 31/86

VarCheck: observações

É subclasse de ClassCheck

Ou seja, ao criar um objeto dessa classe, são herdadosos métodos vistos na parte 1 da analisador semântico.

Como construir um compilador utilizando ferramentas Java – p. 31/86

VarCheck: observações

É subclasse de ClassCheck

Ou seja, ao criar um objeto dessa classe, são herdadosos métodos vistos na parte 1 da analisador semântico.

Antes de iniciar a análise, é chamado o métodoClassCheckRoot(x) que realiza a primeira parte daanálise.

Como construir um compilador utilizando ferramentas Java – p. 31/86

Análise de uma lista de classespublic void VarCheckClassDeclListNode(ListNode x)

{

if (x == null) return;

try {

VarCheckClassDeclNode( (ClassDeclNode) x.node);

}

catch (SemanticException e)

{ // se um erro ocorreu na an alise da classe,

// d a a mensagem, mas faz a an alise para pr oxima classe

System.out.println(e.getMessage());

foundSemanticError++;

}

VarCheckClassDeclListNode(x.next);

}

Como construir um compilador utilizando ferramentas Java – p. 32/86

Análise de uma declaração de classe

Se uma superclasse foi definida, verifica se asuperclasse existe.

Como construir um compilador utilizando ferramentas Java – p. 33/86

Análise de uma declaração de classe

Se uma superclasse foi definida, verifica se asuperclasse existe.

Se existe, atualiza a tabela de símbolos.

Como construir um compilador utilizando ferramentas Java – p. 33/86

Análise de uma declaração de classe

Se uma superclasse foi definida, verifica se asuperclasse existe.

Se existe, atualiza a tabela de símbolos.

Não verifica (ainda) circularidade

Como construir um compilador utilizando ferramentas Java – p. 33/86

Análise de uma declaração de classe

Se uma superclasse foi definida, verifica se asuperclasse existe.

Se existe, atualiza a tabela de símbolos.

Não verifica (ainda) circularidade

class A extends Bclass B extends Cclass C extends A

Como construir um compilador utilizando ferramentas Java – p. 33/86

Análise de uma declaração de classepublic void VarCheckClassDeclNode(ClassDeclNode x)

throws SemanticException {

Symtable temphold = Curtable; // salva tabela corrente

EntryClass c = null;

EntryClass nc;

if (x == null) return;

if (x.supername != null) { // verifica se superclasse foi def inida

c = (EntryClass) Curtable.classFindUp(x.supername.imag e);

if (c == null) { // Se n ao achou superclasse, ERRO

throw new SemanticException(x.position, "Superclass "+

x.supername.image + " not found");

}

}

nc = (EntryClass) Curtable.classFindUp(x.name.image);

nc.parent = c; // coloca na tabela o apontador p/ superclasse

Curtable = nc.nested; // tabela corrente = tabela da classe

VarCheckClassBodyNode(x.body);

Curtable = temphold; // recupera tabela corrente

}

Como construir um compilador utilizando ferramentas Java – p. 34/86

Análise de uma declaração de classe// procura classe na tabela

nc = (EntryClass) Curtable.classFindUp(x.name.image);

// procura nos niveis mais externos

if ( Curtable.levelup != null ) {

Symtable oneUp = Curtable.levelup.mytable;

EntryClass nc1 = (EntryClass) oneUp.classFindUp(x.name. image);

if (nc1 != null) { // j a declarada, ERRO

throw new SemanticException(x.name,

"Class " + x.name.image + " already declared");

}

}

nc.parent = c; // coloca na tabela o apontador p/ superclasse

Curtable = nc.nested; // tabela corrente = tabela da classe

VarCheckClassBodyNode(x.body);

Curtable = temphold; // recupera tabela corrente

}

Como construir um compilador utilizando ferramentas Java – p. 35/86

Outras declarações

Dentro de uma classe, existem declarações

Classes aninhadas

Variáveis

Construtores

Métodos

Como construir um compilador utilizando ferramentas Java – p. 36/86

Trata o corpo de uma classepublic void VarCheckClassBodyNode(ClassBodyNode x)

{

if (x == null) return;

VarCheckClassDeclListNode(x.clist);

VarCheckVarDeclListNode(x.vlist);

VarCheckConstructDeclListNode(x.ctlist);

// se n ao existe constructor(), insere um falso

if ( Curtable.methodFindInclass("constructor", null) == null)

{

Curtable.add(new EntryMethod("constructor",

Curtable.levelup, true));

}

VarCheckMethodDeclListNode(x.mlist);

}

Obs: construtor falso.

Como construir um compilador utilizando ferramentas Java – p. 37/86

Declaração de variáveis

MyClass x, y;

Como construir um compilador utilizando ferramentas Java – p. 38/86

Declaração de variáveis

MyClass x, y;

Verificar se MyClass existe na T.S.

Como construir um compilador utilizando ferramentas Java – p. 38/86

Declaração de variáveis

MyClass x, y;

Verificar se MyClass existe na T.S.

Funciona para int ou string?

Como construir um compilador utilizando ferramentas Java – p. 38/86

Declaração de variáveis

MyClass x, y;

Verificar se MyClass existe na T.S.

Funciona para int ou string?

Cada variável na declaração é inserida na T.S. corrente.

Como construir um compilador utilizando ferramentas Java – p. 38/86

Declaração de variáveis

MyClass x, y;

Verificar se MyClass existe na T.S.

Funciona para int ou string?

Cada variável na declaração é inserida na T.S. corrente.

Declarações repetidas?

Como construir um compilador utilizando ferramentas Java – p. 38/86

Declaração de variáveis

MyClass x, y;

Verificar se MyClass existe na T.S.

Funciona para int ou string?

Cada variável na declaração é inserida na T.S. corrente.

Declarações repetidas?

Não são verificadas pois não é possível ainda verificarse na superclasse existe uma variável com o mesmonome.

Como construir um compilador utilizando ferramentas Java – p. 38/86

Declaração de variáveispublic void VarCheckVarDeclNode(VarDeclNode x)

throws SemanticException {

EntryTable c;

ListNode p;

if (x == null) return;

// acha entrada do tipo da vari avel

c = Curtable.classFindUp(x.position.image);

// se n ao achou, ERRO

if (c == null)

throw new SemanticException(x.position, "Class "+

x.position.image + " not found");

// para cada vari avel da declarac ao, cria uma entrada na tabela

for (p = x.vars; p != null; p = p.next) {

VarNode q = (VarNode) p.node;

Curtable.add(new EntryVar(q.position.image, c, q.dim)) ;

}

}

Como construir um compilador utilizando ferramentas Java – p. 39/86

Declaração de construtor

Verifica o tipo de cada parâmetro.

Como construir um compilador utilizando ferramentas Java – p. 40/86

Declaração de construtor

Verifica o tipo de cada parâmetro.

Cria uma Entryrec com os tipos dos parâmetros.

Como construir um compilador utilizando ferramentas Java – p. 40/86

Declaração de construtor

Verifica o tipo de cada parâmetro.

Cria uma Entryrec com os tipos dos parâmetros.

Procura um construtor igual apenas na classecorrente.

Como construir um compilador utilizando ferramentas Java – p. 40/86

Declaração de construtor

Verifica o tipo de cada parâmetro.

Cria uma Entryrec com os tipos dos parâmetros.

Procura um construtor igual apenas na classecorrente.

Insere um método com nome “constructor” na tabela desímboloscorrente.

Como construir um compilador utilizando ferramentas Java – p. 40/86

Declaração de construtorpublic void VarCheckConstructDeclNode(ConstructDeclNo de x)

throws SemanticException

{

EntryMethod c;

EntryRec r = null;

EntryTable e;

ListNode p;

VarDeclNode q;

VarNode u;

int n;

if (x == null) return;

p = x.body.param;

n = 0;

Como construir um compilador utilizando ferramentas Java – p. 41/86

Declaração de construtorwhile (p != null) // para cada par ametro do construtor

{

q = (VarDeclNode) p.node; // q = no com a declarac ao do par ametro

u = (VarNode) q.vars.node; // u = no com o nome e dimens ao

n++;

// acha a entrada do tipo na tabela

e = Curtable.classFindUp(q.position.image);

// se n ao achou: ERRO

if (e == null)

throw new SemanticException(q.position, "Class " +

q.position.image + " not found");

// constr oi a lista com os par ametros

r = new EntryRec(e, u.dim, n, r);

p = p.next;

}

if (r != null)

r = r.inverte(); // inverte a lista

Como construir um compilador utilizando ferramentas Java – p. 42/86

Declaração de construtor// procura construtor com essa assinatura dentro da mesma cl asse

c = Curtable.methodFindInclass("constructor", r);

if (c == null)

{ // se n ao achou, insere

c = new EntryMethod("constructor", Curtable.levelup,0 ,r );

Curtable.add(c);

}

else // construtor j a definido na mesma classe: ERRO

throw new SemanticException(x.position, "Constructor " +

Curtable.levelup.name +

"(" + (r == null? "" : r.toStr()) + ")" +

" already declared");

}

Como construir um compilador utilizando ferramentas Java – p. 43/86

Declaração de método

Como declaração de construtor

Como construir um compilador utilizando ferramentas Java – p. 44/86

Declaração de método

Como declaração de construtor

Usa o nome do método em vez da palavra “constructor”

Como construir um compilador utilizando ferramentas Java – p. 44/86

Declaração de método

Como declaração de construtor

Usa o nome do método em vez da palavra “constructor”

Procura o tipo de retorno para ver se foi declarado

Como construir um compilador utilizando ferramentas Java – p. 44/86

Declaração de método

Como declaração de construtor

Usa o nome do método em vez da palavra “constructor”

Procura o tipo de retorno para ver se foi declarado

Insere na tabela normalmente

Como construir um compilador utilizando ferramentas Java – p. 44/86

Análise semântica: parte 3

É a mais complexa das três.

Como construir um compilador utilizando ferramentas Java – p. 45/86

Análise semântica: parte 3

É a mais complexa das três.

Diversos aspectos são tratados.

Como construir um compilador utilizando ferramentas Java – p. 45/86

Análise semântica: parte 3

É a mais complexa das três.

Diversos aspectos são tratados.

Declaração de classes e variáveis.

Como construir um compilador utilizando ferramentas Java – p. 45/86

Análise semântica: parte 3

É a mais complexa das três.

Diversos aspectos são tratados.

Declaração de classes e variáveis.

Comandos.

Como construir um compilador utilizando ferramentas Java – p. 45/86

Análise semântica: parte 3

É a mais complexa das três.

Diversos aspectos são tratados.

Declaração de classes e variáveis.

Comandos.

Expressões.

Como construir um compilador utilizando ferramentas Java – p. 45/86

Análise semântica: parte 3

É a mais complexa das três.

Diversos aspectos são tratados.

Declaração de classes e variáveis.

Comandos.

Expressões.

Particularmente importante é a chacagem de tipos.

Como construir um compilador utilizando ferramentas Java – p. 45/86

Análise semântica: parte 3

É a mais complexa das três.

Diversos aspectos são tratados.

Declaração de classes e variáveis.

Comandos.

Expressões.

Particularmente importante é a chacagem de tipos.

Ou seja: abrange toda a árvore sintática.

Como construir um compilador utilizando ferramentas Java – p. 45/86

Checagem de tipo

if ( expr )comando 1;

elsecomando 2;

if ( b )return 0;

Como construir um compilador utilizando ferramentas Java – p. 46/86

Checagem de tipo

IfNode

VarNode ReturnNode

Token: b IntConstNode

Token: 0

procurar a variável b na tabela de símbolos

pegar o tipo com que a variável foi declarada

lançar uma exceção caso o tipo não seja int

Como construir um compilador utilizando ferramentas Java – p. 47/86

Outros tipos de expressão

Nem sempre expressão é apenas uma variável.

Existem 13 tipos de ExpreNode como: IntConstNode,VarNode, AddNode, MultNode, RelationalNode

Expressões podem ser compostas de subexpressões.

Cada método que analisa um desses nós deve sercapaz de computar o tipo correspondente.

Exemplo:

if ( a + b > 10 )return 0;

Como construir um compilador utilizando ferramentas Java – p. 48/86

Exemplo

IfNode

RelationalNode ReturnNode

AddNode Token: > IntConstNode IntConstNode

VarNode Token: + VarNode Token: 10 Token: 0

Token: a Token: b

Como construir um compilador utilizando ferramentas Java – p. 49/86

Tipo de uma expressãoAntes de saber qual o tipo da expressão de controleRelationalNode, é necessário calcular o tipo de cadasubexpressão.

Como construir um compilador utilizando ferramentas Java – p. 50/86

Tipo de uma expressãoAntes de saber qual o tipo da expressão de controleRelationalNode, é necessário calcular o tipo de cadasubexpressão.

É preciso saber se “a + b” e “10” são expressões do tipointeiro para poderem ser comparadas por meio dooperador >.

Como construir um compilador utilizando ferramentas Java – p. 50/86

Tipo de uma expressãoAntes de saber qual o tipo da expressão de controleRelationalNode, é necessário calcular o tipo de cadasubexpressão.

É preciso saber se “a + b” e “10” são expressões do tipointeiro para poderem ser comparadas por meio dooperador >.

É preciso saber se as variáveis “a” e “b” são do tipointeiro para poderem ser somadas e produzir umresultado inteiro.

Como construir um compilador utilizando ferramentas Java – p. 50/86

Tipo de uma expressãoAntes de saber qual o tipo da expressão de controleRelationalNode, é necessário calcular o tipo de cadasubexpressão.

É preciso saber se “a + b” e “10” são expressões do tipointeiro para poderem ser comparadas por meio dooperador >.

É preciso saber se as variáveis “a” e “b” são do tipointeiro para poderem ser somadas e produzir umresultado inteiro.

O tipo é calculado “de baixo para cima”, a partir dassubesxpressões mais simples.

Como construir um compilador utilizando ferramentas Java – p. 50/86

Tipo de uma expressãoAntes de saber qual o tipo da expressão de controleRelationalNode, é necessário calcular o tipo de cadasubexpressão.

É preciso saber se “a + b” e “10” são expressões do tipointeiro para poderem ser comparadas por meio dooperador >.

É preciso saber se as variáveis “a” e “b” são do tipointeiro para poderem ser somadas e produzir umresultado inteiro.

O tipo é calculado “de baixo para cima”, a partir dassubesxpressões mais simples.

O método que analisa uma expressão retorna o seu tipo.

Como construir um compilador utilizando ferramentas Java – p. 50/86

Regras doRelationalNode

se os dois operandos forem inteiros, a expressão estáOK e o seu tipo é int ;

Como construir um compilador utilizando ferramentas Java – p. 51/86

Regras doRelationalNode

se os dois operandos forem inteiros, a expressão estáOK e o seu tipo é int ;

se os dois operandos forem string, a expressão é válidasomente se o operador for de igualdade oudesigualdade;

Como construir um compilador utilizando ferramentas Java – p. 51/86

Regras doRelationalNode

se os dois operandos forem inteiros, a expressão estáOK e o seu tipo é int ;

se os dois operandos forem string, a expressão é válidasomente se o operador for de igualdade oudesigualdade;

idem para dois objetos de tipos comparáveis (tiposiguais ou um é subclasse do outro);

Como construir um compilador utilizando ferramentas Java – p. 51/86

Regras doRelationalNode

se os dois operandos forem inteiros, a expressão estáOK e o seu tipo é int ;

se os dois operandos forem string, a expressão é válidasomente se o operador for de igualdade oudesigualdade;

idem para dois objetos de tipos comparáveis (tiposiguais ou um é subclasse do outro);

strings e objetos podem ser comparados quanto àigualdade e à desigualdade com um outro operando queseja null.

Como construir um compilador utilizando ferramentas Java – p. 51/86

Geração de código

MyClass x;a = x.myMethod( b + c);

criar as instruções para somar esses valores e produzirum resultado inteiro;

chamar o método MyClass.myMethod(int).

Como construir um compilador utilizando ferramentas Java – p. 52/86

Geração de código

MyClass x;a = x.myMethod( b + c);

transformar o valor inteiro de b em um string;

concatenar o valor de a com esse valor transformado,produzindo como resultado um string;

chamar o método MyClass.myMethod(string).

Como construir um compilador utilizando ferramentas Java – p. 53/86

Método principal// verifica se pode operar sobre a arvore sint atica

if ( parser.token_source.foundLexError()

+ parser.contParseError == 0)

{

if (print_tree) // exibir a arvore

{

PrintTree prt = new PrintTree();

prt.printRoot(root); // chama m etodo para imprimir arvore

}

TypeCheck tc = new TypeCheck();

try {

tc.TypeCheckRoot(root);

System.out.println("0 Semantic Errors found");

}

catch (SemanticException e)

{

System.out.println(e.getMessage());

}

Como construir um compilador utilizando ferramentas Java – p. 54/86

Análise da raizpublic void TypeCheckRoot(ListNode x)

throws SemanticException

{

// faz an alise das vari aveis e m etodos

VarCheckRoot(x);

// faz an alise do corpo dos m etodos

TypeCheckClassDeclListNode(x);

if (foundSemanticError != 0) // se houve erro,

throw new SemanticException(foundSemanticError

" Semantic Errors found

}

Como construir um compilador utilizando ferramentas Java – p. 55/86

Declaração de classepublic void TypeCheckClassDeclNode(ClassDeclNode x)

throws SemanticException

{

Symtable temphold = Curtable; // salva tabela corrente

EntryClass nc;

if (x == null) return;

nc = (EntryClass) Curtable.classFindUp(x.name.image);

if ( circularSuperclass(nc, nc.parent) )

{ // se existe declarac ao circular, ERRO

nc.parent = null;

throw new SemanticException(x.position, "Circular inher itance");

}

Curtable = nc.nested; // tabela corrente = tabela da classe

TypeCheckClassBodyNode(x.body);

Curtable = temphold; // recupera tabela corrente

}

Como construir um compilador utilizando ferramentas Java – p. 56/86

Herança circular// verifica se existe refer encia circular de superclasses

private boolean circularSuperclass(EntryClass orig, Ent ryClass e)

{

if ( e == null) return false;

if (orig == e )

return true;

return circularSuperclass(orig, e.parent);

}

Como construir um compilador utilizando ferramentas Java – p. 57/86

Análise de construtor// acha a entrada do construtor na tabela

t = Curtable.methodFind("constructor", r);

CurMethod = t; // guarda m etodo corrente

// inicia um novo escopo na tabela corrente

Curtable.beginScope();

// pega a entrada da classe corrente na tabela

thisclass = (EntryClass) Curtable.levelup;

thisvar = new EntryVar("this", thisclass, 0);

Curtable.add(thisvar); // inclui vari avel local "this" com no. 0

Returntype = null; // tipo de retorno do m etodo = nenhum

nesting = 0; // n ıvel de aninhamento de comandos for

Nlocals = 1; // inicializa n umero de vari aveis locais

TypeCheckMethodBodyNode(x.body);

t.totallocals = Nlocals; // n umero de vari aveis locais do m etodo

Curtable.endScope(); // retira vari aveis locais da tabela

}

Como construir um compilador utilizando ferramentas Java – p. 58/86

Tratamento dos comandos

A partir desse ponto “para baixo” é feito o tratamentodos comandos que aparecem na árvore sintática.

Como construir um compilador utilizando ferramentas Java – p. 59/86

Tratamento dos comandos

A partir desse ponto “para baixo” é feito o tratamentodos comandos que aparecem na árvore sintática.

Cada tipo de nó (cada comando) diferente é tratado demodo diferente.

Como construir um compilador utilizando ferramentas Java – p. 59/86

Tratamento dos comandos

A partir desse ponto “para baixo” é feito o tratamentodos comandos que aparecem na árvore sintática.

Cada tipo de nó (cada comando) diferente é tratado demodo diferente.

Pode ser um tratamento muito simples (BlockNode,PrintNode) ou complexo (VarDeclNode).

Como construir um compilador utilizando ferramentas Java – p. 59/86

BlockNodepublic void TypeCheckBlockNode(BlockNode x) {

Curtable.beginScope(); // in ıcio de um escopo

TypeCheckStatementListNode(x.stats);

Curtable.endScope(); // final do escopo, libera vars. loca is

}

public void TypeCheckStatementListNode(ListNode x) {

if (x == null) return;

try {

TypeCheckStatementNode( (StatementNode) x.node);

}

catch (SemanticException e) {

System.out.println(e.getMessage());

foundSemanticError++;

}

TypeCheckStatementListNode(x.next);

}

Como construir um compilador utilizando ferramentas Java – p. 60/86

PrintNodepublic void TypeCheckPrintNode(PrintNode x)

throws SemanticException

{

type t;

if (x == null) return;

// t = tipo e dimens ao do resultado da express ao

t = TypeCheckExpreNode(x.expr);

// tipo tem que ser string e dimens ao tem que ser 0

if ( t.ty != STRING_TYPE || t.dim != 0 )

throw new SemanticException(x.position,

"string expression required");

}

Notar os erros que podem ocorrer.

Como construir um compilador utilizando ferramentas Java – p. 61/86

Declaração de variável localpublic void TypeCheckLocalVarDeclNode(VarDeclNode x)

throws SemanticException

{

ListNode p;

VarNode q;

EntryVar l, u;

EntryTable c;

if (x == null) return;

// procura tipo da declarac ao na tabela de s ımbolos

c = Curtable.classFindUp(x.position.image);

// se n ao achou, ERRO

if (c == null)

throw new SemanticException(x.position, "Class "+

x.position.image + " not found.");

Verifica se tipo existe.

Como construir um compilador utilizando ferramentas Java – p. 62/86

Declaração de variável localfor (p = x.vars; p != null; p = p.next)

{

q = (VarNode) p.node;

l = Curtable.varFind(q.position.image);

// se vari avel j a existe e preciso saber que tipo de vari avel e

if ( l != null)

{

// verifica se e local, definida no escopo corrente

if (l.scope == Curtable.scptr) // se for, ERRO

throw new SemanticException(q.position, "Variable "+

p.position.image + " already declared");

Como construir um compilador utilizando ferramentas Java – p. 63/86

Declaração de variáveis locais

Procura a variável na tabela de símbolos.

Como construir um compilador utilizando ferramentas Java – p. 64/86

Declaração de variáveis locais

Procura a variável na tabela de símbolos.

Se achou, pode ser um erro (ou não).

Como construir um compilador utilizando ferramentas Java – p. 64/86

Declaração de variáveis locais

Procura a variável na tabela de símbolos.

Se achou, pode ser um erro (ou não).

l.scope indica em qual scopo foi inserida a variável.

Como construir um compilador utilizando ferramentas Java – p. 64/86

Declaração de variáveis locais

Procura a variável na tabela de símbolos.

Se achou, pode ser um erro (ou não).

l.scope indica em qual scopo foi inserida a variável.

Curtable.scptr indica qual o scopo corrente.

Como construir um compilador utilizando ferramentas Java – p. 64/86

Declaração de variáveis locais

Procura a variável na tabela de símbolos.

Se achou, pode ser um erro (ou não).

l.scope indica em qual scopo foi inserida a variável.

Curtable.scptr indica qual o scopo corrente.

Se forem iguais, significa que variável já existe noescopo corrente.

Como construir um compilador utilizando ferramentas Java – p. 64/86

Declaração de variáveis locais// c.c. verifica se e uma vari avel de classe

if (l.localcount < 0) // se for, d a uma advert encia

System.out.println("Line " + q.position.beginLine +

" Column " + q.position.beginColumn +

" Warning: Variable " + q.position.image +

" hides a class variable");

else // sen ao, e uma vari avel local em outro escopo

System.out.println("Line " + q.position.beginLine +

" Column " + q.position.beginColumn +

" Warning: Variable " + q.position.image +

" hides a parameter or a local variable");

Advertência: esconde variável já definida.

Como construir um compilador utilizando ferramentas Java – p. 65/86

Declaração de variáveis locaisCurtable.add(

new EntryVar(q.position.image, c, q.dim, Nlocals++)

);

Insere na tabela.

Como construir um compilador utilizando ferramentas Java – p. 66/86

Comando de atribuiçãopublic void TypeCheckAtribNode(AtribNode x)

throws SemanticException

{

type t1, t2;

EntryVar v;

if (x == null) return;

// verifica se o n o filho tem um tipo v alido

if ( ! (x.expr1 instanceof DotNode ||

x.expr1 instanceof IndexNode ||

x.expr1 instanceof VarNode) )

throw new SemanticException(x.position,

"Invalid left side of assignment");

Como construir um compilador utilizando ferramentas Java – p. 67/86

Comando de atribuição// verifica se e uma atribuic ao para "this"

if ( x.expr instanceof VarNode )

{

EntryVar v = Curtable.varFind(x.expr.position.image);

if ( v != null && v.localcount == 0) // e a vari avel local 0?

{

throw new SemanticException(x.position,

"Assigning to variable \"this\" is not legal");

}

}

Como construir um compilador utilizando ferramentas Java – p. 68/86

Comando de atribuiçãot1 = TypeCheckExpreNode(x.expr1);

t2 = TypeCheckExpreNode(x.expr2);

// verifica tipos das express oes

// verifica dimens oes

if ( t1.dim != t2.dim )

throw new SemanticException(x.position,

"Invalid dimensions in assignment");

Compatibilidade de tipos.

int[][] x, y;

x = new int[10][10];

y = x[0];

Como construir um compilador utilizando ferramentas Java – p. 69/86

Comando de atribuição// verifica se lado esquerdo e uma classe e direito e null, OK

if (t1.ty instanceof EntryClass && t2.ty == NULL_TYPE )

return;

// verifica se t2 e subclasse de t1

if ( ! ( isSubClass(t2.ty,t1.ty) || isSubClass(t1.ty,t2.t y) ) )

throw new SemanticException(x.position,

"Incompatible types for assignment ");

Como construir um compilador utilizando ferramentas Java – p. 70/86

Atribuição de subclasses

Nesse último caso, vale uma explicação sobre a semânticaque queremos dar a este comando. Primeiro, se o tipo dolado direito for uma subclasse do tipo do lado esquerdo,então a atribuição é feita naturalmente, sem problemas. Nocaso inverso, antes de fazer a atribuição, o sistema deexecução faz por conta própria a coerção dos tipos.Obviamente, se a coerção não puder ser feita, um erro deexecução ocorre.

Como construir um compilador utilizando ferramentas Java – p. 71/86

Atribuição de subclasseclass A extends C {

int methA() {C var1;A var2;B var3;var1 = new A(); // OKvar2 = var1; // OK c/ coerçãovar3 = var1; // ERRO

}}

class B extends C ...class C ...

Como construir um compilador utilizando ferramentas Java – p. 72/86

Análise das expressõesUma expressão em X

++ pode ser uma simplesconstante ou variável, ou uma expressão composta dediversas expressões mais simples.

Como construir um compilador utilizando ferramentas Java – p. 73/86

Análise das expressõesUma expressão em X

++ pode ser uma simplesconstante ou variável, ou uma expressão composta dediversas expressões mais simples.

O tipo de uma expressão é calculado com base nostipos das suas subexpressões.

Como construir um compilador utilizando ferramentas Java – p. 73/86

Análise das expressõesUma expressão em X

++ pode ser uma simplesconstante ou variável, ou uma expressão composta dediversas expressões mais simples.

O tipo de uma expressão é calculado com base nostipos das suas subexpressões.

O método que trata uma expressão deve computar eretornar um objeto do tipo “type”.

Como construir um compilador utilizando ferramentas Java – p. 73/86

Classetypepublic class type {public EntryTable ty; // entrada na tabelapublic int dim; // dimens ao

public type(EntryTable t, int d){

ty = t;dim = d;

}

Como construir um compilador utilizando ferramentas Java – p. 74/86

Tipo de uma constante

Para as constantes, obter o seu tipo é trivial.

Como construir um compilador utilizando ferramentas Java – p. 75/86

Tipo de uma constante

Para as constantes, obter o seu tipo é trivial.

O próprio tipo do nó da árvore sintática determina qual otipo da constante.

Como construir um compilador utilizando ferramentas Java – p. 75/86

Tipo de uma constante

Para as constantes, obter o seu tipo é trivial.

O próprio tipo do nó da árvore sintática determina qual otipo da constante.

Somente no caso de uma constante inteira é necessáriauma verificação extra.

Como construir um compilador utilizando ferramentas Java – p. 75/86

Tipo de uma constante

Para as constantes, obter o seu tipo é trivial.

O próprio tipo do nó da árvore sintática determina qual otipo da constante.

Somente no caso de uma constante inteira é necessáriauma verificação extra.

Para verificar se é uma constante válida, utilizamos umachamada ao método Integer.parseInt da API Java.

Como construir um compilador utilizando ferramentas Java – p. 75/86

Constante inteirapublic type TypeCheckIntConstNode(IntConstNode x)

throws SemanticException {

int k;

if (x == null) return null;

// tenta transformar imagem em n umero inteiro

try

{

k = Integer.parseInt(x.position.image);

}

catch(NumberFormatException e)

{ // se deu erro, formato e inv alido

// (possivelmente fora dos limites)

throw new SemanticException(x.position, "Invalid int con stant");

}

return new type(INT_TYPE, 0);

}

Como construir um compilador utilizando ferramentas Java – p. 76/86

Constante string ou nullpublic type TypeCheckStringConstNode(StringConstNode x )

{

if (x == null) return null;

return new type( STRING_TYPE, 0);

}

public type TypeCheckNullConstNode(NullConstNode x)

{

if (x == null) return null;

return new type( NULL_TYPE, 0);

}

Como construir um compilador utilizando ferramentas Java – p. 77/86

Tipo de uma variável

Para uma variável também não é difícil calcular seu tipo.

Como construir um compilador utilizando ferramentas Java – p. 78/86

Tipo de uma variável

Para uma variável também não é difícil calcular seu tipo.

Basta consultar a tabela de símbolos.

Como construir um compilador utilizando ferramentas Java – p. 78/86

Tipo de uma variável

Para uma variável também não é difícil calcular seu tipo.

Basta consultar a tabela de símbolos.

Isto é feito utilizando o conhecido métodoSymtable.varFind

Como construir um compilador utilizando ferramentas Java – p. 78/86

Tipo de uma variável

Para uma variável também não é difícil calcular seu tipo.

Basta consultar a tabela de símbolos.

Isto é feito utilizando o conhecido métodoSymtable.varFind

O nome está no nó VarNode sendo analisado.

Como construir um compilador utilizando ferramentas Java – p. 78/86

Tipo de um VarNodepublic type TypeCheckVarNode(VarNode x) throws SemanticE xception

{

EntryVar p;

if (x == null) return null;

// procura vari avel na tabela

p = Curtable.varFind(x.position.image);

// se n ao achou, ERRO

if (p == null)

throw new SemanticException(x.position, "Variable " +

x.position.image + " not found");

return new type(p.type, p.dim);

}

Como construir um compilador utilizando ferramentas Java – p. 79/86

Chamada de métodocalcula o tipo da expressão que está no seu primeirofilho e que representa a expressão à esquerda do “.” nachamada do método

Como construir um compilador utilizando ferramentas Java – p. 80/86

Chamada de métodocalcula o tipo da expressão que está no seu primeirofilho e que representa a expressão à esquerda do “.” nachamada do método

se a dimensão é maior que zero. Caso seja, um erro foiencontrado, pois um array não pode ter um métodoassociado a ele;

Como construir um compilador utilizando ferramentas Java – p. 80/86

Chamada de métodocalcula o tipo da expressão que está no seu primeirofilho e que representa a expressão à esquerda do “.” nachamada do método

se a dimensão é maior que zero. Caso seja, um erro foiencontrado, pois um array não pode ter um métodoassociado a ele;

se o tipo calculado corresponde a uma classe. Casonão seja, um erro foi encontrado, pois tipos simples nãopodem ter métodos.

Como construir um compilador utilizando ferramentas Java – p. 80/86

Tipo de um CallNodepublic type TypeCheckCallNode(CallNode x) throws Semanti cException {

EntryClass c;

EntryMethod m;

type t1, t2;

if (x == null) return null;

// calcula tipo do primeiro filho

t1 = TypeCheckExpreNode(x.expr);

// se for array, ERRO

if ( t1.dim > 0 )

throw new SemanticException(x.position,

"Arrays do not have methods");

// se n ao for uma classe, ERRO

if (! (t1.ty instanceof EntryClass))

throw new SemanticException(x.position, "Type " + t1.ty.n ame +

" does not have methods");

Como construir um compilador utilizando ferramentas Java – p. 81/86

Chamada de métodoEm seguida são calculados os tipos para cada um dosargumentos.

Como construir um compilador utilizando ferramentas Java – p. 82/86

Chamada de métodoEm seguida são calculados os tipos para cada um dosargumentos.

Utilizando o nome do método, que é um dos filhos do nócorrente, e a lista de tipos dos argumentos, realiza-seuma busca na tabela de símbolos para achar o métodoadequado.

Como construir um compilador utilizando ferramentas Java – p. 82/86

Chamada de métodoEm seguida são calculados os tipos para cada um dosargumentos.

Utilizando o nome do método, que é um dos filhos do nócorrente, e a lista de tipos dos argumentos, realiza-seuma busca na tabela de símbolos para achar o métodoadequado.

A busca deve ser feita na classe adequada, ou seja, naclasse que foi calculada no início.

Como construir um compilador utilizando ferramentas Java – p. 82/86

Chamada de métodoEm seguida são calculados os tipos para cada um dosargumentos.

Utilizando o nome do método, que é um dos filhos do nócorrente, e a lista de tipos dos argumentos, realiza-seuma busca na tabela de símbolos para achar o métodoadequado.

A busca deve ser feita na classe adequada, ou seja, naclasse que foi calculada no início.

A entrada do método na tabela de símbolos diz-nos qualé o tipo retornado pela chamada.

Como construir um compilador utilizando ferramentas Java – p. 82/86

Tipo de um CallNode// pega tipos dos argumentos

t2 = TypeCheckExpreListNode(x.args);

// procura o m etodo desejado na classe t1.ty

c = (EntryClass) t1.ty;

m = c.nested.methodFind(x.meth.image, (EntryRec) t2.ty) ;

// se n ao achou, ERRO

if (m == null)

throw new SemanticException(x.position, "Method "

+ x.meth.image

+ "(" + (t2.ty == null ? "" : ((EntryRec) t2.ty).toStr())

+ ") not found in class " + c.name);

return new type(m.type, m.dim);

}

Como construir um compilador utilizando ferramentas Java – p. 83/86

Expressão de adição/subtração

AddNode possui dois filhos ExpreNode e o tipo deoperação a ser executada.

Como construir um compilador utilizando ferramentas Java – p. 84/86

Expressão de adição/subtração

AddNode possui dois filhos ExpreNode e o tipo deoperação a ser executada.

São calculados os tipos das subexpressões.

Como construir um compilador utilizando ferramentas Java – p. 84/86

Expressão de adição/subtração

AddNode possui dois filhos ExpreNode e o tipo deoperação a ser executada.

São calculados os tipos das subexpressões.

Expressões devem ter tipo sem dimensão.

Como construir um compilador utilizando ferramentas Java – p. 84/86

Expressão de adição/subtração

AddNode possui dois filhos ExpreNode e o tipo deoperação a ser executada.

São calculados os tipos das subexpressões.

Expressões devem ter tipo sem dimensão.

Dois inteiros podem ser somados ou subtraídos.

Como construir um compilador utilizando ferramentas Java – p. 84/86

Expressão de adição/subtração

AddNode possui dois filhos ExpreNode e o tipo deoperação a ser executada.

São calculados os tipos das subexpressões.

Expressões devem ter tipo sem dimensão.

Dois inteiros podem ser somados ou subtraídos.

Soma pode ser realizada entre strings e inteiros.

Como construir um compilador utilizando ferramentas Java – p. 84/86

Tipo de um AddNodepublic type TypeCheckAddNode(AddNode x)

throws SemanticException {

type t1, t2;

int op; // operac ao

int i, j;

if (x == null) return null;

op = x.position.kind;

t1 = TypeCheckExpreNode(x.expr1);

t2 = TypeCheckExpreNode(x.expr2);

// se dimens ao > 0, ERRO

if ( t1.dim > 0 || t2.dim > 0 )

throw new SemanticException(x.position, "Can not use " +

x.position.image + " for arrays");

Como construir um compilador utilizando ferramentas Java – p. 85/86

Tipo de um AddNodei = j = 0;

if (t1.ty == INT_TYPE)

i++;

else if (t1.ty == STRING_TYPE)

j++;

if (t2.ty == INT_TYPE)

i++;

else if (t2.ty == STRING_TYPE)

j++;

// dois operadores inteiro, OK

if (i == 2)

return new type(INT_TYPE, 0);

// um inteiro e um string. S o pode somar

if ( op == langXConstants.PLUS && i+j == 2)

return new type(STRING_TYPE, 0);

throw new SemanticException(x.position, "Invalid types f or " +

x.position.image);

}

Como construir um compilador utilizando ferramentas Java – p. 86/86