/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * This file is part of Beaver Parser Generator.                       *
 * Copyright (C) 2003,2005 Alexander Demenchuk <alder@softanvil.com>.  *
 * All rights reserved.                                                *
 * See the file "LICENSE" for the terms and conditions for copying,    *
 * distribution and modification of Beaver.                            *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

package beaver.spec.parser;

import beaver.comp.util.Log;
import beaver.*;
import beaver.spec.ast.*;
import java.util.ArrayList;

/**
 * This class is a LALR parser generated by
 * <a href="http://beaver.sourceforge.net">Beaver</a> v0.9.6
 * from the grammar specification "beaver.grammar".
 */
public class GrammarParser extends Parser {
	static public class Terminals {
		static public final short EOF = 0;
		static public final short IDENT = 1;
		static public final short SEMI = 2;
		static public final short TYPEOF = 3;
		static public final short HEADER = 4;
		static public final short PACKAGE = 5;
		static public final short CLASS = 6;
		static public final short EMBED = 7;
		static public final short INIT = 8;
		static public final short GOAL = 9;
		static public final short IMPORT = 10;
		static public final short TERMINALS = 11;
		static public final short LEFT = 12;
		static public final short RIGHT = 13;
		static public final short NONASSOC = 14;
		static public final short BAR = 15;
		static public final short CODE = 16;
		static public final short AT = 17;
		static public final short COMMA = 18;
		static public final short TEXT = 19;
		static public final short IS = 20;
		static public final short QUESTION = 21;
		static public final short PLUS = 22;
		static public final short STAR = 23;
		static public final short DOT = 24;

		static public final String[] NAMES = {
			"EOF",
			"IDENT",
			"SEMI",
			"TYPEOF",
			"HEADER",
			"PACKAGE",
			"CLASS",
			"EMBED",
			"INIT",
			"GOAL",
			"IMPORT",
			"TERMINALS",
			"LEFT",
			"RIGHT",
			"NONASSOC",
			"BAR",
			"CODE",
			"AT",
			"COMMA",
			"TEXT",
			"IS",
			"QUESTION",
			"PLUS",
			"STAR",
			"DOT"
		};
	}

	static final ParsingTables PARSING_TABLES = new ParsingTables(
		"U9pLbqbmLKKKXlztBm42n8GGXinXa459a2Ga94moAGwe33AZKEMQXMkjOgrLhbsuTg5LbbM" +
		"wK9T2GWX1a8G4XIX31iAKYKcG7B##xmP2h8wQqYfvV$rzJlT$Uhgtxkb#Kd10fVQRKhH9#$" +
		"IQnjgFcgjvcgy5UaRFQg6ALQ95UawBKPxI7CrKe5BA5CtMqqhJ63laxV50eLvLkIhrlDRg1" +
		"RsaQctLTktINljTaxtQWB9im8ExAh2x7jpHKhlZmMsjijiUtD8ok#N1JQsqcnxqQxNrUz2d" +
		"bwtFWrvjiLuFUhJHUZperklMxS4DRROR7bndlkiUNDERTis3g$Ixwi4LxR0h7dJHhyk3ozf" +
		"jbptef5#d1nrwopeyQ9UitOFpQESzQ4Dhy#0IsYKFBg9TzE02sWKF3CttEsx7DKjJxRJAbA" +
		"abAjH4EsR7D45Jd0PEHuXyvJiDD5Y39YbRESgrUtPFwwpEwfJknd4QE6jdzMBirqL8ZXFvp" +
		"3JUpKHyaugOgHdy38xQKQLQlTMhmfeYd8cqPerp6gYFS0ISiLghLPNLM8scMOkrQ8toh37I" +
		"ZZWDr4HeYT1eZSgmKtRE3ckwjTe9hTSCEwaDzeFzfEKef#mmE6SdOAkTX2Xst#vBMc6$sA$" +
		"QfftQexVrYjxGi5#aRugHJKE2NUOh2mJahLdahJbahiTpLheoo5dPMWopwL50ZnBAAc#F11" +
		"akr1Zou5YDuoccygOcyYxIo989uDToHzbloYYr9V$1c2EjSoGjvtyqtnFIZwpnn6jyUK5SP" +
		"lEbvIelgXMISzoNDpakfsgQfcj6N7CHnN6R#uepefQAg4n695kJ4NyU9vkueJCvg#WzkFx9" +
		"rIJZ1stfOwCCZNDbMUnNFeptbK64yjWkZUtWV8wPb5bncGuKFR$C8P4HXXyIH3o2jFzWCkK" +
		"jX3dHtfHe8wmFMmCVm6xO9GKyhM01CIdObN0rhAA#3Eku5j8$G4zy3nlmK#4ac0#Bu6pQM#" +
		"cp7Tj1VIvSXty8EnvkHQk66#0s#0vy5xfbVWG$WP$1Rs0jR8ASfUfX35SVm7x7E6bOvjKM$" +
		"9duRc$xyTVZpyT$7v$n0zQX3x7pQA#0pVYhi6vDdCF16kncOZx7tuE$3$zRdaylrgrvBsq7" +
		"y3dh0zOThC172tRG$Xva7S5Ex0UGPnVimduCMKUm6$if$DfjZZ4xuO1x1mVZ3UEs3$6$ZEr" +
		"NnFKCjWydlqLnN3zpJF35ZKIDei$V77VZlpJE5t#XTppo4y4Gls28Npryp$oMSuOdOC0vBk" +
		"ZEQCU0SppWH4$yGxhxGiZv7t832Ba3XDm2Gku18JU1a9j0o5qWv3OGyWM6t0rIE6kJvsrEd" +
		"DCBo8W5qJ#c10oZB5H4FO$rkSnKZ2t6bc1Bi8N456BBgBjyKuujZ#yCbL4kIJnaXSkcVm2p" +
		"BaPq");

