/*
 * 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;
  // DEBUG_PARSER = 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.
}
