/media/sda-magnetic/david/Dokumente-15/fernuni-hagen/cs-i-ii/old-cs-2-03/java-new/Arithmetic26-3/Arithmetic.java


public class Arithmetic {

     String [] SourceCodes = new String[10]; 
   
   Arithmetic (String [] args) {
        int i;
        try {
            for (i = 0;  i < args.length;  i++) 
                SourceCodes[i] = args[i];
                
            Prog prg = new Prog (SourceCodes[0]);
        }
        catch (ArrayIndexOutOfBoundsException e) {
            System.out.println ("You must give at least one argument");
        }

   }
   

   
    public  class Prog {
    
    Prog (String SourceCode1) {
        asm = new Asm();
        tr = new Terminal();
        reg = new Register();
        this.SourceCode = SourceCode1;
                
        Squnce sq = new Squnce();
        sq.squnce();
        
        printtree(sq);
        
        asm.insertEndOf();
        
                
        asm.virtualMachine();         
    }
    
    
    void printtree (NotTerminal t) {
        if (t != null) {
            if (t.getid1() != null) {
                System.out.print ("id1: " + t.getid1()); 
            }
            if (t.getid2() != null) {
                System.out.print ("id1: " + t.getid2()); 
            }
            if (t.getid3() != null) {
                System.out.print ("id1: " + t.getid3()); 
            }
            if (t.getid4() != null) {
                System.out.print ("id1: " + t.getid4()); 
            }
            if (t.getid5() != null) {
                System.out.print ("id1: " + t.getid5()); 
            }
            if (t.getterminal1() != null) {
                System.out.print ("terminal1 : " + t.getterminal1());
            }
            if (t.getterminal2() != null) {
                System.out.print ("terminal2 : " + t.getterminal2());
            }
            if (t.getterminal3() != null) {
                System.out.print ("terminal3 : " + t.getterminal3());
            }
            if (t.getterminal4() != null) {
                System.out.print ("terminal4 : " + t.getterminal4());
            }
            if (t.getterminal5() != null) {
                System.out.print ("terminal5 : " + t.getterminal5());
            }
            if (t.getterminal6() != null) {
                System.out.print ("terminal6 : " + t.getterminal6());
            }
            if (t.getterminal7() != null) {
                System.out.print ("terminal7 : " + t.getterminal7());
            }
            System.out.println ();
            System.out.println ();
            if (t.getnt1() != null)
                printtree (t.getnt1());
            if (t.getnt2() != null)
                printtree (t.getnt2());
            if (t.getnt3() != null)
                printtree (t.getnt3());
            if (t.getnt4() != null)
                printtree (t.getnt4());
            if (t.getnt5() != null)
                printtree (t.getnt5());
    
        }
    }
    
    
     String SourceCode;
    
     Register reg = new Register();
     Terminal tr = new Terminal();
     Asm asm = new Asm();
        
     public class Asm {
         String [][] asm;
         int asmcount;
         int [] regs; 
         int [] vars;
    
        Asm () {
            asmcount = 0;
            asm = new String [1024*64][4];
            regs = new int[1024*64];
            vars = new int[26];
        }
        
 
        
         int getcounter () {
            return asmcount;
        }
        
         void asmcounter (String opcode, String op1, String op2, String op3) {
            try {
                asm[asmcount][0] = opcode;
                asm[asmcount][1] = op1;
                asm[asmcount][2] = op2;
                asm[asmcount][3] = op3;
                asmcount++;
            }
            catch (ArrayIndexOutOfBoundsException e) {
                System.out.println ("Your code doesn't fit in the space given within the memory model of the programs virtual machine");
                System.exit(-1);
            }
        }
        
         void insertEndOf () {
            asm[asmcount][0] = "stop";
            asmcount++;
        }
        
         void asmsetcounter (int asmcnt, String opcode, String op1, String op2, String op3) {
                asm[asmcnt][0] = opcode;
                asm[asmcnt][1] = op1;
                asm[asmcnt][2] = op2;
                asm[asmcnt][3] = op3;
        }
        
