/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Grammar for PigScript

options {
  // Generate non-static functions
  STATIC = false;
  // Case is ignored in keywords
  IGNORE_CASE = true;
  JAVA_UNICODE_ESCAPE = true;
}

PARSER_BEGIN(PigScriptParser)
package org.apache.pig.tools.pigscript.parser;

import java.io.IOException;
import java.io.InputStream;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
import org.apache.pig.impl.util.StringUtils;

import jline.ConsoleReader;

public abstract class PigScriptParser
{
	protected boolean mInteractive;
	protected ConsoleReader mConsoleReader;

	public void setInteractive(boolean interactive)
	{
		mInteractive = interactive;
		token_source.interactive = interactive;
	}

    public int getLineNumber()
    {
        return jj_input_stream.getBeginLine();
    }

	public void setConsoleReader(ConsoleReader c)
    {
        mConsoleReader = c;
        token_source.consoleReader = c;
    }

	abstract public void prompt();

	abstract protected void quit();

	abstract protected void printAliases() throws IOException;

	abstract protected void printClear();

	abstract protected void processFsCommand(String[] cmdTokens) throws IOException;

	abstract protected void processShCommand(String[] cmdTokens) throws IOException;

	abstract protected void processSQLCommand(String cmdTokens) throws IOException;

	abstract protected void processDescribe(String alias) throws IOException;

	abstract protected void processExplain(String alias, String script, boolean isVerbose, String format, String target, List<String> params, List<String> files) throws IOException, ParseException;

	abstract protected void processRegister(String jar) throws IOException;

	abstract protected void processRegister(String path, String scriptingEngine, String namespace) throws IOException, ParseException;

	abstract protected void processSet(String key, String value) throws IOException, ParseException;

    abstract protected void processSet() throws IOException, ParseException;
    
    abstract protected void processHistory(boolean withNumbers);

	abstract protected void processCat(String path) throws IOException;

	abstract protected void processCD(String path) throws IOException;

	abstract protected void processDump(String alias) throws IOException;

	abstract protected void processKill(String jobid) throws IOException;

	abstract protected void processLS(String path) throws IOException;

	abstract protected void processPWD() throws IOException;

	abstract protected void printHelp();

	abstract protected void processMove(String src, String dst) throws IOException;

	abstract protected void processCopy(String src, String dst) throws IOException;

	abstract protected void processCopyToLocal(String src, String dst) throws IOException;

	abstract protected void processCopyFromLocal(String src, String dst) throws IOException;

	abstract protected void processMkdir(String dir) throws IOException;

	abstract protected void processPig(String cmd) throws IOException;

	abstract protected void processRemove(String path, String opt) throws IOException;

	abstract protected void processIllustrate(String alias, String script, String target, List<String> params, List<String> files) throws IOException, ParseException;

	abstract protected void processScript(String script, boolean batch, List<String> params, List<String> files) throws IOException, ParseException;

    abstract protected void processDefault(String key, String value) throws IOException;

    abstract protected void processDeclare(String key, String value) throws IOException;

	static String unquote(String s)
	{
		if (s.charAt(0) == '\'' && s.charAt(s.length()-1) == '\'')
			return s.substring(1, s.length()-1);
		else
			return s;
	}

}
PARSER_END(PigScriptParser)

// Skip all tabs and spaces
SKIP : { " " |  "\t" }

// Skip comments(single line and multiline)
SKIP : {
   <"--"(~["\r","\n"])*>
|  <"#!" (~["\r","\n"])*>
|  <"/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/">
}

// tokens

