All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.javaparser.javaccimpl.ParserImpl.jj Maven / Gradle / Ivy

The newest version!
/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. ParserImpl.jj */
/*@egen*/
//-------- JavaCC and JJTree options --------

options
{
	// Create nonstatic parser for thread-safeness.
	static	= false;

	// Allow unicode tokens
	java_unicode_escape	= true;

	                                
	     	       

	                                                                
	           	     

	                                                      
	                	        

	                                                                             
	                	       
}


//-------- Predefined parser code --------

PARSER_BEGIN(ParserImpl)

package jadex.javaparser.javaccimpl;

import jadex.common.SReflect;
import java.util.Map;
import java.util.ArrayList;


/**
 *  The Jadex parser parses all types of expressions in ADF and queries.
 */
class ParserImpl/*@bgen(jjtree)*/implements ParserImplTreeConstants/*@egen*/
{/*@bgen(jjtree)*/
  protected JJTParserImplState jjtree = new JJTParserImplState();

/*@egen*/
	//-------- constants --------

	/** The class not found identifier. */
	protected static Object	NOTFOUND	= new Object(); 

	//-------- attributes --------

	/** The imports. */
	protected String[]	imports;

	/** The local parameters (name->type). */
	protected Map	params;
	
	/** The class loader. */
	protected ClassLoader classloader;

	//-------- attribute accessors --------

	/**
	 *  Set the imports (comma separated packages).
	 *  @param imports	The imports.
	 */
	protected void	setImports(String[] imports)
	{
		this.imports	= imports;
	}

	/**
	 *  Get the imports (comma separated packages).
	 *  @return	The imports.
	 */
	protected String[]	getImports()
	{
		return this.imports;
	}

	/**
	 *  Set the parameters.
	 */
	protected void	setParameters(Map params)
	{
		this.params	= params;
	}
	
	/**
	 *  Set the classloader.
	 *  @param classloader The classloader.
	 */
	protected void	setClassLoader(ClassLoader classloader)
	{
		this.classloader = classloader;
	}
	
	/**
	 *  Get the classloader.
	 *  @return	The classloader.
	 */
	protected ClassLoader getClassLoader()
	{
		return this.classloader;
	}

	//-------- helper methods --------

	/**
	 *  Find a class using imports.
	 *  @param name	The class name.
	 *  @return The class, or null if not found.
	 */
	protected Class	findClass0(String name)
	{
		return SReflect.findClass0(name, imports, classloader);
	}

	/**
	 *  Find a class using imports.
	 *  @param name	The class name.
	 *  @return The class.
	 *  @throws ClassNotFoundException when the class is not found in the imports.
	 */
	protected Class	findClass(String name) throws ClassNotFoundException
	{
		return SReflect.findClass(name, imports, classloader);
	}

	/**
	 *  Check if an inner class exists.
	 *  @param outer	The outer class.
	 *  @param inner	The name of the inner class.
	 *  @return The inner class, or null if not found.
	 */
	protected Class	getInnerClass(Class outer, String inner)
	{
		return SReflect.classForName0(outer.getName()+"$"+inner, classloader);
	}

	/**
	 *  Check if a token is an identifier.
	 *  Needed, because the extension keywords
	 *  (like SELECT, ALL etc.) may occur as identifier
	 *  (e.g. java.util.logging.Level.ALL).
	 */
	protected boolean	isIdentifier(Token token)
	{
		return token.kind==IDENTIFIER
			|| token.kind==SELECT
			|| token.kind==ALL
			|| token.kind==ANY
			|| token.kind==ONE
			|| token.kind==IOTA
			|| token.kind==FROM
			|| token.kind==IN
			|| token.kind==WHERE
			|| token.kind==ORDER
			|| token.kind==BY
			|| token.kind==ASC
			|| token.kind==DESC;
 	}

	/**
	 *  Unescape a string.
	 */
   	protected String        unescape(String str)
    {
    	StringBuffer	buf	= new StringBuffer(str);
    	int	idx	= buf.indexOf("\\");
    	while(idx!=-1 && buf.length()>idx+1)
    	{
    		if(buf.charAt(idx+1)=='b')
    			buf.replace(idx, idx+2, "\b");
    		else if(buf.charAt(idx+1)=='t')
    			buf.replace(idx, idx+2, "\t");
    		else if(buf.charAt(idx+1)=='n')
    			buf.replace(idx, idx+2, "\n");
    		else if(buf.charAt(idx+1)=='f')
    			buf.replace(idx, idx+2, "\f");
    		else if(buf.charAt(idx+1)=='r')
    			buf.replace(idx, idx+2, "\r");
    		else if(buf.charAt(idx+1)=='"')
    			buf.replace(idx, idx+2, "\"");
    		else if(buf.charAt(idx+1)=='\'')
    			buf.replace(idx, idx+2, "'");
    		else if(buf.charAt(idx+1)=='\\')
    			buf.replace(idx, idx+2, "\\");
    		
        	idx	= buf.indexOf("\\", idx+1);
    	}

       // Todo: escape octal codes.
       return buf.toString();
    }

	/**
	 *  Peek to some non-top node.
	 */
	public Node	peekNode(JJTParserImplState jjtree, int i)
	{
		Node	ret;
		if(i>0)
		{
			Node[]	stack	= new Node[i];
			for(int s=i-1; s>=0; s--)
				stack[s]	= jjtree.popNode();
			ret	= jjtree.peekNode();
			for(Node n: stack)
				jjtree.pushNode(n);
		}
		else if(i==0)
		{
			ret	= jjtree.peekNode();
		}
		else
		{
			throw new IndexOutOfBoundsException(""+i);
		}
		return ret;
	}
}
PARSER_END(ParserImpl)


//******** Grammar starts here ********


//-------- Tokens --------

// Whitespaces
SKIP:
{
	" "
|	"\t"
|	"\n"
|	"\r"
|	"\f"
}

// Comments.
SPECIAL_TOKEN:
{
	// "//" followed by arbitrary characters (except \n, \r) and then \r or \n.
	

	// ???
|	
}

// Reserved Words
TOKEN:
{
	
|	
}