         void virtualMachine () {
            int i;
            int reg1;
            int var1 = 0;
            int op2 = 0;
            int op3 = 0;
            int z = 0;
        
        
            try {
                for (i = 0;  (i < asmcount) && (z < 8192);  i++, z++) {                
                    if (asm[i][0].equals("add") || asm[i][0].equals("mul") || asm[i][0].equals("ge") || asm[i][0].equals("le") || asm[i][0].equals("eq") || asm[i][0].equals("ne") || asm[i][0].equals("ls") || asm[i][0].equals("ge")) {
                    
                    
                        if(asm[i][1].length() >= 3) {
                            if((asm[i][1].charAt(0) == '_') && (asm[i][1].charAt(1) == 'r')) {
                                reg1 = Integer.parseInt(asm[i][1].substring(2));
                    
                                if(asm[i][2].length() >= 3) {
                                    if((asm[i][2].charAt(0) == '_') && (asm[i][2].charAt(1) == 'r')) 
                                        op2 = regs[Integer.parseInt(asm[i][2].substring(2))];
                                    else if((asm[i][2].charAt(0) >= '0') && (asm[i][2].charAt(0) <= '9')) 
                                        op2 = Integer.parseInt(asm[i][2]);
                                    else if((asm[i][2].charAt(0) >= 'a') && (asm[i][2].charAt(0) <= 'z')) 
                                        op2 = vars[(int)(asm[i][2].charAt(0)) - (int)('a')];

                                }
                                else if((asm[i][2].charAt(0) >= '0') && (asm[i][2].charAt(0) <= '9')) {
                                    op2 = Integer.parseInt(asm[i][2]);
                                } 
                                else if((asm[i][2].charAt(0) >= 'a') && (asm[i][2].charAt(0) <= 'z')) {
                                    op2 = vars[(int)(asm[i][2].charAt(0)) - (int)('a')];
                                } 
                    
                                if(asm[i][3].length() >= 3) {
                                    if((asm[i][3].charAt(0) == '_') && (asm[i][3].charAt(1) == 'r')) 
                                        op3 = regs[Integer.parseInt(asm[i][3].substring(2))];
                                    else if((asm[i][3].charAt(0) >= '0') && (asm[i][3].charAt(0) <= '9')) 
                                        op3 = Integer.parseInt(asm[i][3]);
                                    else if((asm[i][3].charAt(0) >= 'a') && (asm[i][3].charAt(0) <= 'z')) 
                                        op3 = vars[(int)(asm[i][3].charAt(0)) - (int)('a')];

                                }
                                else if((asm[i][3].charAt(0) >= '0') && (asm[i][3].charAt(0) <= '9')) 
                                    op3 = Integer.parseInt(asm[i][3]);
                                else if((asm[i][3].charAt(0) >= 'a') && (asm[i][3].charAt(0) <= 'z')) 
                                    op3 = vars[(int)(asm[i][3].charAt(0)) - (int)('a')];

                                    
                                if (asm[i][0].equals("add")) 
                                    regs[reg1] = op2 + op3;
                                else if (asm[i][0].equals("mul")) 
                                    regs[reg1] = op2 * op3;
                                else if (asm[i][0].equals("le")) {
                                   if (op2 <= op3)
                                        regs[reg1] = 1;
                                    else
                                        regs[reg1] = 0;
                                }
                                else if (asm[i][0].equals("ge")) {
                                   if (op2 >= op3)
                                        regs[reg1] = 1;
                                    else
                                        regs[reg1] = 0;
                                }
                                else if (asm[i][0].equals("eq")) {
                                   if (op2 == op3)
                                        regs[reg1] = 1;
                                    else
                                        regs[reg1] = 0;
                                }
                                else if (asm[i][0].equals("no")) {
                                   if (op2 != op3)
                                        regs[reg1] = 1;
                                    else
                                        regs[reg1] = 0;
                                }
                                else if (asm[i][0].equals("ls")) {
                                   if (op2 < op3)
                                        regs[reg1] = 1;
                                    else
                                        regs[reg1] = 0;
                                }
                                else if (asm[i][0].equals("gr")) {
                                   if (op2 > op3)
                                        regs[reg1] = 1;
                                    else
                                        regs[reg1] = 0;
                                }
                            }
                        }
                    }
                    else if (asm[i][0].equals("mov")) {               
                        if((asm[i][1].charAt(0) >= 'a') && (asm[i][1].charAt(0) <= 'z')) {
                            var1 = (int)(asm[i][1].charAt(0)) - (int)('a');
                            if(asm[i][2].length() >= 3) {
                                if((asm[i][2].charAt(0) == '_') && (asm[i][2].charAt(1) == 'r')) 
                                    op2 = regs[Integer.parseInt(asm[i][2].substring(2))];
                                else if((asm[i][2].charAt(0) >= '0') && (asm[i][2].charAt(0) <= '9')) 
                                    op2 = Integer.parseInt(asm[i][2]);
                            }
                            else if((asm[i][2].charAt(0) >= '0') && (asm[i][2].charAt(0) <= '9')) {
                                op2 = Integer.parseInt(asm[i][2]);
                            } 
                        }
                        vars[var1] = op2;
                    }
                    else if (asm[i][0].equals("print")) {               
                        if((asm[i][1].charAt(0) == '_') && (asm[i][1].charAt(1) == 'r')) {
                            reg1 = Integer.parseInt(asm[i][1].substring(2));
                            System.out.println ("print line: " + i + " - register: " + reg1 + " - value : "  + regs[reg1]);
                        }
                        else if((asm[i][1].charAt(0) >= 'a') && (asm[i][1].charAt(0) <= 'z')) {
                            var1 = (int)(asm[i][1].charAt(0)) - (int)('a');
                            System.out.println ("print line: " + i + " - variable: " + var1 + " - value : "  + vars[var1]);
                        }
                    }
                    else if (asm[i][0].equals("print")) {               
                        if((asm[i][1].charAt(0) == '_') && (asm[i][1].charAt(1) == 'r')) {
                            reg1 = Integer.parseInt(asm[i][1].substring(2));
                            System.exit (regs[reg1]);
                        }
                        else if((asm[i][1].charAt(0) >= 'a') && (asm[i][1].charAt(0) <= 'z')) {
                            var1 = (int)(asm[i][1].charAt(0)) - (int)('a');
                            System.exit (vars[var1]);
                        }
                    }
                    else if (asm[i][0].equals("jmp")) 
                        i = Integer.parseInt(asm[i][1])-1;
                    else if (asm[i][0].equals("jcond")) {
                        if(regs[Integer.parseInt(asm[i][2].substring(2))] ==0)
                           i = Integer.parseInt(asm[i][1])-1; 
                    }
                    else if (asm[i][0].equals("call")) {
                            String cmd;
                            String varxy;
                            int progcount;
                            progcount = (int) (asm[i][1].charAt(1) - 'f');
                            
                            varxy = SourceCodes[progcount].substring ("input".length(), "inputx".length());
                            cmd = SourceCodes[progcount].substring ("inputx;".length(), SourceCodes[progcount].length());
                            cmd = varxy + ":=" + regs[Integer.parseInt(asm[i][3].substring(2))] + ";" + cmd;
                   
                            Prog prg = new Prog (cmd);                            
                    }
                    else if (asm[i][0].equals("stop")) break;
                }
            }
            catch (ArrayIndexOutOfBoundsException e) {
                System.out.println ("Your code uses more than the maximum of the allowed number of registers");
                System.exit(-1);
            }
            catch (Exception e) {
            
            }
            if (z == 2048) {
               System.out.println ("Your program does to much time need");
               System.exit(-1);
            }
            
        }
    }
        
