public void buildDFA()
	throws CopperException
	{
		// Initialize E to empty.
		dfaLALR1 = new LALR1DFA();
		HashSet<LALR1State> fringe1 = new HashSet<LALR1State>();
		HashSet<LALR1State> fringe2 = new HashSet<LALR1State>();
		// Initialize T to {Closure([STARTPRIME ::= (*) startSym EOF,  t]}.
		LALR1State newState = new LALR1State();
		grammar.addProductionAttributes(
		 grammar.getStartProd(),
		 new ProductionAttributes(
		  new GrammarName(FringeSymbols.STARTPRIME.getId()),
		  InputPosition.initialPos(),
		  0,
		  null,
		  grammar.getStartLayout(),
		  new TerminalClass(FringeSymbols.STARTPRIME.getId()),
		  ""));
		primeItem = new LALR1StateItem(grammar.getStartProd());
		newState.addItem(primeItem);
		LALR1State J = itemClosure(newState);
		dfaLALR1.addState(J);
		fringe1.add(J);
		primeState = J;
		// Repeat until E and T do not change:
		boolean setsChanged = true;
		while(setsChanged)
		{
			setsChanged = false;
			// For each state I in T:
			for(LALR1State I : fringe1)
			{
				// DEBUG-BEGIN
				if(logger.isLoggable(CompilerLogMessageSort.TICK)) logger.logTick(MasterController.DOT_WINDOW,".");
				// DEBUG-END
				// For each item [A ::= a (*) X b,  w] in I:
				for(LALR1StateItem item : I.getItems())
				{
					if(item.isShiftable())
					{
						GrammarSymbol X = item.getSymbolAtPosition();
						if(X.equals(FringeSymbols.EOF) ||
						  !isWanted(X)) continue;
						// Let J be Goto(I,X).
						J = itemGoto(I,X);
						// T = union(T,J).
						if(dfaLALR1.addState(J)) fringe2.add(J);
						// E = union(E,I->X->J).
						dfaLALR1.addTransition(I,X,J);
					}
				}
			}
			if(!fringe2.isEmpty())
			{
				fringe1 = fringe2;
				fringe2 = new HashSet<LALR1State>();
				setsChanged = true;
			}
		}
	}