// Case insensitive tokens.
TOKEN[IGNORE_CASE]:
{
	< SELECT: "select" >
|	< ALL: "all" >
|	< ANY: "any" >
|	< ONE: "one" >
|	< IOTA: "iota" >
|	< FROM: "from" >
|	< IN: "in" >
|	< WHERE: "where" >
|	< ORDER: "order" >
|	< BY: "by" >
|	< ASC: "asc" >
|	< DESC: "desc" >
}

// Basic types
TOKEN:
{
	
|	
|	
|	
|	
|	
|	
|	
}

// Predefined literals
TOKEN:
{
	
|	
|	
}

// Literals
TOKEN:
{
	// Integer may be decimal, hex, or octal.
	 (["l","L"])?
		|  (["l","L"])?
		|  (["l","L"])?
	>
|	<#DECIMAL_LITERAL: ("0") | (["1"-"9"] (["0"-"9"])*) >
|	<#HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
|	<#OCTAL_LITERAL: "0" (["1"-"9"]) (["0"-"7"])* >

	// Float (may have exponent).
|	)? (["f","F","d","D"])?
		| "." (["0"-"9"])+ ()? (["f","F","d","D"])?
		| (["0"-"9"])+  (["f","F","d","D"])?
		| (["0"-"9"])+ ()? ["f","F","d","D"]
	>
|	<#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >

	// Character (contained in single quotes).
|	

	// String (contained in double quotes).
|	
}

// "?" used in conditional and for clips variable identifiers
TOKEN:
{
	
}


// Identifiers (have to start with letter).
TOKEN:
{
	)?  (|)* >

	// Allowed characters for LETTER.
|	<#LETTER:[
		"$",
		"A"-"Z",
		"_",
		"a"-"z",
		"\u00c0"-"\u00d6",
		"\u00d8"-"\u00f6",
		"\u00f8"-"\u00ff",
		"\u0100"-"\u1fff",
		"\u3040"-"\u318f",
		"\u3300"-"\u337f",
		"\u3400"-"\u3d2d",
		"\u4e00"-"\u9fff",
		"\uf900"-"\ufaff"
	]>

/*	 (|)* >

	// Allowed characters for LETTER without "$".
|	<#LETTERNOTDOLLAR:[
//		"$",	// $
		"A"-"Z",
		"_",
		"a"-"z",
		"\u00c0"-"\u00d6",
		"\u00d8"-"\u00f6",
		"\u00f8"-"\u00ff",
		"\u0100"-"\u1fff",
		"\u3040"-"\u318f",
		"\u3300"-"\u337f",
		"\u3400"-"\u3d2d",
		"\u4e00"-"\u9fff",
		"\uf900"-"\ufaff"
	]>
*/

	// Allowed characters for DIGIT.
|	<#DIGIT:[
		"0"-"9",
		"\u0660"-"\u0669",
		"\u06f0"-"\u06f9",
		"\u0966"-"\u096f",
		"\u09e6"-"\u09ef",
		"\u0a66"-"\u0a6f",
		"\u0ae6"-"\u0aef",
		"\u0b66"-"\u0b6f",
		"\u0be7"-"\u0bef",
		"\u0c66"-"\u0c6f",
		"\u0ce6"-"\u0cef",
		"\u0d66"-"\u0d6f",
		"\u0e50"-"\u0e59",
		"\u0ed0"-"\u0ed9",
		"\u1040"-"\u1049"
	]>
}


// Separators.
TOKEN:
{
	< LPAREN: "(" >
|	< RPAREN: ")" >
|	< LBRACE: "{" >
|	< RBRACE: "}" >
|	< LBRACKET: "[" >
|	< RBRACKET: "]" >
|	< SEMICOLON: ";" >
|	< COMMA: "," >
|	< DOT: "." >
}

/*
TOKEN : /* OPERATORS * /
{
  < GT: ">" >
| < LT: "<" >
| < BANG: "!" >
| < TILDE: "~" >
| < HOOK: "?" >
| < COLON: ":" >
| < EQ: "==" >
| < LE: "<=" >
| < GE: ">=" >
| < NE: "!=" >
| < SC_OR: "||" >
| < SC_AND: "&&" >
| < INCR: "++" >
| < DECR: "--" >
| < PLUS: "+" >
| < MINUS: "-" >
| < STAR: "*" >
| < SLASH: "/" >
| < BIT_AND: "&" >
| < BIT_OR: "|" >
| < XOR: "^" >
| < REM: "%" >
| < LSHIFT: "<<" >
| < RSIGNEDSHIFT: ">>" >
| < RUNSIGNEDSHIFT: ">>>" >
}
*/

//-------- Grammer rules --------

/**
 *  Parse the supplied expression.
 *  @return The root node of the generated tree.
 */
ExpressionNode parseExpression()       :
{}
{
	// Expect a single expression, without trailing characters.
	Expression() 
	{
		// Return the root of the generated tree.
		return (ExpressionNode)jjtree.rootNode();
	}
}

/**
 *  Parse the supplied type expression.
 *  @return The class given by the type expression.
 */
Class parseType()       :
{}
{
	// Expect a single type expression, without trailing characters.
	Type() 
	{
		// Return the value of the type expression.
		return (Class)((TypeNode)jjtree.rootNode()).getValue(null);
	}
}

/**
 *  The start rule.
 *  All other rules are invoked by this rule,
 *  and may recursively reinvoke this rule.
 */