     public class Register {
        int regcount;
        Register () {
            this.regcount = -1;
        }
        
        String getnext() {
            regcount++;
            return "_r" + regcount;
        }
    }
    
    
     public class Terminal {
        int count;
        Terminal() {
            this.count = 0;
        }
        
        int getCount() {
            return this.count;
        }
        void setCount(int count) {
            this.count = count;
        }
            
        boolean isPlus() {
            if (SourceCode.length() <= count)
                return false;
            if(SourceCode.charAt(count) == '+') {
                count++;
                return true;
            }   
            return false;
        }
        boolean isMult() {
            if (SourceCode.length() <= count)
                return false;
            if(SourceCode.charAt(count) == '*') {
                count++;
                return true;
            }
            return false;
        }
        boolean isOpenRoundBracket() {
            if (SourceCode.length() <= count)
                return false;
            if(SourceCode.charAt(count) == '(') {
                count++;
                return true;
            }
            return false;
        }
        boolean isClosedRoundBracket() {
            if (SourceCode.length() <= count)
                return false;
            if(SourceCode.charAt(count) == ')') {
                count++;
                return true;
            }
            return false;
        }
        boolean isSemicolon() {
            if (SourceCode.length() <= count)
                return false;
            if(SourceCode.charAt(count) == ';') {
                count++;
                return true;
            }
            return false;
        }
        boolean isSet() {
            if (SourceCode.length() <= count+1)
                return false;
            if((SourceCode.charAt(count) == ':') && (SourceCode.charAt(count+1) == '=')) {
                count+=2;
                return true;
            }
            return false;
        }

