como construir um compilador utilizando ferramentas...

Post on 03-Jul-2020

7 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Como construir um compilador utilizandoferramentas Java

Aula 9 – Construção da árvore sintática

Prof. Marcio Delamarodelamaro@icmc.usp.br

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

O que temos até agora

JavaCCjavac

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

Erros sintáticos

Não erros

langX

SintáticoAnalisador

prog.x

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

O que queremos

JavaCCjavac

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

kfdfdjkfdsjkfdsjkfdkfdsjk

Erros sintáticos

Não erros

langX

SintáticoAnalisador

prog.x

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

O que é árvore sintática

Dada a GLC, uma árvore sintática é uma árvore rotuladacuja raiz tem sempre o não-terminal inicial como rótulo.Numa derivação

S ⇒ α1α2...αn

o nó S tem como filhos n nós rotulados α1 até αn.

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

Exemploclass test {

}

class test2 {

}

〈program〉

〈classlist〉 EOF

〈classdecl〉 〈classlist〉

class test 〈classbody〉 〈classdecl〉

{ } class test2 〈classbody〉

{ }

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

Árvore sintática abstrata

〈program〉

〈classlist〉

〈classdecl〉 〈classlist〉

test 〈classbody〉 〈classdecl〉

λ test2 〈classbody〉

λ

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

Construção da árvore

À medida que um não terminal é reconhecido, um nó daárvore é criado

De baixo para cima

Cada execução de um dos métodos associados aosnão-terminais cria um nó da árvore e “pendura” nele osnós filhos.

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

Construção da árvore

Tokens reconhecidos naquele método e pelos outrosnós criados pelas chamadas a outro métodos denão-terminais.

Cada nó da árvore é representado por um objeto Javaque possui referências a outro objetos, que são seusfilhos.

Nós diferentes são representados por objetos dediferentes classes.

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

Hierarquia de classes

Todas as classes que representam os nós têm umasuperclasse em comum

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

Hierarquia de classes

Todas as classes que representam os nós têm umasuperclasse em comum

GeneralNode

ClassDeclNode ListNode

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

GeneralNode

package syntacticTree;import Token;

abstract public class GeneralNode {public Token position;

public GeneralNode(Token x) {position = x;

}

}

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

Modificações no .jjcada método correspondente aos não-terminais poderetornar um valor. Cada um desses métodos retorna onó que construiu, permitindo que o método que fez achamada possa utilizar esse nó;

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

Modificações no .jjcada método correspondente aos não-terminais poderetornar um valor. Cada um desses métodos retorna onó que construiu, permitindo que o método que fez achamada possa utilizar esse nó;

cada token consumido pelo AS pode ser utilizado pelosmétodos dos não-terminais para construir o nó daárvore. Para isso, basta “atribuir” o token que aparecena definição BNF para uma variável e, depois, utilizá-lana construção do nó;

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

Modificações no .jjcada método correspondente aos não-terminais poderetornar um valor. Cada um desses métodos retorna onó que construiu, permitindo que o método que fez achamada possa utilizar esse nó;

cada token consumido pelo AS pode ser utilizado pelosmétodos dos não-terminais para construir o nó daárvore. Para isso, basta “atribuir” o token que aparecena definição BNF para uma variável e, depois, utilizá-lana construção do nó;

a cada token e a cada chamada de um método de umnão-terminal que aparecem nas definições BNF épossível associar código Java que é executado.

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

classdecl – retornoClassDeclNode classdecl(RecoverySet g)

throws ParseEOFException :

{}

{

try {

<CLASS> <IDENT> [ <EXTENDS> <IDENT> ]

classbody(g)

}

catch (ParseException e) {

consumeUntil(g, e, "classdecl");

}

}

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

classdecl – tokensClassDeclNode classdecl(RecoverySet g) throws ParseEOFException :

{

Token t1 = null;

}

{

try {

t1 = <CLASS> <IDENT> [ <EXTENDS> <IDENT> ] classbody(g)

}

catch (ParseException e)

{

consumeUntil(g, e, "classdecl");

}

}

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

classdecl – tokensClassDeclNode classdecl(RecoverySet g) throws ParseEOFException :

{

Token t1 = null, t2 = null, t3 = null;

}

