/media/sda-magnetic/david/Dok-15-2023-11-27/fernuni-hagen/cs-i-ii/old-cs-2-01/2021-11-20-java/Arithmetic.java


class Arithmetic {
    public static Lexer lex = new Lexer ("(5+2)*3)");
    public static void main (String [] args) {
    
    }
    public static class Lexer {
        static int i;
        static int j;
        static String lexstream;
        static char ch;
        
        
        Lexer (String lexstream) {
            this.lexstream = lexstream;
            i = 0;
            j = 0;
        }
        
        public static char getnext () {
            if ((lexstream.charAt (i) == ' ') || (lexstream.charAt (i) == '\t') || (lexstream.charAt (i) == '\n') || (lexstream.charAt (i) == '\r')) 
                while ((lexstream.charAt (i) == ' ') || (lexstream.charAt (i) == '\t') || (lexstream.charAt (i) == '\n') || (lexstream.charAt (i) == '\r')) 
                    i++;
            if (lexstream.charAt (i) == '(') {
                j = 1;
                i++;
                ch = '(';
            }   
            else if (lexstream.charAt (i) == ')') {
                j = 1;
                i++;
                ch = ')';
            }   
            else if (lexstream.charAt (i) == '*') {
                j = 1;
                i++;
                ch = '*';
            }   
            else if (lexstream.charAt (i) == '+') {
                j = 1;
                i++;
                ch = '+';
            }   
            else if ((lexstream.charAt (i) >= '0') && (lexstream.charAt (i) <= '9')) {
                ch = lexstream.charAt (i);
                j = 1;
                i++;
            }   
            else {
                System.out.println ("error");
                System.exit (2);
            }
            return ch;
        }
        public static void undo () {
            i = i-j;
            j = 0;
        }
    }
    
    /* Syntaxregeln
    expr ::= term expr2
    expr2 ::= '+' term expr2 | e
    term ::= fact term2
    term2 ::= '*' fact term2 | e
    fact ::= const | '(' expr ')'
    */
    
    public class Syntaxtree {
        public Syntaxtree left;
        public Syntaxtree right;
        public char value;
        
        public static int getval () {
            System.out.println (this.value);
            if (this.left != null)
                this.left.getval ();
            if (this.right != null)
                this.right.getval ();
        }
    }
    
    public static class Expr extends Syntaxtree {
        Expr () {
            this.right = new Term ();
            this.left = new Expr2 ();
            this.value = '+';
        }
    }
    public static class Expr2 extends Syntaxtree  {
        Expr2 () {
            if (lex.getnext () == '+') {
                this.right = new Term ();
                this.left = new Expr2 ();
                this.value = '+';
            }
            else {
                lex.undo ();
                this.right = null;
                this.left = null;
                this.value = '0';
            }
        }
    
    }
    public static class Term extends Syntaxtree  {
        Term () {
            char ch;
            ch = lex.getnext ();
            
            if (ch == '(') {
                this.right = new Expr ();
                if ((ch = lex.getnext ()) != ')') {
                    System.out.println ("Error");
                    System.exit(1);
                }
                this.left = new Term2 ();
                this.value = '*';
            }
            else {
                lex.undo ();
                this.right = new Fact ();
                this.left = new Term2 ();
                this.value = '*';
            }
        }
    }
    public static class Term2 extends Syntaxtree  {
        public static char ch;
        Term2 () {
            

            if ((lex.getnext ()) == '*') {
                if ((ch = lex.getnext ()) == '(') {
                    this.right = new Expr ();
                    if ((ch = lex.getnext ()) != ')') {
                        System.out.println ("error");
                        System.exit (1);
                    }
                    this.right = new Term2 ();
                    this.value = '*';
                }
                else {
                    lex.undo ();
                    this.right = new Fact ();
                    this.left = new Term2 ();
                    this.value = '*';
                }
            }
            else {
                lex.undo ();
                this.right = null;
                this.left = null;
                this.value = '1';
            
            }
        
        }
    
    }
    public static class Fact extends Syntaxtree  {
        public char ch;
        Fact () {
            if (((ch = lex.getnext ()) >= '0') && (lex.getnext () <= '9')) {
                this.value = ch;
                this.right = null;
                this.left = null;
            }
        }
    
    }

}