        boolean isPrint() {
            if (SourceCode.length() <= (count + "print".length()))
                return false;
            if(SourceCode.substring(count, count + "print".length()).equals("print")) {
                count += "print".length();
                return true;
            }
            return false;
        }
        boolean isReturn() {
            if (SourceCode.length() <= (count + "return".length()))
                return false;
            if(SourceCode.substring(count, count + "return".length()).equals("return")) {
                count += "return".length();
                return true;
            }
            return false;
        }
        boolean isWhile() {
            if (SourceCode.length() <= (count + "WHILE".length()))
                return false;
            if(SourceCode.substring(count, count + "WHILE".length()).equals("WHILE")) {
                count += "WHILE".length();
                return true;
            }
            return false;
        }
        boolean isDo() {
            if (SourceCode.length() <= (count + "DO".length()))
                return false;
            if(SourceCode.substring(count, count + "DO".length()).equals("DO")) {
                count += "DO".length();
                return true;
            }
            return false;
        }
        boolean isThen() {
            if (SourceCode.length() <= (count + "THEN".length()))
                return false;
            if(SourceCode.substring(count, count + "THEN".length()).equals("THEN")) {
                count += "THEN".length();
                return true;
            }
            return false;
        }
        boolean isIf() {
            if (SourceCode.length() <= (count + "IF".length()))
                return false;
            if(SourceCode.substring(count, count + "IF".length()).equals("IF")) {
                count += "IF".length();
                return true;
            }
            return false;
        }
        boolean isElse() {
            if (SourceCode.length() <= (count + "ELSE".length()))
                return false;
            if(SourceCode.substring(count, count + "ELSE".length()).equals("ELSE")) {
                count += "ELSE".length();
                return true;
            }
            return false;
        }

        boolean isBegin() {
            if (SourceCode.length() <= (count + "BEGIN".length()))
                return false;
            if(SourceCode.substring(count, count + "BEGIN".length()).equals("BEGIN")) {
                count += "BEGIN".length();
                return true;
            }
            return false;
        }
        boolean isEnd() {
            if (SourceCode.length() <= (count + "END".length()))
                return false;
            if(SourceCode.substring(count, count + "END".length()).equals("END")) {
                count += "END".length();
                return true;
            }
            return false;
        }

        String isConst () {
            String str = "";
            
            if (SourceCode.length() <= count)
                str = null;
            if (!((SourceCode.charAt(count) >= '0') && (SourceCode.charAt(count) <= '9')))
                str = null;
                
            if (count < SourceCode.length()) {
                while ((SourceCode.charAt(count) >= '0') && (SourceCode.charAt(count) <= '9')) {
                    str = str + Character.toString(SourceCode.charAt(count));
                    count++;
                    if (count >= SourceCode.length())
                        break;
                }
            }
            return str;
        }
        String isVarName () {
            String str = "";
            
            if (SourceCode.length() <= count)
                return null;
            if (!((SourceCode.charAt(count) >= 'a') && (SourceCode.charAt(count) <= 'z')))
                return null;        
            str = Character.toString(SourceCode.charAt(count));
            count++;
            return str;
            
        }
        String isSubRoutine () {
            String str = "";
            if (SourceCode.length() <= (count+2))
                return null;
            if (SourceCode.charAt(count) != '$')
                return null;
            if ((SourceCode.charAt(count+1) >= 'f') && (SourceCode.charAt(count+1) <= 'j')) {
                if (SourceCode.charAt(count+2) == '(') {
                    str = SourceCode.substring (count, count+2);
                    count += 3;
                }
                else 
                    return null;
            }
            else
                return null;
            return str;
        }
        String isCop () {
            String str = "";
            
            if ((count+1) < (SourceCode.length())) {
               if ((SourceCode.charAt(count) == '<') && (SourceCode.charAt(count+1) == '=')) {
                  count+=2;
                  str = "le";
                }
                else if ((SourceCode.charAt(count) == '>') && (SourceCode.charAt(count+1) == '=')) {
                   count+=2;
                   str = "ge";
                }
                else if ((SourceCode.charAt(count) == '=') && (SourceCode.charAt(count+1) == '=')) {
                   count+=2;
                   str = "eq";
                }
                else if ((SourceCode.charAt(count) == '!') && (SourceCode.charAt(count+1) == '=')) {
                   count+=2;
                   str = "ne";
                }
                else if ((SourceCode.charAt(count) == '=')) {
                   count+=1;
                   str = "eq";
                }
                else if (SourceCode.charAt(count) == '<') {
                   count+=1;
                   str = "ls";
                }
                else if (SourceCode.charAt(count) == '>') {
                   count+=1;
                   str = "gr";
                }
                else
                  str = null;
            }
            else if (SourceCode.length() <= count) {
                return null;
            }
            else {
                if (SourceCode.charAt(count) == '=')
                   str = "eq";
                else if (SourceCode.charAt(count) == '<') 
                   str = "ls";
                else if (SourceCode.charAt(count) == '>') 
                   str = "gr";
                else 
                   str = null;
               count++;
            }
            return str;
        }

    }
    
    
     public class NotTerminal {
        
