Archived

This topic is now archived and is closed to further replies.

[java] Null Pointer Problem in Finite State Machine

This topic is 5110 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, I am writing a Finite State Machine program and it''s all but done except for this stupid null pointer exception that I cannot track down. Here''s the code: Machine.java
/**
 * Machine.java
 * @author Cory Swanson
 * @version 1.0
 *
 * This class defines the Finite State Machine and
 * controls the running of such.
 */

import java.util.*;
import java.io.*;

public class Machine
{
	private static StringTokenizer tokenizer;
	private static String machineOutput;
	private static BufferedReader fin;
	private static State currentState;
	private static State[] stateArray;
	private static String alphabet;
	private static int numStates, numAlpha;

	public static String runMachine(String filename, String input)
	{
		initMachine(filename);

		makeMachine();
		
		return doItMan(input);
	}

	public static BufferedReader openFileForReading(String filename)
	{
		BufferedReader in=null;
		try
		{
			in = new BufferedReader(new FileReader(filename));
		}
		catch(FileNotFoundException e)
		{
			System.out.println("Error: File " + filename + " not found, nimrod!");
			System.exit(1);
		}
		return in;
	}

	public static String readLineFromFile(BufferedReader r)
	{
		String line="";
		try
		{
			line=r.readLine();
		}
		catch(IOException e)
		{
			System.out.println("Your file sucks -- unable to read a line.");
			System.exit(1);
		}
		return line;
	}

	public static int readIntFromFile(BufferedReader r)
	{
		int num=0;
		try
		{
			num=r.read();
		}
		catch(IOException e)
		{
			System.out.println("Your file sucks -- unable to read an int.");
			System.exit(1);
		}
		return num;
	}

	public static void initMachine(String filename)
	{
		fin = openFileForReading(filename);

		numStates = readIntFromFile(fin);
		numAlpha = readIntFromFile(fin);
		alphabet = readLineFromFile(fin);

		stateArray = new State[numStates];
		for(int i=0; i<stateArray.length; i++)
		{
			stateArray[i] = new State(i);
		}

		currentState = stateArray[0];
		
	}

	public static void makeMachine()
	{
		int nextState;
		String temp;

		for(int i=0; i<stateArray.length; i++)
		{
			for(int j=0; j<alphabet.length(); j++)
			{
				nextState = readIntFromFile(fin);
				stateArray[i].createTransition(alphabet.charAt(j), stateArray[i]);
			}
		}

		String output = "";

		for(int i=0; i<stateArray.length; i++)
		{
			for(int j=0; j<alphabet.length(); j++)
			{
				temp = readLineFromFile(fin);
				tokenizer = new StringTokenizer(temp);
				output = tokenizer.nextToken("\"") + " ";
				stateArray[i].setOutput(alphabet.charAt(j), output);
				if(tokenizer.hasMoreTokens()) tokenizer.nextToken("\"");
			}
		}
	}

	public static String doItMan(String input)
	{
		String finalOutput = "";
		for(int i=0; i<input.length(); i++)
		{
			finalOutput += currentState.getOutput(input.charAt(i));
			currentState = (currentState.getTransition(input.charAt(i))).getState();
		}
		return finalOutput;
	}

	public static void main(String[] args)
	{
		String filename = args[0];

		String results = runMachine(filename, "QQCDNQNDTQDDQNCCTDNQDCTQQNNDDDC");
		System.out.println(results);
	}
}


State.java
   
/**
 * State.java
 * @author Cory Swanson
 * @version 1.0
 *
 * This class defines a State object for use in a Finite
 * State Machine.
 */

import java.util.*;

public class State
{
	private Hashtable transitionTable;
	private Hashtable outputs;
	private int stateNum;

	public State(int stateNum)
	{
		this.stateNum = stateNum;
		transitionTable = new Hashtable();
		outputs = new Hashtable();
	}

	public int getStateNum()
	{
		return stateNum;
	}

	public Transition createTransition(char c, State s)
	{
		return new Transition(c, s);
	}

	public void setTransition(char c, Transition t)
	{
		String key=c+"";
		transitionTable.put(key, t);
	}

