// 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.dsource.org/projects/goldie, Goldie Homepage)

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

Prerequisites for Building:
- [Required]    DMD 1.043 (LDC untested)
- [Required]    Tango 0.99.8
- [Required]    SemiTwistDTools trunk r82
- [Recommended] Rebuild 0.76
DMD 1.044+ with Tango Trunk might work, but is untested.
Rebuild 0.78 might work, but is quirky and not recommended.
*/

module samples.parseAnything.main;

import tango.io.Stdout;
import tango.io.device.File;

import goldie.all;

int main(char[][] args)
{
	if(args.length != 2 && args.length != 3)
	{
		Stdout("Usage: parseAnything source_file [gold_cgt_file]").newline;
		Stdout.newline;
		Stdout("Samples: parseAnything valid_sample2.calc").newline;
		Stdout("         parseAnything valid_sample2.calc lang/calc.cgt").newline;
		return 1;
	}
	
	char[] srcFile = args[1];

	char[] langFile;
	if(args.length == 3)
		langFile = args[2];
	else
		langFile = Goldie.inferLanguageFilenameOf(srcFile);
	
	// Load language
	auto lang = Goldie.loadCGT(langFile);
	Stdout.formatln("Grammar Info:");
	Stdout.formatln("File:   {}", lang.filename);
	Stdout.formatln("Name:   {}", lang.name);
	Stdout.formatln("Verson: {}", lang.ver);
	Stdout.formatln("Author: {}", lang.author);
	Stdout.formatln("About:  {}", lang.about);
	Stdout.formatln("");
	
	// Load and parse source
	GoldParser parser = lang.parseFile(srcFile);
	
	TokGold root = parser.parseTree;
	Stdout.formatln("Root of parse tree:");
	Stdout.formatln("  type: {}", root.typeName);
	Stdout.formatln("  name: {}", root.name);
	Stdout.formatln("");

	TokGold firstTerminal = root.firstLeaf;
	Stdout.formatln("First terminal in parse tree:");
	Stdout.formatln("  type: {}", firstTerminal.typeName);
	Stdout.formatln("  name: {}", firstTerminal.name);
	Stdout.formatln("  content: '{}'", firstTerminal);
	Stdout.formatln("  line: {}", firstTerminal.line);
	Stdout.formatln("");

	TokGold lastTerminal = root.lastLeaf;
	Stdout.formatln("Last terminal in parse tree:");
	Stdout.formatln("  type: {}", lastTerminal.typeName);
	Stdout.formatln("  name: {}", lastTerminal.name);
	Stdout.formatln("  content: '{}'", lastTerminal);
	Stdout.formatln("  line: {}", lastTerminal.line);
	Stdout.formatln("");

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

	return 0;
}