void Expression()       :
{}
{
	// Start with the expression with the least precedence.
	// This is done to create an expression tree conforming
	// to operator precedence:
	// Rules with higher precedence will create subnodes
	// of nodes create by rules with lower precedence.

	// For select tokens, we have to check, if its a select-statement,
	// or just a class or package name (e.g. Select.func(x,y)).
	LOOKAHEAD(
		[
			  LOOKAHEAD(, {getToken(2).kind != DOT})	t1=
			| LOOKAHEAD(, {getToken(2).kind != DOT})	t1=
			| LOOKAHEAD(, {getToken(2).kind != DOT})	t1=
			| LOOKAHEAD(, {getToken(2).kind != DOT})	t1= 
		]
		(LOOKAHEAD(ConditionalExpression()  [Type()] t2=Identifier() )
		(ConditionalExpression()
			
				(LOOKAHEAD(Type() Identifier())	(Type() t2=Identifier()) | t2=Identifier())
				 ConditionalExpression()
			{vars.add(t2);}
			(
				LOOKAHEAD("," [Type()] Identifier() )
				("," [Type()] t2=Identifier()  ConditionalExpression())
				{vars.add(t2);}
			)*
		)
		// Shortcut "SELECT  FROM ".
		|((/*@bgen(jjtree) #ParameterNode(true) */
                   {
                     ParameterNode jjtn001 = new ParameterNode(this, JJTPARAMETERNODE);
                     boolean jjtc001 = true;
                     jjtree.openNodeScope(jjtn001);
                   }
                   try {
/*@egen*/(LOOKAHEAD(Type() Identifier())	(Type() t2=Identifier()) | t2=Identifier())/*@bgen(jjtree)*/
                   } catch (Throwable jjte001) {
                     if (jjtc001) {
                       jjtree.clearNodeScope(jjtn001);
                       jjtc001 = false;
                     } else {
                       jjtree.popNode();
                     }
                     if (jjte001 instanceof RuntimeException) {
                       throw (RuntimeException)jjte001;
                     }
                     if (jjte001 instanceof ParseException) {
                       throw (ParseException)jjte001;
                     }
                     throw (Error)jjte001;
                   } finally {
                     if (jjtc001) {
                       jjtree.closeNodeScope(jjtn001, true);
                     }
                   }
/*@egen*/                 
			{
				((ExpressionNode)jjtree.peekNode()).setText(t2);
				vars.add(t2);
			}
			 ConditionalExpression())
		))
		[ t3=	ConditionalExpression() ]
		[ t4= 	ConditionalExpression() [ t5= | t5= ] ]
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte002) {
          if (jjtc002) {
            jjtree.clearNodeScope(jjtn002);
            jjtc002 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte002 instanceof RuntimeException) {
            throw (RuntimeException)jjte002;
          }
          if (jjte002 instanceof ParseException) {
            throw (ParseException)jjte002;
          }
          throw (Error)jjte002;
        } finally {
          if (jjtc002) {
            jjtree.closeNodeScope(jjtn002, jjtree.nodeArity() > 1);
          }
        }
/*@egen*/                
	{
		// Set node properties.
		if(t1!=null)	((SelectNode)jjtree.peekNode()).setText(t1.kind==ONE ? "any" : t1.image);
		((SelectNode)jjtree.peekNode()).setVariables((String[])vars.toArray(new String[vars.size()]));
		if(t3!=null)	((SelectNode)jjtree.peekNode()).setWhere(true);
		if(t4!=null)	((SelectNode)jjtree.peekNode()).setOrderBy(true);
		if(t5!=null)	((SelectNode)jjtree.peekNode()).setOrder(t5.image);
	}
}

/**
 *  The conditional expression (bool ? exp1 : exp2).
 *  Creates ConditionalNode if present (not yet implemented).
 */
void ConditionalExpression()       :
{}
{/*@bgen(jjtree) #ConditionalNode(> 1) */
        {
          ConditionalNode jjtn001 = new ConditionalNode(this, JJTCONDITIONALNODE);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*/
	( ConditionalOrExpression() [  ConditionalExpression() ":" ConditionalExpression() ]
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte001) {
          if (jjtc001) {
            jjtree.clearNodeScope(jjtn001);
            jjtc001 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte001 instanceof RuntimeException) {
            throw (RuntimeException)jjte001;
          }
          if (jjte001 instanceof ParseException) {
            throw (ParseException)jjte001;
          }
          throw (Error)jjte001;
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1);
          }
        }
/*@egen*/                     
}

/**
 *  Or expression.
 *  If present, creates BooleanNode with arbitrary number of subnodes.
 */
void ConditionalOrExpression()       :
{	Token t	= null; }	// Declare local variable.
{/*@bgen(jjtree) #BooleanNode(> 1) */
        {
          BooleanNode jjtn001 = new BooleanNode(this, JJTBOOLEANNODE);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*/
	( ConditionalAndExpression() ( t="||" ConditionalAndExpression() )*
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte001) {
          if (jjtc001) {
            jjtree.clearNodeScope(jjtn001);
            jjtc001 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte001 instanceof RuntimeException) {
            throw (RuntimeException)jjte001;
          }
          if (jjte001 instanceof ParseException) {
            throw (ParseException)jjte001;
          }
          throw (Error)jjte001;
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1);
          }
        }
/*@egen*/                 
	{
		// When token is set, node was created.
		// Set node text to specify boolean operation.
		if(t!=null)	((ExpressionNode)jjtree.peekNode()).setText("||");
	}
}

/**
 *  And expression.
 *  If present, creates BooleanNode with arbitrary number of subnodes.
 */
void ConditionalAndExpression()       :
{	Token t	= null; }	// Declare local variable.
{/*@bgen(jjtree) #BooleanNode(> 1) */
        {
          BooleanNode jjtn001 = new BooleanNode(this, JJTBOOLEANNODE);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*/
	( InclusiveOrExpression() ( t="&&" InclusiveOrExpression() )*
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte001) {
          if (jjtc001) {
            jjtree.clearNodeScope(jjtn001);
            jjtc001 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte001 instanceof RuntimeException) {
            throw (RuntimeException)jjte001;
          }
          if (jjte001 instanceof ParseException) {
            throw (ParseException)jjte001;
          }
          throw (Error)jjte001;
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1);
          }
        }
/*@egen*/                 
	{
		// When token is set, node was created.
		// Set node text to specify boolean operation.
		if(t!=null)	((ExpressionNode)jjtree.peekNode()).setText("&&");
	}
}

/**
 *  Bitwise Or expression (|).
 *  If present, creates MathNode(s) with two subnodes.
 */
void InclusiveOrExpression()       :
{}
{
	ExclusiveOrExpression()
	(/*@bgen(jjtree) #MathNode( 2) */
                {
                  MathNode jjtn001 = new MathNode(this, JJTMATHNODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/
		( ( "|" ExclusiveOrExpression() )
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001,  2);
                  }
                }
/*@egen*/             
		{
			// Set node text to specify math operation.
			((ExpressionNode)jjtree.peekNode()).setText("|");
		}
	)*
}

/**
 *  Bitwise XOr expression (^).
 *  If present, creates MathNode(s) with two subnodes.
 */
