public static TreeModel parseTree(String string, Grammar grammar,
			LRParseTable table) {
		string = string + "$";
		int p = 0;
		IntStack stack = new IntStack();
		stack.push(0);
		Production[] productions = grammar.getProductions();
		int nodeNum = 0;
		while (true) {
			int state = stack.peekInt();
			String read = "" + string.charAt(p);
			String entry = table.getValueAt(state, read);
			if (entry.length() == 0) {
				// Error! No derivation.
				// //System.out.println("Parse error");
				DefaultMutableTreeNode node = new DefaultMutableTreeNode();
				Object[] elements = stack.toArray();
				for (int i = 0; i < elements.length; i++)
					if (elements[i] instanceof MutableTreeNode)
						node.add((MutableTreeNode) elements[i]);
				return new DefaultTreeModel(node);
			} else if (entry.charAt(0) == 's') {
				// Shift!
				TreeNode node = new DefaultMutableTreeNode(read, false);
				stack.push(node); // Push the symbol.
				stack.push(Integer.parseInt(entry.substring(1)));
				p++; // Move to next input symbol.
			} else if (entry.charAt(0) == 'r') {
				// Reduce!
				int prodNumber = Integer.parseInt(entry.substring(1));
				Production red = productions[prodNumber];
				DefaultMutableTreeNode node = new DefaultMutableTreeNode(red
						.getLHS());
				for (int i = 0; i < red.getRHS().length(); i++) {
					stack.pop(); // Pops the state.
					MutableTreeNode c = (MutableTreeNode) stack.pop();
					node.insert(c, 0);
					// Pops the symbol.
				}
				state = stack.peekInt();
				stack.push(node);
				stack.push(Integer.parseInt(table.getValueAt(state, red
						.getLHS())));
				// //System.out.println(red);
			} else if (entry.charAt(0) == 'a') {
				// //System.out.println("Acceptance!");
				stack.pop();
				return new DefaultTreeModel((TreeNode) stack.pop());
			}
		}
	}