        NotTerminal nt1 = null;
        NotTerminal nt2 = null;
        NotTerminal nt3 = null;
        NotTerminal nt4 = null;
        NotTerminal nt5 = null;
        
        String id1 = null;
        String id2 = null;
        String id3 = null;
        String id4 = null;
        String id5 = null;
        
        String terminal1 = null;
        String terminal2 = null;
        String terminal3 = null;
        String terminal4 = null;
        String terminal5 = null;
        String terminal6 = null;
        String terminal7 = null;
        
        void setnt1 (NotTerminal nt1, String id1) {this.nt1 = nt1;this.id1=id1;}
        void setnt2 (NotTerminal nt2, String id2) {this.nt2 = nt2;this.id2=id2;}
        void setnt3 (NotTerminal nt3, String id3) {this.nt3 = nt3;this.id3=id3;}
        void setnt4 (NotTerminal nt4, String id4) {this.nt4 = nt4;this.id4=id4;}
        void setnt5 (NotTerminal nt5, String id5) {this.nt5 = nt5;this.id5=id5;}
        
        void setterminal1 (String terminal1) {this.terminal1 = terminal1;}
        void setterminal2 (String terminal2) {this.terminal2 = terminal2;}
        void setterminal3 (String terminal3) {this.terminal3 = terminal3;}
        void setterminal4 (String terminal4) {this.terminal4 = terminal4;}
        void setterminal5 (String terminal5) {this.terminal5 = terminal5;}
        void setterminal6 (String terminal6) {this.terminal6 = terminal6;}
        void setterminal7 (String terminal7) {this.terminal7 = terminal7;}
        
        NotTerminal getnt1 () {return this.nt1;}
        NotTerminal getnt2 () {return this.nt2;}
        NotTerminal getnt3 () {return this.nt3;}
        NotTerminal getnt4 () {return this.nt4;}
        NotTerminal getnt5 () {return this.nt5;}
        
        String getid1 () {return this.id1;}
        String getid2 () {return this.id2;}
        String getid3 () {return this.id3;}
        String getid4 () {return this.id4;}
        String getid5 () {return this.id5;}
        
        String getterminal1 () {return this.terminal1;}
        String getterminal2 () {return this.terminal2;}
        String getterminal3 () {return this.terminal3;}
        String getterminal4 () {return this.terminal4;}
        String getterminal5 () {return this.terminal5;}
        String getterminal6 () {return this.terminal6;}
        String getterminal7 () {return this.terminal7;}
        
        NotTerminal() {}
    }
    
     public class BoolExpr extends NotTerminal {
        String op1;
        String op2;
        String op3;
        String cop;
        
        BoolExpr () {}
        
        String boolexpr() {
            NumExpr ne1 = new NumExpr();
            NumExpr ne2 = new NumExpr(); 
            if ((op1 = ne1.numexpr()) != null) {
               setnt1(ne1, "numexpr");
               if ((cop = tr.isCop()) != null) {
                  setterminal1 (cop);
                  if ((op2 = ne2.numexpr()) != null) {
                     setnt2(ne2, "numexpr");
                     op3 = reg.getnext();
                     asm.asmcounter(cop, op3, op1, op2);
                     return op3;
                  }
               }
            }
            return null;
        }
    }
    
     public class Squnce extends NotTerminal {
        String op1;
        
        Squnce () {}
        