{

try {

t1 = <CLASS> t2 = <IDENT> [ <EXTENDS> t3 = <IDENT> ]

classbody(g)

}

catch (ParseException e)

{

consumeUntil(g, e, "classdecl");

}

}

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

classdecl – nós filhosClassDeclNode classdecl(RecoverySet g) throws ParseEOFException :

{

Token t1 = null, t2 = null, t3 = null;

ClassBodyNode c1 = null;

}

{

try {

t1 = <CLASS> t2 = <IDENT> [ <EXTENDS> t3 = <IDENT> ]

c1 = classbody(g)

}

catch (ParseException e)

{

consumeUntil(g, e, "classdecl");

}

}

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

classdecl – retornoClassDeclNode classdecl(RecoverySet g) throws ParseEOFException :

{

Token t1 = null, t2 = null, t3 = null;

ClassBodyNode c1 = null;

}

{

try {

t1 = <CLASS> t2 = <IDENT> [ <EXTENDS> t3 = <IDENT> ]

c1 = classbody(g)

{ return new ClassDeclNode(t1, t2, t3, c1); }

}

catch (ParseException e)

{

consumeUntil(g, e, "classdecl");

}

}

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

classdecl – erro sintáticoClassDeclNode classdecl(RecoverySet g) throws ParseEOFException :

{

Token t1 = null, t2 = null, t3 = null;

ClassBodyNode c1 = null;

}

{

try {

t1 = <CLASS> t2 = <IDENT> [ <EXTENDS> t3 = <IDENT> ]

c1 = classbody(g)

{ return new ClassDeclNode(t1, t2, t3, c1); }

}

catch (ParseException e)

{

consumeUntil(g, e, "classdecl");

return new ClassDeclNode(t1, t2, t3, c1);

}

}

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

classdeclClassDeclNode classdecl(RecoverySet g) throws ParseEOFE xception :

{

Token t1 = null, t2 = null, t3 = null;

ClassBodyNode c1 = null;

}

{

try {

t1 = <CLASS> t2 = <IDENT> [ <EXTENDS> t3 = <IDENT> ]

c1 = classbody(g)

{ return new ClassDeclNode(t1, t2, t3, c1); }

}

catch (ParseException e)

{

consumeUntil(g, e, "classdecl");

return new ClassDeclNode(t1, t2, t3, c1);

}

}

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

ClassDeclNodepackage syntacticTree;

import Token;

public class ClassDeclNode extends GeneralNode {

public Token name;

public Token supername;

public ClassBodyNode body;

public ClassDeclNode(Token t1, Token t2, Token t3, ClassBo dyNode c)

{

//passa token de refer encia para construtor da superclasse

super(t1);

name = t2;

supername = t3;

body = c;

}

}

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

ClassDeclNodepackage syntacticTree;

import Token;

public class ClassDeclNode extends GeneralNode {

public Token name;

public Token supername;

public ClassBodyNode body;

public ClassDeclNode(Token t1, Token t2, Token t3, ClassBo dyNode c)

{

//passa token de refer encia para construtor da superclasse

super(t1);

name = t2;

supername = t3;

body = c;

}

}

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

ClassDeclNodepackage syntacticTree;

import Token;

public class ClassDeclNode extends GeneralNode {

public Token name;

public Token supername;

public ClassBodyNode body;

public ClassDeclNode(Token t1, Token t2, Token t3, ClassBo dyNode c)

{

//passa token de refer encia para construtor da superclasse

super(t1);

name = t2;

supername = t3;

body = c;

}

}

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

classdecl – exemplo

class a extends b {

...

}

ClassDeclNode

Token: a Token: b ClassBodyNode

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

Nó inicialListNode program() throws ParseEOFException : {

RecoverySet g = First.program;

ListNode l = null, d = null;

}

{

<EOF>

|

( l = classlist(g)

try {

<EOF> {return l;}

}

catch (ParseException e)

{

consumeUntil(g, e, "program");

}

[ d = program() ]

) { return l;}

}

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

ListNode

ListNode

GeneralNode ListNode

GeneralNode ListNode

GeneralNode

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

ListNodeclass a extends b { ... }

class b { ... }

class c { ...}

ListNode

ClassDeclNode ListNode

ClassDeclNode ListNode

ClassDeclNode

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

classlistListNode classlist(RecoverySet g)

throws ParseEOFException :

