public static GrammarSource buildAST(CompilerLogger logger,Hashtable<Symbol,IntermediateSymbolNode> intermediateRep)
	throws CopperException
	{
		GrammarSource grammarData = new GrammarSource();
		
		
		SymGatherer symGatherer = new SymGatherer(grammarData);
		symGatherer.symGather(logger,intermediateRep);
		
		if(grammarData.getStartSym() == null)
		{
			if(logger.isLoggable(CompilerLogMessageSort.ERROR)) logger.logErrorMessage(CompilerLogMessageSort.ERROR,null,"No start symbol specified");
			return null;
		}

		grammarData.constructPrecedenceRelationsGraph();

		RegexDependencyChecker regexDepChecker = new RegexDependencyChecker(grammarData,symGatherer.sortedNodes);
		regexDepChecker.regexDepCheck(logger,intermediateRep);

		LinkedList<Terminal> regexQueue = new LinkedList<Terminal>();
		regexDepChecker.regexDependencies.detectCycles(logger,"Regex dependency check",regexQueue);
		
		for(Terminal regexTerm : regexQueue)
		{
			ParsedRegex holeyRegex = (ParsedRegex) intermediateRep.get(regexTerm.getId()).attributes.get("regex").second();
			ParsedRegex filledRegex = null;
			try
			{
				filledRegex = holeyRegex.fillMacroHoles(grammarData); 
			}
			catch(UnsupportedOperationException ex)
			{
				if(logger.isLoggable(CompilerLogMessageSort.ERROR)) logger.logErrorMessage(CompilerLogMessageSort.ERROR,intermediateRep.get(regexTerm.getId()).attributes.get("regex").first(),ex.getMessage());
				continue;
			}
			grammarData.addRegex(regexTerm,filledRegex);
		}
		
		return grammarData;
	}