	public Transition getTransition(char c)
	{
		String key=c+"";
		return (Transition)transitionTable.get(key);
	}

	public void setOutput(char c, String s)
	{
		String key=c+"";
		outputs.put(key, s);
	}

	public String getOutput(char c)
	{
		String key=c+"";
		return (String)outputs.get(key);
	}
}


Transition.java
   
public class Transition
{
	private String output;
	private State state;
	private char alpha;
		
	public Transition(char c, State s)
	{
		alpha = c;
		state = s;
	}

	public State getState()
	{
		return state;
	}

	public void setOutput(String s)
	{
		output = s;
	}
	
	public String getOutput()
	{
		return this.output;
	}
}


Here''s the text file which defines the FSM:
   

9
5
NDQTC
1 2 5 0 0
2 3 6 0 0
3 4 2 0 0
4 5 3 0 0
5 6 4 7 0
6 5 5 7 8
6 6 6 7 8
1 2 5 7 7
1 2 5 8 8
"$0.05" "$0.10" "$0.25" "Buuzzzzzaaap!" "Buuzzzzzaaap!"
"$0.10" "$0.15" "$0.30" "Buuzzzzzaaap!" "Buuzzzzzaaap!"
"$0.15" "$0.20" "Quarter" "Buuzzzzzaaap!" "Buuzzzzzaaap!"
"$0.20" "$0.30" "Quarter" "Buuzzzzzaaap!" "Buuzzzzzaaap!"
"$0.25" "Dime" "Quarter" "Tea" "Buuzzzzzaaap!"
"$0.30" "Dime" "Quarter" "Tea and Nickel" "Coffee"
"Nickel" "Dime" "Quarter" "Tea and Dime" "Coffee and Nickel"
"$0.05" "$0.10" "0.25" "Buuzzzzzaaap!" "Buuzzzzzaaap!"
"$0.05" "$0.10" "0.25" "Buuzzzzzaaap!" "Buuzzzzzaaap!"
Any ideas? I''m getting a null pointer in the main method but can''t locate it at all!! ARGH! Thanks in advance!

Share this post


Link to post
Share on other sites
Ok... It says:

Exception in thread "main" java.lang.NullPointerException
at Machine.doItMan(Machine.java:130)
at Machine.runMachine(Machine.java:29)
at Machine.main(Machine.java:139)

Thanks for the help, by the way!

Share this post


Link to post
Share on other sites
Your exception isn''t triggered in in main() but in doItMan(), line 130 (as the stack trace clearly says). Perhaps it would be easier if you tried looking there yourself. It''s a bit difficult to check from here, but I''d suspect the input parameter to be null as a quick guess.

Share this post


Link to post
Share on other sites
The line it is erroring on is:

currentState = (currentState.getTransition(input.charAt(i)).getState();

From the constructor call in the main method and the call to doItMan(input) should all be valid, shouldn''t it?

Share this post


Link to post
Share on other sites
If I could find it in my debugger I wouldn''t be here...

I used print statements right before the line which is erroring to print the current char, as well as for the input variable.

The input variable is ok. When printing the current character in the input string, however, it is only printing the first one... which means that the line which is erroring (mentioned above) is throwing the error right off the bat. I suspect that it can''t find the transitionTable variable in the currentState but I am not sure.

Anyone have any ideas?

Share this post


Link to post
Share on other sites
According to the stack trace, the exception definately happens in doItMan(), not any function called from there. Check all variables involved. Perhaps currentState is null? A simple System.out.println(currentState) should be able to verify this.

Share this post


Link to post
Share on other sites
Here is the problem...

When you call the method makeMachine(), you are calling another method called createTransition(char c, Transition t). If you look at that method, you will see that you are creating a new State object, and returning it, but you are not setting it into the hash table like you do in setTransition(char c, Transition t). So even though you are creating the new state, nothing is going into the hash table, and when you call currentState.getTransition(input.charAt(i)), it returns null because there is nothing in the hash table.

Hope that helps...


Glass_Knife
I think, therfore I am.
I think?

Share this post


Link to post
Share on other sites