Como construir um compilador utilizandoferramentas Java
Aula 9 – Construção da árvore sintática
Prof. Marcio [email protected]
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