void ExclusiveOrExpression()       :
{}
{
	AndExpression()
	(/*@bgen(jjtree) #MathNode( 2) */
                {
                  MathNode jjtn001 = new MathNode(this, JJTMATHNODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/
		( ( "^" AndExpression() )
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001,  2);
                  }
                }
/*@egen*/             
		{
			// Set node text to specify math operation.
			((ExpressionNode)jjtree.peekNode()).setText("^");
		}
	)*
}

/**
 *  Bitwise And expression (&).
 *  If present, creates MathNode(s) with two subnodes.
 */
void AndExpression()       :
{}
{
	EqualityExpression()
	(/*@bgen(jjtree) #MathNode( 2) */
                {
                  MathNode jjtn001 = new MathNode(this, JJTMATHNODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/
		( ( "&" EqualityExpression() )
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001,  2);
                  }
                }
/*@egen*/             
		{
			// Set node text to specify math operation.
			((ExpressionNode)jjtree.peekNode()).setText("&");
		}
	)*
}

/**
 *  Test for (un)equality.
 *  If present, creates CompareNode(s) with two subnodes.
 */
void EqualityExpression()       :
{	Token	t; }	// Declare local variable.
{
	InstanceOfExpression()
	(/*@bgen(jjtree) #CompareNode( 2) */
                {
                  CompareNode jjtn001 = new CompareNode(this, JJTCOMPARENODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/
		( ( t="==" | t="!=" ) InstanceOfExpression()
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001,  2);
                  }
                }
/*@egen*/                
		{
			// Set node text to specify compare operation.
			((ExpressionNode)jjtree.peekNode()).setText(t.image);
		}
	)*
}

/**
 *  Instance of operator.
 *  If present, creates CompareNode with two subnodes.
 */
void InstanceOfExpression()       :
{}
{
	RelationalExpression()
	(/*@bgen(jjtree) #CompareNode( 2) */
                {
                  CompareNode jjtn001 = new CompareNode(this, JJTCOMPARENODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/
		( "instanceof" Type()
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001,  2);
                  }
                }
/*@egen*/                
		{
			// Set node text to specify compare operation.
			((ExpressionNode)jjtree.peekNode()).setText("instanceof");
		}
	)?
}

/**
 *  Comparison expression
 *  If present, creates CompareNode(s) with two subnodes.
 */
void RelationalExpression()       :
{	Token	t; }	// Declare local variable.
{
	ShiftExpression()
	(/*@bgen(jjtree) #CompareNode( 2) */
                {
                  CompareNode jjtn001 = new CompareNode(this, JJTCOMPARENODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/
		( ( t="<" | t=">" | t="<=" | t=">=" ) ShiftExpression()
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001,  2);
                  }
                }
/*@egen*/                
		{
			// Set node text to specify compare operation.
			((ExpressionNode)jjtree.peekNode()).setText(t.image);
		}
	)*
}

/**
 *  Shift operation.
 *  If present, creates MathNode(s) with two subnodes.
 */
void ShiftExpression()       :
{	String	exp; }	// Declare local variable.
{
	AdditiveExpression()
	(
		LOOKAHEAD(2)/*@bgen(jjtree) #MathNode( 2) */
                {
                  MathNode jjtn001 = new MathNode(this, JJTMATHNODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/ 
		( ( "<<" {exp="<<";} | LOOKAHEAD(3) RUNSIGNEDSHIFT() {exp=">>>";} | RSIGNEDSHIFT() {exp=">>";} ) AdditiveExpression()
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001,  2);
                  }
                }
/*@egen*/             
		{
			// Set node text to specify math operation.
			((ExpressionNode)jjtree.peekNode()).setText(exp);
		}
	)*
}

/* We use productions to match >>>, >> and > so that we can keep the
* type declaration syntax with generics clean
*/
void RUNSIGNEDSHIFT()      :
{}
{
	( ">" ">" ">" )
}
void RSIGNEDSHIFT()      :
{}
{
	( ">" ">" )
}

/**
 *  Additive operation.
 *  If present, creates MathNode(s) with two subnodes.
 */
void AdditiveExpression()       :
{	Token	t; }	// Declare local variable.
{
	MultiplicativeExpression()
	(/*@bgen(jjtree) #MathNode( 2) */
                {
                  MathNode jjtn001 = new MathNode(this, JJTMATHNODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/
		( ( t="+" | t="-" ) MultiplicativeExpression()
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001,  2);
                  }
                }
/*@egen*/             
		{
			// Set node text to specify math operation.
			((ExpressionNode)jjtree.peekNode()).setText(t.image);
		}
	)*
}

/**
 *  Multiplicative operation.
 *  If present, creates MathNode(s) with two subnodes.
 */
void MultiplicativeExpression()       :
{	Token	t; }	// Declare local variable.
{
	UnaryExpression()
	(/*@bgen(jjtree) #MathNode( 2) */
                {
                  MathNode jjtn001 = new MathNode(this, JJTMATHNODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/
		( ( t="*" | t="/" | t="%" ) UnaryExpression()
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001,  2);
                  }
                }
/*@egen*/             
		{
			// Set node text to specify math operation.
			((ExpressionNode)jjtree.peekNode()).setText(t.image);
		}
	)*
}

/**
 *  Unary math operation.
 *  If present, creates MathNode with single subnode.
 */
void UnaryExpression()       :
{	Token	t; }	// Declare local variable.
{/*@bgen(jjtree) #MathNode( 1) */
        {
          MathNode jjtn001 = new MathNode(this, JJTMATHNODE);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*/
	( ( t="+" | t="-" ) UnaryExpression()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte001) {
          if (jjtc001) {
            jjtree.clearNodeScope(jjtn001);
            jjtc001 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte001 instanceof RuntimeException) {
            throw (RuntimeException)jjte001;
          }
          if (jjte001 instanceof ParseException) {
            throw (ParseException)jjte001;
          }
          throw (Error)jjte001;
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001,  1);
          }
        }
/*@egen*/             
	{
		// Set node text to specify compare operation.
		((ExpressionNode)jjtree.peekNode()).setText(t.image);
	}
|	UnaryExpressionNotPlusMinus()
}

/**
 *  Logical or bitwise Not operator.
 *  If present, creates BooleanNode or MathNode with single subnode.
 *  Otherwise goes on with cast or primary expression.
 */