        boolean squnce() {
            Stmnt st = new Stmnt();
            if (st.stmnt()) {
                setnt1 (st, "stmt");
                if (tr.isSemicolon()) {
                    setterminal1 (";");
                    Squnce sq = new Squnce();
                    sq.squnce();
                    setnt2 (sq, "squnce");
                }
                return true;
            }
            return false;
        }
    }
    
     public class Assgnmnt extends NotTerminal {
        int oldCount;
        String varnam;
        String op2;
        
        Assgnmnt() {}
        
        boolean assgnmnt () {
            oldCount = tr.getCount();
            if ((varnam = tr.isVarName()) != null) {
                setterminal1 (varnam);
                if (tr.isSet()) {
                    setterminal2 (":=");
                    NumExpr ne = new NumExpr();
                    op2 = ne.numexpr();
                    setnt1 (ne, "numexpr");
                    asm.asmcounter("mov", varnam, op2, null);
                }
                else {
                    tr.setCount(oldCount);
                    return false;
                }
            }
            else {
                tr.setCount(oldCount);
                return false;
            }
            return true;
        }
    }

     public class Loop extends NotTerminal {
        int label1;
        int label2;
        int label3;
        String boolreg;
        Loop() {}
        
        boolean loop () {
            if (tr.isWhile()) {
                setterminal1 ("WHILE");
                label1 = asm.getcounter();
                BoolExpr be = new BoolExpr();
                if ((boolreg = be.boolexpr()) != null) {
                    setnt1 (be, "boolexpr");
                    label2 = asm.getcounter();
                    asm.asmcounter("xxx", null, null, null);
                    if (tr.isDo()) {  
                        setterminal2 ("DO");
                        if (tr.isBegin()) {
                            setterminal3 ("BEGIN");
                            Squnce st = new Squnce();
                            if (st.squnce()) { 
                                setnt2 (st, "squnce");
                                if (tr.isEnd()) {
                                    setterminal4 ("END");
                                    asm.asmcounter("jmp", Integer.toString(label1), null, null);
                                    label3 = asm.getcounter();
                                    asm.asmsetcounter(label2, "jcond", Integer.toString(label3), boolreg, null);
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            return false;
        }
    }

     public class Cond1 extends NotTerminal {
        int label1;
        int label2;
        int label3;
        String boolreg;
        Cond1() {}
        
        boolean cond () {
            if (tr.isIf()) {
                setterminal1 ("IF");
                BoolExpr be = new BoolExpr();
                if ((boolreg = be.boolexpr()) != null) {
                    setnt1 (be, "boolexpr");
                    label2 = asm.getcounter();
                    asm.asmcounter("xxx", null, null, null);
                    if (tr.isThen()) {  
                        setterminal2 ("THEN");
                        if (tr.isBegin()) {
                            setterminal3 ("BEGIN");
                            Squnce st = new Squnce();
                            if (st.squnce()) { 
                                setnt2 (st, "squnce");
                                if (tr.isEnd()) {
                                    setterminal4 ("END");
                                    label3 = asm.getcounter();
                                    asm.asmsetcounter(label2, "jcond", Integer.toString(label3), boolreg, null);
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            return false;
        }
    }

     public class Cond2 extends NotTerminal {
        int label1;
        int label2;
        int label3;
        int label4;
        int label5;
        int label6;
        String boolreg;
        Cond2() {}
        
        boolean cond () {
            if (tr.isIf()) {
                setterminal1 ("IF");
                BoolExpr be = new BoolExpr();
                if ((boolreg = be.boolexpr()) != null) {
                    setnt1 (be, "boolexpr");
                    label2 = asm.getcounter();
                    asm.asmcounter("xxx", null, null, null);
                    if (tr.isThen()) {  
                        setterminal2 ("THEN");
                        if (tr.isBegin()) {
                            setterminal3 ("BEGIN");
                            Squnce st = new Squnce();
                            if (st.squnce()) { 
                                setnt2 (st, "squnce");
                                if (tr.isEnd()) {
                                    setterminal4 ("END");
                                    label4 = asm.getcounter();
                                    asm.asmcounter("xxx", null, null, null);
                                    label6 = asm.getcounter();
                                    if (tr.isElse()) {
                                        setterminal5 ("ELSE");
                                        if (tr.isBegin()) {
                                            setterminal6 ("BEGIN");
                                            Squnce st2 = new Squnce();
                                            if (st2.squnce()) {
                                                setnt3 (st2, "squnce");
                                                if (tr.isEnd()) {
                                                    setterminal7 ("END");
                                                    asm.asmsetcounter(label2, "jcond", Integer.toString(label6), boolreg, null);
                                                    label5 = asm.getcounter();
                                                    asm.asmsetcounter(label4, "jmp", Integer.toString(label5), boolreg, null);
                                                    return true;                                            
                                                }
                                            }
                                        }
                                    }
                                    else {
                                        label3 = asm.getcounter();
                                        asm.asmsetcounter(label2, "jcond", Integer.toString(label3), boolreg, null);
                                        return true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return false;
        }
    }
    
     public class Stmnt extends NotTerminal {
        String op1;
        Stmnt () {}
        Assgnmnt as = new Assgnmnt();
        Loop lp = new Loop();
        Cond2 cd = new Cond2();
        
        boolean stmnt () {
            if (tr.isPrint()) {
                setterminal1 ("PRINT");
                NumExpr ne = new NumExpr();
                op1 = ne.numexpr();
                setnt1 (ne, "numexpr");
                asm.asmcounter("print", op1, null, null);
                return true;
            }
            if (tr.isReturn()) {
                setterminal1 ("RETURN");
                NumExpr ne = new NumExpr();
                op1 = ne.numexpr();
                setnt1 (ne, "numexpr");
                asm.asmcounter("return", op1, null, null);
                return true;
            }
            else if (as.assgnmnt()) {setnt1 (as, "assgnment"); return true;}
            else if (lp.loop()) {setnt1 (lp, "loop"); return true;}
            else if (cd.cond()) {setnt1 (cd, "cond"); return true;}
            return false;
        }
    }

    
     public class NumExpr extends NotTerminal {
        String op1;
        String op2;
        String op3;
        
        NumExpr () {}
        
        String numexpr () {
            Term t = new Term();
            op1 = t.term();
            setnt1 (t, "term");
            
            if (tr.isPlus()) {
                setterminal1 ("+");
                NumExpr e = new NumExpr();
                
                op2 = e.numexpr();
                setnt2 (e, "numexpr");
                op3 = reg.getnext();
                asm.asmcounter ("add", op3, op1, op2);
                return op3;
            }
            return op1;
        }
    }

     public class Term extends NotTerminal {
        String op1;
        String op2;
        String op3;
        
        Term () {}
        
        String term () {
            Factor f = new Factor();
            op1 = f.factor();
            setnt1 (f, "fac");
            if (tr.isMult()) {
                setterminal1 ("*");
                Term t = new Term(); 
                op2 = t.term();
                setnt2 (t, "term");
                op3 = reg.getnext();
                asm.asmcounter ("mul", op3, op1, op2);
                return op3;
            }
            return op1;
        }
    }
    
    public class Const extends NotTerminal {
        Const () {}
    }

     public class Factor extends NotTerminal {
        String op1, op2, op3;
        
        Factor () {}
        
        String factor () {
            if (tr.isOpenRoundBracket()) {
                setterminal1 ("(");
                NumExpr e = new NumExpr();
                op1 = e.numexpr();
                setnt1 (e, "numexpr");
                if (tr.isClosedRoundBracket()) {
                    setterminal2 (")");
                    return op1;
                }
                else
                    System.out.println ("Error");
            }
            else if ((op1 = tr.isConst()) != null) {
                Const cnst = new Const();
                setnt1 (cnst, "const");
                setterminal1 (op1);
                op3 = reg.getnext();
                asm.asmcounter ("add", op3, "0", op1);
                return op3;
            }
            else if ((op1 = tr.isVarName()) != null) {
                setterminal1 (op1);
                op3 = reg.getnext();
                asm.asmcounter ("add", op3, "0", op1);
                return op3;
            }
            else if ((op2 = tr.isSubRoutine()) != null) {
                NumExpr e = new NumExpr();
                setnt1 (e, "subroutine-call2");
                op3 = e.numexpr();
                setnt2 (e, "numexpr");
                op1 = reg.getnext();
                if (tr.isClosedRoundBracket()) {
                    asm.asmcounter ("call", op2, op1, op3);
                }
                else 
                    System.out.println ("Error");
            }
            else {
                System.out.println ("Error");
                op1 = null;
            }
            return op1;
        }
    }
}}