// Goldie: GOLD Engine for D
// Tools: GRMC: Grammar Compiler
// Written in the D programming language.

/++
Compiles a GOLD .grm file to .cgt

$(WEB http://www.semitwist.com/goldie/, Goldie Homepage)

Author:
$(WEB www.semitwist.com, Nick Sabalausky)

To re-generate the static language used by this app, run
the following command from the main Goldie directory:
    makeBuiltinStaticLangs

This has been tested to work with DMD 2.052
+/

//TODO: GOLD allows Terminals named "EOF" or "Error", support this.
//TODO? Disallow set names like {He.llo} (and figure out the rule for what's allowed)
//TODO: Handle "Virtual Terminals"
//TODO: Goldie.compileGrammar* should throw, not send errors to stdout.
//TODO: Warning on unused terminals/nonterminals
//TODO: Maintain toks so later-processing-stage errors can report correct line/col

module tools.grmc.main;

import std.conv;
import std.path;
import std.stdio;
import std.string;

import semitwist.util.all;
import goldie.all;
import tools.util;

import tools.grmc.cmd;

int main(string[] args)
{
	auto cmdArgs = new CmdArgs(args);
	if(cmdArgs.shouldExit())
		return 1;
	
	Language lang;
	Language.compileGrammarGoldCompatibility = cmdArgs.goldCompat;
	if(cmdArgs.dot || cmdArgs.verbose)
		lang = Language.compileGrammarFileDebug(cmdArgs.grmFile);
	else
		lang = Language.compileGrammarFile(cmdArgs.grmFile);
		
	if(!lang)
		return 1;
	
	if(cmdArgs.verbose)
	{
		writeln("Number of NFA States:  ", lang.nfaNumStates);
		//writeln("Number of raw DFA States: ", lang.dfaRawNumStates);
		writeln("Number of DFA States:  ", lang.dfaTable.length);
		writeln("Number of LALR States: ", lang.lalrTable.length);
	}

	if(cmdArgs.dot)
	{
		string dotFilename;

		dotFilename = cmdArgs.cgtFile~".nfa.dot";
		if(cmdArgs.verbose)
			writeln("Saving NFA to '", dotFilename, "'");
		std.file.write(dotFilename, lang.nfaDot);

		//dotFilename = cmdArgs.cgtFile~".dfaRaw.dot";
		//if(cmdArgs.verbose)
		//	writeln("Saving raw unoptimized DFA to '", dotFilename, "'");
		//std.file.write(dotFilename, lang.dfaRawDot);

		dotFilename = cmdArgs.cgtFile~".dfa.dot";
		if(cmdArgs.verbose)
			writeln("Saving DFA to '", dotFilename, "'");
		std.file.write(dotFilename, lang.dfaDot);
	}

	if(cmdArgs.verbose)
		writeln("Saving CGT to '", cmdArgs.cgtFile, "'");
	lang.save(cmdArgs.cgtFile);
	return 0;
}
