/// This module was generated by the StaticLang tool from
/// Goldie v0.8: http://www.semitwist.com/goldie/

// Goldie: GOLD Engine for D
// GoldieLib
// Written in the D programming language.

module goldie.langs.grm.token;

version = Goldie_StaticStyle;
private enum _packageName = "goldie.langs.grm";
private enum _shortPackageName = "grm";
version(Goldie_StaticStyle) {} else
	version = Goldie_DynamicStyle;

version(Goldie_StaticStyle)
version(DigitalMars)
{
	import std.compiler;
	static if(version_major == 2 && version_minor == 57)
		static assert(false, "Goldie's static-style and grammar compiling don't work on DMD 2.057 due to DMD Issue #7375");
}

version(Goldie_StaticStyle)
{
	// Ensure Goldie versions match
	import goldie.ver;
	static if(goldieVerStr != "0.8")
	{
		pragma(msg,
			"You're using Goldie v"~goldieVerStr~", but this static-style language "~
			"was generated with Goldie v0.8. You must regenerate the langauge "~
			"with 'goldie-staticlang'."
		);
		static assert(false, "Mismatched Goldie versions");
	}
}

import std.algorithm;
import std.exception;
import std.functional;
import std.string;
import std.traits;
import std.typecons;

import semitwist.treeout;
import semitwist.util.all;

import goldie.base;
import goldie.exception;
import goldie.lang;

static if(__traits(compiles, std.ascii.digits))
{
	import std.ascii;
	private alias std.ascii.digits digits;
	private alias std.ascii.letters letters;
}

private alias semitwist.util.ctfe.ctfe_strip ctfe_strip;

version(Goldie_StaticStyle)
{
	import goldie.token;
	mixin(`
		import `~_packageName~`.lang;
	`);
}

version(Goldie_DynamicStyle)
{
	enum CommentType
	{
		None,
		Line,
		Block,
	}

	enum TokenToStringMode
	{
		Compact,           // Omit all whitespace, error and comment tokens.
		CompactWithSpaces, // Like Compact, but adds a space between each token.
		
		Smart,             // Default: Like Compact, but adds a space between two
						   //   tokens whenever the last character of the first
						   //   token and the first character of the second token
						   //   are both either alphanumeric or an underscore.

		// Full doesn't currently work after the parse phase because
		// ignored tokens are not currently preserved by the parser.
		//TODO: Fix this
		Full,              // Includes all whitespace, error and comment tokens.
	}
}