// commands
TOKEN: {<CAT: "cat">}
TOKEN: {<CLEAR: "clear">}
TOKEN: {<FS: "fs">}
TOKEN: {<SH:"sh">}
TOKEN: {<CD: "cd">}
TOKEN: {<COPY: "cp">}
TOKEN: {<COPYFROMLOCAL: "copyFromLocal">}
TOKEN: {<COPYTOLOCAL: "copyToLocal">}
TOKEN: {<DUMP: "dump">}
TOKEN: {<DUMP_SHORT: "\\d">}
TOKEN: {<DESCRIBE: "describe">}
TOKEN: {<DESCRIBE_SHORT: "\\de">}
TOKEN: {<ALIASES: "aliases">}
TOKEN: {<EXPLAIN: "explain">}
TOKEN: {<EXPLAIN_SHORT: "\\e">}
TOKEN: {<HELP: "help">}
TOKEN: {<HISTORY: "history">}
TOKEN: {<KILL: "kill">}
TOKEN: {<LS: "ls">}
TOKEN: {<MOVE: "mv">}
TOKEN: {<MKDIR: "mkdir">}
TOKEN: {<PWD: "pwd">}
TOKEN: {<QUIT: "quit">}
TOKEN: {<QUIT_SHORT: "\\q">}
TOKEN: {<REGISTER: "register">}
TOKEN: {<USING: "using">}
TOKEN: {<AS: "as"> }
TOKEN: {<REMOVE: "rm">}
TOKEN: {<REMOVEFORCE: "rmf">}
TOKEN: {<SET: "set">}
TOKEN: {<ILLUSTRATE: "illustrate">}
TOKEN: {<ILLUSTRATE_SHORT: "\\i">}
TOKEN: {<RUN: "run">}
TOKEN: {<EXEC: "exec">}
TOKEN: {<PARAM: "-param">}
TOKEN: {<PARAM_FILE: "-param_file">}
TOKEN: {<SCRIPT: "-script">}
TOKEN: {<DOT: "-dot">}
TOKEN: {<XML: "-xml">}
TOKEN: {<OUT: "-out">}
TOKEN: {<BRIEF: "-brief">}
TOKEN: {<N: "-n">}
TOKEN: {<PIGDEFAULT: "%default" >}
TOKEN: {<DECLARE: "%declare" >} 

// internal use commands
TOKEN: {<SCRIPT_DONE: "scriptDone">}

// Define pig command as
// (1) Starting with "split"/"define"/"store"/"import" or assignment (A=) or multi-assignment (A, B, ...=) followed by
// (2) Single statement followed by ; and newline or
// (3) Block of statements enclosed in

TOKEN_MGR_DECLS : {
        int pigBlockLevel = 0;
        int funcBlockLevel = 0;
        int tupleSchemaLevel = 0;
        int bagSchemaLevel = 0;
        int bagConstantLevel = 0;
	int prevState = DEFAULT;
	boolean interactive = false;
	ConsoleReader consoleReader = null;
    Stack<Integer> stack = new Stack<Integer>();
	public void secondary_prompt()
	{
		if (interactive)
		{
			/*System.err.print(">> ");
			System.err.flush();*/
		    consoleReader.setDefaultPrompt(">> ");
		}
	}

    public int getState(int state) {
        if(!stack.empty()) return stack.pop();
        return state;
    }

    public void saveState(int state) {
        stack.push(state);
    }

}

<DEFAULT> MORE :
{
    <"sql"> : SQL_START
}

<SQL_START> MORE :
{
    <";"> : SQL_END
|   <("\n" | "\r" | "\r\n")> {secondary_prompt();}
|   <(~[])>
}

<SQL_END> TOKEN : {
        <SQL: ""> {    matchedToken.image = image.toString();
        }: DEFAULT
}

<DEFAULT> MORE :
{
    <"split"> : PIG_START
|   <"define"> : PIG_START
|   <"store"> : PIG_START
|   <"assert"> : PIG_START
|   <"import"> : PIG_START
|   <(["a"-"z", "A"-"Z"])+(["a"-"z", "A"-"Z"] | ["0"-"9"] | "_")*(" " | "\t")*"="> : PIG_START
|   <"=>" (" " | "\t")*> : PIG_START
|   < <IDENTIFIER> (" " | "\t")* ("," (" " | "\t")* <IDENTIFIER> )* (" " | "\t")* "="> : PIG_START
|   < <IDENTIFIER> (" " | "\t")* "(" > : PIG_START
}

