// Goldie: GOLD Engine for D
// Samples: Parse Anything
// Written in the D programming language.

/++
Parses any source file according to any GOLD language and displays
basic information about both the language and the parsed source.

Try using the included "lang/calc.cgt" language on the "*.calc" files.
Or use your own GOLD language and source.

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

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

This has been tested to work with DMD 2.052
+/

module samples.parseAnything.main;

import std.stdio;
import semitwist.util.all : getExecPath;

import goldie.all;

int main(string[] args)
{
	if(args.length != 3)
	{
		writeln("Usage: goldie-parseAnything source_file gold_cgt_file");
		writeln();
		writeln("Sample: goldie-parseAnything lang/valid_sample2.calc lang/calc.cgt");
		return 1;
	}
	
	string srcFile  = args[1];
	string langFile = args[2];
	
	// Load language
	Language lang = Language.loadCGT(langFile);
	writefln("Grammar Info:");
	writefln("File:    %s", lang.filename);
	writefln("Name:    %s", lang.name);
	writefln("Version: %s", lang.ver);
	writefln("Author:  %s", lang.author);
	writefln("About:   %s", lang.about);
	writefln("");
	
	// Load and parse source
	Parser parser = lang.parseFileX(srcFile);
	
	Token root = parser.parseTreeX;
	writefln("Root of parse tree:");
	writefln("  type: %s", root.typeName);
	writefln("  name: %s", root.name);
	writefln("");

	Token firstTerminal = root.firstLeaf;
	writefln("First terminal in parse tree:");
	writefln("  type: %s", firstTerminal.typeName);
	writefln("  name: %s", firstTerminal.name);
	writefln("  content: '%s'", firstTerminal);
	writefln("  line: %s", firstTerminal.line);
	writefln("");

	Token lastTerminal = root.lastLeaf;
	writefln("Last terminal in parse tree:");
	writefln("  type: %s", lastTerminal.typeName);
	writefln("  name: %s", lastTerminal.name);
	writefln("  content: '%s'", lastTerminal);
	writefln("  line: %s", lastTerminal.line);
	writefln("");

	writefln("Root of parse tree has %s child node(s):", root.subX.length);
	foreach(int i, Token tok; root.subX)
	{
		if(tok.type == SymbolType.NonTerminal)
		{
			writefln("  Node index %s is a NonTerminal '%s' with %s child node(s)",
			                i, tok.name, tok.subX.length);
			writefln("    and content '%s'", tok);
			writefln("    and raw content:");
			writefln("%s", parser.lexer.source[tok.srcIndexStart..tok.srcIndexEnd]);
		}
		else
		{
			writefln("  Node index %s is a %s '%s'",
			                i, tok.typeName, tok.name);
		}
	}

	return 0;
}