{

ClassDeclNode c = null;

ListNode l = null;

RecoverySet f = First.classlist.union(g);

}

{

(

c = classdecl(f) [ l = classlist(g) ]

) { return new ListNode(c, l);}

}

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

classbodyClassBodyNode classbody(RecoverySet g)

throws ParseEOFException :

{

ListNode c = null,

v = null,

ct = null,

m = null;

VarDeclNode vd;

ConstructDeclNode cd;

MethodDeclNode md;

Token t = null;

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

classbodytry {

t = <LBRACE>

[c = classlist(f5)]

(LOOKAHEAD(3) vd = vardecl(f2) <SEMICOLON>

{ if ( v == null)

v = new ListNode(vd);

else

v.add(vd);

}

) *

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

classbody(cd = constructdecl(f4)

{ if ( ct == null)

ct = new ListNode(cd);

else

ct.add(cd);

}

) *

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

classbody(md = methoddecl(f3)

{ if ( m == null)

m = new ListNode(md);

else

m.add(md);

}

) *

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

classbody<RBRACE>

{ return new ClassBodyNode(t, c, v, ct, m); }

}

catch (ParseException e)

{

consumeUntil(g, e, "classbody");

return new ClassBodyNode(t, c, v, ct, m);

}

}

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

classbody – exemplo

class teste {class a { ... }class b { ... }

int c, d;string e, f;

constructor (int g){ ... }

int h(){ ... }

}

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

classbody – exemplo

ClassDeclNode

Token: teste ClassBodyNode

ListNode ListNode

ListNode VarDeclNode ListNode ConstructDeclNode ListNode

ClassDeclNode ListNode VarDeclNode MethodDeclNode

ClassDeclNode

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

Caso especial – StatementNode

VarDeclNode AtribNode

StatementNode

IfNode PrintNode

GeneralNode

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

statementStatementNode statement(RecoverySet g)

throws ParseEOFException : {

StatementNode s = null;

}

{

try {

( s = vardecl(f1) <SEMICOLON> |

s = atribstat(f1) <SEMICOLON> |

s = printstat(f1) <SEMICOLON> |

. . .

) {return s;}

}

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

StatementNode – exemplo

int[][] m(string b[], int c){

;c = 0;

}

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

StatementNode – exemplo

MethodDeclNode

Token: int 2 Token: m MethodBodyNode

ListNode BlockNode

VarDeclNode ListNode ListNode

Token: string ListNode VarDeclNode NopNode ListNode

VarNode Token: int ListNode AtribNode

Token: b 1 VarNode

Token: c 0

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

StatementNode – exemplo IIif ( a == b)

if ( c < d )a = 10;

else{

b = 0;c = 1024;

}

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

StatementNode – exemplo II

IfNode

ExpreNode IfNode

ExpreNode AtribNode BlockNode

ListNode

AtribNode ListNode

AtribNode

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

StatementNode – exemplo III

for ( i = 0 ; i < a; i = i + 1)for (j = i + 1; j < b; j = j + 1){

b = 0;c = 1024;

}

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

StatementNode – exemplo III

ForNode

AtribNode ExpreNode AtribNode ForNode

AtribNode ExpreNode AtribNode BlockNode

ListNode

AtribNode ListNode

AtribNode

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

ExpreNode – outra exceção

Assim como StatementNode, o ExpreNode é umaclasse abstrata.

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

ExpreNode – outra exceção

Assim como StatementNode, o ExpreNode é umaclasse abstrata.

Dela descendem tipos diferentes de nós.

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

ExpreNode – outra exceção

Assim como StatementNode, o ExpreNode é umaclasse abstrata.

Dela descendem tipos diferentes de nós.

CallNode, DotNode, IndexNode, NewObjectNode,AddNode, MultNode, RelationalNode, etc.

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

ExpreNode – exemplo

a + b + c

AddNode

AddNode Token: + VarNode

VarNode Token: + VarNode Token: c

Token: a Token: b

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

ExpreNode – exemplo IIa + b.x < -3 * c[2]

RelationalNode

AddNode Token: < MultNode

VarNode Token: + DotNode Token: * IndexNode

Token: a VarNode Token: x UnaryNode VarNode intConstNode

Token: b Token: - IntConstNode Token: c Token: 2

Token: 3

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

top related