	static class Events extends Parser.Events
	{
		private final Log log;

		Events(Log log)
		{
			this.log = log;
		}

		public void scannerError(Scanner.Exception e)
		{
			log.error(e);
		}
		public void syntaxError(Symbol token)
		{
			log.error(token, "unexpected token");
		}
		public void unexpectedTokenRemoved(Symbol token)
		{
			log.warning(token, "recovered by removing unexpected token");
		}
		public void missingTokenInserted(Symbol token)
		{
			log.warning(token, "recovered by inserting missing '" + Terminals.NAMES[token.getId()] + "'");
		}
		public void misspelledTokenReplaced(Symbol token)
		{
			log.warning(token, "recovered by replacing misspelled token with '" + Terminals.NAMES[token.getId()] + "'");
		}
		public void errorPhraseRemoved(Symbol error)
		{
			log.warning(error, "recovered by removing error phrase");
		}
	}

	private Log log;

	public GrammarParser(Log log)
	{
		this();
		report = new Events(this.log = log);
	}

	public GrammarParser() {
		super(PARSING_TABLES);
	}

	protected Symbol invokeReduceAction(int rule_num, int offset) {
		switch(rule_num) {
			case 0: // lst$declaration = declaration
			{
					ArrayList lst = new ArrayList(); lst.add(_symbols[offset + 1].value); return new Symbol(lst);
			}
			case 1: // lst$declaration = lst$declaration declaration
			{
					((ArrayList) _symbols[offset + 1].value).add(_symbols[offset + 2].value); return _symbols[offset + 1];
			}
			case 4: // lst$rule = rule
			{
					ArrayList lst = new ArrayList(); lst.add(_symbols[offset + 1].value); return new Symbol(lst);
			}
			case 5: // lst$rule = lst$rule rule
			{
					((ArrayList) _symbols[offset + 1].value).add(_symbols[offset + 2].value); return _symbols[offset + 1];
			}
			case 6: // grammar = opt$lst$declaration.decl lst$rule.rules
			{
					final Symbol _symbol_decl = _symbols[offset + 1];
					final ArrayList _list_decl = (ArrayList) _symbol_decl.value;
					final Declaration[] decl = _list_decl == null ? new Declaration[0] : (Declaration[]) _list_decl.toArray(new Declaration[_list_decl.size()]);
					final Symbol _symbol_rules = _symbols[offset + 2];
					final ArrayList _list_rules = (ArrayList) _symbol_rules.value;
					final Rule[] rules = _list_rules == null ? new Rule[0] : (Rule[]) _list_rules.toArray(new Rule[_list_rules.size()]);
					
					return new GrammarTreeRoot(decl, rules);
			}
			case 19: // declaration = error.e SEMI
			{
					final Symbol e = _symbols[offset + 1];
					
					log.error(e, "malformed declaration"); return new Declaration.Error();
			}
			case 20: // header = HEADER CODE.code SEMI
			{
					final Symbol code = _symbols[offset + 2];
					
					return new Declaration.Header(code);
			}
			case 21: // package = PACKAGE TEXT.name SEMI
			{
					final Symbol name = _symbols[offset + 2];
					
					return new Declaration.PackageName(name);
			}
			case 22: // import = IMPORT txt_list.names SEMI
			{
					final Symbol _symbol_names = _symbols[offset + 2];
					final ArrayList _list_names = (ArrayList) _symbol_names.value;
					final beaver.Symbol[] names = _list_names == null ? new beaver.Symbol[0] : (beaver.Symbol[]) _list_names.toArray(new beaver.Symbol[_list_names.size()]);
					
					return new Declaration.Imports(names);
			}
			case 23: // class_name = CLASS TEXT.name SEMI
			{
					final Symbol name = _symbols[offset + 2];
					
					return new Declaration.ClassName(name);
			}
			case 24: // class_code = EMBED CODE.code SEMI
			{
					final Symbol code = _symbols[offset + 2];
					
					return new Declaration.ClassCode(code);
			}
			case 25: // class_init = INIT CODE.code SEMI
			{
					final Symbol code = _symbols[offset + 2];
					
					return new Declaration.ConstructorCode(code);
			}
			case 26: // grammar_goal = GOAL IDENT.name SEMI
			{
					final Symbol name = _symbols[offset + 2];
					
					return new Declaration.Goal(name);
			}
			case 27: // terminals = TERMINALS sym_list.symbols SEMI
			{
					final Symbol _symbol_symbols = _symbols[offset + 2];
					final ArrayList _list_symbols = (ArrayList) _symbol_symbols.value;
					final beaver.Symbol[] symbols = _list_symbols == null ? new beaver.Symbol[0] : (beaver.Symbol[]) _list_symbols.toArray(new beaver.Symbol[_list_symbols.size()]);
					
					return new Declaration.Terminals(symbols);
			}
			case 28: // left_assoc = LEFT sym_list.symbols SEMI
			{
					final Symbol _symbol_symbols = _symbols[offset + 2];
					final ArrayList _list_symbols = (ArrayList) _symbol_symbols.value;
					final beaver.Symbol[] symbols = _list_symbols == null ? new beaver.Symbol[0] : (beaver.Symbol[]) _list_symbols.toArray(new beaver.Symbol[_list_symbols.size()]);
					
					return new Declaration.LeftAssoc(symbols);
			}
			case 29: // right_assoc = RIGHT sym_list.symbols SEMI
			{
					final Symbol _symbol_symbols = _symbols[offset + 2];
					final ArrayList _list_symbols = (ArrayList) _symbol_symbols.value;
					final beaver.Symbol[] symbols = _list_symbols == null ? new beaver.Symbol[0] : (beaver.Symbol[]) _list_symbols.toArray(new beaver.Symbol[_list_symbols.size()]);
					
					return new Declaration.RightAssoc(symbols);
			}
			case 30: // nonassoc = NONASSOC sym_list.symbols SEMI
			{
					final Symbol _symbol_symbols = _symbols[offset + 2];
					final ArrayList _list_symbols = (ArrayList) _symbol_symbols.value;
					final beaver.Symbol[] symbols = _list_symbols == null ? new beaver.Symbol[0] : (beaver.Symbol[]) _list_symbols.toArray(new beaver.Symbol[_list_symbols.size()]);
					
					return new Declaration.NonAssoc(symbols);
			}
			case 31: // typeof = TYPEOF sym_list.symbols IS TEXT.type SEMI
			{
					final Symbol _symbol_symbols = _symbols[offset + 2];
					final ArrayList _list_symbols = (ArrayList) _symbol_symbols.value;
					final beaver.Symbol[] symbols = _list_symbols == null ? new beaver.Symbol[0] : (beaver.Symbol[]) _list_symbols.toArray(new beaver.Symbol[_list_symbols.size()]);
					final Symbol type = _symbols[offset + 4];
					
					return new Declaration.TypeOf(symbols, type);
			}
			case 32: // txt_list = TEXT
			{
					ArrayList lst = new ArrayList(); lst.add(_symbols[offset + 1]); return new Symbol(lst);
			}
			case 33: // txt_list = txt_list COMMA TEXT
			{
					((ArrayList) _symbols[offset + 1].value).add(_symbols[offset + 3]); return _symbols[offset + 1];
			}
			case 34: // sym_list = IDENT
			{
					ArrayList lst = new ArrayList(); lst.add(_symbols[offset + 1]); return new Symbol(lst);
			}
			case 35: // sym_list = sym_list COMMA IDENT
			{
					((ArrayList) _symbols[offset + 1].value).add(_symbols[offset + 3]); return _symbols[offset + 1];
			}
			case 36: // rule = IDENT.name IS def_list.defs SEMI
			{
					final Symbol name = _symbols[offset + 1];
					final Symbol _symbol_defs = _symbols[offset + 3];
					final ArrayList _list_defs = (ArrayList) _symbol_defs.value;
					final Rule.Definition[] defs = _list_defs == null ? new Rule.Definition[0] : (Rule.Definition[]) _list_defs.toArray(new Rule.Definition[_list_defs.size()]);
					
					return new Rule(name, defs);
			}
			case 37: // rule = error.e SEMI
			{
					final Symbol e = _symbols[offset + 1];
					
					log.error(e, "malformed production");
					return new Rule(new Symbol(""), new Rule.Definition[] {});
			}
			case 38: // def_list = definition
			{
					ArrayList lst = new ArrayList(); lst.add(_symbols[offset + 1].value); return new Symbol(lst);
			}
			case 39: // def_list = def_list BAR definition
			{
					((ArrayList) _symbols[offset + 1].value).add(_symbols[offset + 3].value); return _symbols[offset + 1];
			}
			case 40: // lst$def_element = def_element
			{
					ArrayList lst = new ArrayList(); lst.add(_symbols[offset + 1].value); return new Symbol(lst);
			}
			case 41: // lst$def_element = lst$def_element def_element
			{
					((ArrayList) _symbols[offset + 1].value).add(_symbols[offset + 2].value); return _symbols[offset + 1];
			}
			case 48: // definition = opt$lst$def_element.elts opt$rule_precedence.prec opt$CODE.code
			{
					final Symbol _symbol_elts = _symbols[offset + 1];
					final ArrayList _list_elts = (ArrayList) _symbol_elts.value;
					final Rule.Definition.Element[] elts = _list_elts == null ? new Rule.Definition.Element[0] : (Rule.Definition.Element[]) _list_elts.toArray(new Rule.Definition.Element[_list_elts.size()]);
					final Symbol prec = _symbols[offset + 2];
					final Symbol code = _symbols[offset + 3];
					
					return new Rule.Definition(elts, prec, code);
			}
			case 49: // definition = error.e
			{
					final Symbol e = _symbols[offset + 1];
					
					log.error(e, "malformed nonterminal definition");
					return new Rule.Definition(null, new Symbol(null), new Symbol(null));
			}
			case 54: // def_element = IDENT.name opt$alias.alias opt$ebnf_symbol.ebnf_mark
			{
					final Symbol name = _symbols[offset + 1];
					final Symbol alias = _symbols[offset + 2];
					final Symbol ebnf_mark = _symbols[offset + 3];
					
					return new Rule.Definition.Element(name, alias, ebnf_mark);
			}
			case 2: // opt$lst$declaration = 
			case 42: // opt$lst$def_element = 
			case 44: // opt$rule_precedence = 
			case 46: // opt$CODE = 
			case 50: // opt$alias = 
			case 52: // opt$ebnf_symbol = 
			{
				return new Symbol(null);
			}
			case 3: // opt$lst$declaration = lst$declaration
			case 7: // declaration = header
			case 8: // declaration = package
			case 9: // declaration = import
			case 10: // declaration = class_name
			case 11: // declaration = class_code
			case 12: // declaration = class_init
			case 13: // declaration = grammar_goal
			case 14: // declaration = typeof
			case 15: // declaration = terminals
			case 16: // declaration = left_assoc
			case 17: // declaration = right_assoc
			case 18: // declaration = nonassoc
			case 43: // opt$lst$def_element = lst$def_element
			case 45: // opt$rule_precedence = rule_precedence
			case 47: // opt$CODE = CODE
			case 51: // opt$alias = alias
			case 53: // opt$ebnf_symbol = ebnf_symbol
			case 56: // ebnf_symbol = QUESTION
			case 57: // ebnf_symbol = PLUS
			case 58: // ebnf_symbol = STAR
			{
				return _symbols[offset + 1];
			}
			case 55: // alias = DOT IDENT
			case 59: // rule_precedence = AT IDENT
			{
				return _symbols[offset + 2];
			}
			default:
				throw new IllegalArgumentException("unknown production #" + rule_num);
		}
	}
}