<PIG_START> MORE :
{
	<"'"> {prevState = PIG_START;} : IN_STRING
|	<"`"> {prevState = PIG_START;} : IN_COMMAND
|	<(" " | "\t")+["A","a"]["S","s"](" " | "\t")+ > {prevState = PIG_START;} : SCHEMA_DEFINITION
|   <(" " | "\t")+["G","g"]["E","e"]["N","n"]["E","e"]["R","r"]["A","a"]["T","t"]["E","e"](" " | "\t" | "\r" | "\n")+ > {prevState = PIG_START;} : GENERATE
|       <"{"> {pigBlockLevel = 1;} : IN_BLOCK
|       <"}"> {if (true) throw new TokenMgrError("Unmatched '}'", TokenMgrError.LEXICAL_ERROR);}
|       <";"> : PIG_END
|	<"--"> {prevState = PIG_START;} : SINGLE_LINE_COMMENT
|	<"/*"> {prevState = PIG_START;} : MULTI_LINE_COMMENT
|	<("\n" | "\r" | "\r\n")> {secondary_prompt();}
|       <(~[])>
}

<SINGLE_LINE_COMMENT> MORE :
{
	<("\n" | "\r" | "\r\n")> {SwitchTo(prevState); if(prevState != DEFAULT) secondary_prompt();}
|       <(~[])>
}

<MULTI_LINE_COMMENT> MORE :
{
	<"*/"> {SwitchTo(prevState);}
|	<("\n" | "\r" | "\r\n")> {secondary_prompt();}
|       <(~[])>
}

<IN_STRING> MORE :
{
	<"\\'">
|	<"'"> { SwitchTo(prevState);}
|	<("\n" | "\r" | "\r\n")> {secondary_prompt();}
|	<(~[])>
}

<IN_COMMAND> MORE :
{
	<"\\`">
|	<"`"> { SwitchTo(prevState);}
|	<("\n" | "\r" | "\r\n")> {secondary_prompt();}
|	<(~[])>
}

<GENERATE> MORE :
{
    <"{">
    {
        bagConstantLevel++;
        prevState = getState(prevState);
        saveState(prevState);
        prevState = GENERATE;
    } : BAG_CONSTANT
|	<(" " | "\t")+["A","a"]["S","s"](" " | "\t")+>
    {
        prevState = getState(prevState);
        saveState(prevState);
        prevState = GENERATE;
     } : SCHEMA_DEFINITION
|   <"--">
    {
        prevState = getState(prevState);
        saveState(prevState);
        prevState = GENERATE;
    } : SINGLE_LINE_COMMENT
|      <"/*">
    {
        prevState = getState(prevState);
        saveState(prevState);
        prevState = GENERATE;
    } : MULTI_LINE_COMMENT
|   <"'">
    {
        prevState = getState(prevState);
        saveState(prevState);
        prevState = GENERATE;
    } : IN_STRING
|	<";">
    {
        prevState = getState(prevState);
        if(prevState == PIG_START) {
            input_stream.backup(1);
            image.deleteCharAt(image.length()-1);
        }
        SwitchTo(prevState);
    }
|	<("\n" | "\r" | "\r\n")> {secondary_prompt();}
|	<(~[])>
}

<SCHEMA_DEFINITION> MORE :
{
    <"("> {tupleSchemaLevel++;}
|   <")">
    {
        if ((tupleSchemaLevel == 0) && (bagSchemaLevel == 0)) {
        // This means parenthesis is not from this schema_def.
        // Putting back ")" although others do not check parenthesis at this time.
        // This is a bandaid workaround for the issue with inline-op which
        // also uses parenthesis.
        // Real fix would be to move out of using this javacc parser. (PIG-2597)
            input_stream.backup(1);
            image.deleteCharAt(image.length()-1);
            SwitchTo(prevState);
        }
        tupleSchemaLevel--; if ((tupleSchemaLevel == 0) && (bagSchemaLevel == 0)) SwitchTo(prevState);
    }
|   <"{"> {bagSchemaLevel++;}
|   <"}"> {bagSchemaLevel--; if ((tupleSchemaLevel == 0) && (bagSchemaLevel == 0)) SwitchTo(prevState); }
|	<("," | ";" )>
    {
        if ((tupleSchemaLevel == 0) && (bagSchemaLevel == 0)) {
            input_stream.backup(1);
            image.deleteCharAt(image.length()-1);
            SwitchTo(prevState);
        }
    }
|	<("\n" | "\r" | "\r\n")> {secondary_prompt();}
|	<(~[])>
}