void UnaryExpressionNotPlusMinus()       :
{}
{/*@bgen(jjtree) #BooleanNode( 1) */
        {
          BooleanNode jjtn001 = new BooleanNode(this, JJTBOOLEANNODE);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*/
	( ( "!" ) UnaryExpression()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte001) {
          if (jjtc001) {
            jjtree.clearNodeScope(jjtn001);
            jjtc001 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte001 instanceof RuntimeException) {
            throw (RuntimeException)jjte001;
          }
          if (jjte001 instanceof ParseException) {
            throw (ParseException)jjte001;
          }
          throw (Error)jjte001;
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001,  1);
          }
        }
/*@egen*/                
	{
		// Set node text to specify boolean operation.
		((ExpressionNode)jjtree.peekNode()).setText("!");
	}
|/*@bgen(jjtree) #MathNode( 1) */
        {
          MathNode jjtn002 = new MathNode(this, JJTMATHNODE);
          boolean jjtc002 = true;
          jjtree.openNodeScope(jjtn002);
        }
        try {
/*@egen*/	( ( "~" ) UnaryExpression()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte002) {
          if (jjtc002) {
            jjtree.clearNodeScope(jjtn002);
            jjtc002 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte002 instanceof RuntimeException) {
            throw (RuntimeException)jjte002;
          }
          if (jjte002 instanceof ParseException) {
            throw (ParseException)jjte002;
          }
          throw (Error)jjte002;
        } finally {
          if (jjtc002) {
            jjtree.closeNodeScope(jjtn002,  1);
          }
        }
/*@egen*/             
	{
		// Set node text to specify matz operation.
		((ExpressionNode)jjtree.peekNode()).setText("~");
	}

	// Use lookahead to distinguish "(" type ")" vs. "(" expression ")".
|	LOOKAHEAD( "(" Type() ")" )
	CastExpression()

|	PrimaryExpression()
}

/**
 *  A cast node changes the static type of an unary expression,
 *  but does not affect the value.
 *  Creates a cast node having as child the type node and the unary expression.
 */
