Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple enum for java automaton

I'm trying to implement this automaton example : http://www.javacodegeeks.com/2012/03/automaton-implementation-in-java.html.

However, an error keeps on being displayed while running the program :

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: 
           String index out of range: 3
at java.lang.String.charAt(String.java:686)
at mealy.Input.read(Input.java:7)
at mealy.States$4.next(Input.java:46)
at mealy.Test.main(Test.java:9)

I tried modifying the lines responsible for the error but nothing changed. Could someone please take a look at this program and help me find a solution?

I have the following .java :

State.java :

interface State {
    public State next(Input in);
}

NB : I had to change the original "public Stat next()" into "public State next(Input in);"

Input.java :

class Input {
    private String input;
    private int current;
    public Input(String input) {this.input = input;}
    char read() { return input.charAt(current++); }
}

enum States implements State {
    Init {
        @Override
        public State next(Input word) {
            switch(word.read()) {
                case 'a': return A;
                default: return Fail;
            }
        }
    },
    A {
        @Override
        public State next(Input word) {
            switch(word.read()) {
                case 'a': return A;
                case 'b': return B;
                case 'c': return C;
                case 'd': return null;
                default: return Fail;
            }
        }
    },
    B {
        @Override
        public State next(Input word) {
            switch(word.read()) {
                case 'b': return B;
                case 'c': return C;
                case 'd': return null;
                default: return Fail;
            }
        }
    },
    C {
        @Override
        public State next(Input word) {
            switch(word.read()) {
                case 'c': return C;
                case 'd': return null;
                default: return Fail;
            }
        }
    },
    Fail {
        @Override
        public State next(Input word) {
               return Fail;
        }
    };

    public abstract State next(Input word);
}

Test.java :

public class Test {
    public static void main(String args[]){
        State s;
        Input in = new Input("abc");

        for(s = States.Init; s != null || s != States.Fail; s = s.next(in)) {}
        if(s == States.Init) {System.out.println("Valid!");}
        else {System.out.println("Failed");}
    }
}
like image 741
Fabrice Sopoglian Avatar asked Dec 19 '25 20:12

Fabrice Sopoglian


1 Answers

There appears to be a bug in the Input class. When you attempt to read the character after the last one, it throws an exception you are not handling in main. I would change Input so that it return a token you can handle in your state machine.

BTW I suggest you have a look at this for context. http://vanillajava.blogspot.co.uk/2011/06/java-secret-using-enum-as-state-machine.html

I assume Attila was looking to provide a simple, working example. I will see if he can fix his code.

like image 181
Peter Lawrey Avatar answered Dec 22 '25 09:12

Peter Lawrey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!