<BAG_CONSTANT> MORE :
{
    <"{"> {bagConstantLevel++;}
|   <"}"> {bagConstantLevel--; if (bagConstantLevel == 0) SwitchTo(prevState);}
|	<("\n" | "\r" | "\r\n")> {secondary_prompt();}
|	<(~[])>
}

<IN_BLOCK> MORE :
{
	<"\""> {prevState = IN_BLOCK;} : IN_DOUBLE_QUOTED_STRING
|	<(" " | "\t")+["A","a"]["S","s"](" " | "\t")+ > {prevState = IN_BLOCK;} : SCHEMA_DEFINITION
|   <(" " | "\t")+["G","g"]["E","e"]["N","n"]["E","e"]["R","r"]["A","a"]["T","t"]["E","e"](" " | "\t" | "\r" | "\n")+> {prevState = IN_BLOCK;} : GENERATE
|	<"{"> {pigBlockLevel++;}
|       <"}"(";")?> {pigBlockLevel--; if (pigBlockLevel == 0) SwitchTo(PIG_END);}
|	<"'"> {prevState = IN_BLOCK;} : IN_STRING
|	<"`"> {prevState = IN_BLOCK;} : IN_COMMAND
|	<"--"> {prevState = IN_BLOCK;} : SINGLE_LINE_COMMENT
|	<"/*"> {prevState = IN_BLOCK;} : MULTI_LINE_COMMENT
|	<("\n" | "\r" | "\r\n")> {secondary_prompt();}
|       <(~[])>
}

<IN_DOUBLE_QUOTED_STRING> MORE :
{
    <"\\\"">
|   <"\""> { SwitchTo(prevState);}
|   <("\n" | "\r" | "\r\n")> {secondary_prompt();}
|   <(~[])>
}

<PIG_END> TOKEN :
{
        <PIG: ""> { 	matchedToken.image = image.toString();
			//System.out.println("image = " +  matchedToken.image);
		}: DEFAULT
}

// other
TOKEN: {<EOL:  "\r" | "\n" | "\r\n">}
TOKEN: {<QUOTE: "'">}
TOKEN: {<SEMICOLON: ";">}
TOKEN:
{
	<#LETTER : ["a"-"z", "A"-"Z"] >
|	<#DIGIT : ["0"-"9"] >
|	<#SPECIALCHAR : ["_"] >
|	<#FSSPECIALCHAR: ["/"]>
|	<#FLOAT: <INTEGER> ( "." <INTEGER> )? | "." <INTEGER> >
|	<#INTEGER: ( <DIGIT> )+ >
|	<#NUMBER: <INTEGER> | <FLOAT> | <FLOAT> ( ["e","E"] ([ "-","+"])? <FLOAT> )?>
}
TOKEN: {<PREVREL: "@">}
TOKEN: {<IDENTIFIER: (<LETTER>)+(<DIGIT> | <LETTER> | <SPECIALCHAR> | "::")*>}
TOKEN: {<PATH: (~["(", ")", ";", "\r", " ", "\t", "\n"])+>}
TOKEN : { <QUOTEDSTRING :  "'"
      (   (~["'","\\","\n","\r"])
        | ("\\"
            ( ["n","t","b","r","f","\\","'"] )
          )
        | ("\\u"
            ["0"-"9","A"-"F","a"-"f"]
            ["0"-"9","A"-"F","a"-"f"]
            ["0"-"9","A"-"F","a"-"f"]
            ["0"-"9","A"-"F","a"-"f"]
          )
      )*
      "'"> }
TOKEN: {<SHELLCMD: "`" (~["`"])* "`" >}
void parse() throws IOException:
{
	Token t1, t2, t3;
	String engine = null, namespace = null;
	List<String> cmdTokens = new ArrayList<String>();
}