void CastExpression()           :
{/*@bgen(jjtree) CastNode */
  CastNode jjtn000 = new CastNode(this, JJTCASTNODE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) CastNode */
        try {
/*@egen*/
	"(" Type() ")" UnaryExpression()/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

/**
 *  The basic form of an object expression.
 *  Consists of statement for initial object value (primary prefix)
 *  e.g., a constructor invocation.
 *  The prefix may be followed by an arbitrary number
 *  of subsequent operations (primary suffix)
 *  e.g., a method invocation or field access.
 */
void PrimaryExpression()       :
{}
{
	PrimaryPrefix()	( PrimarySuffix() )*
}

/**
 *  The expression for initial values i.e.,
 *  the leaves of every expression.
 *  Creates a single node representing the value,
 *  which may be a literal, parameter, constructor or static method invocation,
 *  field access, or array creation.
 *  For parsing braces, expressions like "(" expression ")" are also
 *  represented as primary prefix.
 */
void PrimaryPrefix()       :
{ String t=null; Token lit=null; }
{
	Literal()
|	"(" Expression() ")"

	// Context method
//|	LOOKAHEAD("@" Identifier() "(")
//	( "@" t=Identifier() Arguments()
//	) #ReflectNode(1)
//	{
//		((ReflectNode)jjtree.peekNode()).setText(t);
//		((ReflectNode)jjtree.peekNode()).setType(ReflectNode.CONTEXT_METHOD);
//	}

	// Context field
//|	( "@" t=Identifier()
//	) #ReflectNode(0)
//	{
//		((ReflectNode)jjtree.peekNode()).setText(t);
//		((ReflectNode)jjtree.peekNode()).setType(ReflectNode.CONTEXT_FIELD);
//	}
	// Constructor.
|	LOOKAHEAD("new" Name() [ TypeArguments() ] "(")/*@bgen(jjtree) #ReflectNode( 2) */
        {
          ReflectNode jjtn001 = new ReflectNode(this, JJTREFLECTNODE);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*/
	( "new" Name() [ TypeArguments() ] Arguments()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte001) {
          if (jjtc001) {
            jjtree.clearNodeScope(jjtn001);
            jjtc001 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte001 instanceof RuntimeException) {
            throw (RuntimeException)jjte001;
          }
          if (jjte001 instanceof ParseException) {
            throw (ParseException)jjte001;
          }
          throw (Error)jjte001;
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001,  2);
          }
        }
/*@egen*/                
	{ ((ReflectNode)jjtree.peekNode()).setType(ReflectNode.CONSTRUCTOR); }

|	ArrayExpression()

	// Static method (have to use semantic lookahead, hack???)
|	LOOKAHEAD({lookaheadStaticMethod()})/*@bgen(jjtree) #ReflectNode( 2) */
        {
          ReflectNode jjtn002 = new ReflectNode(this, JJTREFLECTNODE);
          boolean jjtc002 = true;
          jjtree.openNodeScope(jjtn002);
        }
        try {
/*@egen*/
	( Name() "." t=Identifier() Arguments()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte002) {
          if (jjtc002) {
            jjtree.clearNodeScope(jjtn002);
            jjtc002 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte002 instanceof RuntimeException) {
            throw (RuntimeException)jjte002;
          }
          if (jjte002 instanceof ParseException) {
            throw (ParseException)jjte002;
          }
          throw (Error)jjte002;
        } finally {
          if (jjtc002) {
            jjtree.closeNodeScope(jjtn002,  2);
          }
        }
/*@egen*/                
	{
		((ReflectNode)jjtree.peekNode()).setText(t);
		((ReflectNode)jjtree.peekNode()).setType(ReflectNode.STATIC_METHOD);
	}

	// Static field (allow primitive or array for .class "field")
|	LOOKAHEAD( Type() )/*@bgen(jjtree) #ReflectNode( 1) */
        {
          ReflectNode jjtn003 = new ReflectNode(this, JJTREFLECTNODE);
          boolean jjtc003 = true;
          jjtree.openNodeScope(jjtn003);
        }
        try {
/*@egen*/
	( ( Type() ) "." t=Identifier()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte003) {
          if (jjtc003) {
            jjtree.clearNodeScope(jjtn003);
            jjtc003 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte003 instanceof RuntimeException) {
            throw (RuntimeException)jjte003;
          }
          if (jjte003 instanceof ParseException) {
            throw (ParseException)jjte003;
          }
          throw (Error)jjte003;
        } finally {
          if (jjtc003) {
            jjtree.closeNodeScope(jjtn003,  1);
          }
        }
/*@egen*/                
	{
		((ReflectNode)jjtree.peekNode()).setText(t);
		((ReflectNode)jjtree.peekNode()).setType(ReflectNode.STATIC_FIELD);
	}
	
	// Parameter[-x] for preconditions.
	| LOOKAHEAD(4)/*@bgen(jjtree) #ParameterNode(true) */
        {
          ParameterNode jjtn004 = new ParameterNode(this, JJTPARAMETERNODE);
          boolean jjtc004 = true;
          jjtree.openNodeScope(jjtn004);
        }
        try {
/*@egen*/
	( t=Identifier() "[" "-" lit= "]"
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte004) {
          if (jjtc004) {
            jjtree.clearNodeScope(jjtn004);
            jjtc004 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte004 instanceof RuntimeException) {
            throw (RuntimeException)jjte004;
          }
          if (jjte004 instanceof ParseException) {
            throw (ParseException)jjte004;
          }
          throw (Error)jjte004;
        } finally {
          if (jjtc004) {
            jjtree.closeNodeScope(jjtn004, true);
          }
        }
/*@egen*/                 
	{ ((ExpressionNode)jjtree.peekNode()).setText(t+"[-"+lit+"]");}
	
	// Parameter.
|/*@bgen(jjtree) #ParameterNode(true) */
        {
          ParameterNode jjtn005 = new ParameterNode(this, JJTPARAMETERNODE);
          boolean jjtc005 = true;
          jjtree.openNodeScope(jjtn005);
        }
        try {
/*@egen*/	//LOOKAHEAD({params!=null && params.containsKey(getToken(1).image)})
	( t=Identifier()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte005) {
          if (jjtc005) {
            jjtree.clearNodeScope(jjtn005);
            jjtc005 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte005 instanceof RuntimeException) {
            throw (RuntimeException)jjte005;
          }
          if (jjte005 instanceof ParseException) {
            throw (ParseException)jjte005;
          }
          throw (Error)jjte005;
        } finally {
          if (jjtc005) {
            jjtree.closeNodeScope(jjtn005, true);
          }
        }
/*@egen*/                 
	{ ((ExpressionNode)jjtree.peekNode()).setText(t);}

}

/**
 *  Method to lookahead for a class name.
 */
boolean	classname()       :
{}
{{
	// Starts with name.
	String	name	= null;
	int	next	= 1;
	boolean	havename	= false;

	if(isIdentifier(getToken(next)))
	{
		name	= getToken(next).image;
		havename	= findClass0(name)!=null;
		next++;
	}
	else
	{
		return false;
	}

	// Append "."  while available and class not found.
	while(!havename && getToken(next).kind==DOT && isIdentifier(getToken(next+1)))
	{
		name	+= "." + getToken(next+1).image;
		havename	= findClass0(name)!=null;
		next	+= 2;
	}

	return havename;
}}

/**
 *  Method to lookahead for static methods.
 *  Expects Name() "." Identifier() "(".
 *  Syntactic lookahead doesn't work correctly in this case
 *  (don't ask me why).
 */
boolean	lookaheadStaticMethod()       :
{}
{{
	// Starts with name.
	String	name	= null;
	int	next	= 1;
	boolean	havename	= false;

	if(isIdentifier(getToken(next)))
	{
		name	= getToken(next).image;
		havename	= findClass0(name)!=null;
		next++;
	}
	else
	{
		return false;
	}

	// Append "."  while available and class not found.
	while(!havename && getToken(next).kind==DOT && isIdentifier(getToken(next+1)))
	{
		name	+= "." + getToken(next+1).image;
		havename	= findClass0(name)!=null;
		next	+= 2;
	}

	if(!havename)
	{
		return false;
	}

	// Found name, now search for "."  "(".
	return getToken(next).kind==DOT && isIdentifier(getToken(next+1))
		&& getToken(next+2).kind==LPAREN;
}}

/**
 *  Subsequent operations to perform on an initial value.
 *  Creates nodes for selection from array, method invocation, field access,
 *  or filling in of collection values.
 */
void PrimarySuffix()       :
{	String	identifier;}	// Declare local variable.
{/*@bgen(jjtree) #SelectionNode( 2) */
        {
          SelectionNode jjtn001 = new SelectionNode(this, JJTSELECTIONNODE);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*/
	// Selection from Array.
	( "[" Expression() "]"
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte001) {
          if (jjtc001) {
            jjtree.clearNodeScope(jjtn001);
            jjtc001 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte001 instanceof RuntimeException) {
            throw (RuntimeException)jjte001;
          }
          if (jjte001 instanceof ParseException) {
            throw (ParseException)jjte001;
          }
          throw (Error)jjte001;
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001,  2);
          }
        }
/*@egen*/                  

	// Nonstatic method.
|	LOOKAHEAD("." Identifier() "(")/*@bgen(jjtree) #ReflectNode( 2) */
        {
          ReflectNode jjtn002 = new ReflectNode(this, JJTREFLECTNODE);
          boolean jjtc002 = true;
          jjtree.openNodeScope(jjtn002);
        }
        try {
/*@egen*/
	( "." identifier=Identifier() Arguments()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte002) {
          if (jjtc002) {
            jjtree.clearNodeScope(jjtn002);
            jjtc002 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte002 instanceof RuntimeException) {
            throw (RuntimeException)jjte002;
          }
          if (jjte002 instanceof ParseException) {
            throw (ParseException)jjte002;
          }
          throw (Error)jjte002;
        } finally {
          if (jjtc002) {
            jjtree.closeNodeScope(jjtn002,  2);
          }
        }
/*@egen*/                
	{
		((ReflectNode)jjtree.peekNode()).setText(identifier);
		((ReflectNode)jjtree.peekNode()).setType(ReflectNode.METHOD);
	}

	// Nonstatic field.
|/*@bgen(jjtree) #ReflectNode( 1) */
        {
          ReflectNode jjtn003 = new ReflectNode(this, JJTREFLECTNODE);
          boolean jjtc003 = true;
          jjtree.openNodeScope(jjtn003);
        }
        try {
/*@egen*/	( "." identifier=Identifier()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte003) {
          if (jjtc003) {
            jjtree.clearNodeScope(jjtn003);
            jjtc003 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte003 instanceof RuntimeException) {
            throw (RuntimeException)jjte003;
          }
          if (jjte003 instanceof ParseException) {
            throw (ParseException)jjte003;
          }
          throw (Error)jjte003;
        } finally {
          if (jjtc003) {
            jjtree.closeNodeScope(jjtn003,  1);
          }
        }
/*@egen*/                
	{
		((ReflectNode)jjtree.peekNode()).setText(identifier);
		((ReflectNode)jjtree.peekNode()).setType(ReflectNode.FIELD);
	}

|/*@bgen(jjtree) #CollectionNode( 2) */
        {
          CollectionNode jjtn004 = new CollectionNode(this, JJTCOLLECTIONNODE);
          boolean jjtc004 = true;
          jjtree.openNodeScope(jjtn004);
        }
        try {
/*@egen*/	// Collection content ({val1, ...}, {key1=val1, ...})
	( CollectionContent()
	)/*@bgen(jjtree)*/
        } catch (Throwable jjte004) {
          if (jjtc004) {
            jjtree.clearNodeScope(jjtn004);
            jjtc004 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte004 instanceof RuntimeException) {
            throw (RuntimeException)jjte004;
          }
          if (jjte004 instanceof ParseException) {
            throw (ParseException)jjte004;
          }
          throw (Error)jjte004;
        } finally {
          if (jjtc004) {
            jjtree.closeNodeScope(jjtn004,  2);
          }
        }
/*@egen*/                   
}

/**
 *  A literal value.
 *  Creates a constant node, with the value filled in.
 */
// Todo: Support long, float, hex, exponents, escapes in characters, strings...
void Literal()               :
{/*@bgen(jjtree) ConstantNode */
  ConstantNode jjtn000 = new ConstantNode(this, JJTCONSTANTNODE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/ Token t=null; }
{/*@bgen(jjtree) ConstantNode */
        try {
/*@egen*/
	( t= )/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		String	string	= t.image;
		boolean	l	= false;
		int	radix	= 10;

		if(string.endsWith("l") || string.endsWith("L"))
		{
			l	= true;
			string	= string.substring(0, string.length()-1);
		}

		if(string.startsWith("0x"))
		{
			radix	= 16;
			string	= string.substring(2);
		}
		else if(string.length()>1 && string.startsWith("0"))
		{
			radix	= 8;
			string	= string.substring(1);
		}

		if(l)	
			jjtn000.setValue(Long.valueOf(string, radix));
		else
			jjtn000.setValue(Integer.valueOf(string, radix));
	}

|	( t= )/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		if(t.image.endsWith("f") || t.image.endsWith("F"))
			jjtn000.setValue(Float.valueOf(t.image.substring(0, t.image.length()-1)));
		else if(t.image.endsWith("d") || t.image.endsWith("D"))
			jjtn000.setValue(Double.valueOf(t.image.substring(0, t.image.length()-1)));
		else
			jjtn000.setValue(Double.valueOf(t.image));
	}

|	( t= )/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		// Get unescaped character between ''.
		jjtn000.setValue(Character.valueOf(unescape(
			t.image.substring(1, t.image.length()-1)).charAt(0)));
	}

|	( t= )/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		// Get string between "".
		jjtn000.setValue(unescape(t.image.substring(1, t.image.length()-1)));
	}

|	"true"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{ jjtn000.setValue(Boolean.TRUE); }

|	"false"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{ jjtn000.setValue(Boolean.FALSE); }

|	"null"/*@bgen(jjtree)*/
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
	// { jjtThis.setValue(null); }	// ;-)
}

/**
 *  Arguments of a method call or constructor invocation.
 *  Creates a single arguments node, which contains subnodes for
 *  all argument expressions.
 */
void Arguments()                :
{/*@bgen(jjtree) ArgumentsNode */
  ArgumentsNode jjtn000 = new ArgumentsNode(this, JJTARGUMENTSNODE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) ArgumentsNode */
        try {
/*@egen*/
	"("
		[ Expression() ( "," Expression() )* ]
	")"/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

/**
 *  For creating arrays with or without content.
 *  Creates an array node, with two subnodes
 *  for array type and arguments.
 */
void ArrayExpression()            :
{/*@bgen(jjtree) ArrayNode */
  ArrayNode jjtn000 = new ArrayNode(this, JJTARRAYNODE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) ArrayNode */
        try {
/*@egen*/
	// Array with content (new MyClass[]{val1, val2,...})
	LOOKAHEAD("new" ( Name() | PrimitiveType() ) [ TypeArguments() ] "[" "]")
	( "new" Type() ArrayContent()
	)/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{ jjtn000.setType(ArrayNode.ARRAY); }

|	// Array with dimensions (new MyClass[5][2])
	LOOKAHEAD("new" ( Name() | PrimitiveType() ) [ TypeArguments() ] "[")
	( "new" ( Name() | PrimitiveType() )  [ TypeArguments() ] ArrayDimensions()
	)/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{ jjtn000.setType(ArrayNode.ARRAY_DIMENSION); }/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

/**
 *  Inline content specification of an array.
 *  Creates a single arguments node, which contains subnodes for
 *  all content values.
 */
void ArrayContent()                :
{/*@bgen(jjtree) ArgumentsNode */
  ArgumentsNode jjtn000 = new ArgumentsNode(this, JJTARGUMENTSNODE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) ArgumentsNode */
        try {
/*@egen*/
	"{" [ Expression() ( "," Expression() )* ] "}"/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

/**
 *  Array size specification.
 *  Creates a single arguments node, which contains subnodes for
 *  all dimension values.
 */
void ArrayDimensions()                :
{/*@bgen(jjtree) ArgumentsNode */
  ArgumentsNode jjtn000 = new ArgumentsNode(this, JJTARGUMENTSNODE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/ int i=0; }	// Local variable to compute offset to type node.
{/*@bgen(jjtree) ArgumentsNode */
        try {
/*@egen*/
	// Brackets with values represent dimension specifications.
	(
		LOOKAHEAD(2)
		"[" Expression() "]"
		{
			i++;
			// Append array dimension to type node.
			// System.out.println("node is: "+peekNode(jjtree, i));
			((TypeNode)peekNode(jjtree, i)).appendText("[]");
		}
	)+

	// Subsequent brackets without values
	// just change the underlying component type.
	// Use lookahead to handle [2][][1] with primary suffix.
	(
		LOOKAHEAD(2) "[" "]"
		{
			// Append array dimension to type node.
			// System.out.println("und hier: "+peekNode(jjtree, i));
			((TypeNode)peekNode(jjtree, i)).appendText("[]");
		}
	)*/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

/**
 *  Inline content specification of a collection.
 *  Creates a single arguments node, which contains subnodes for
 *  all content values. Map content values are represented in
 *  turn by an arguments node with two subnodes for key and value.
 */
void CollectionContent()                :
{/*@bgen(jjtree) ArgumentsNode */
  ArgumentsNode jjtn000 = new ArgumentsNode(this, JJTARGUMENTSNODE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) ArgumentsNode */
        try {
/*@egen*/
	"{"/*@bgen(jjtree) #ArgumentsNode(> 1) */
                {
                  ArgumentsNode jjtn001 = new ArgumentsNode(this, JJTARGUMENTSNODE);
                  boolean jjtc001 = true;
                  jjtree.openNodeScope(jjtn001);
                }
                try {
/*@egen*/
		// First content value
		( [Expression() [ "=" Expression() ] ]
		)/*@bgen(jjtree)*/
                } catch (Throwable jjte001) {
                  if (jjtc001) {
                    jjtree.clearNodeScope(jjtn001);
                    jjtc001 = false;
                  } else {
                    jjtree.popNode();
                  }
                  if (jjte001 instanceof RuntimeException) {
                    throw (RuntimeException)jjte001;
                  }
                  if (jjte001 instanceof ParseException) {
                    throw (ParseException)jjte001;
                  }
                  throw (Error)jjte001;
                } finally {
                  if (jjtc001) {
                    jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1);
                  }
                }
/*@egen*/                   	// create arguments node, only for key=value

		// Subsequent content values are preceeded by ",".
		(/*@bgen(jjtree) #ArgumentsNode(> 1) */
                        {
                          ArgumentsNode jjtn002 = new ArgumentsNode(this, JJTARGUMENTSNODE);
                          boolean jjtc002 = true;
                          jjtree.openNodeScope(jjtn002);
                        }
                        try {
/*@egen*/
			( "," Expression() [ "=" Expression() ]
			)/*@bgen(jjtree)*/
                        } catch (Throwable jjte002) {
                          if (jjtc002) {
                            jjtree.clearNodeScope(jjtn002);
                            jjtc002 = false;
                          } else {
                            jjtree.popNode();
                          }
                          if (jjte002 instanceof RuntimeException) {
                            throw (RuntimeException)jjte002;
                          }
                          if (jjte002 instanceof ParseException) {
                            throw (ParseException)jjte002;
                          }
                          throw (Error)jjte002;
                        } finally {
                          if (jjtc002) {
                            jjtree.closeNodeScope(jjtn002, jjtree.nodeArity() > 1);
                          }
                        }
/*@egen*/                   	// create arguments node, only for key=value
		)*
	"}"/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

/**
 *  Parse Java type (class or basic type,
 *  with or without array brackets).
 *  Creates TypeNode.
 */
void Type()       :
{}
{	
	( PrimitiveType() | Name() ) [ TypeArguments() ]
	(
		( "[" "]" )
		{
			((ExpressionNode)jjtree.peekNode()).appendText("[]");
		}
	)*
}

/**
 *  Parse primitive type.
 *  Creates type node.
 */
void PrimitiveType()           :
{/*@bgen(jjtree) TypeNode */
  TypeNode jjtn000 = new TypeNode(this, JJTTYPENODE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) TypeNode */
        try {
/*@egen*/
	// Already set constant value to speed up precompilation.

	"boolean"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		jjtn000.setText("boolean");
		jjtn000.setConstantValue(boolean.class);
	}
|	"char"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		jjtn000.setText("char");
		jjtn000.setConstantValue(char.class);
	}
|	"byte"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		jjtn000.setText("byte");
		jjtn000.setConstantValue(byte.class);
	}
|	"short"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		jjtn000.setText("short");
		jjtn000.setConstantValue(short.class);
	}
|	"int"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		jjtn000.setText("int");
		jjtn000.setConstantValue(int.class);
	}
|	"long"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		jjtn000.setText("long");
		jjtn000.setConstantValue(long.class);
	}
|	"float"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		jjtn000.setText("float");
		jjtn000.setConstantValue(float.class);
	}
|	"double"/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{
		jjtn000.setText("double");
		jjtn000.setConstantValue(double.class);
	}/*@bgen(jjtree)*/
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

/**
 *  Parse class name (with package) into given type node.
 *  Use SReflect.findClass, to assure that class exists.
 */
void Name()           :
{/*@bgen(jjtree) TypeNode */
        TypeNode jjtn000 = new TypeNode(this, JJTTYPENODE);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/	String	identifier;	Class	type;}	// Declare local variables.
{/*@bgen(jjtree) TypeNode */
        try {
/*@egen*/

	LOOKAHEAD({classname()})
	identifier	= Identifier()
	{
		// Set node text to identifier using token image.
		jjtn000.setText(identifier);
		// Set type.
		type	= findClass0(jjtn000.getText());
	}

	(
		// Continue expansion, while class not found.
		LOOKAHEAD(".", {type==null
			|| getInnerClass(type, getToken(2).image)!=null})
		"." identifier	= Identifier()
		{
			if(type==null)
			{
				// Append identifier to node text using token image.
				jjtn000.appendText(".");
				jjtn000.appendText(identifier);
				// Set type.
				type	= findClass0(jjtn000.getText());
			}
			else
			{
				// Append identifier to node text using token image.
				jjtn000.appendText("$");
				jjtn000.appendText(identifier);
				// Set type.
				type	= getInnerClass(type, identifier);
			}
		}
	)*/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

/**
 *  Parse identifier and return token string.
 */
String Identifier()       :
{	Token t; }	// Declare local variable.
{
	(
		  t=
		| t=