/media/sda-magnetic/david/Dok-15-2023-11-27/fernuni-hagen/cs-i-ii/old-cs-2-03/java-new/2020-11-23/final/StreamProgLexer.java


public class StreamProgLexer {

    public static void main (String [] args) {
        try {
            int ch, ch2;
            CharEingabeStrom cs;
            cs = new StringLeser (args[0]);
            cs = new UmlautSzFilter (cs);
            //cs = new GrossBuchstabenFilter (cs);
            
            CharEingabeStrom while_stream;
            CharEingabeStrom begin_stream;
            CharEingabeStrom end_stream;
            CharEingabeStrom if_stream;
            CharEingabeStrom then_stream;
            CharEingabeStrom else_stream;
            CharEingabeStrom do_stream;
            CharEingabeStrom empty_character_stream;
            CharEingabeStrom newline_stream;
            CharEingabeStrom tab_stream;
            
            while_stream = new StringLeserLoop ("WHILE");
            begin_stream = new StringLeserLoop ("BEGIN");
            end_stream = new StringLeserLoop ("END");
            if_stream = new StringLeserLoop ("IF");
            then_stream = new StringLeserLoop ("THEN");
            else_stream = new StringLeserLoop ("ELSE");
            do_stream = new StringLeserLoop ("DO");
            empty_character_stream = new StringLeserLoop (" ");
            newline_stream = new StringLeserLoop ("\n");
            tab_stream = new StringLeserLoop ("\t");
            
            
            while ((ch = cs.read()) != -1) {
                if (((ch2 = while_stream.read()) != ch) && (ch2 != -1)) {
                    while (ch2 != -1) 
                        ch2 = while_stream.read();
                }
                else if (ch2 == -1)
                    System.out.println ("WHILE found");
                
            }
        }
        catch (ArrayIndexOutOfBoundsException e) {
            System.out.println ("usage: java StreamProg arg1");
        }
    }
    
    interface CharEingabeStrom {
        int read();
    }

    public static class StringLeser implements CharEingabeStrom {
        private String quelle;
        private int index;
        
        public StringLeser (String quelle) {
            this.quelle = quelle;
        }
    
        @Override
        public int read () {
            if ((index == quelle.length()))
                return -1;
            return quelle.charAt (index++);
        }
    }


    public static class StringLeserLoop implements CharEingabeStrom {
        private String quelle;
        private int index;
        
        public StringLeserLoop (String quelle) {
            this.quelle = quelle;
        }
    
        @Override
        public int read () {
            if ((index == quelle.length())) {
                index = 0;
                return -1;
            }
            return quelle.charAt (index++);
        }
    }
    
    
    public static class GrossBuchstabenFilter implements CharEingabeStrom {
        private CharEingabeStrom quelle;
        
        public GrossBuchstabenFilter (CharEingabeStrom quelle) {
            this.quelle = quelle;
        }
        
        @Override
        public int read () {
            int zeichen = quelle.read();
            if (zeichen == -1)
                return -1;
            return Character.toUpperCase ((char) zeichen);
        }    
    }
    
    public static class UmlautSzFilter implements CharEingabeStrom {
        private CharEingabeStrom quelle;
        private int puffer = -1;
        
        public UmlautSzFilter (CharEingabeStrom quelle) {
            this.quelle = quelle;
        }
        
        @Override 
        public int read () {
            if (puffer != -1) {
                int zeichen = puffer;
                puffer = -1;
                return zeichen;
            }
            else {
                int zeichen = quelle.read ();
                if (zeichen == -1)
                    return -1;
                switch ((char) zeichen) {
                    case '\u00C4':
                        puffer = 'e';
                        return 'A';
                    case '\u00D6':
                        puffer = 'e';
                        return 'O';
                    case '\u00DC':
                        puffer = 'e';
                        return 'U';
                    case '\u00E4':
                        puffer = 'e';
                        return 'a';
                    case '\u00F6':
                        puffer = 'e';
                        return 'o';
                    case '\u00FC':
                        puffer = 'e';
                        return 'u';
                    case '\u00DF':
                        puffer = 's';
                        return 's';
                    default:
                        return zeichen;
                }
            }
        }
    }
}