{
	(
	<EOL>
	{prompt();}
	|
	<FS>
	(
	t1 = GetPath()
	{
		cmdTokens.add(t1.image);
		while(true){
			try{
				t1=GetPath();
				cmdTokens.add(t1.image);
			}catch(ParseException e){
				break;
			}
		}
		processFsCommand(cmdTokens.toArray(new String[cmdTokens.size()]));
	}
	)+
	|
	<SH>
	(
	t1 = GetValue()
	{
		cmdTokens.add(t1.image);
		while(true){
			try{
				t1=GetValue();
				cmdTokens.add(StringUtils.unescapeInputString(unquote(t1.image)));
			}catch(ParseException e){
				break;
			}
		}
		processShCommand(cmdTokens.toArray(new String[cmdTokens.size()]));
	}
	)+
	|
	<CAT>
	(
	t1 = GetPath()
	{processCat(t1.image);}
	)+
	|
	Clear()
	|
	<CD>
	(
		t1 = GetPath()
		{processCD(t1.image);}
		|
		{processCD(null);}
	)
	|
	<COPY>
	t1 = GetPath()
	t2 = GetPath()
	{processCopy(t1.image, t2.image);}
	|
	<COPYFROMLOCAL>
	t1 = GetPath()
	t2 = GetPath()
	{processCopyFromLocal(t1.image, t2.image);}
	|
	<COPYTOLOCAL>
	t1 = GetPath()
	t2 = GetPath()
	{processCopyToLocal(t1.image, t2.image);}
	|
	(<DUMP> | <DUMP_SHORT>)
	(
	        (t1 = <IDENTIFIER>
                | t1 = <PREVREL>)
		{processDump(t1.image);}
		|
		{processDump(null);}
	)
	|
    Illustrate()
	|
	(<DESCRIBE> | <DESCRIBE_SHORT>)
	(
		(t1 = <IDENTIFIER>
                | t1 = <PREVREL>)
		{processDescribe(t1.image);}
		|
		{processDescribe(null);}
	)
	|
	<ALIASES>
	{printAliases();}
	|
	Explain()
	|
	<HELP>
	{printHelp();}
	|
	History()
	|
	<KILL>
	t1 = <IDENTIFIER>
	{processKill(t1.image);}
	|
	<LS>
	(
		t1 = GetPath()
		{processLS(t1.image);}
		|
		{processLS(null);}
	)
	|
	<MOVE>
	t1 = GetPath()
	t2 = GetPath()
	{processMove(t1.image, t2.image);}
	|
	<MKDIR>
	t1 = GetPath()
	{processMkdir(t1.image);}
	|
	t1 = <SQL>
	{processSQLCommand(t1.image);}
	|
	t1 = <PIG>
	{processPig(t1.image);}
	|
	<PWD>
	{processPWD();}
	|
	(<QUIT> | <QUIT_SHORT>)
	{quit();}
	|
	<REGISTER>
	t1 = GetPath()
	[
	<USING> t2 = GetPath()
	{ engine = t2.image; }
		[
			<AS> t3 = <IDENTIFIER>
			{namespace = t3.image; }
		]
	]
	{processRegister(unquote(t1.image), engine, namespace); }
	|
	Script()
	|
	<REMOVE>
	(
		t1 = GetPath()
		{processRemove(t1.image, null);}
	)+
	|
	<REMOVEFORCE>
	(
		t1 = GetPath()
		{processRemove(t1.image, "force");}
	)+
	|
	<SCRIPT_DONE>
	{quit();}
	|
	<SET>
	(
		t1 = GetKey()
		t2 = GetValue()
		{processSet(t1.image, unquote(t2.image));}
    	|
		{processSet();}
	)
	|
    <PIGDEFAULT>
	t1 = GetKey()
	t2 = GetDefaultValue()
	{processDefault(t1.image, t2.image);}
	|
	<DECLARE>
	t1 = GetKey()
	t2 = GetDefaultValue()
	{processDeclare(t1.image, t2.image);}
	|
	<EOF>
	{quit();}
	|
	<SEMICOLON>
	{}
	|
	// handle invalid token
	handle_invalid_command(EOL)
	{prompt();}
	)
}

void Clear():
{
}
{
	<CLEAR>
	{printClear();}
}

void Illustrate() throws IOException:
{
	Token t;
	String alias = null;
        String script = null;
	String target=null;
	ArrayList<String> params;
	ArrayList<String> files;

}
{
	(<ILLUSTRATE> | <ILLUSTRATE_SHORT>)
	{
		params = new ArrayList<String>();
		files = new ArrayList<String>();
	}
	(
		<OUT>
		t = GetPath()
		{target = t.image;}
		|
		<SCRIPT>
		t = GetPath()
		{script = t.image;}
		|
		<PARAM>
		t = GetPath()
		{params.add(t.image);}
		|
		<PARAM_FILE>
		t = GetPath()
		{files.add(t.image);}
	)*
	(
		(t = <IDENTIFIER>
                | t = <PREVREL>)
		{alias = t.image;}
	)?
	{processIllustrate(alias, script, target, params, files);}
}