version(Goldie_StaticStyle)
{
	template Token_grm()
	{
		alias Base_Token_grm Token_grm;
	}

	template Token_grm(string staticName=null)
	{
		static if(staticName == "(")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == ")")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "*")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "+")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "-")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "::=")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "<Content>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Definition>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Grammar>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Handle>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Handles>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Kleene Opt>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Parameter Body>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Parameter Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Parameter Items>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Parameter>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Reg Exp 2>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Reg Exp Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Reg Exp Seq>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Reg Exp>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Rule Decl>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Set Decl>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Set Exp>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Set Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Symbol>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Terminal Decl>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<Terminal Name>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<nl opt>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "<nl>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName) Token_grm;
		else static if(staticName == "=")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "?")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "Comment End")
			alias _Token_grm!(SymbolType.CommentEnd, staticName) Token_grm;
		else static if(staticName == "Comment Line")
			alias _Token_grm!(SymbolType.CommentLine, staticName) Token_grm;
		else static if(staticName == "Comment Start")
			alias _Token_grm!(SymbolType.CommentStart, staticName) Token_grm;
		else static if(staticName == "EOF")
			alias _Token_grm!(SymbolType.EOF, staticName) Token_grm;
		else static if(staticName == "Error")
			alias _Token_grm!(SymbolType.Error, staticName) Token_grm;
		else static if(staticName == "Newline")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "Nonterminal")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "ParameterName")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "SetLiteral")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "SetName")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "Terminal")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else static if(staticName == "Whitespace")
			alias _Token_grm!(SymbolType.Whitespace, staticName) Token_grm;
		else static if(staticName == "|")
			alias _Token_grm!(SymbolType.Terminal, staticName) Token_grm;
		else
			static assert(false,
				"Invalid token: Token_grm!('"~staticName~"')");
	}

	template Token_grm(SymbolType staticSymbolType, string staticName)
	{
		static if(staticSymbolType == SymbolType.EOF && staticName == "EOF")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Error && staticName == "Error")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Whitespace && staticName == "Whitespace")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.CommentEnd && staticName == "Comment End")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.CommentLine && staticName == "Comment Line")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.CommentStart && staticName == "Comment Start")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "-")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "(")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == ")")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "*")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "::=")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "?")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "|")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "+")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "=")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "Newline")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "Nonterminal")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "ParameterName")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "SetLiteral")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "SetName")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.Terminal && staticName == "Terminal")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Content>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Definition>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Grammar>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Handle>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Handles>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Kleene Opt>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<nl>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<nl opt>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Parameter>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Parameter Body>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Parameter Item>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Parameter Items>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Reg Exp>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Reg Exp 2>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Reg Exp Item>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Reg Exp Seq>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Rule Decl>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Set Decl>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Set Exp>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Set Item>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Symbol>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Terminal Decl>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else static if(staticSymbolType == SymbolType.NonTerminal && staticName == "<Terminal Name>")
			alias _Token_grm!(staticSymbolType, staticName) Token_grm;
		else
			static assert(false,
				"Invalid token: Token_grm!(SymbolType."~
				goldSymbolTypeToString(staticSymbolType)~", '"~staticName~"')");
	}

	private template Token_grm(string staticName, int staticRuleId)
	{
		static if(staticRuleId == 0 && staticName == "<Grammar>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 1 && staticName == "<Content>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 2 && staticName == "<Content>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 3 && staticName == "<Definition>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 4 && staticName == "<Definition>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 5 && staticName == "<Definition>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 6 && staticName == "<Definition>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 7 && staticName == "<nl opt>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 8 && staticName == "<nl opt>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 9 && staticName == "<nl>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 10 && staticName == "<nl>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 11 && staticName == "<Parameter>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 12 && staticName == "<Parameter Body>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 13 && staticName == "<Parameter Body>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 14 && staticName == "<Parameter Items>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 15 && staticName == "<Parameter Items>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 16 && staticName == "<Parameter Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 17 && staticName == "<Parameter Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 18 && staticName == "<Parameter Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 19 && staticName == "<Parameter Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 20 && staticName == "<Parameter Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 21 && staticName == "<Set Decl>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 22 && staticName == "<Set Exp>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 23 && staticName == "<Set Exp>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 24 && staticName == "<Set Exp>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 25 && staticName == "<Set Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 26 && staticName == "<Set Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 27 && staticName == "<Terminal Decl>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 28 && staticName == "<Terminal Name>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 29 && staticName == "<Terminal Name>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 30 && staticName == "<Reg Exp>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 31 && staticName == "<Reg Exp>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 32 && staticName == "<Reg Exp Seq>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 33 && staticName == "<Reg Exp Seq>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 34 && staticName == "<Reg Exp Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 35 && staticName == "<Reg Exp Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 36 && staticName == "<Reg Exp Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 37 && staticName == "<Reg Exp Item>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 38 && staticName == "<Reg Exp 2>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 39 && staticName == "<Reg Exp 2>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 40 && staticName == "<Kleene Opt>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 41 && staticName == "<Kleene Opt>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 42 && staticName == "<Kleene Opt>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 43 && staticName == "<Kleene Opt>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 44 && staticName == "<Rule Decl>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 45 && staticName == "<Handles>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 46 && staticName == "<Handles>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 47 && staticName == "<Handle>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 48 && staticName == "<Handle>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 49 && staticName == "<Symbol>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else static if(staticRuleId == 50 && staticName == "<Symbol>")
			alias _Token_grm!(SymbolType.NonTerminal, staticName, staticRuleId) Token_grm;
		else
			static assert(false,
				"Invalid token: Token_grm!('"~
				staticName~"', "~ctfe_i2a(staticRuleId)~")");
	}

	template isCorrectToken_grm(string token, int type, string name)
	{
		static if(token == name)
			static if(Language_grm.staticIsSymbolNameAmbiguous(token))
				static assert(false, "Token name '"~staticName~
					"' is ambiguous, please specify SymbolType"~
					" (ex: Token_grm!(SymbolType.Terminal, \"+\"))\n"~
					"Possible types: ["~Language_grm.symbolTypesByName(name).goldSymbolTypesToString()~"]");
			else
				enum bool isCorrectToken_grm = true;
		else
			enum bool isCorrectToken_grm = false;
	}
	
	template isCorrectToken_grm(token, int type, string name)
	{
		static if(is( token:_Token_grm!(cast(SymbolType)type, name) ))
			enum bool isCorrectToken_grm = true;
		else
			enum bool isCorrectToken_grm = false;
	}
	
	template Token_grm(string staticName, subTokenTypes...)
		if(
			subTokenTypes.length != 0 &&
			(subTokenTypes.length > 1 || !isIntegral!(typeof(subTokenTypes[0])))
		)
	{
		alias _Token_grm!(SymbolType.NonTerminal, staticName, ruleIdOf_grm!(staticName, subTokenTypes)) Token_grm;
	}
	
	//TODO? Move this to goldie.lang
	template ruleIdOf_grm(string staticName, subTokenTypes...)
	{
		static if(
			staticName == "<Grammar>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<Content>")
		)
			enum int ruleIdOf_grm = 0;
		else static if(
			staticName == "<Content>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Content>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<Definition>")
		)
			enum int ruleIdOf_grm = 1;
		else static if(
			staticName == "<Content>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Definition>")
		)
			enum int ruleIdOf_grm = 2;
		else static if(
			staticName == "<Definition>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Parameter>")
		)
			enum int ruleIdOf_grm = 3;
		else static if(
			staticName == "<Definition>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Set Decl>")
		)
			enum int ruleIdOf_grm = 4;
		else static if(
			staticName == "<Definition>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Terminal Decl>")
		)
			enum int ruleIdOf_grm = 5;
		else static if(
			staticName == "<Definition>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Rule Decl>")
		)
			enum int ruleIdOf_grm = 6;
		else static if(
			staticName == "<nl opt>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Newline") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>")
		)
			enum int ruleIdOf_grm = 7;
		else static if(
			staticName == "<nl opt>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, null)
		)
			enum int ruleIdOf_grm = 8;
		else static if(
			staticName == "<nl>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Newline") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl>")
		)
			enum int ruleIdOf_grm = 9;
		else static if(
			staticName == "<nl>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Newline")
		)
			enum int ruleIdOf_grm = 10;
		else static if(
			staticName == "<Parameter>" && subTokenTypes.length == 5 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "ParameterName") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, "=") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Parameter Body>") &&
			isCorrectToken_grm!(subTokenTypes[4], SymbolType.NonTerminal, "<nl>")
		)
			enum int ruleIdOf_grm = 11;
		else static if(
			staticName == "<Parameter Body>" && subTokenTypes.length == 4 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Parameter Body>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, "|") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Parameter Items>")
		)
			enum int ruleIdOf_grm = 12;
		else static if(
			staticName == "<Parameter Body>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Parameter Items>")
		)
			enum int ruleIdOf_grm = 13;
		else static if(
			staticName == "<Parameter Items>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Parameter Items>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<Parameter Item>")
		)
			enum int ruleIdOf_grm = 14;
		else static if(
			staticName == "<Parameter Items>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Parameter Item>")
		)
			enum int ruleIdOf_grm = 15;
		else static if(
			staticName == "<Parameter Item>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "ParameterName")
		)
			enum int ruleIdOf_grm = 16;
		else static if(
			staticName == "<Parameter Item>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Terminal")
		)
			enum int ruleIdOf_grm = 17;
		else static if(
			staticName == "<Parameter Item>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "SetLiteral")
		)
			enum int ruleIdOf_grm = 18;
		else static if(
			staticName == "<Parameter Item>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "SetName")
		)
			enum int ruleIdOf_grm = 19;
		else static if(
			staticName == "<Parameter Item>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Nonterminal")
		)
			enum int ruleIdOf_grm = 20;
		else static if(
			staticName == "<Set Decl>" && subTokenTypes.length == 5 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "SetName") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, "=") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Set Exp>") &&
			isCorrectToken_grm!(subTokenTypes[4], SymbolType.NonTerminal, "<nl>")
		)
			enum int ruleIdOf_grm = 21;
		else static if(
			staticName == "<Set Exp>" && subTokenTypes.length == 4 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Set Exp>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, "+") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Set Item>")
		)
			enum int ruleIdOf_grm = 22;
		else static if(
			staticName == "<Set Exp>" && subTokenTypes.length == 4 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Set Exp>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, "-") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Set Item>")
		)
			enum int ruleIdOf_grm = 23;
		else static if(
			staticName == "<Set Exp>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Set Item>")
		)
			enum int ruleIdOf_grm = 24;
		else static if(
			staticName == "<Set Item>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "SetLiteral")
		)
			enum int ruleIdOf_grm = 25;
		else static if(
			staticName == "<Set Item>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "SetName")
		)
			enum int ruleIdOf_grm = 26;
		else static if(
			staticName == "<Terminal Decl>" && subTokenTypes.length == 5 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Terminal Name>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, "=") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Reg Exp>") &&
			isCorrectToken_grm!(subTokenTypes[4], SymbolType.NonTerminal, "<nl>")
		)
			enum int ruleIdOf_grm = 27;
		else static if(
			staticName == "<Terminal Name>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Terminal Name>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.Terminal, "Terminal")
		)
			enum int ruleIdOf_grm = 28;
		else static if(
			staticName == "<Terminal Name>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Terminal")
		)
			enum int ruleIdOf_grm = 29;
		else static if(
			staticName == "<Reg Exp>" && subTokenTypes.length == 4 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Reg Exp>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, "|") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Reg Exp Seq>")
		)
			enum int ruleIdOf_grm = 30;
		else static if(
			staticName == "<Reg Exp>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Reg Exp Seq>")
		)
			enum int ruleIdOf_grm = 31;
		else static if(
			staticName == "<Reg Exp Seq>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Reg Exp Seq>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<Reg Exp Item>")
		)
			enum int ruleIdOf_grm = 32;
		else static if(
			staticName == "<Reg Exp Seq>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Reg Exp Item>")
		)
			enum int ruleIdOf_grm = 33;
		else static if(
			staticName == "<Reg Exp Item>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "SetLiteral") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<Kleene Opt>")
		)
			enum int ruleIdOf_grm = 34;
		else static if(
			staticName == "<Reg Exp Item>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "SetName") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<Kleene Opt>")
		)
			enum int ruleIdOf_grm = 35;
		else static if(
			staticName == "<Reg Exp Item>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Terminal") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<Kleene Opt>")
		)
			enum int ruleIdOf_grm = 36;
		else static if(
			staticName == "<Reg Exp Item>" && subTokenTypes.length == 4 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "(") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<Reg Exp 2>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, ")") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Kleene Opt>")
		)
			enum int ruleIdOf_grm = 37;
		else static if(
			staticName == "<Reg Exp 2>" && subTokenTypes.length == 3 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Reg Exp 2>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.Terminal, "|") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.NonTerminal, "<Reg Exp Seq>")
		)
			enum int ruleIdOf_grm = 38;
		else static if(
			staticName == "<Reg Exp 2>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Reg Exp Seq>")
		)
			enum int ruleIdOf_grm = 39;
		else static if(
			staticName == "<Kleene Opt>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "+")
		)
			enum int ruleIdOf_grm = 40;
		else static if(
			staticName == "<Kleene Opt>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "?")
		)
			enum int ruleIdOf_grm = 41;
		else static if(
			staticName == "<Kleene Opt>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "*")
		)
			enum int ruleIdOf_grm = 42;
		else static if(
			staticName == "<Kleene Opt>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, null)
		)
			enum int ruleIdOf_grm = 43;
		else static if(
			staticName == "<Rule Decl>" && subTokenTypes.length == 5 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Nonterminal") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, "::=") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Handles>") &&
			isCorrectToken_grm!(subTokenTypes[4], SymbolType.NonTerminal, "<nl>")
		)
			enum int ruleIdOf_grm = 44;
		else static if(
			staticName == "<Handles>" && subTokenTypes.length == 4 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Handles>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<nl opt>") &&
			isCorrectToken_grm!(subTokenTypes[2], SymbolType.Terminal, "|") &&
			isCorrectToken_grm!(subTokenTypes[3], SymbolType.NonTerminal, "<Handle>")
		)
			enum int ruleIdOf_grm = 45;
		else static if(
			staticName == "<Handles>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Handle>")
		)
			enum int ruleIdOf_grm = 46;
		else static if(
			staticName == "<Handle>" && subTokenTypes.length == 2 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.NonTerminal, "<Handle>") &&
			isCorrectToken_grm!(subTokenTypes[1], SymbolType.NonTerminal, "<Symbol>")
		)
			enum int ruleIdOf_grm = 47;
		else static if(
			staticName == "<Handle>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, null)
		)
			enum int ruleIdOf_grm = 48;
		else static if(
			staticName == "<Symbol>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Terminal")
		)
			enum int ruleIdOf_grm = 49;
		else static if(
			staticName == "<Symbol>" && subTokenTypes.length == 1 &&
			isCorrectToken_grm!(subTokenTypes[0], SymbolType.Terminal, "Nonterminal")
		)
			enum int ruleIdOf_grm = 50;
		else
			static assert(false,
				"Invalid rule: ruleIdOf_grm!('"~staticName~"', ...)"); //TODO: expand that "..."
	}
	
	template SubTokenType_grm(int ruleId, int index)
	{
		static if(ruleId == 0 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 0 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<Content>") SubTokenType_grm;
		else static if(ruleId == 1 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Content>") SubTokenType_grm;
		else static if(ruleId == 1 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<Definition>") SubTokenType_grm;
		else static if(ruleId == 2 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Definition>") SubTokenType_grm;
		else static if(ruleId == 3 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Parameter>") SubTokenType_grm;
		else static if(ruleId == 4 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Set Decl>") SubTokenType_grm;
		else static if(ruleId == 5 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Terminal Decl>") SubTokenType_grm;
		else static if(ruleId == 6 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Rule Decl>") SubTokenType_grm;
		else static if(ruleId == 7 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Newline") SubTokenType_grm;
		else static if(ruleId == 7 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 9 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Newline") SubTokenType_grm;
		else static if(ruleId == 9 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl>") SubTokenType_grm;
		else static if(ruleId == 10 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Newline") SubTokenType_grm;
		else static if(ruleId == 11 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "ParameterName") SubTokenType_grm;
		else static if(ruleId == 11 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 11 && index == 2)
			alias Token_grm!(SymbolType.Terminal, "=") SubTokenType_grm;
		else static if(ruleId == 11 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Parameter Body>") SubTokenType_grm;
		else static if(ruleId == 11 && index == 4)
			alias Token_grm!(SymbolType.NonTerminal, "<nl>") SubTokenType_grm;
		else static if(ruleId == 12 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Parameter Body>") SubTokenType_grm;
		else static if(ruleId == 12 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 12 && index == 2)
			alias Token_grm!(SymbolType.Terminal, "|") SubTokenType_grm;
		else static if(ruleId == 12 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Parameter Items>") SubTokenType_grm;
		else static if(ruleId == 13 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Parameter Items>") SubTokenType_grm;
		else static if(ruleId == 14 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Parameter Items>") SubTokenType_grm;
		else static if(ruleId == 14 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<Parameter Item>") SubTokenType_grm;
		else static if(ruleId == 15 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Parameter Item>") SubTokenType_grm;
		else static if(ruleId == 16 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "ParameterName") SubTokenType_grm;
		else static if(ruleId == 17 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Terminal") SubTokenType_grm;
		else static if(ruleId == 18 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "SetLiteral") SubTokenType_grm;
		else static if(ruleId == 19 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "SetName") SubTokenType_grm;
		else static if(ruleId == 20 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Nonterminal") SubTokenType_grm;
		else static if(ruleId == 21 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "SetName") SubTokenType_grm;
		else static if(ruleId == 21 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 21 && index == 2)
			alias Token_grm!(SymbolType.Terminal, "=") SubTokenType_grm;
		else static if(ruleId == 21 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Set Exp>") SubTokenType_grm;
		else static if(ruleId == 21 && index == 4)
			alias Token_grm!(SymbolType.NonTerminal, "<nl>") SubTokenType_grm;
		else static if(ruleId == 22 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Set Exp>") SubTokenType_grm;
		else static if(ruleId == 22 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 22 && index == 2)
			alias Token_grm!(SymbolType.Terminal, "+") SubTokenType_grm;
		else static if(ruleId == 22 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Set Item>") SubTokenType_grm;
		else static if(ruleId == 23 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Set Exp>") SubTokenType_grm;
		else static if(ruleId == 23 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 23 && index == 2)
			alias Token_grm!(SymbolType.Terminal, "-") SubTokenType_grm;
		else static if(ruleId == 23 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Set Item>") SubTokenType_grm;
		else static if(ruleId == 24 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Set Item>") SubTokenType_grm;
		else static if(ruleId == 25 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "SetLiteral") SubTokenType_grm;
		else static if(ruleId == 26 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "SetName") SubTokenType_grm;
		else static if(ruleId == 27 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Terminal Name>") SubTokenType_grm;
		else static if(ruleId == 27 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 27 && index == 2)
			alias Token_grm!(SymbolType.Terminal, "=") SubTokenType_grm;
		else static if(ruleId == 27 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp>") SubTokenType_grm;
		else static if(ruleId == 27 && index == 4)
			alias Token_grm!(SymbolType.NonTerminal, "<nl>") SubTokenType_grm;
		else static if(ruleId == 28 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Terminal Name>") SubTokenType_grm;
		else static if(ruleId == 28 && index == 1)
			alias Token_grm!(SymbolType.Terminal, "Terminal") SubTokenType_grm;
		else static if(ruleId == 29 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Terminal") SubTokenType_grm;
		else static if(ruleId == 30 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp>") SubTokenType_grm;
		else static if(ruleId == 30 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 30 && index == 2)
			alias Token_grm!(SymbolType.Terminal, "|") SubTokenType_grm;
		else static if(ruleId == 30 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp Seq>") SubTokenType_grm;
		else static if(ruleId == 31 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp Seq>") SubTokenType_grm;
		else static if(ruleId == 32 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp Seq>") SubTokenType_grm;
		else static if(ruleId == 32 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp Item>") SubTokenType_grm;
		else static if(ruleId == 33 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp Item>") SubTokenType_grm;
		else static if(ruleId == 34 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "SetLiteral") SubTokenType_grm;
		else static if(ruleId == 34 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<Kleene Opt>") SubTokenType_grm;
		else static if(ruleId == 35 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "SetName") SubTokenType_grm;
		else static if(ruleId == 35 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<Kleene Opt>") SubTokenType_grm;
		else static if(ruleId == 36 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Terminal") SubTokenType_grm;
		else static if(ruleId == 36 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<Kleene Opt>") SubTokenType_grm;
		else static if(ruleId == 37 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "(") SubTokenType_grm;
		else static if(ruleId == 37 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp 2>") SubTokenType_grm;
		else static if(ruleId == 37 && index == 2)
			alias Token_grm!(SymbolType.Terminal, ")") SubTokenType_grm;
		else static if(ruleId == 37 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Kleene Opt>") SubTokenType_grm;
		else static if(ruleId == 38 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp 2>") SubTokenType_grm;
		else static if(ruleId == 38 && index == 1)
			alias Token_grm!(SymbolType.Terminal, "|") SubTokenType_grm;
		else static if(ruleId == 38 && index == 2)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp Seq>") SubTokenType_grm;
		else static if(ruleId == 39 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Reg Exp Seq>") SubTokenType_grm;
		else static if(ruleId == 40 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "+") SubTokenType_grm;
		else static if(ruleId == 41 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "?") SubTokenType_grm;
		else static if(ruleId == 42 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "*") SubTokenType_grm;
		else static if(ruleId == 44 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Nonterminal") SubTokenType_grm;
		else static if(ruleId == 44 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 44 && index == 2)
			alias Token_grm!(SymbolType.Terminal, "::=") SubTokenType_grm;
		else static if(ruleId == 44 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Handles>") SubTokenType_grm;
		else static if(ruleId == 44 && index == 4)
			alias Token_grm!(SymbolType.NonTerminal, "<nl>") SubTokenType_grm;
		else static if(ruleId == 45 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Handles>") SubTokenType_grm;
		else static if(ruleId == 45 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<nl opt>") SubTokenType_grm;
		else static if(ruleId == 45 && index == 2)
			alias Token_grm!(SymbolType.Terminal, "|") SubTokenType_grm;
		else static if(ruleId == 45 && index == 3)
			alias Token_grm!(SymbolType.NonTerminal, "<Handle>") SubTokenType_grm;
		else static if(ruleId == 46 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Handle>") SubTokenType_grm;
		else static if(ruleId == 47 && index == 0)
			alias Token_grm!(SymbolType.NonTerminal, "<Handle>") SubTokenType_grm;
		else static if(ruleId == 47 && index == 1)
			alias Token_grm!(SymbolType.NonTerminal, "<Symbol>") SubTokenType_grm;
		else static if(ruleId == 49 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Terminal") SubTokenType_grm;
		else static if(ruleId == 50 && index == 0)
			alias Token_grm!(SymbolType.Terminal, "Nonterminal") SubTokenType_grm;
		else
			static assert(false,
				"Invalid subtoken: SubTokenType_grm!("~ctfe_i2a(ruleId)~", "~ctfe_i2a(index)~")");
	}
	
	private class _Token_grm(SymbolType staticSymbolType, string staticName, int staticRuleId) : _Token_grm!(staticSymbolType, staticName)
	{
		// StringOf is a workaround for DMD Bug #1748
		//TODO: expand that "..."
		static enum string StringOf = "Token_grm!("~fullSymbolTypeToString(staticSymbolType)~", "~staticName.stringof~", ...)";

		//TODO: This should take Token_{langaugeName}[], not Token[]
		this(Token[] sub, Language lang)
		{
			super(sub, lang, staticRuleId);
		}

		@property SubTokenType_grm!(staticRuleId, index) sub(int index)()
		{
			return cast(SubTokenType_grm!(staticRuleId, index))subX[index];
		}
	}

	private class Base_Token_grm : Token
	{
		static enum string StringOf = "Token_grm";

		this(Symbol symbol, Language lang, string content,
					string file="{unknown}", ptrdiff_t line=0,
					ptrdiff_t srcIndexStart=0, ptrdiff_t srcIndexEnd=0,
					CommentType commentMode=CommentType.None,
					string debugInfo="")
		{
			super(
				symbol, lang, content,
				file, line,
				srcIndexStart, srcIndexEnd,
				commentMode,
				debugInfo
			);
		}
		
		this(Symbol symbol, Token[] sub, Language lang, int ruleId)
		{
			super(symbol, sub, lang, ruleId);
		}
	}
}

version(Goldie_DynamicStyle)
{
	//TODO: Change to @property member of Token when DMD BUG3051 is fixed.
	auto traverse(T : Token)(T _this)
	{
		return traverse!""(_this);
	}

	//TODO: Change to @property member of Token when DMD BUG3051 is fixed.
	auto traverse(alias pred)(Token _this)
		if(
			(is(typeof(pred):string) && pred == "") ||
			is(typeof(unaryFun!pred))
		)
	{
		struct Result
		{
			Token start;
			
			this(Token start)
			{
				this.start = start;
				
				stack = new Stack!StackElem();
				stack ~= StackElem(-1, start);
				
				advance();
			}
			
			private Token _front;

			private struct StackElem
			{
				size_t index;
				Token token;
			}
			private Stack!StackElem stack;
			
			private void advance()
			{
				while(!stack.empty)
				{
					// Advance to next subtoken
					stack.top.index++;
					
					// Reached last subtoken?
					if(stack.top.index >= stack.top.token.subX.length)
					{
						stack.pop();
						continue;
					}
					
					// Set new subtoken
					_front = stack.top.token.subX[stack.top.index];

					// Enter current subtoken?
					static if(is(typeof(pred):string) && (pred.ctfe_strip() == "" || pred.ctfe_strip() == "true"))
					{
						stack ~= StackElem(-1, _front);
						return;
					}
					else
					{
						if(unaryFun!pred(_front))
						{
							stack ~= StackElem(-1, _front);
							return;
						}
					}
				}
				
				_front = null;
			}
			
			void skip()
			{
				// Move to end of this token, then advance.
				stack.top.index = stack.top.token.subX.length;
				advance();
			}
			
			Token front()
			{
				return _front;
			}

			void popFront()
			{
				advance();
			}
			
			@property bool empty()
			{
				return stack.empty;
			}

			@property auto save()
			{
				auto r = Result(start);
				r._front = _front;
				r.stack = stack.dup;
				return r;
			}
		}

		return Result(_this);
	}
}

//TODO: Add way to get token's rule in string form (like what's shown in dumpcgt)
//TODO? Make wrong ctor private in Token_calc!{symbol}? Make all ctors private in Token_calc?
version(Goldie_DynamicStyle)
class Token
{
	private string content = "";
	mixin(getter!(int, "ruleId"));
	mixin(getter!(string, "debugInfo"));
	mixin(getter!(CommentType, "commentMode"));
	mixin(getter!(Language, "lang"));
	SymbolType type;
	Symbol symbol;
	
	this(
		Symbol symbol, Language lang, string content,
		string file="{unknown}", ptrdiff_t line=0,
		ptrdiff_t srcIndexStart=0, ptrdiff_t srcIndexEnd=0,
		CommentType commentMode=CommentType.None,
		string debugInfo=""
	)
	{
		this.content = content;
		
		// Workaround for DMD Bug #2881
		this._commentMode = commentMode;
		
		mixin(initMemberX("this._%s = %s",
			"lang", "file", "line", "debugInfo",
			"srcIndexStart", "srcIndexEnd"
		));
		this._ruleId = -1;
		this.symbol = symbol;
		this.type = symbol.type;
		
		if(type == SymbolType.NonTerminal)
			throw new IllegalArgumentException("Called wrong constructor for NonTerminal");
	}

	this(Symbol symbol, Token[] sub, Language lang, int ruleId)
	{
		//TODO: Ensure ruleId is valid for this symbol in both dynamic and static
		this.symbol = symbol;
		this._ruleId = ruleId;
		this._lang = lang;
		this.type = symbol.type;
		this.subX = sub;
		
		if(type != SymbolType.NonTerminal)
			throw new IllegalArgumentException("Called wrong constructor for token that isn't a NonTerminal");
	}
	
	// The sub-tokens of this token (if this is a NonTerminal)
	Token[] subX;
	
	//TODO: Replace these op overloads with alias this once DMD #3537 is fixed.
	//TODO: Make make subX private once Goldie drops support for < DMD 2.057 (due to opDollar)
	//TODO: Need to "replace these op overloads with alias this" AND "make subX private",
	//      but do ONLY ONE of those tasks until the following DMD "alias this"
	//      issues are fixed: #3537, #3626, #5973, #6456
	//alias subX this;
	
	@property size_t length()
	{
		return subX.length;
	}
	
	size_t opDollar()
	{
		return subX.length;
	}
	
	Token opIndex(size_t index)
	{
		return subX[index];
	}

	Token opIndexAssign(Token tok, size_t index)
	{
		return subX[index] = tok;
	}

	Token[] opSlice()
	{
		return subX[];
	}

	Token[] opSlice(size_t a, size_t b)
	{
		return subX[a..b];
	}

	Token[] opSliceAssign(Token tok)
	{
		return subX[] = tok;
	}

	Token[] opSliceAssign(Token tok, size_t a, size_t b)
	{
		return subX[a..b] = tok;
	}

	Token[] opSliceAssign(Token[] toks)
	{
		return subX[] = toks;
	}

	Token[] opSliceAssign(Token[] toks, size_t a, size_t b)
	{
		return subX[a..b] = toks;
	}

	int opApply(int delegate(ref Token) dg)
	{
		int result = 0;

		foreach(ref Token tok; subX)
		{
			result = dg(tok);
			if(result)
				break;
		}
		return result;
	}

	int opApply(int delegate(ref size_t, ref Token) dg)
	{
		int result = 0;

		foreach(size_t i, ref Token tok; subX)
		{
			result = dg(i, tok);
			if(result)
				break;
		}
		return result;
	}

	int opApplyReverse(int delegate(ref Token) dg)
	{
		int result = 0;

		foreach_reverse(ref Token tok; subX)
		{
			result = dg(tok);
			if(result)
				break;
		}
		return result;
	}

	int opApplyReverse(int delegate(ref size_t, ref Token) dg)
	{
		int result = 0;

		foreach_reverse(size_t i, ref Token tok; subX)
		{
			result = dg(i, tok);
			if(result)
				break;
		}
		return result;
	}
	
	mixin(getterLazy!(ptrdiff_t, "line", q{
		if(type == SymbolType.NonTerminal && subX.length > 0)
			return firstLeaf.line;
		else
			return _line;
	}));
	
	mixin(getterLazy!(string, "file", q{
		if(type == SymbolType.NonTerminal && subX.length > 0)
			return firstLeaf.file;
		else
			return _file;
	}));
	
	mixin(getterLazy!(ptrdiff_t, "srcIndexStart", q{
		if(type == SymbolType.NonTerminal && subX.length > 0)
			return firstLeaf.srcIndexStart;
		else
			return _srcIndexStart;
	}));
	
	mixin(getterLazy!(ptrdiff_t, "srcIndexEnd", q{
		if(type == SymbolType.NonTerminal && subX.length > 0)
			return lastLeaf.srcIndexEnd;
		else
			return _srcIndexEnd;
	}));
	
	mixin(getterLazy!(Token, "firstLeaf", q{
		if(type == SymbolType.NonTerminal && subX.length > 0)
		{
			foreach(Token subToken; subX)
			{
				if(subToken.type != SymbolType.NonTerminal || subToken.subX.length > 0)
					return subToken.firstLeaf;
			}
		}

		return this;
	}));
	
	mixin(getterLazy!(Token, "lastLeaf", q{
		if(type == SymbolType.NonTerminal && subX.length > 0)
		{
			foreach_reverse(Token subToken; subX)
			{
				if(subToken.type != SymbolType.NonTerminal || subToken.subX.length > 0)
					return subToken.lastLeaf;
			}
		}

		return this;
	}));
	
	@property ptrdiff_t srcLength()
	{
		return srcIndexEnd - srcIndexStart;
	}

	@property string typeName()
	{
		return symbolTypeToString(type);
	}

	@property string name()
	{
		return symbol.name;
	}

	//TODO? Change-to/suppliment-with something that returns Token_blah!(SymbolType.NonTerminal, "foo")
	mixin(getterLazy!(string, "fullName", q{
		return "%s.%s".format(typeName, name);
	}));
	
	private void ensureValidSymbol(string symbolName)
	{
		if(!_lang.isSymbolNameValid(symbolName))
			throw new Exception(
				"'%s' is not a valid symbol name"
					.format(symbolName)
			);
	}

	bool matches(string parentSymbol, string[] subSymbols...)
	{
		if(_lang.isSymbolNameAmbiguous(parentSymbol))
			throw new Exception(
				"Symbol '%s' is ambiguous, it could be any of the following types: %s\nmatches() doesn't yet support disambiguation of symbol names at runtime."
					.format(parentSymbol, _lang.symbolTypesStrByName(parentSymbol))
			);

		ensureValidSymbol(parentSymbol);

		bool isParentNonTerminal =
			_lang.symbolsByName(parentSymbol)[0].type == SymbolType.NonTerminal;
		
		if(type == SymbolType.NonTerminal && isParentNonTerminal)
			return ruleId == _lang.ruleIdOf(parentSymbol, subSymbols);
		else if(type != SymbolType.NonTerminal && !isParentNonTerminal)
			return parentSymbol == symbol.name && subSymbols.length == 0;
		else
			return false;
	}
	
	//TODO: Optimize with compile-time tricks
	T get(T)(int index=0) if(is(T : Token) && !is(T == Token) && __traits(compiles, T.staticName))
	{
		enforce(index >= 0, "index must be positive");

		foreach(tok; subX)
		if(auto staticTok = cast(T)tok)
		{
			if(index == 0)
				return staticTok;
			else
				index--;
		}
		
		return null;
	}
	
	Ts[$-1] get(Ts...)() if(Ts.length > 1)
	{
		static assert(
			is(Ts[0] : Token) && !is(Ts[0] == Token) && __traits(compiles, Ts[0].staticName),
			"T must be a static-style Token class"
		);

		auto subTok = get!(Ts[0])(0);
		if(subTok)
		{
			static if(Ts.length == 1)
				return subTok;
			else
				return subTok.get!(Ts[1..$]);
		}
		else
			return cast(Ts[$-1])null;
	}

	Token get()(string symbolName, int index=0)
	{
		enforce(index >= 0, "index must be positive");
		ensureValidSymbol(symbolName);

		foreach(tok; subX)
		if(tok.name == symbolName)
		{
			if(index == 0)
				return tok;
			else
				index--;
		}
		
		return null;
	}
	
	Token get()(string[] symbolNames)
	{
		if(symbolNames.length == 0)
			return this;
		
		auto symName = symbolNames[0];
		auto subTok = get(symName);
		if(subTok)
			return subTok.get(symbolNames[1..$]);
		else
			return null;
	}
	
	T getRequired(T)(int index=0) if(is(T : Token) && !is(T == Token))
	{
		auto result = get!(T)(index);

		if(result is null)
			throw new Exception("Token not found");
		
		return result;
	}
	
	Ts[$-1] getRequired(Ts...)() if(Ts.length > 1)
	{
		auto result = get!(Ts)();

		if(result is null)
			throw new Exception("Token not found");
		
		return result;
	}
	
	Token getRequired()(string symbolName, int index=0)
	{
		auto result = get(symbolName, index);

		if(result is null)
			throw new Exception(`Doesn't exist: getRequired(%s, %s)`.format(symbolName.escapeDDQS(), index));
		
		return result;
	}
	
	Token getRequired()(string[] symbolNames)
	{
		auto result = get(symbolNames);

		if(result is null)
			throw new Exception("Token not found");
		
		return result;
	}
	
	override string toString()
	{
		return toString(TokenToStringMode.Smart);
	}
	
	string toString(TokenToStringMode mode)
	{
		switch(mode)
		{
		case TokenToStringMode.Compact:
			return toStringCompact();
			
		case TokenToStringMode.CompactWithSpaces:
			return toStringCompactWithSpaces();
			
		case TokenToStringMode.Smart:
			return toStringSmart();
			
		case TokenToStringMode.Full:
			return toStringFull();
			
		default:
			throw new InternalException("Unknown TokenToStringMode: #%s".format(mode));
		}
	}
	
	string toStringCompact()
	{
		string ret;
		
		switch(type)
		{
		case SymbolType.NonTerminal:
			foreach(Token tok; subX)
				ret ~= tok.toStringCompact();
			break;
			
		case SymbolType.Terminal:
			ret = content;
			break;
			
		case SymbolType.Whitespace:
		case SymbolType.EOF:
		case SymbolType.CommentStart:
		case SymbolType.CommentEnd:
		case SymbolType.CommentLine:
		case SymbolType.Error:
			ret = "";
			break;
			
		default:
			throw new InternalException("Unknown SymbolType: #%s".format(type));
		}
		
		return ret;
	}
	
	string toStringCompactWithSpaces()
	{
		string ret;
		
		switch(type)
		{
		case SymbolType.NonTerminal:
			string[] toks;
			foreach(Token tok; subX)
				toks ~= tok.toStringCompactWithSpaces();
			ret = toks.join(" ");
			break;
			
		case SymbolType.Terminal:
			ret = content;
			break;
			
		case SymbolType.Whitespace:
		case SymbolType.EOF:
		case SymbolType.CommentStart:
		case SymbolType.CommentEnd:
		case SymbolType.CommentLine:
		case SymbolType.Error:
			ret = "";
			break;
			
		default:
			throw new InternalException("Unknown SymbolType: #%s".format(type));
		}
		
		return ret;
	}

	string toStringSmart()
	{
		string ret;
		
		switch(type)
		{
		case SymbolType.NonTerminal:
			string[] toks;
			foreach(Token tok; subX)
			{
				string tokStr = tok.toStringSmart();
				
				if(tokStr == "")
					continue;
					
				if( toks.length > 0 &&
					contains(letters~digits~'_', tokStr[0]     ) &&
					contains(letters~digits~'_', toks[$-1][$-1]) )
				{
					toks ~= " ";
				}

				toks ~= tokStr;
			}
			ret = toks.join("");
			break;
			
		case SymbolType.Terminal:
			ret = content;
			break;
			
		case SymbolType.Whitespace:
		case SymbolType.EOF:
		case SymbolType.CommentStart:
		case SymbolType.CommentEnd:
		case SymbolType.CommentLine:
		case SymbolType.Error:
			ret = "";
			break;
			
		default:
			throw new InternalException("Unknown SymbolType: #%s".format(type));
		}
		
		return ret;
	}

	string toStringFull()
	{
		string ret;
		
		if(type == SymbolType.NonTerminal)
		{
			foreach(Token tok; subX)
				ret ~= tok.toStringFull();
		}
		else
			ret = content;
			
		return ret;
	}

	TreeNode toTreeNode(size_t index=0)
	{
		auto start = srcIndexStart;
		auto node = new TreeNode( "%s: %s".format(index, name) );
		node.addAttribute("srcIndexStart", start);
		//node.addAttribute("srcIndexEnd", srcIndexEnd());
		node.addAttribute("srcLength", srcIndexEnd - start);
		node.addAttribute("line", line+1);
		node.addAttribute("type", typeName);
		node.addAttribute("symbol", name);
		if(_debugInfo != "")
			node.addAttribute("debugInfo", debugInfo);
		//node.addAttribute("content", toStringRaw());
		
		if(type == SymbolType.NonTerminal)
		foreach(size_t i, Token tok; subX)
			node.addContent(tok.toTreeNode(i));
		
		return node;
	}
	
	TreeNode toPsuedoTreeNode()
	{
		auto node = new TreeNode(toString(TokenToStringMode.Full));
		node.addAttribute("symbol", fullName);

		if(type == SymbolType.NonTerminal)
		foreach(Token tok; subX)
			node.addContent(tok.toPsuedoTreeNode());
		
		return node;
	}
}

version(Goldie_StaticStyle)
{
	private class _Token_grm(SymbolType staticSymbolType, string _staticName) : Base_Token_grm
	{
		// StringOf is a workaround for DMD Bug #1748
		static enum string StringOf = "Token_calc!("~fullSymbolTypeToString(staticSymbolType)~", "~staticName.stringof~")";
		static enum string staticName = _staticName;
		
		static if(staticSymbolType != SymbolType.NonTerminal) // Terminal?
		{

			// Static Terminal ctor
			this(
				Language lang, string content,
				string file="{unknown}", ptrdiff_t line=0,
				ptrdiff_t srcIndexStart=0, ptrdiff_t srcIndexEnd=0,
				CommentType commentMode=CommentType.None,
				string debugInfo=""
			)
			{
				static if(staticSymbolType == SymbolType.EOF && staticName == "EOF")
				int staticId = 0;
			else static if(staticSymbolType == SymbolType.Error && staticName == "Error")
				int staticId = 1;
			else static if(staticSymbolType == SymbolType.Whitespace && staticName == "Whitespace")
				int staticId = 2;
			else static if(staticSymbolType == SymbolType.CommentEnd && staticName == "Comment End")
				int staticId = 3;
			else static if(staticSymbolType == SymbolType.CommentLine && staticName == "Comment Line")
				int staticId = 4;
			else static if(staticSymbolType == SymbolType.CommentStart && staticName == "Comment Start")
				int staticId = 5;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "-")
				int staticId = 6;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "(")
				int staticId = 7;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == ")")
				int staticId = 8;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "*")
				int staticId = 9;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "::=")
				int staticId = 10;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "?")
				int staticId = 11;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "|")
				int staticId = 12;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "+")
				int staticId = 13;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "=")
				int staticId = 14;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "Newline")
				int staticId = 15;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "Nonterminal")
				int staticId = 16;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "ParameterName")
				int staticId = 17;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "SetLiteral")
				int staticId = 18;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "SetName")
				int staticId = 19;
			else static if(staticSymbolType == SymbolType.Terminal && staticName == "Terminal")
				int staticId = 20;
			else
				static assert(false,
					"Invalid token: Token_grm!(SymbolType."~
					goldSymbolTypeToString(staticSymbolType)~", '"~staticName~"')");
				super(
					language_grm.symbolTable[staticId],
					lang, content,
					file, line,
					srcIndexStart, srcIndexEnd,
					commentMode,
					debugInfo
				);
			}

		}
		else
		{

			// Static NonTerminal ctor
			this(Token[] sub, Language lang, int ruleId)
			{
				static if(staticName == "<Content>")
				int staticId = 21;
			else static if(staticName == "<Definition>")
				int staticId = 22;
			else static if(staticName == "<Grammar>")
				int staticId = 23;
			else static if(staticName == "<Handle>")
				int staticId = 24;
			else static if(staticName == "<Handles>")
				int staticId = 25;
			else static if(staticName == "<Kleene Opt>")
				int staticId = 26;
			else static if(staticName == "<nl>")
				int staticId = 27;
			else static if(staticName == "<nl opt>")
				int staticId = 28;
			else static if(staticName == "<Parameter>")
				int staticId = 29;
			else static if(staticName == "<Parameter Body>")
				int staticId = 30;
			else static if(staticName == "<Parameter Item>")
				int staticId = 31;
			else static if(staticName == "<Parameter Items>")
				int staticId = 32;
			else static if(staticName == "<Reg Exp>")
				int staticId = 33;
			else static if(staticName == "<Reg Exp 2>")
				int staticId = 34;
			else static if(staticName == "<Reg Exp Item>")
				int staticId = 35;
			else static if(staticName == "<Reg Exp Seq>")
				int staticId = 36;
			else static if(staticName == "<Rule Decl>")
				int staticId = 37;
			else static if(staticName == "<Set Decl>")
				int staticId = 38;
			else static if(staticName == "<Set Exp>")
				int staticId = 39;
			else static if(staticName == "<Set Item>")
				int staticId = 40;
			else static if(staticName == "<Symbol>")
				int staticId = 41;
			else static if(staticName == "<Terminal Decl>")
				int staticId = 42;
			else static if(staticName == "<Terminal Name>")
				int staticId = 43;
			else
				static assert(false,
					"Invalid token: Token_grm!(SymbolType."~
					goldSymbolTypeToString(staticSymbolType)~", '"~staticName~"')");
				super(language_grm.symbolTable[staticId], sub, lang, ruleId);
			}

		}
	}
}
