Compiler Construction/TestState.java

// TestState.java

/*
    Copyright 2005 Takuya Murata

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
import java.util.*;
 
public final class TestState extends junit.framework.TestCase {
    private void assertSame (State x[], State y[]) {
        assertEquals (x.length, y.length);
        
        Set<State> set = new HashSet<State> ();
        set.addAll (Arrays.asList (x));
        set.removeAll (Arrays.asList (y));
        assertTrue (set.isEmpty ());
    }
    
    private void assertSame (String message, State x[], State y[]) {
        assertEquals (message, x.length, y.length);
        
        Set<State> set = new HashSet<State> ();
        set.addAll (Arrays.asList (x));
        set.removeAll (Arrays.asList (y));
        assertTrue (message, set.isEmpty ());
    }

    private State s0, s1, s2, s3;

    public void setUp () {
        // This automaton recognizes (a|b)*abb
        s0 = new State ("s0");
        s1 = new State ("s1");
        s2 = new State ("s2");
        s3 = new State ("s3");
        
        s0.setTransition ('a', s0);
        s0.setTransition ('b', s0);
        s0.setTransition ('a', s1);
        
        s1.setTransition ('b', s2);
        s2.setTransition ('b', s3);
    }
    
    public void test_closure () {
        State s4 = new State ("s4");
        s4.setTransition (State.EMPTY, s0);
        
        State s5 = new State ("s5");
        s5.setTransition (State.EMPTY, s4);
        
        assertSame (new State[] { s0 }, s0.closure ());
        assertSame (new State[] { s1 }, s1.closure ());
        assertSame (new State[] { s2 }, s2.closure ());
        assertSame (new State[] { s0, s4 }, s4.closure ());
        assertSame (Arrays.asList (s5.closure ()).toString (),
            new State[] { s0, s4, s5 }, s5.closure ());
        assertSame (new State[] { s0, s1, }, s5.move ('a'));
    }
    
    public void test_move () {
        assertTrue (Arrays.asList (s0.move ("abb")).contains (s3));
        assertTrue (Arrays.asList (s0.move ("babb")).contains (s3));
        assertTrue (!Arrays.asList (s0.move ("babba")).contains (s3));
    }
    
    public void test_toDFA () {
        State s0 = this.s0.toDFA ();
        //s0.prettyPrint (System.err);
        State q3 = s0.moveDFA ("abb");  // this is the only way to get 'q3'.
        assertSame (q3, s0.moveDFA ("abb"));
        assertSame (q3, s0.moveDFA ("babb"));
        assertNotSame (q3, s0.moveDFA ("babba"));
    }
    
    public void test_moveDFA () {
        State s0 = this.s0.toDFA ();
        assertEquals (1, s0.move ("abb").length);
        //s0.prettyPrint (System.err);
        assertSame (s0.moveDFA ("abb"), s0.move ("abb")[0]);
    }
    
    public void test_stringSequence () {
        State if_s[] = State.stringSequence ("if");
        assertTrue (Arrays.asList (if_s[0].move ("if")).contains (if_s[1]));
        assertTrue (!Arrays.asList (if_s[0].move ("abc")).contains (if_s[1]));
        assertTrue (!Arrays.asList (if_s[0].move ("iF")).contains (if_s[1]));
        
        State int_s[] = State.stringSequence ("int");
        State s = new State ("s");
        s.setTransition (State.EMPTY, if_s[0]);
        s.setTransition (State.EMPTY, int_s[0]);
        s = s.toDFA ();
//      s.prettyPrint (System.err);
        
        State acc_if = s.moveDFA ("if"), acc_int = s.moveDFA ("int");
        assertSame (acc_if, s.moveDFA ("if"));
        assertSame (acc_int, s.moveDFA ("int"));
    }
    
    public void test_stringSequence_ignoreCase () {
        State if_s[] = State.stringSequenceIgnoreCase ("if");
        assertTrue (Arrays.asList (if_s[0].move ("IF")).contains (if_s[1]));
        assertTrue (!Arrays.asList (if_s[0].move ("abc")).contains (if_s[1]));
        assertTrue (Arrays.asList (if_s[0].move ("iF")).contains (if_s[1]));
        
        State int_s[] = State.stringSequenceIgnoreCase ("int");
        State s = new State ("s");
        s.setTransition (State.EMPTY, if_s[0]);
        s.setTransition (State.EMPTY, int_s[0]);
        s = s.toDFA ();
        //s.prettyPrint (System.err);
        
        State acc_if = s.moveDFA ("If"), acc_int = s.moveDFA ("iNt");
        assertSame (acc_if, s.moveDFA ("if"));
        assertSame (acc_int, s.moveDFA ("int"));
    }
}