init with {: System.err.println("Interpreteur Brainfuck (compact)"); :} action code {: /* la machine brainfuck */ int ptr=0; byte bande[]=new byte[33333]; /* construction d'un AST pour interpretation */ abstract class AST { abstract public void exec(); } class PTR extends AST { /* PTR_INC et PTR_DEC */ int num; /* repetitions consecutives et signe */ public PTR(int n) { num=n; } public void exec() { ptr+=num; } } class VAL extends AST { /* VAL_INC et VAL_DEC */ int num; /* repetitions consecutives et signe */ public VAL(int n) { num=n; } public void exec() { bande[ptr]+=num; } } class PUT extends AST { public void exec() { System.out.write(bande,ptr,1); } } class GET extends AST { public void exec() { try {System.in.read(bande,ptr,1);} catch (java.io.IOException e) {} } } class Loop extends AST { /* la boucle= liste d'instructions */ java.util.ArrayList insts; public Loop() { insts = new java.util.ArrayList(); } public void loopAdd(AST i) { insts.add(i); } public void exec() { while (bande[ptr]!=0) for ( AST f : insts) f.exec(); } } :} terminal Integer PTR, VAL; terminal PUTCHAR, GETCHAR, LOOP_IN, LOOP_OUT; nonterminal ListeInst; nonterminal AST Inst ; nonterminal Loop loop; ListeInst ::= /* vide */ {: :} | ListeInst Inst:inst {: inst.exec(); :} ; Inst ::= PTR:n {: RESULT = new PTR(n); :} | VAL:n {: RESULT = new VAL(n); :} | GETCHAR {: RESULT = new GET(); :} | PUTCHAR {: RESULT = new PUT(); :} | LOOP_IN loop:l LOOP_OUT {: RESULT = l; :} ; loop ::= /* vide */ {: RESULT = new Loop(); :} | loop:l Inst:i {: RESULT=l; RESULT.loopAdd(i); :} ;