void History():
{
	boolean withNumbers = true;
}
{
	<HISTORY>
	(
		<N>
        {withNumbers = false;}
	)?
	{processHistory(withNumbers);}
}

void Explain() throws IOException:
{
	Token t;
	String alias = null;
        String script = null;
	String format="text";
	String target=null;
	boolean isVerbose = true;
	ArrayList<String> params;
	ArrayList<String> files;

}
{
	(<EXPLAIN> | <EXPLAIN_SHORT>)
	{
		params = new ArrayList<String>();
		files = new ArrayList<String>();
	}
	(
		<BRIEF>
		{isVerbose = false;}
         	|
         	<DOT>
        	{format = "dot";}
         	|
         	<XML>
         	{format = "xml";}
         	|
		<OUT>
		t = GetPath()
		{target = t.image;}
		|
		<SCRIPT>
		t = GetPath()
		{script = t.image;}
		|
		<PARAM>
		t = GetPath()
		{params.add(t.image);}
		|
		<PARAM_FILE>
		t = GetPath()
		{files.add(t.image);}
	)*
	(
		(t = <IDENTIFIER>
                | t = <PREVREL>)
		{alias = t.image;}
	)?
	{processExplain(alias, script, isVerbose, format, target, params, files);}
}

void Script() throws IOException:
{
    Token t;
    String script = null;
    boolean batch = false;
    ArrayList<String> params;
    ArrayList<String> files;
}
{
	(
 		<RUN>
		{batch = false;}
	|
		<EXEC>
		{batch = true;}
	)
    	{
		params = new ArrayList<String>();
		files = new ArrayList<String>();
	}
	(
		<PARAM>
		t = GetPath()
		{params.add(t.image);}
	|
		<PARAM_FILE>
		t = GetPath()
		{files.add(t.image);}
	)*
	(
		t = GetPath()
		{script = t.image;}
	)?
	{processScript(script, batch, params, files);}
}

Token GetPath() :
{
	Token t;
}
{
	(
	t = <IDENTIFIER>
	|
	t = <PATH>
	|
	t = GetReserved()
	)
	{return t;}
}

Token GetKey() :
{
	Token t;
}
{
	t = GetPath()
	{return t;}
}

Token GetValue() :
{
	Token t;
}
{
	(
	t = GetPath()
	|
	t = <QUOTEDSTRING>
	)

	{return t;}
}

Token GetDefaultValue() :
{
	Token t;
}
{
	(
	t = GetPath()
	|
	t = <QUOTEDSTRING>
	|
	t = <SHELLCMD>
	)

	{return t;}
}

Token GetReserved () :
{
	Token t;
}
{
	(
	t = <CAT>
	|
	t = <CD>
	|
	t = <CLEAR>
	|
	t = <COPY>
	|
	t = <COPYFROMLOCAL>
	|
	t = <COPYTOLOCAL>
	|
	t = <DUMP>
	|
	t = <DUMP_SHORT>
	|
	t = <DESCRIBE>
	|
	t = <DESCRIBE_SHORT>
	|
	t = <ALIASES>
	|
	t = <EXPLAIN>
	|
	t = <EXPLAIN_SHORT>
	|
	t = <ILLUSTRATE>
	|
	t = <ILLUSTRATE_SHORT>
	|
	t = <HELP>
	|
	t = <HISTORY>
	|
	t = <KILL>
	|
	t = <LS>
	|
	t = <MOVE>
	|
	t = <MKDIR>
	|
	t = <PWD>
	|
	t = <QUIT>
	|
	t = <QUIT_SHORT>
	|
	t = <REGISTER>
	|
	t = <USING>
	|
	t = <AS>
	|
	t = <REMOVE>
	|
	t = <SET>
	|
	t = <SCRIPT_DONE>
	|
	t = <RUN>
	|
	t = <EXEC>
	)

	{return t;}
}

JAVACODE
void handle_invalid_command(int kind)
{
	throw generateParseException();  // throw the exception object.
}
