parser.jj

//========================================================== -*- Java -*- ===
// The ILOG Rules parser
//===========================================================================

options
{
    STATIC = false;
    JAVA_UNICODE_ESCAPE = true;
    CACHE_TOKENS = true;
    USER_CHAR_STREAM = true;
}

//---------------------------------------------------------------------------
// The parser class definition
//---------------------------------------------------------------------------

PARSER_BEGIN(IlrParser)

package ilog.rules.parser;
import ilog.rules.factory.*;
import ilog.rules.util.prefs.IlrMessages;
import java.util.*;
import java.io.*;

class IlrParser
{
    IlrRulesetParser rulesetParser;

    private static final int PredEQ = 1;
    private static final int PredNE = 2;
    private static final int PredLT = 3;
    private static final int PredLE = 4;
    private static final int PredGT = 5;
    private static final int PredGE = 6;
    // Modified for in and !in predicate
    private static final int PredIN = 7;
    private static final int PredNIN = 8;
    // End - Modified for in and !in predicate

    private static final int SimpleClassExpr = 1;
    private static final int NotClassExpr = 2;
    private static final int ExistsClassExpr = 3;
    private static final int CollectClassExpr = 4;

    private int flowIndex = 1;
    private Token lastCommonTaskToken=null;

  private Number parseIntegerLiteral(Token t,int sign)
  {
    IlrRulesetParser parser = rulesetParser;
    String str = t.image;
    int len = str.length();
    char last = str.charAt(len-1);
    String prefix = (sign == 1) ? "" : "-";

    if (Character.toLowerCase(last) != 'l')
      {
	try
	  {
	    String value = str;
	    if (value.startsWith("0x"))
	      return Integer.valueOf(prefix + value.substring(2),16);
	    if (value.startsWith("0") && value.length() > 1)
	      return Integer.valueOf(prefix + value.substring(1),8);
	    return Integer.valueOf(prefix + value);
	  }
	catch(NumberFormatException ex)
	  {
	    String msg = IlrMessages.format("messages.Parsing.0", str);
	    parser.reporter.insertException(parser,t,msg);
	    return new Integer(0);
	  }
      }

    try
      {
	String value = str.substring(0,len-1);
	if (value.startsWith("0x"))
	  return Long.valueOf(prefix + value.substring(2),16);
	if (value.startsWith("0") && value.length() > 1)
	  return Long.valueOf(prefix + value.substring(1),8);
	return Long.valueOf(prefix + value);
      }
    catch(NumberFormatException ex)
      {
	String msg = IlrMessages.format("messages.Parsing.1", str);
	parser.reporter.insertException(parser,t,msg);
	return new Long(0);
      }
  }

  private Number parseFloatLiteral(Token t,int sign)
  {
    IlrRulesetParser parser = rulesetParser;
    String str = t.image;
    int len = str.length();
    char last = str.charAt(len-1);
    // This is true if we are in double mode for float literals
    boolean doubleType = false;
    String valuestring;
    String prefix = (sign == 1) ? "" : "-";

    if (Character.toLowerCase(last) == 'f')
      {
	doubleType = false;
	valuestring = prefix + str.substring(0,len-1);
      }
    else if (Character.toLowerCase(last) == 'd')
      {
	doubleType = true;
	valuestring = prefix + str.substring(0,len-1);
      }
    else if (rulesetParser.reflect.getDoubleModeForLiterals())
      {
	// we are in the new double literal mode set for C++
	doubleType = true;
	valuestring = prefix + str;
      }
    else
      {
	// we are in the old compatible float mode for JRules.
	doubleType = false;
	valuestring = prefix + str;
      }

    if (!doubleType)
      {
	try
	  {
	    Float x = Float.valueOf(valuestring);
	    if (x.isInfinite())
	      {
		String msg = IlrMessages.format("messages.Parsing.2", str);
		parser.reporter.insertException(parser,t,msg);
	      }
	    return x;
	  }
	catch(NumberFormatException ex)
	  {
	      String msg = IlrMessages.format("messages.Parsing.3", str);
	      parser.reporter.insertException(parser,t,msg);
	      return new Float(0);
	  }
      }
    else
      {
	try
	  {
	    Double x = Double.valueOf(valuestring);
	    if (x.isInfinite())
	      {
		  String msg = IlrMessages.format("messages.Parsing.4", str);
		  parser.reporter.insertException(parser,t,msg);
	      }
	    return x;
	  }
	catch(NumberFormatException ex)
	  {
	      String msg = IlrMessages.format("messages.Parsing.5", str);
	      parser.reporter.insertException(parser,t,msg);
	      return new Double(0);
	  }
      }
  }

    private static Character parseCharacterLiteral(String str)
      {
	  int index = 0;
	  char input = str.charAt(index++);
	  if (input != '\\') return new Character(input);

	  // Now, we have an escape sequence character!
	  input = str.charAt(index++);
	  switch(input)
	    {
	      case 'n': return new Character('\n');
	      case 't': return new Character('\t');
	      case 'b': return new Character('\b');
	      case 'r': return new Character('\r');
	      case 'f': return new Character('\f');
	      case '\\': return new Character('\\');
	      case '\'': return new Character('\'');
	      case '\"': return new Character('\"');
	    }
	  return null;
      }

    private static String parseStringLiteral(String str)
      {
	  int len = str.length();
	  StringBuffer buffer = new StringBuffer(len);
	  char input;
	  int index = 0;
	  while (index < len)
	    {
		input = str.charAt(index++);
		if (input != '\\')
		  {
		      buffer.append(input);
		      continue;
		  }

		// Now, we have an escape sequence character!
		input = str.charAt(index++);
		switch(input)
		  {
		    case 'n': buffer.append('\n'); break;
		    case 't': buffer.append('\t'); break;
		    case 'b': buffer.append('\b'); break;
		    case 'r': buffer.append('\r'); break;
		    case 'f': buffer.append('\f'); break;
		    case '\\': buffer.append('\\'); break;
		    case '\'': buffer.append('\''); break;
		    case '\"': buffer.append('\"'); break;
		  }
	    }
	  return buffer.toString();
      }

    private String syncOn(String[] arr)
      {
	  String found = null;
	  int len = arr.length;
	  Token t;
	  while ((t = getToken(1)) != null)
	    {
		if (t.kind == EOF) break;

		for (int i = 0; i < len; i++)
		  {
		      if (t.image.equals(arr[i]))
			{
			    found = arr[i];
			    break;
			}
		  }

		if (found != null) break;
		else getNextToken();
	    }
	  return found;
      }
};

PARSER_END(IlrParser)

//---------------------------------------------------------------------------
// White spaces to be skipped
//---------------------------------------------------------------------------

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

MORE:
{
    "//" : IN_SINGLE_LINE_COMMENT
    |
    <"/**" ~["/"]>
    : IN_FORMAL_COMMENT
    |
    "/*" : IN_MULTI_LINE_COMMENT
}

<IN_SINGLE_LINE_COMMENT>SPECIAL_TOKEN :
{
    <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT
}

<IN_FORMAL_COMMENT>SPECIAL_TOKEN:
{
    <FORMAL_COMMENT: "*/" >
      {
	  // Removes the first 3 characters and the last 2 characters
	  // from the matched string
	  String sstr = image.toString();
	  int slen = sstr.length();
	  matchedToken.image = sstr.substring(3,slen-2);
      }
    : DEFAULT
}

<IN_MULTI_LINE_COMMENT>
SPECIAL_TOKEN :
{
    <MULTI_LINE_COMMENT: "*/"> : DEFAULT
}

<IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
MORE :
{
    < ~[] >
}

//---------------------------------------------------------------------------
// Reserved words of the rule language
//---------------------------------------------------------------------------

TOKEN :
{
    <IMPORT: "import">
  | <USING: "using">
  | <NEW: "new">
  | <SETUP: "setup">
  | <RULESET: "ruleset">
  | <RULE: "rule">
  | <PROPERTY: "property">
  | <PRIORITY: "priority">
  | <PACKET: "packet">
  | <WHEN: "when">
  | <THEN: "then">
  | <NOT: "not">
  | <EXISTS: "exists">
  | <COLLECT: "collect">
  | <WHERE: "where">
  | <FROM: "from">
  | <IN: "in">
  | <LOGICAL: "logical">
  | <EVENT: "event">
  | <WAIT: "wait">
  | <UNTIL: "until">
  | <EVALUATE: "evaluate">
  | <REFRESH: "refresh">
  | <ASSERT: "assert">
  | <INSERT: "insert">
  | <RETRACT: "retract">
  | <UPDATE: "update">
  | <APPLY: "apply">
  | <MODIFY: "modify">
  | <BIND: "bind">
  | <VAR: "var">
  | <EXECUTE: "execute">
  | <WHILE: "while">
  | <FOR: "for">
  | <FUNCTION: "function">
  | <RETURN: "return">
  | <BREAK: "break">
  | <CONTINUE: "continue">
  | <IF: "if">
  | <ELSE: "else">
  | <TIMEOUT: "timeout">
  | <INSTANCEOF: "instanceof">
  | <IS: "is">
  | <TIMEOF: "timeof">
  | <OCCURSIN: "occursin">
  | <BEFORE: "before">
  | <AFTER: "after">
  | <DOLLARSIGN: "$">
  | <THROW: "throw">
  | <TRY: "try">
  | <CATCH: "catch">
  | <FINALLY: "finally">
  | <UNKNOWN: "isunknown">
  | <KNOWN: "isknown">
  | <RULETASK: "ruletask">
  | <FUNCTIONTASK: "functiontask">
  | <FLOWTASK: "flowtask">
  | <BODY: "body">
  | <SWITCH: "switch">
  | <CASE: "case">
  | <DEFLT: "default">
  | <FORK: "fork">
  | <GOTO: "goto">
  | <OUT: "out">
  | <INOUT: "inout">
  | <INITIALACTION: "initialaction">
  | <FINALACTION: "finalaction">
  | <FIRING: "firing">
  | <FIRINGLIMIT: "firinglimit">
  | <ORDERING: "ordering">
  | <SELECT: "select">
  | <DYNSELECT: "dynamicselect">
  | <FILTER: "filter">
  | <AGENDAFILTER: "agendafilter">
  | <COMPLETIONFLAG: "completionflag">
  | <INSTANCES: "instances">
  | <HASHER: "hasher">
  | <ITERATOR: "iterator">
  | <MATCHEDCLASSES: "matchedclasses">
  | <ALGORITHM: "algorithm">
}

//---------------------------------------------------------------------------
// Some constants
//---------------------------------------------------------------------------

TOKEN :
{
    <NULL: "null"> | <TRUE: "true"> | <FALSE: "false">
}

//---------------------------------------------------------------------------
// Literals
//   Warning: for Character & String literals, octal escape sequences
//   are not supported!
//---------------------------------------------------------------------------

TOKEN :
{
    <INTEGER_LITERAL:
      <DECIMAL_LITERAL> (["l","L"])?
      | <HEX_LITERAL> (["l","L"])?
      | <OCTAL_LITERAL> (["l","L"])?
    >
    | < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
    | < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
    | < #OCTAL_LITERAL: "0" (["0"-"7"])* >
    |
      < FLOATING_POINT_LITERAL:
        (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
      | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
      | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
      | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
      >
    | <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
    | <CHARACTER_LITERAL:
      "'"
      (   (~["'","\\","\n","\r"])
        | ("\\" ( ["n","t","b","r","f","\\","'","\""] ))
      )
      "'"
      >
	{
	    String cstr = image.toString();
	    int clen = cstr.length();
	    matchedToken.image = cstr.substring(1,clen-1);
	}
    | <STRING_LITERAL:
      "\""
      (   (~["\"","\\","\n","\r"])
        | ("\\" ( ["n","t","b","r","f","\\","'","\""] ))
      )*
      "\""
      >
	{
	    String sstr = image.toString();
	    int slen = sstr.length();
	    matchedToken.image = sstr.substring(1,slen-1);
	}
}

//---------------------------------------------------------------------------
// Identifiers
//   Very important: see also ilog.rules.tests.IlrUnicharGenerator class
//   which is used to generate the character ranges.
//---------------------------------------------------------------------------

TOKEN :
{
    <IDENTIFIER: <LETTER> (<FOLLOWING>)*>
  |
    <#LETTER:
      [
"\u8000"-"\u9fa5",
"\uac00"-"\ud7a3",
"\uf900"-"\ufa2d",
"\ufb00"-"\ufb06",
"\ufb13"-"\ufb17",
"\ufb1f"-"\ufb28",
"\ufb2a"-"\ufb36",
"\ufb38"-"\ufb3c",
"\ufb3e"-"\ufb3e",
"\ufb40"-"\ufb41",
"\ufb43"-"\ufb44",
"\ufb46"-"\ufbb1",
"\ufbd3"-"\ufd3d",
"\ufd50"-"\ufd8f",
"\ufd92"-"\ufdc7",
"\ufdf0"-"\ufdfb",
"\ufe33"-"\ufe34",
"\ufe4d"-"\ufe4f",
"\ufe69"-"\ufe69",
"\ufe70"-"\ufe72",
"\ufe74"-"\ufe74",
"\ufe76"-"\ufefc",
"\uff04"-"\uff04",
"\uff21"-"\uff3a",
"\uff3f"-"\uff3f",
"\uff41"-"\uff5a",
"\uff66"-"\uffbe",
"\uffc2"-"\uffc7",
"\uffca"-"\uffcf",
"\uffd2"-"\uffd7",
"\uffda"-"\uffdc",
"\uffe0"-"\uffe1",
"\uffe5"-"\uffe6",
"\u0024"-"\u0024",
"\u0041"-"\u005a",
"\u005f"-"\u005f",
"\u0061"-"\u007a",
"\u00a2"-"\u00a5",
"\u00aa"-"\u00aa",
"\u00b5"-"\u00b5",
"\u00ba"-"\u00ba",
"\u00c0"-"\u00d6",
"\u00d8"-"\u00f6",
"\u00f8"-"\u01f5",
"\u01fa"-"\u0217",
"\u0250"-"\u02a8",
"\u02b0"-"\u02b8",
"\u02bb"-"\u02c1",
"\u02d0"-"\u02d1",
"\u02e0"-"\u02e4",
"\u037a"-"\u037a",
"\u0386"-"\u0386",
"\u0388"-"\u038a",
"\u038c"-"\u038c",
"\u038e"-"\u03a1",
"\u03a3"-"\u03ce",
"\u03d0"-"\u03d6",
"\u03da"-"\u03da",
"\u03dc"-"\u03dc",
"\u03de"-"\u03de",
"\u03e0"-"\u03e0",
"\u03e2"-"\u03f3",
"\u0401"-"\u040c",
"\u040e"-"\u044f",
"\u0451"-"\u045c",
"\u045e"-"\u0481",
"\u0490"-"\u04c4",
"\u04c7"-"\u04c8",
"\u04cb"-"\u04cc",
"\u04d0"-"\u04eb",
"\u04ee"-"\u04f5",
"\u04f8"-"\u04f9",
"\u0531"-"\u0556",
"\u0559"-"\u0559",
"\u0561"-"\u0587",
"\u05d0"-"\u05ea",
"\u05f0"-"\u05f2",
"\u0621"-"\u063a",
"\u0640"-"\u064a",
"\u0671"-"\u06b7",
"\u06ba"-"\u06be",
"\u06c0"-"\u06ce",
"\u06d0"-"\u06d3",
"\u06d5"-"\u06d5",
"\u06e5"-"\u06e6",
"\u0905"-"\u0939",
"\u093d"-"\u093d",
"\u0958"-"\u0961",
"\u0985"-"\u098c",
"\u098f"-"\u0990",
"\u0993"-"\u09a8",
"\u09aa"-"\u09b0",
"\u09b2"-"\u09b2",
"\u09b6"-"\u09b9",
"\u09dc"-"\u09dd",
"\u09df"-"\u09e1",
"\u09f0"-"\u09f3",
"\u0a05"-"\u0a0a",
"\u0a0f"-"\u0a10",
"\u0a13"-"\u0a28",
"\u0a2a"-"\u0a30",
"\u0a32"-"\u0a33",
"\u0a35"-"\u0a36",
"\u0a38"-"\u0a39",
"\u0a59"-"\u0a5c",
"\u0a5e"-"\u0a5e",
"\u0a72"-"\u0a74",
"\u0a85"-"\u0a8b",
"\u0a8d"-"\u0a8d",
"\u0a8f"-"\u0a91",
"\u0a93"-"\u0aa8",
"\u0aaa"-"\u0ab0",
"\u0ab2"-"\u0ab3",
"\u0ab5"-"\u0ab9",
"\u0abd"-"\u0abd",
"\u0ae0"-"\u0ae0",
"\u0b05"-"\u0b0c",
"\u0b0f"-"\u0b10",
"\u0b13"-"\u0b28",
"\u0b2a"-"\u0b30",
"\u0b32"-"\u0b33",
"\u0b36"-"\u0b39",
"\u0b3d"-"\u0b3d",
"\u0b5c"-"\u0b5d",
"\u0b5f"-"\u0b61",
"\u0b85"-"\u0b8a",
"\u0b8e"-"\u0b90",
"\u0b92"-"\u0b95",
"\u0b99"-"\u0b9a",
"\u0b9c"-"\u0b9c",
"\u0b9e"-"\u0b9f",
"\u0ba3"-"\u0ba4",
"\u0ba8"-"\u0baa",
"\u0bae"-"\u0bb5",
"\u0bb7"-"\u0bb9",
"\u0c05"-"\u0c0c",
"\u0c0e"-"\u0c10",
"\u0c12"-"\u0c28",
"\u0c2a"-"\u0c33",
"\u0c35"-"\u0c39",
"\u0c60"-"\u0c61",
"\u0c85"-"\u0c8c",
"\u0c8e"-"\u0c90",
"\u0c92"-"\u0ca8",
"\u0caa"-"\u0cb3",
"\u0cb5"-"\u0cb9",
"\u0cde"-"\u0cde",
"\u0ce0"-"\u0ce1",
"\u0d05"-"\u0d0c",
"\u0d0e"-"\u0d10",
"\u0d12"-"\u0d28",
"\u0d2a"-"\u0d39",
"\u0d60"-"\u0d61",
"\u0e01"-"\u0e2e",
"\u0e30"-"\u0e30",
"\u0e32"-"\u0e33",
"\u0e3f"-"\u0e46",
"\u0e81"-"\u0e82",
"\u0e84"-"\u0e84",
"\u0e87"-"\u0e88",
"\u0e8a"-"\u0e8a",
"\u0e8d"-"\u0e8d",
"\u0e94"-"\u0e97",
"\u0e99"-"\u0e9f",
"\u0ea1"-"\u0ea3",
"\u0ea5"-"\u0ea5",
"\u0ea7"-"\u0ea7",
"\u0eaa"-"\u0eab",
"\u0ead"-"\u0eae",
"\u0eb0"-"\u0eb0",
"\u0eb2"-"\u0eb3",
"\u0ebd"-"\u0ebd",
"\u0ec0"-"\u0ec4",
"\u0ec6"-"\u0ec6",
"\u0edc"-"\u0edd",
"\u0f40"-"\u0f47",
"\u0f49"-"\u0f69",
"\u10a0"-"\u10c5",
"\u10d0"-"\u10f6",
"\u1100"-"\u1159",
"\u115f"-"\u11a2",
"\u11a8"-"\u11f9",
"\u1e00"-"\u1e9b",
"\u1ea0"-"\u1ef9",
"\u1f00"-"\u1f15",
"\u1f18"-"\u1f1d",
"\u1f20"-"\u1f45",
"\u1f48"-"\u1f4d",
"\u1f50"-"\u1f57",
"\u1f59"-"\u1f59",
"\u1f5b"-"\u1f5b",
"\u1f5d"-"\u1f5d",
"\u1f5f"-"\u1f7d",
"\u1f80"-"\u1fb4",
"\u1fb6"-"\u1fbc",
"\u1fbe"-"\u1fbe",
"\u1fc2"-"\u1fc4",
"\u1fc6"-"\u1fcc",
"\u1fd0"-"\u1fd3",
"\u1fd6"-"\u1fdb",
"\u1fe0"-"\u1fec",
"\u1ff2"-"\u1ff4",
"\u1ff6"-"\u1ffc",
"\u203f"-"\u2040",
"\u207f"-"\u207f",
"\u20a0"-"\u20ac",
"\u2102"-"\u2102",
"\u2107"-"\u2107",
"\u210a"-"\u2113",
"\u2115"-"\u2115",
"\u2118"-"\u211d",
"\u2124"-"\u2124",
"\u2126"-"\u2126",
"\u2128"-"\u2128",
"\u212a"-"\u2131",
"\u2133"-"\u2138",
"\u2160"-"\u2182",
"\u3005"-"\u3005",
"\u3007"-"\u3007",
"\u3021"-"\u3029",
"\u3031"-"\u3035",
"\u3041"-"\u3094",
"\u309b"-"\u309e",
"\u30a1"-"\u30fa",
"\u30fc"-"\u30fe",
"\u3105"-"\u312c",
"\u3131"-"\u318e",
"\u4e00"-"\u7fff"
      ]>
  |
    <#FOLLOWING:
      [
"\u8000"-"\u9fa5",
"\uac00"-"\ud7a3",
"\uf900"-"\ufa2d",
"\ufb00"-"\ufb06",
"\ufb13"-"\ufb17",
"\ufb1e"-"\ufb28",
"\ufb2a"-"\ufb36",
"\ufb38"-"\ufb3c",
"\ufb3e"-"\ufb3e",
"\ufb40"-"\ufb41",
"\ufb43"-"\ufb44",
"\ufb46"-"\ufbb1",
"\ufbd3"-"\ufd3d",
"\ufd50"-"\ufd8f",
"\ufd92"-"\ufdc7",
"\ufdf0"-"\ufdfb",
"\ufe20"-"\ufe23",
"\ufe33"-"\ufe34",
"\ufe4d"-"\ufe4f",
"\ufe69"-"\ufe69",
"\ufe70"-"\ufe72",
"\ufe74"-"\ufe74",
"\ufe76"-"\ufefc",
"\ufeff"-"\ufeff",
"\uff04"-"\uff04",
"\uff10"-"\uff19",
"\uff21"-"\uff3a",
"\uff3f"-"\uff3f",
"\uff41"-"\uff5a",
"\uff66"-"\uffbe",
"\uffc2"-"\uffc7",
"\uffca"-"\uffcf",
"\uffd2"-"\uffd7",
"\uffda"-"\uffdc",
"\uffe0"-"\uffe1",
"\uffe5"-"\uffe6",
"\u0000"-"\u0008",
"\u000e"-"\u001b",
"\u0024"-"\u0024",
"\u0030"-"\u0039",
"\u0041"-"\u005a",
"\u005f"-"\u005f",
"\u0061"-"\u007a",
"\u007f"-"\u009f",
"\u00a2"-"\u00a5",
"\u00aa"-"\u00aa",
"\u00b5"-"\u00b5",
"\u00ba"-"\u00ba",
"\u00c0"-"\u00d6",
"\u00d8"-"\u00f6",
"\u00f8"-"\u01f5",
"\u01fa"-"\u0217",
"\u0250"-"\u02a8",
"\u02b0"-"\u02b8",
"\u02bb"-"\u02c1",
"\u02d0"-"\u02d1",
"\u02e0"-"\u02e4",
"\u0300"-"\u0345",
"\u0360"-"\u0361",
"\u037a"-"\u037a",
"\u0386"-"\u0386",
"\u0388"-"\u038a",
"\u038c"-"\u038c",
"\u038e"-"\u03a1",
"\u03a3"-"\u03ce",
"\u03d0"-"\u03d6",
"\u03da"-"\u03da",
"\u03dc"-"\u03dc",
"\u03de"-"\u03de",
"\u03e0"-"\u03e0",
"\u03e2"-"\u03f3",
"\u0401"-"\u040c",
"\u040e"-"\u044f",
"\u0451"-"\u045c",
"\u045e"-"\u0481",
"\u0483"-"\u0486",
"\u0490"-"\u04c4",
"\u04c7"-"\u04c8",
"\u04cb"-"\u04cc",
"\u04d0"-"\u04eb",
"\u04ee"-"\u04f5",
"\u04f8"-"\u04f9",
"\u0531"-"\u0556",
"\u0559"-"\u0559",
"\u0561"-"\u0587",
"\u0591"-"\u05a1",
"\u05a3"-"\u05b9",
"\u05bb"-"\u05bd",
"\u05bf"-"\u05bf",
"\u05c1"-"\u05c2",
"\u05c4"-"\u05c4",
"\u05d0"-"\u05ea",
"\u05f0"-"\u05f2",
"\u0621"-"\u063a",
"\u0640"-"\u0652",
"\u0660"-"\u0669",
"\u0670"-"\u06b7",
"\u06ba"-"\u06be",
"\u06c0"-"\u06ce",
"\u06d0"-"\u06d3",
"\u06d5"-"\u06dc",
"\u06df"-"\u06e8",
"\u06ea"-"\u06ed",
"\u06f0"-"\u06f9",
"\u0901"-"\u0903",
"\u0905"-"\u0939",
"\u093c"-"\u094d",
"\u0951"-"\u0954",
"\u0958"-"\u0963",
"\u0966"-"\u096f",
"\u0981"-"\u0983",
"\u0985"-"\u098c",
"\u098f"-"\u0990",
"\u0993"-"\u09a8",
"\u09aa"-"\u09b0",
"\u09b2"-"\u09b2",
"\u09b6"-"\u09b9",
"\u09bc"-"\u09bc",
"\u09be"-"\u09c4",
"\u09c7"-"\u09c8",
"\u09cb"-"\u09cd",
"\u09d7"-"\u09d7",
"\u09dc"-"\u09dd",
"\u09df"-"\u09e3",
"\u09e6"-"\u09f3",
"\u0a02"-"\u0a02",
"\u0a05"-"\u0a0a",
"\u0a0f"-"\u0a10",
"\u0a13"-"\u0a28",
"\u0a2a"-"\u0a30",
"\u0a32"-"\u0a33",
"\u0a35"-"\u0a36",
"\u0a38"-"\u0a39",
"\u0a3c"-"\u0a3c",
"\u0a3e"-"\u0a42",
"\u0a47"-"\u0a48",
"\u0a4b"-"\u0a4d",
"\u0a59"-"\u0a5c",
"\u0a5e"-"\u0a5e",
"\u0a66"-"\u0a74",
"\u0a81"-"\u0a83",
"\u0a85"-"\u0a8b",
"\u0a8d"-"\u0a8d",
"\u0a8f"-"\u0a91",
"\u0a93"-"\u0aa8",
"\u0aaa"-"\u0ab0",
"\u0ab2"-"\u0ab3",
"\u0ab5"-"\u0ab9",
"\u0abc"-"\u0ac5",
"\u0ac7"-"\u0ac9",
"\u0acb"-"\u0acd",
"\u0ae0"-"\u0ae0",
"\u0ae6"-"\u0aef",
"\u0b01"-"\u0b03",
"\u0b05"-"\u0b0c",
"\u0b0f"-"\u0b10",
"\u0b13"-"\u0b28",
"\u0b2a"-"\u0b30",
"\u0b32"-"\u0b33",
"\u0b36"-"\u0b39",
"\u0b3c"-"\u0b43",
"\u0b47"-"\u0b48",
"\u0b4b"-"\u0b4d",
"\u0b56"-"\u0b57",
"\u0b5c"-"\u0b5d",
"\u0b5f"-"\u0b61",
"\u0b66"-"\u0b6f",
"\u0b82"-"\u0b83",
"\u0b85"-"\u0b8a",
"\u0b8e"-"\u0b90",
"\u0b92"-"\u0b95",
"\u0b99"-"\u0b9a",
"\u0b9c"-"\u0b9c",
"\u0b9e"-"\u0b9f",
"\u0ba3"-"\u0ba4",
"\u0ba8"-"\u0baa",
"\u0bae"-"\u0bb5",
"\u0bb7"-"\u0bb9",
"\u0bbe"-"\u0bc2",
"\u0bc6"-"\u0bc8",
"\u0bca"-"\u0bcd",
"\u0bd7"-"\u0bd7",
"\u0be7"-"\u0bef",
"\u0c01"-"\u0c03",
"\u0c05"-"\u0c0c",
"\u0c0e"-"\u0c10",
"\u0c12"-"\u0c28",
"\u0c2a"-"\u0c33",
"\u0c35"-"\u0c39",
"\u0c3e"-"\u0c44",
"\u0c46"-"\u0c48",
"\u0c4a"-"\u0c4d",
"\u0c55"-"\u0c56",
"\u0c60"-"\u0c61",
"\u0c66"-"\u0c6f",
"\u0c82"-"\u0c83",
"\u0c85"-"\u0c8c",
"\u0c8e"-"\u0c90",
"\u0c92"-"\u0ca8",
"\u0caa"-"\u0cb3",
"\u0cb5"-"\u0cb9",
"\u0cbe"-"\u0cc4",
"\u0cc6"-"\u0cc8",
"\u0cca"-"\u0ccd",
"\u0cd5"-"\u0cd6",
"\u0cde"-"\u0cde",
"\u0ce0"-"\u0ce1",
"\u0ce6"-"\u0cef",
"\u0d02"-"\u0d03",
"\u0d05"-"\u0d0c",
"\u0d0e"-"\u0d10",
"\u0d12"-"\u0d28",
"\u0d2a"-"\u0d39",
"\u0d3e"-"\u0d43",
"\u0d46"-"\u0d48",
"\u0d4a"-"\u0d4d",
"\u0d57"-"\u0d57",
"\u0d60"-"\u0d61",
"\u0d66"-"\u0d6f",
"\u0e01"-"\u0e2e",
"\u0e30"-"\u0e3a",
"\u0e3f"-"\u0e4e",
"\u0e50"-"\u0e59",
"\u0e81"-"\u0e82",
"\u0e84"-"\u0e84",
"\u0e87"-"\u0e88",
"\u0e8a"-"\u0e8a",
"\u0e8d"-"\u0e8d",
"\u0e94"-"\u0e97",
"\u0e99"-"\u0e9f",
"\u0ea1"-"\u0ea3",
"\u0ea5"-"\u0ea5",
"\u0ea7"-"\u0ea7",
"\u0eaa"-"\u0eab",
"\u0ead"-"\u0eae",
"\u0eb0"-"\u0eb9",
"\u0ebb"-"\u0ebd",
"\u0ec0"-"\u0ec4",
"\u0ec6"-"\u0ec6",
"\u0ec8"-"\u0ecd",
"\u0ed0"-"\u0ed9",
"\u0edc"-"\u0edd",
"\u0f18"-"\u0f19",
"\u0f20"-"\u0f29",
"\u0f35"-"\u0f35",
"\u0f37"-"\u0f37",
"\u0f39"-"\u0f39",
"\u0f3e"-"\u0f47",
"\u0f49"-"\u0f69",
"\u0f71"-"\u0f84",
"\u0f86"-"\u0f8b",
"\u0f90"-"\u0f95",
"\u0f97"-"\u0f97",
"\u0f99"-"\u0fad",
"\u0fb1"-"\u0fb7",
"\u0fb9"-"\u0fb9",
"\u10a0"-"\u10c5",
"\u10d0"-"\u10f6",
"\u1100"-"\u1159",
"\u115f"-"\u11a2",
"\u11a8"-"\u11f9",
"\u1e00"-"\u1e9b",
"\u1ea0"-"\u1ef9",
"\u1f00"-"\u1f15",
"\u1f18"-"\u1f1d",
"\u1f20"-"\u1f45",
"\u1f48"-"\u1f4d",
"\u1f50"-"\u1f57",
"\u1f59"-"\u1f59",
"\u1f5b"-"\u1f5b",
"\u1f5d"-"\u1f5d",
"\u1f5f"-"\u1f7d",
"\u1f80"-"\u1fb4",
"\u1fb6"-"\u1fbc",
"\u1fbe"-"\u1fbe",
"\u1fc2"-"\u1fc4",
"\u1fc6"-"\u1fcc",
"\u1fd0"-"\u1fd3",
"\u1fd6"-"\u1fdb",
"\u1fe0"-"\u1fec",
"\u1ff2"-"\u1ff4",
"\u1ff6"-"\u1ffc",
"\u200c"-"\u200f",
"\u202a"-"\u202e",
"\u203f"-"\u2040",
"\u206a"-"\u206f",
"\u207f"-"\u207f",
"\u20a0"-"\u20ac",
"\u20d0"-"\u20dc",
"\u20e1"-"\u20e1",
"\u2102"-"\u2102",
"\u2107"-"\u2107",
"\u210a"-"\u2113",
"\u2115"-"\u2115",
"\u2118"-"\u211d",
"\u2124"-"\u2124",
"\u2126"-"\u2126",
"\u2128"-"\u2128",
"\u212a"-"\u2131",
"\u2133"-"\u2138",
"\u2160"-"\u2182",
"\u3005"-"\u3005",
"\u3007"-"\u3007",
"\u3021"-"\u302f",
"\u3031"-"\u3035",
"\u3041"-"\u3094",
"\u3099"-"\u309e",
"\u30a1"-"\u30fa",
"\u30fc"-"\u30fe",
"\u3105"-"\u312c",
"\u3131"-"\u318e",
"\u4e00"-"\u7fff"
      ]>
  | <VARIABLE: "?" <IDENTIFIER>>
    {
	matchedToken.image = image.toString().substring(1);
    }
}

//---------------------------------------------------------------------------
// This token matches ALL UNMATCHED characters.
//   If some lexical error occurs, we should add a token to cover that
//   case instead of catching lexical token errors. In fact, the lexical
//   analysis should always be successful.
//---------------------------------------------------------------------------

TOKEN :
{
  < LPAREN: "(" > | < RPAREN: ")" > | < LBRACE: "{" > | < RBRACE: "}" >
  | < LBRACKET: "[" > | < RBRACKET: "]" >
  | < SEMICOLON: ";" > | < COMMA: "," > | < DOT: "." >
    | <QMARK: "?">
    | <INCR: "++">
    | <DECR: "--">
    | <UNMATCHED: ~["!","&","+","-","*","%","/",":","=","<",">"]>
}

//---------------------------------------------------------------------------
// Identifiers and variables (to support old "?name" syntax)
// This is a list of reserved keywords (can not used as identifiers):
//
//   Java:
//      "return", "break", "continue", "if", "else","new", "instanceof"
//   JRules:
//      "not", "exists", "collect", "logical", "bind", "var", "wait", "until",
//      "timeout", "evaluate", "execute", "refresh", "event", "timeof",
//      "isunknown", "isknown"
//---------------------------------------------------------------------------

Token Identifier() :
{
    Token t;
}
{
    (t=<IDENTIFIER>
     | t="assert"
     | t="insert"
     | t="retract"
     | t="update"
     | t="modify"
     | t="apply"
     | t="execute"
     | t="rule"
     | t="packet"
     | t="priority"
     | t="property"
     | t="ruleset"
     | t="import"
     | t="using"
     | t="setup"
     | t="when"
     | t="then"
     | t="where"
     | t="from"
     | t="in"
     | t="while"
     | t="for"
     | t="function"
     | t="occursin"
     | t="before"
     | t="after"
     | t="$"
     | t="functiontask"
     | t="ruletask"
     | t="flowtask"
     | t="body"
     | t="initialaction"
     | t="finalaction"
     | t="firing"
     | t="firinglimit"
     | t="ordering"
     | t="select"
     | t="dynamicselect"
     | t="filter"
     | t="agendafilter"
     | t="out"
     | t="inout"
     | t="completionflag"
     | t="default"
     | t="iterator"
     | t="algorithm"
     | t="matchedclasses"
     | t="wait"        // BR2003.816
     | t="is"          // BR2002.1147
     )
    { return t; }
}


Token[] ExtendedIdentifier() :
{
    Vector tokens = new Vector();
    Token[] tokenArray;
    Token t1,t2;
}
{
    ( t1=Identifier() { tokens.addElement( t1 ); }
         ( ( t1="." t2=Identifier() )
	   { tokens.addElement( t1 );
	     tokens.addElement( t2 ); } )*
     )
    {
	tokenArray = new Token[ tokens.size() ];
	for ( int i=0; i<tokens.size(); i++) {
	    tokenArray[i] = (Token) tokens.elementAt(i);
	}
	return tokenArray;
    }

}

// User Wish 2000.19: "Use of JRules language keywords in package names"
Token PossiblePackageName() :
{
    Token t;
}
{
    t=PossiblePacketName()
    { return t; }
}
Token PossiblePacketName() :
{
    Token t;
}
{
    (t=Identifier()
     | t="return"
     | t="break"
     | t="continue"
     | t="if"
     | t="else"
     | t="new"
     | t="instanceof"
     | t="timeof"
     | t="not"
     | t="exists"
     | t="collect"
     | t="logical"
     | t="event"
     | t="bind"
     | t="var"
     | t="until"
     | t="timeout"
     | t="evaluate"
     | t="refresh"
     | t="throw"
     | t="try"
     | t="catch"
     | t="finally"
     | t="isunknown"
     | t="isknown"
    )
    { return t; }
}

Token Variable() :
{
    Token t;
}
{
    (t=Identifier() | t=<VARIABLE>) { return t; }
}

//---------------------------------------------------------------------------
// Literals of the language
//---------------------------------------------------------------------------

void LiteralLookahead() :
{
}
{
   <INTEGER_LITERAL>
   | <FLOATING_POINT_LITERAL>
   | <CHARACTER_LITERAL>
   | <STRING_LITERAL>
   | "true"
   | "false"
   | "null"
}

// This rule is bad (missing the sign for the integers and floats)
// and should not be used anymore.

IlrConstantExpression Literal() :
{
    Object object;
    IlrReflect reflect;
    IlrReflectClass type;
    IlrConstantExpression expr;
    IlrConstantValue value;
    Token t;
}
{
   t=<INTEGER_LITERAL>
   {
     reflect = rulesetParser.reflect;
     object = parseIntegerLiteral(t,1);
     if (object instanceof Integer) type = reflect.intType();
     else type = reflect.longType();
     value = new IlrConstantValue(reflect,type,object);
     return new IlrConstantExpression(t,value);
   }
   | t=<FLOATING_POINT_LITERAL>
   {
     reflect = rulesetParser.reflect;
     object = parseFloatLiteral(t,1);
     if (object instanceof Float) type = reflect.floatType();
     else type = reflect.doubleType();
     value = new IlrConstantValue(reflect,type,object);
     return new IlrConstantExpression(t,value);
   }
   | t=<CHARACTER_LITERAL>
   {
     reflect = rulesetParser.reflect;
     object = parseCharacterLiteral(t.image);
     type = reflect.charType();
     value = new IlrConstantValue(reflect,type,object);
     return new IlrConstantExpression(t,value);
   }
   | t=<STRING_LITERAL>
   {
     reflect = rulesetParser.reflect;
     object = parseStringLiteral(t.image);
     type= reflect.stringClass();
     value = new IlrConstantValue(reflect,type,object);
     return new IlrConstantExpression(t,value);
    }
   | t="true"
   {
     reflect = rulesetParser.reflect;
     value = reflect.factory.TRUE;
     return new IlrConstantExpression(t,value);
   }
   | t="false"
   {
     reflect = rulesetParser.reflect;
     value = reflect.factory.FALSE;
     return new IlrConstantExpression(t,value);
   }
   | t="null"
   {
     reflect = rulesetParser.reflect;
     value = reflect.factory.NULL;
     return new IlrConstantExpression(t,value);
   }
}

// This rule should be used instead of previous one.

IlrConstantExpression SignedLiteral() :
{
  Object object;
  IlrReflect reflect;
  IlrReflectClass type;
  IlrConstantExpression expr;
  IlrConstantValue value;
  Token t;
  int sign = 1;
}
{
  ( ( "+" ) { sign = 1; } | ( "-" ) { sign = -1; } ) ?
    ( t=<INTEGER_LITERAL>
      {
	reflect = rulesetParser.reflect;
	object = parseIntegerLiteral(t,sign);
	if (object instanceof Integer) type = reflect.intType();
	else type = reflect.longType();
	value = new IlrConstantValue(reflect,type,object);
	return new IlrConstantExpression(t,value);
      }
    | t=<FLOATING_POINT_LITERAL>
      {
	reflect = rulesetParser.reflect;
	object = parseFloatLiteral(t,sign);
	if (object instanceof Float) type = reflect.floatType();
	else type = reflect.doubleType();
	value = new IlrConstantValue(reflect,type,object);
	return new IlrConstantExpression(t,value);
      }
    )
   | t=<CHARACTER_LITERAL>
   {
     reflect = rulesetParser.reflect;
     object = parseCharacterLiteral(t.image);
     type = reflect.charType();
     value = new IlrConstantValue(reflect,type,object);
     return new IlrConstantExpression(t,value);
   }
   | t=<STRING_LITERAL>
   {
     reflect = rulesetParser.reflect;
     object = parseStringLiteral(t.image);
     type= reflect.stringClass();
     value = new IlrConstantValue(reflect,type,object);
     return new IlrConstantExpression(t,value);
    }
   | t="true"
   {
     reflect = rulesetParser.reflect;
     value = reflect.factory.TRUE;
     return new IlrConstantExpression(t,value);
   }
   | t="false"
   {
     reflect = rulesetParser.reflect;
     value = reflect.factory.FALSE;
     return new IlrConstantExpression(t,value);
   }
   | t="null"
   {
     reflect = rulesetParser.reflect;
     value = reflect.factory.NULL;
     return new IlrConstantExpression(t,value);
   }
}

void SignedNumberLookahead () :
{}
{
    ( "+" | "-" )
    ( <INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> )
}

IlrConstantExpression SignedNumberExpression ():
{
    IlrFactory factory;
    IlrConstantExpression expr;
    IlrConstantValue value;
    Token t;
    Number number;
    int sign = 0;
}
{
    (   ( "+" ) { sign = 1; }
      | ( "-" ) { sign = -1; }
    )
    ( t=<INTEGER_LITERAL>
      {
	factory = rulesetParser.reflect.factory;
	number = parseIntegerLiteral(t,sign);
	if (number instanceof Integer)
	  value = factory.new ConstantValue(number.intValue());
	else
	  value = factory.new ConstantValue(number.longValue());
	return new IlrConstantExpression(t,value);
      }
    | t=<FLOATING_POINT_LITERAL>
      {
	factory = rulesetParser.reflect.factory;
	number = parseFloatLiteral(t,sign);
	if (number instanceof Float)
	  value = factory.new ConstantValue(number.floatValue());
	else
	  value = factory.new ConstantValue(number.doubleValue());
	return new IlrConstantExpression(t,value);
      }
    )
}

//---------------------------------------------------------------------------
// The type names
//   Simple type name is used to specify simple type, eventually using
//   package name. They are used in the import statement. type name is
//   used for a general type, including array type.
//   Example: ilog.rules.IlrRule, java.util.Vector, Form, or int[]
//---------------------------------------------------------------------------

IlrSimpleTypeExpression SimpleTypeName() :
{
    Vector vector = new Vector(5,2);
    Token t;
}
{
    t=Identifier() { vector.addElement(t); }
    (LOOKAHEAD(2) "." t=Identifier() { vector.addElement(t); })*
    {
	int len = vector.size();
	Token[] tokens = new Token[len];
	for (int i = 0; i < len; i++) tokens[i] = (Token)vector.elementAt(i);
	return new IlrSimpleTypeExpression(tokens);
    }
}

// Wish 2002.127
IlrSimpleTypeExpression SimplePackageTypeName() :
{
    Vector vector = new Vector(5,2);
    Token t;
}
{
    t=PossiblePackageName() { vector.addElement(t); }
    (LOOKAHEAD(2) "." t=PossiblePackageName() { vector.addElement(t); })*
    {
	int len = vector.size();
	Token[] tokens = new Token[len];
	for (int i = 0; i < len; i++) tokens[i] = (Token)vector.elementAt(i);
	return new IlrSimpleTypeExpression(tokens);
    }
}

IlrTypeExpression TypeName() :
{
    Token open;
    Token close;
    IlrTypeExpression type;
}
{
    type=SimpleTypeName()
    (
     open="[" close="]" { type = new IlrArrayTypeExpression(open,close,type); }
    )*
    {
	return type;
    }
}

//---------------------------------------------------------------------------
// Utility methods: parser entry points
//---------------------------------------------------------------------------

IlrRuleDefinition ParseRuleDefinition() :
{
    IlrRuleDefinition rule = null;
    Token keyword;
    Token[] t;
}
{
    keyword="rule" t=ExtendedIdentifier() { rule = new IlrRuleDefinition(keyword,t); }
    "{" RuleBodyDefinition(rule) "}" (";")? <EOF> { return rule; }
}

//---------------------------------------------------------------------------
// The ruleset definition
//   A ruleset begins with some imports statements (can be absent),
//   Then an initialization rule (optional),
//   Then some rule definitions.
//   Then EOF.
//---------------------------------------------------------------------------

void RulesetDefinition(IlrRulesetParser ruleset) :
{}
{
    (ImportDefinition(ruleset))*
    (PropertyDefinition(ruleset))?
    (SetupDefinition(ruleset))?
    (
     FunctionDefinition(ruleset) 
     | RuleDefinition(ruleset) 
     | TaskDefinition()
     )*
    <EOF>
}

//---------------------------------------------------------------------------
// The taskset definition
//   Then some task definitions.
//   Then EOF.
//---------------------------------------------------------------------------

void TasksetDefinition(IlrRulesetParser ruleset) :
{}
{
    (ImportDefinition(ruleset))*
    (PropertyDefinition(ruleset))?
    (SetupDefinition(ruleset))?
    (TaskDefinition())*
    <EOF>
}

//---------------------------------------------------------------------------
// Imports
//   This statement imports Java classes used in the rules.
//   Specific class names or whole package can be used.
//   In the subsequent class names, when package are not specified, they
//   are seached in the imported classes and packages.
//   Examples:
//     import java.util.*;
//     import mypackage.myclass;
//   Note: Implicit imports are:
//     import java.lang.*;
//     import ilog.rules.*;
//---------------------------------------------------------------------------

void ImportDefinition(IlrRulesetParser ruleset) :
{}
{
    try
      {
	  ProtectedImportDefinition(ruleset)
      }
    catch(ParseException ex)
      {
	  ruleset.reporter.insertException(ruleset,ex);
	  String[] arr = {"import", "rule", "function",
			 "functiontask", "ruletask", "flowtask"};
	  syncOn(arr);
	  ruleset.currentDefinition = null;
      }
}

// Wish 2002.127: SimpleTypeName replaced by SimplePackageTypeName
// to allow 'event' in package name
void ProtectedImportDefinition(IlrRulesetParser ruleset) :
{
    Token keyword;
    IlrSimpleTypeExpression type;
    IlrImportDefinition definition;
}
{
    keyword="import" type=SimplePackageTypeName()
      {
	  definition = new IlrImportDefinition(keyword,type);
	  ruleset.addDefinition(definition);
	  ruleset.currentDefinition = definition;
      }
    ["." "*" { definition.importAll=true; } ] ";"
      {
	  ruleset.currentDefinition = null;
      }
    |
    keyword="using" type=SimplePackageTypeName() ";"
      {
	  definition = new IlrImportDefinition(keyword,type);
	  definition.importAll=true;
	  ruleset.addDefinition(definition);
	  ruleset.currentDefinition = definition;
      }
}



Defines the values for properties. The property values can be any literal, or a type name (can be an array) such as java.lang.String. If the type name is followed by ("a string"), then we use a format.


IlrPropertyDefinition.Element Property() :
{
  Token token=null;
  IlrSimpleTypeExpression property;
  IlrConstantExpression constant;
  IlrTypeExpression type;
  Token t = null;
  IlrPropertyDefinition.Element el;
}
{
    try {
	token="property" property=SimpleTypeName() "="
	    (
	     constant=SignedLiteral()
		{
		    el = new IlrPropertyDefinition.Element(token,property,constant);
		}
	     |
	     type=TypeName() ("(" t=<STRING_LITERAL> ")")?
		{
		    el = new IlrPropertyDefinition.Element(token,property,type,t);
		}
	     )
	    ";" 
	    { return el; }
    }
    catch(ParseException ex)
	{
	    lastCommonTaskToken = token;
	    throw ex;
	}
}

//---------------------------------------------------------------------------
// The ruleset properties
//---------------------------------------------------------------------------

void PropertyDefinition(IlrRulesetParser ruleset) :
{
    Token keyword;
    IlrSimpleTypeExpression rulesetName;
    IlrPropertyDefinition definition;
    IlrPropertyDefinition.Element prop;
}
{
    keyword="ruleset" rulesetName=SimpleTypeName()
      {
	 definition = new IlrPropertyDefinition(keyword,rulesetName);
	 ruleset.addDefinition(definition);
	 ruleset.currentDefinition = definition;
      }
    (
     ";"
     |
     "{"
     ( RulesetSettings(definition) )*
     "}"
     (";")?
     )
      {
	  ruleset.currentDefinition = null;
      }
}

void RulesetSettings(IlrPropertyDefinition definition) :
{
    IlrPropertyDefinition.Element prop;
}
{
    LOOKAHEAD(1) prop=Property()
      {
	if (!definition.containsProperty(prop)) definition.addProperty(prop);
	else
	{
	    String msg = IlrMessages.format("messages.Parsing.6", prop.getName());
	    rulesetParser.reporter.insertError(prop.getError(rulesetParser,msg));
	}
      }
      |
	  RulesetVariableDeclaration()
      |
	  ClassInstancesDeclaration()
      |
	  HasherDeclaration()
	      {}  
}

void ClassInstancesDeclaration() :
{
    IlrClassInstancesDefinition instances=null;
    Token keyword;
    IlrTypeExpression type;
    IlrExpression expr;
}
{
    keyword = "instances" "(" type = TypeName() ")" "="
	{
	    instances = new IlrClassInstancesDefinition(keyword, type);
	    rulesetParser.addDefinition(instances);
	}
    (
     InstancesList(instances)
     |
     expr = Expression() ";" { instances.setInstances(expr); }
    )
	{}
}

void InstancesList(IlrClassInstancesDefinition instances) :
{
    IlrExpression expr;
}
{
    "{"
   ("}" 
   |
    (
	expr = Expression() { instances.addInstance(expr); }
        ("," expr = Expression() { instances.addInstance(expr); })*	
     "}"
	)
    )
 (";")?
	    {}
}

void HasherDeclaration() :
{
    IlrExpression expr=null;
    IlrTypeExpression typeExpr=null;
    Token variable=null;
    Token keyword=null;
    IlrHasherDefinition definition=null;
}
{
    keyword = "hasher" "(" typeExpr = TypeName() variable = Variable() ")" "="
	expr = Expression() ";"
	{
	    definition = new IlrHasherDefinition(keyword, typeExpr,
						 variable, expr);
	    rulesetParser.addDefinition(definition);
	}
}

void ModifierLookAhead() :
{
}
{
    ("in" | "inout") TypeName() Variable()
}

void
RulesetVariableDeclaration() :
{
    IlrRulesetVariableDefinition definition=null;
    //	rulesetParser.rulesetVariableDefinition;
    Token keyword=null;
    Token name;
    IlrTypeExpression type;
    IlrRulesetVariable expr;
    IlrBindExpression bindExpr;
    IlrExpression value=null;
    Token end;
    int modifier=IlrRulesetVariable.RulesetBind;
}
{
    (
     LOOKAHEAD(3)
     (keyword = "in" { modifier |= IlrRulesetVariable.In; }
      |
      keyword = "inout" { modifier |=
			  IlrRulesetVariable.In | IlrRulesetVariable.Out; }
      )
            type = TypeName() name = Variable() end = ";"
	{
	    if (definition == null)
	    {
		definition = new IlrRulesetVariableDefinition(keyword);
		//		rulesetParser.rulesetVariableDefinition = definition;
		rulesetParser.addDefinition(definition);
	    }
	    expr = new IlrRulesetVariable(keyword, end, name, type, modifier);
	    definition.addVariable(expr);
	}
    |
     [
       LOOKAHEAD(3) keyword = "out" { modifier |= IlrRulesetVariable.Out; }
     ] 

	type = TypeName()
	name = Variable() 
	("=" value = Expression() end = ";"
	 | 
	 end = ";")
	{
	    if (keyword == null)
	      keyword = type.getBeginToken();
	    if (definition == null)
	    {
		definition = new IlrRulesetVariableDefinition(keyword);
		//		rulesetParser.rulesetVariableDefinition = definition;
		rulesetParser.addDefinition(definition);
	    }
	    if (value != null)
	    {
		bindExpr = new IlrBindExpression(keyword,end,name,value);
		bindExpr.modifier = modifier;
		if ((modifier & IlrRulesetVariable.Out) != 0)
		{
		    definition.addReturnBindingExpression(bindExpr);
		    definition.addReturnBindingType(type);
		}
		else
		{
		    definition.addVariableBindingExpression(bindExpr);
		    definition.addVariableBindingType(type);
		}
	    }
	    else
	    {
		expr = new IlrRulesetVariable(keyword, end, name, type,
					      modifier);
		definition.addVariable(expr);
	    }
	}
     )
	{
	}
}
//---------------------------------------------------------------------------
// The setup rule (or initialization rule)
//   Is used to initialize the execution context. This is a rule without
//   conditions (with only actions). The actions are executed as soon
//   as the context is created.
//---------------------------------------------------------------------------

void SetupDefinition(IlrRulesetParser ruleset) :
{}
{
    try
      {
	  ProtectedSetupDefinition(ruleset)
      }
    catch(ParseException ex)
      {
	  ruleset.reporter.insertException(ruleset,ex);
	  String[] arr = {"rule", "function", "functiontask", 
			  "flowtask", "ruletask"};
	  syncOn(arr);
	  ruleset.currentDefinition = null;
      }
}

void ProtectedSetupDefinition(IlrRulesetParser ruleset) :
{
    Token keyword,obrace,cbrace;
    IlrSetupDefinition definition;
    IlrActionExpression action;
}
{
    keyword="setup"
      {
	  definition = new IlrSetupDefinition(keyword);
	  ruleset.addDefinition(definition);
	  ruleset.currentDefinition = definition;
      }
    obrace="{" { definition.obrace = obrace; }
    (action=ActionStatement() { definition.actions.addElement(action); })*
    cbrace="}" { definition.cbrace = cbrace; }
    (";")?
      {
	  ruleset.currentDefinition = null;
      }
}

//---------------------------------------------------------------------------
// The rule definition
//   See the next grammar for the rule definition syntax.
//---------------------------------------------------------------------------

void RuleDefinition(IlrRulesetParser ruleset) :
{}
{
    try
      {
	  ProtectedRuleDefinition(ruleset)
      }
    catch(ParseException ex)
      {
	  if (!ex.specialConstructor && "NextRule".equals(ex.getMessage())) {}
	  else
	    {
		ruleset.reporter.insertException(ruleset,ex);
		String[] arr = {"rule", "function", "functiontask", 
				"flowtask", "ruletask"};
		syncOn(arr);
		ruleset.currentDefinition = null;
	    }
      }
}

void ProtectedRuleDefinition(IlrRulesetParser ruleset) :
{
    Token[] trule;
    Token ruleToken;
}
{
    ruleToken="rule" trule=ExtendedIdentifier()
     {
	 IlrRuleDefinition rule = new IlrRuleDefinition(ruleToken,trule);
	 ruleset.addDefinition(rule);
	 ruleset.currentDefinition = rule;
	 if (ruleToken.specialToken != null &&
	     ruleToken.specialToken.kind == FORMAL_COMMENT)
	   rule.setComments(ruleToken.specialToken.image);
     }
    "{" RuleBodyDefinition(rule) "}" (";")?
      {
	  ruleset.currentDefinition = null;
      }
}

//---------------------------------------------------------------------------
// The function definition
//   See the next grammar for the function definition syntax.
//---------------------------------------------------------------------------


void FunctionDefinition(IlrRulesetParser ruleset) :
{}
{
    try
      {
	  ProtectedFunctionDefinition(ruleset)
      }
    catch(ParseException ex)
      {
	  ruleset.reporter.insertException(ruleset,ex);
	  String[] arr = {"rule", "function", "functiontask", 
			  "flowtask", "ruletask"};
	  syncOn(arr);
	  ruleset.currentDefinition = null;
      }
}

void ProtectedFunctionDefinition(IlrRulesetParser ruleset) :
{
    Token keyword,obrace,cbrace;
    Token[] name=null;
    IlrTypeExpression returnType=null;
    IlrFunctionDefinition function;
    IlrActionExpression action;
}
{
    keyword="function" returnType=TypeName() name=ExtendedIdentifier()
     {
	 function = new IlrFunctionDefinition ( keyword, name, returnType );
	 ruleset.addDefinition(function);
	 ruleset.currentDefinition = function;
	 if (keyword.specialToken != null &&
	     keyword.specialToken.kind == FORMAL_COMMENT)
	   function.setComments(keyword.specialToken.image);
     }
    FunctionArgsDefinition ( function )
     obrace="{" { function.obrace = obrace; }
     ( action = ActionStatement () { function.addAction( action ); }  )*
     cbrace="}" { function.cbrace = cbrace; }
     (";")?
	 {
	     ruleset.currentDefinition = null;
	 }
}

void FunctionArgsDefinition(IlrFunctionDefinition function ) :
{
    IlrFunctionArgExpression arg;
}
{
     "("
     ( ")"
      |

       ( arg=FunctionArgDefinition() { function.addArgument ( arg ); } )
       ( "," arg=FunctionArgDefinition() { function.addArgument ( arg ); } )*
       ")"
     )
}

IlrFunctionArgExpression
FunctionArgDefinition () :
{
    IlrTypeExpression type;
    Token name;
}
{
  type=TypeName() name=Variable()
      { return new IlrFunctionArgExpression ( name, type ); }
}


//---------------------------------------------------------------------------
// Rule body
//---------------------------------------------------------------------------

void RuleBodyDefinition(IlrRuleDefinition rule) :
{}
{
    try
      {
	  (RuleParameterAssignments(rule))*
      }
    catch(ParseException ex)
      {
	  IlrRulesetParser ruleset = rulesetParser;
	  lastCommonTaskToken = null;
	  ruleset.reporter.insertException(ruleset,ex);
	  String[] arr = {"rule","when"};
	  String found = syncOn(arr);
	  if ((found == null) || (!found.equals("when"))) return;
      }
    try
      {
	  RuleConditions(rule)
      }
    catch(ParseException ex)
      {
	  IlrRulesetParser ruleset = rulesetParser;
	  ruleset.reporter.insertException(ruleset,ex);
	  String[] arr = {"rule","then"};
	  String found = syncOn(arr);
	  if ((found == null) || (!found.equals("then")))
	    throw new ParseException("NextRule");
      }
    RuleActions(rule)
}

void RuleParameterAssignments(IlrRuleDefinition rule) :
{
    Token token = null;
    Token t;
    IlrExpression expr = null;
    IlrPropertyDefinition.Element prop;
}
{
  t="packet" "=" token=PossiblePacketName() ";"
  {
    if (token != null)
    {
      if (rule.packetToken == null) rule.packetToken = token;
      else
      {
	String msg = IlrMessages.getMessage("messages.Parsing.7");
	rulesetParser.reporter.insertException(rulesetParser,t,msg);
      }
    }
  }
  |
  t="priority" "=" expr=Expression() ";"
  {
    if (expr != null)
    {
      if (rule.priority == null) rule.setPriority(expr);
      else
      {
	String msg = IlrMessages.getMessage("messages.Parsing.8");
	rulesetParser.reporter.insertException(rulesetParser,t,msg);
      }
    }
  }
  |
  prop=Property()
  {
    if (!rule.properties.containsProperty(prop))
      rule.properties.addProperty(prop);
    else
    {
	String msg = IlrMessages.format("messages.Parsing.6", prop.getName());
	rulesetParser.reporter.insertError(prop.getError(rulesetParser,msg));
    }
  }
}

//---------------------------------------------------------------------------
// The task definition
//---------------------------------------------------------------------------

void TaskDefinition() :
{
    IlrTaskDefinition task=null;
}
{
    try
	{
	   task = ProtectedRuleTaskDefinition() {}
	  | 	  
	   task = ProtectedFunctionTaskDefinition() {}
	  |
	   task = ProtectedFlowTaskDefinition() {}
	}
    catch(ParseException ex)
      {
	  if (!ex.specialConstructor) {}
	  else
	    {
		rulesetParser.reporter.insertException(rulesetParser,ex);
		String[] arr = {"rule", "function", "functiontask", 
				"flowtask", "ruletask"};
		String found = syncOn(arr);
		rulesetParser.currentDefinition = null;
	    }
      }
}

IlrTaskDefinition ProtectedRuleTaskDefinition() :
{
    Token[] ttask;
    Token taskToken;
    IlrTaskDefinition task = null;
    IlrTasksetDefinition taskset = rulesetParser.taskset;
}
{
    taskToken="ruletask" ttask=ExtendedIdentifier()
     {
	 if (taskset == null)
	 {
	     taskset = new IlrTasksetDefinition();
	     rulesetParser.taskset = taskset;
	     rulesetParser.addDefinition(taskset);
	 }
	 task = new IlrTaskDefinition(taskToken, ttask,
				      IlrTaskDefinition.RuleTask);
	 rulesetParser.currentDefinition = task;
	 taskset.addTask(task);
	 if (taskToken.specialToken != null &&
	     taskToken.specialToken.kind == FORMAL_COMMENT)
           task.setComments(taskToken.specialToken.image);
     }
    "{" RuleTaskBodyDefinition(task) "}" (";")?
      {
	  rulesetParser.currentDefinition = null;
	  return task;
      }
}
IlrTaskDefinition ProtectedFunctionTaskDefinition() :
{
    Token[] ttask;
    Token taskToken;
    IlrTaskDefinition task = null;
    IlrTasksetDefinition taskset = rulesetParser.taskset;
}
{
    taskToken="functiontask" ttask=ExtendedIdentifier()
     {
	 if (taskset == null)
	 {
	     taskset = new IlrTasksetDefinition();
	     rulesetParser.taskset = taskset;
	     rulesetParser.addDefinition(taskset);
	 }
	 task = new IlrTaskDefinition(taskToken, ttask,
				      IlrTaskDefinition.FunctionTask);
	 rulesetParser.currentDefinition = task;
	 taskset.addTask(task);
	 if (taskToken.specialToken != null &&
	     taskToken.specialToken.kind == FORMAL_COMMENT)
	   task.setComments(taskToken.specialToken.image);
     }
    "{" FunctionTaskBodyDefinition(task) "}" (";")?
      {
	  rulesetParser.currentDefinition = null;
	  return task;
      }
}
IlrTaskDefinition ProtectedFlowTaskDefinition() :
{
    Token[] ttask;
    Token taskToken;
    IlrTaskDefinition task = null;
    IlrTasksetDefinition taskset = rulesetParser.taskset;
}
{
    taskToken="flowtask" ttask=ExtendedIdentifier()
     {
	 if (taskset == null)
	 {
	     taskset = new IlrTasksetDefinition();
	     rulesetParser.taskset = taskset;
	     rulesetParser.addDefinition(taskset);
	 }
	 task = new IlrTaskDefinition(taskToken, ttask,
				      IlrTaskDefinition.FlowTask);
	 rulesetParser.currentDefinition = task;
	 taskset.addTask(task);
	 if (taskToken.specialToken != null &&
	     taskToken.specialToken.kind == FORMAL_COMMENT)
	   task.setComments(taskToken.specialToken.image);
     }
    "{" FlowTaskBodyDefinition(task) "}" (";")?
      {
	  rulesetParser.currentDefinition = null;
	  return task;
      }
}

//---------------------------------------------------------------------------
// Task body
//---------------------------------------------------------------------------

void RuleTaskBodyDefinition(IlrTaskDefinition task) :
{}
{
    (RuleTaskParameterAssignments(task))*
	{}
}

void FunctionTaskBodyDefinition(IlrTaskDefinition task) :
{}
{
    (FunctionTaskParameterAssignments(task))*
	{}
}

void FlowTaskBodyDefinition(IlrTaskDefinition task) :
{}
{
    (FlowTaskParameterAssignments(task))*
	{}
}

void RuleTaskParameterAssignments(IlrTaskDefinition task) :
{
    Token key = null;
    Token filter = null;
    Token mode=null;
    IlrPropertyDefinition.Element prop;
    Vector actions;
    Token var = null;
    int sign = 1;
    IlrExpression filterExpr=null;
    IlrExpression iteratorExpr=null;
    IlrExpression matchOnExpr=null;
    Vector matchOnClasses=null;
    Token algo=null;
    boolean dynamic=false;
}
{
    try {
    (
     key = "body"  { task.tbody = key; }
    (
     LOOKAHEAD(2) "=" 
     (
      filter = "select" { dynamic = false; }
      |
      filter = "dynamicselect" { dynamic = true; }
      )
     "(" var = Variable() ")" 
     try {
	 actions = TaskActions(task) (";")?
	 {
	     task.setComputeRuleInfos(var, actions); 
	     task.dynamicBody = dynamic;
	 }
     }
     catch(ParseException ex)
	{
	    lastCommonTaskToken = key;
	    throw ex;	    
	}
     |
     ("=")? "{"
     (RuleList(task) "}" 
      |
      "}"
      )
     (";")?
     )
   |
       (
	key = "ordering" { task.tordering = key; }
	"=" 
	try {
	    mode = Identifier() ";" 
	    { 
		if ("dynamic".equals(mode.image))
		task.setOrdering(IlrTaskDefinition.Dynamic);
		else if ("literal".equals(mode.image))
		task.setOrdering(IlrTaskDefinition.Literal);
		else if ("sorted".equals(mode.image))
		task.setOrdering(IlrTaskDefinition.Sorted);
		else
		{
		    String msg = IlrMessages.format("messages.Parsing.9", mode.image);
		    rulesetParser.reporter.insertException(rulesetParser, key,
							   msg);
		}
	    }
	}
	catch(ParseException ex)
	   {
		lastCommonTaskToken = key;
		throw ex;	       
	   }
	)
     )
   |
       (
	key = "firing" { task.tfiring = key; }
	"=" 
	try {
	    mode = Identifier() ";" 
	    { 
		if ("rule".equals(mode.image))
		task.setFiring(IlrTaskDefinition.Rule);
		else if ("allrules".equals(mode.image))
		task.setFiring(IlrTaskDefinition.AllRules);
		else
		{
		    String msg = IlrMessages.format("messages.Parsing.10", mode.image);
		    rulesetParser.reporter.insertException(rulesetParser, key,
							  msg);
		}
	    }
	}
	catch(ParseException ex)
	   {
		lastCommonTaskToken = key;
		throw ex;	       
	   }
	)
   |
       (
	key = "firinglimit" { task.tfiringLimit = key; }
	"="
	try {
	    ( "+" { sign = 1; }
	      |
	      "-" { sign = -1; }
	      )?
	    mode = <INTEGER_LITERAL> ";" 
	    { 
		Number object = parseIntegerLiteral(mode,sign);
		task.setFiringLimit(object.intValue());
	    }
	}
	catch(ParseException ex)
	   {
		lastCommonTaskToken = key;
		throw ex;	       
	   }
	)
   |
	(
	 key = "agendafilter" "=" { task.tagendafilter = key; }
	 (LOOKAHEAD(3) filter = "filter" "(" var = Variable() ")"
	  try{
	      actions = TaskActions(task) (";")?
	      { task.setAgendaFilter(var, actions); }
	  }
	  catch(ParseException ex)
	     {
		lastCommonTaskToken = key;
		throw ex;
	     }
	  |
	  filterExpr = Expression() ";"
	     {
		 task.setAgendaFilter(filterExpr);
	     }
	  )
	 )
   |
       (
	key = "iterator" { task.titerator = key; }
	"=" iteratorExpr = Expression() ";"
	   {
	       task.setIterator(iteratorExpr);
	   }
	)
   |
       (
	key = "algorithm" { task.talgorithm = key; }
	"="
	try {
	    algo = Identifier() ";"
	    { 
		if ("default".equals(algo.image))
		task.setAlgorithm(IlrTaskDefinition.DefaultAlgorithm);
		else if ("sequential".equals(algo.image))
		task.setAlgorithm(IlrTaskDefinition.SequentialAlgorithm);
		else
		{
		    String msg = IlrMessages.format("messages.Parsing.14", algo.image);
		    rulesetParser.reporter.insertException(rulesetParser, key, msg);
		}
	    }
	}
	catch(ParseException ex)
	   {
		lastCommonTaskToken = key;
		throw ex;	       
	   }
	)
   |
	(
	 key = "matchedclasses" { task.tmatchOn = key; }
	 try {
	     (
	      LOOKAHEAD(2) "=" matchOnExpr = Expression() ";"
		 { task.setMatchOnExpr(matchOnExpr); }
	      |
	      ("=")? "{"
	      matchOnClasses = MatchOnList(task) "}" (";")?
		 {
		     task.setMatchOnClasses(key, matchOnClasses);
		 }
	      )
	 }
	catch(ParseException ex)
	   {
		lastCommonTaskToken = key;
		throw ex;	       
	   }
	 )
   |
    CommonTaskParameterAssignments(task)
	}
    catch(ParseException ex)
      {
	  IlrRulesetParser ruleset = rulesetParser;
	  if (lastCommonTaskToken != null)
	      {
		  String message =
		      ruleset.reporter.computeTaskErrorMessage(ex,
							       lastCommonTaskToken,
							       task.name);
		  ruleset.reporter.insertException(ruleset,
						   ex.currentToken,
						   message);
		  lastCommonTaskToken = null;
	      }
	  else
	      ruleset.reporter.insertException(ruleset,ex);
	  Vector topLevelTokens = new Vector();
	  topLevelTokens.addElement("rule");
	  topLevelTokens.addElement("function");
	  topLevelTokens.addElement("ruletask");
	  topLevelTokens.addElement("functiontask");
	  topLevelTokens.addElement("flowtask");
	  Vector tokens = new Vector();
	  tokens.addAll(topLevelTokens);

	  tokens.addElement("property");
	  if (task.tbody == null) tokens.addElement("body");
	  if (task.tinitialactions == null) tokens.addElement("initialaction");
	  if (task.tfinalactions == null) tokens.addElement("finalaction");
	  if (task.tordering == null) tokens.addElement("ordering");
	  if (task.tfiring == null) tokens.addElement("firing");
	  if (task.tfiringLimit == null) tokens.addElement("firinglimit");
	  if (task.talgorithm == null) tokens.addElement("algorithm");
	  if (task.titerator == null) tokens.addElement("iterator");
	  if (task.tagendafilter == null) tokens.addElement("agendafilter");
	  if (task.tcompletionflag == null) tokens.addElement("completionflag");
	  if (task.tmatchOn == null) tokens.addElement("matchedclasses");
	  String[] arr = new String[tokens.size()];
	  tokens.copyInto(arr);
	  String found = syncOn(arr);
	  if ((found == null) || topLevelTokens.contains(found))
	      throw ex;
      }
}

void RuleList(IlrTaskDefinition task) :
{
    Token[] expr;
    Vector rules = new Vector(5, 5);
}
{
    expr=ExtendedIdentifier() { rules.addElement(expr); }
    ("," expr=ExtendedIdentifier() { rules.addElement(expr); })*
       {
	   task.setRules(rules);
       }
}

Vector MatchOnList(IlrTaskDefinition task) :
{
    IlrTypeExpression expr;
    Vector classes = new Vector(5, 5);
}
{
    expr=TypeName() { classes.addElement(expr); }
    ("," expr=TypeName() { classes.addElement(expr); })*
       {
	   return classes;
       }
}

void FunctionTaskParameterAssignments(IlrTaskDefinition task) :
{
    Token body = null;
    Vector actions;
}
{
    try {
    body = "body" ("=")?
	{
	    task.tbody = body;
	}
    actions = TaskActions(task) (";")?
	{	    
	    IlrFunctionDefinition def = new IlrFunctionDefinition(body,
								  new Token[0],
								  null);
	    if (actions != null)
	    {
		for(int i=0; i<actions.size(); i++)
		    def.addAction((IlrActionExpression)actions.elementAt(i));
	    }
	    task.setFunction(def);
	}
   |
    CommonTaskParameterAssignments(task)
	}
    catch(ParseException ex)
      {
	  IlrRulesetParser ruleset = rulesetParser;
	  if (lastCommonTaskToken != null)
	      {
		  String message =
		      ruleset.reporter.computeTaskErrorMessage(ex,
							       lastCommonTaskToken,
							       task.name);
		  ruleset.reporter.insertException(ruleset,
						   ex.currentToken,
						   message);
		  lastCommonTaskToken = null;
	      }
	  else
	      ruleset.reporter.insertException(ruleset,ex);
	  Vector topLevelTokens = new Vector();
	  topLevelTokens.addElement("rule");
	  topLevelTokens.addElement("function");
	  topLevelTokens.addElement("ruletask");
	  topLevelTokens.addElement("functiontask");
	  topLevelTokens.addElement("flowtask");
	  Vector tokens = new Vector();
	  tokens.addAll(topLevelTokens);
	  tokens.addElement("property");
	  if (task.tbody == null) tokens.addElement("body");
	  if (task.tinitialactions == null) tokens.addElement("initialaction");
	  if (task.tfinalactions == null) tokens.addElement("finalaction");
	  if (task.tcompletionflag == null) tokens.addElement("completionflag");
	  String[] arr = new String[tokens.size()];
	  tokens.copyInto(arr);
	  String found = syncOn(arr);
	  if ((found == null) || topLevelTokens.contains(found))
	      throw ex;
      }

}

Vector TaskActions(IlrTaskDefinition task) :
{
    Token keyword,obrace,cbrace;
    IlrActionExpression action;
    Vector actions = new Vector(5, 5);
}
{
     obrace="{" { task.bodyobrace = obrace; }
     ( action = ActionStatement () { actions.addElement( action ); }  )*
     cbrace="}" { task.bodycbrace = cbrace; }
	 {
	     return actions;
	 }
}

void FlowTaskParameterAssignments(IlrTaskDefinition task) :
{
    Token body = null;
    IlrFlowDefinition flow=null;
    IlrTasksetDefinition taskset = rulesetParser.taskset;
}
{
    try {
	body = "body" ("=")?
	    { 
		task.tbody = body;
		flow = new IlrFlowDefinition(body, rulesetParser.reflect);
		taskset.addFlow(flow); 
		task.setFlow(flow);
	    }
	try {
	    FlowDefinition(flow) (";")?
	}
	catch(ParseException ex)
	    {
		lastCommonTaskToken = body;
		throw ex;
	    }
	    |
	CommonTaskParameterAssignments(task)
    }
    catch(ParseException ex)
	{
	    IlrRulesetParser ruleset = rulesetParser;
	    if (lastCommonTaskToken != null)
		{
		    String message =
			ruleset.reporter.computeTaskErrorMessage(ex,
								lastCommonTaskToken,
								task.name);
		    ruleset.reporter.insertException(ruleset,
						     ex.currentToken,
						     message);
		    lastCommonTaskToken = null;
		}
	    else
		ruleset.reporter.insertException(ruleset,ex);
	    Vector topLevelTokens = new Vector();
	    topLevelTokens.addElement("rule");
	    topLevelTokens.addElement("function");
	    topLevelTokens.addElement("ruletask");
	    topLevelTokens.addElement("functiontask");
	    topLevelTokens.addElement("flowtask");
	    Vector tokens = new Vector();
	    tokens.addAll(topLevelTokens);
	    tokens.addElement("property");
	    if (task.tbody == null) tokens.addElement("body");
	    if (task.tinitialactions == null) tokens.addElement("initialaction");
	    if (task.tfinalactions == null) tokens.addElement("finalaction");
	    if (task.tcompletionflag == null) tokens.addElement("completionflag");
	    String[] arr = new String[tokens.size()];
	    tokens.copyInto(arr);
	    String found = syncOn(arr);
	    if ((found == null) || topLevelTokens.contains(found))
		throw ex;
	}
}

void CommonTaskParameterAssignments(IlrTaskDefinition task) :
{
    IlrPropertyDefinition.Element prop;
    IlrExpression expr=null;
    Token keyword=null;
}
{
    try {
	(prop=Property()
	    {
		if (!task.properties.containsProperty(prop))
		task.properties.addProperty(prop);
		else
		{
		    String msg = IlrMessages.format("messages.Parsing.6", prop.getName());
		    rulesetParser.reporter.insertError(prop.getError(rulesetParser,msg));
		}
	    }
	 |
	 InitialFinalAction(task)
	 |
	 keyword = "completionflag" { task.tcompletionflag = keyword; }
	 "=" expr = Expression() ";"
	    {
		
		task.setCompletionFlag(expr);
	    }
	 )
	    }
    catch(ParseException ex)
	{
	    if (lastCommonTaskToken == null)
		lastCommonTaskToken = keyword;
	    
	    throw ex;
	}
}

void FlowDefinition(IlrFlowDefinition flow) :
{
    Token obrace;
    Token cbrace;
    IlrFlowNodeExpression node;
    IlrFlowNodeExpression previousNode=null;
}
{
    { flowIndex = 1; }
    obrace = "{"
	("}"
	 |
	(
	 node = FlowStatement(flow)
	    {
		flow.setRoot(node);
		if (!node.isSplitNode())
		  previousNode = node;
		else
		{
		    previousNode = ((IlrSplitNodeExpression)node).joinNode;
		    previousNode.scope = node.scope;
		}
	    }
	 (node = FlowStatement(flow) 
	     {
		 if (node != null)
		 {
		     previousNode.addOutputNode(node); 
		     if (!node.isSplitNode())
		       previousNode = node;
		     else
		     {
			 previousNode =
			     ((IlrSplitNodeExpression)node).joinNode;
			 previousNode.scope = node.scope;
		     }
		 }

	     }
	  )*
	 )
	 cbrace = "}"
	 )
}

IlrFlowNodeExpression FlowStatement(IlrFlowDefinition flow) :
{
    IlrFlowNodeExpression node=null;
}
{
    (LOOKAHEAD(TaskStatement(flow)) node = TaskStatement(flow)
     |
     LOOKAHEAD(WhileFlowStatementLookAhead()) node = WhileFlowStatement(flow)
     |
     LOOKAHEAD(SwitchFlowStatementLookAhead()) node = SwitchFlowStatement(flow)
     |
     LOOKAHEAD(IfFlowStatementLookAhead()) node = IfFlowStatement(flow)
     |
     node = ForkFlowStatement(flow)
     |
     node = GotoStatement(flow)
     |
     node = BreakOrContinueFlowStatement(flow)
     )
	{
	    return node;
	}
}

IlrFlowNodeExpression BreakOrContinueFlowStatement(IlrFlowDefinition flow) :
{
    Token keyword;
    IlrTaskGotoNodeExpression node=null;
    int kind = 0;
    Token end=null;
}
{
    (keyword = "break" { kind = IlrTaskGotoNodeExpression.Break; }
     |
     keyword = "continue" {kind = IlrTaskGotoNodeExpression.Continue; }
     )
	end = ";"
	{
	    node = new IlrTaskGotoNodeExpression(flow, keyword, null, kind, end);
	    node.setFlowIndex(flowIndex++);
	    flow.recordGotoNode(node);
	    return node;
	}
}

IlrFlowNodeExpression GotoStatement(IlrFlowDefinition flow) :
{
    Token keyword;
    Token tlabel;
    IlrFlowNodeExpression node=null;
    IlrTaskGotoNodeExpression gotoNode=null;
    Token end=null;
}
{
    keyword = "goto" tlabel = Identifier() end=";"
	{
	    gotoNode = new IlrTaskGotoNodeExpression(flow, keyword, tlabel,
						     IlrTaskGotoNodeExpression.Goto, end);
	    gotoNode.setFlowIndex(flowIndex++);
	    node = flow.getNode(tlabel);
	    if (node != null)
	    {
		gotoNode.setTargetNode(node);
	    }
	    flow.recordGotoNode(gotoNode);

	    return gotoNode;
	}
}

IlrFlowNodeExpression TaskStatement(IlrFlowDefinition flow) :
{
    Token label = null;
    Token[] ttask;
    IlrFlowNodeExpression node=null;
    Token end=null;
}
{
    (LOOKAHEAD(3) label = Identifier() ":" ttask = ExtendedIdentifier() end = ";"
	{
	    node = flow.getNode(label);
	    if (node == null)
	    {
		node = new IlrTaskInstanceExpression(flow, label, ttask, end);
		node.setFlowIndex(flowIndex++);
		flow.addNamedNode(node);
	    }
	    else
	    {
		String msg = IlrMessages.format("messages.Parsing.11", label.image);
		rulesetParser.reporter.insertException(rulesetParser, label,
						       msg);
	    }
	}
     |
     ttask = ExtendedIdentifier() end = ";"
	{
	    node = new IlrTaskInstanceExpression(flow, ttask, end);
	    node.setFlowIndex(flowIndex++);
	}
     )
	{
	    return node;
	}
}


void IfFlowStatementLookAhead() :
{
}
{
    [Identifier() ":"] "if"
}

IlrFlowNodeExpression IfFlowStatement(IlrFlowDefinition flow) :
{
    Token keyword;
    Token label=null;
    Token elsekeyword=null;
    Token opar;
    Token cpar;
    Token obrace;
    Token cbrace;
    IlrTestExpression test;
    IlrTaskIfNodeExpression ifNode=null;
    IlrReflect reflect = rulesetParser.reflect;
    IlrConstantValue tvalue = reflect.factory.TRUE;
    IlrConstantValue fvalue = reflect.factory.FALSE;
    IlrTaskJoinNodeExpression joinNode=null;
}
{
    [label = Identifier() ":" ]
    keyword = "if" opar = "(" test=TestExpression() cpar = ")"
	{
	    if (label == null)
	       ifNode =
	    new IlrTaskIfNodeExpression(flow, keyword, opar, cpar);
	    else
	    {
	       ifNode =
	    new IlrTaskIfNodeExpression(flow, label, keyword, opar, cpar);
	       flow.addNamedNode(ifNode);
	    }
	    ifNode.setFlowIndex(flowIndex++);
	    ifNode.setTest(test);
	}
    // Then part
    Branch(flow, ifNode, tvalue)
    // Else part
	[
	  LOOKAHEAD(1) elsekeyword="else" 
	  Branch(flow, ifNode, fvalue)
	]
	{
	    if (elsekeyword == null)
		flow.addPendingNode(ifNode, ifNode, fvalue);
	    ifNode.close(flow, keyword);
	    return ifNode;
	}
}

void SwitchFlowStatementLookAhead() :
{
}
{
    [Identifier() ":"] "switch"
}

IlrFlowNodeExpression SwitchFlowStatement(IlrFlowDefinition flow) :
{
    Token keyword;
    boolean defFound=false;
    Token obrace;
    Token cbrace;
    Token label=null;
    IlrExpression expr;
    Token tcase;
    Object object;
    IlrReflectClass type;
    IlrConstantValue constant=null;
    IlrReflect reflect = rulesetParser.reflect;
    IlrTaskSwitchNodeExpression switchNode = null;
    IlrTaskJoinNodeExpression joinNode=null;
    Token opar=null;
    Token cpar=null;
}
{
    [label = Identifier() ":" ]
    keyword = "switch" opar="(" expr = Expression() cpar=")"
	{
	    if (label == null)
	    switchNode =
	    new IlrTaskSwitchNodeExpression(flow, keyword, opar, cpar);
	    else
	    {
		switchNode =
		    new IlrTaskSwitchNodeExpression(flow, label, keyword,
						    opar, cpar);
		 flow.addNamedNode(switchNode);
	    }
	    switchNode.setFlowIndex(flowIndex++);
	    switchNode.setExpression(expr);
	}

    obrace = "{"
	// Case part
	(
	 (LOOKAHEAD(1) keyword = "case" tcase = <INTEGER_LITERAL> ":"
	    {
		object = parseIntegerLiteral(tcase,1);
		if (object instanceof Integer) type = reflect.intType();
		else type = reflect.longType();
		constant = new IlrConstantValue(reflect,type,object);
	    }
	 |
	  keyword = "default" ":" { defFound = true; }
	  )
	 Branch(flow, switchNode, constant)
	    {
		constant = null;
	    }
	 )*
    cbrace = "}"	
	{
	    if (!defFound)
		flow.addPendingNode(switchNode, switchNode, null);
	    switchNode.close(flow, keyword);
	    return switchNode;
	}
}

void WhileFlowStatementLookAhead() :
{
}
{
    LOOKAHEAD(2) "while" "("
   |
    Identifier() ":" "while" "("
}


IlrFlowNodeExpression WhileFlowStatement(IlrFlowDefinition flow) :
{
    Token keyword;
    Token obrace;
    Token cbrace;
    Token label=null;
    IlrTestExpression test;
    IlrTaskWhileNodeExpression whileNode=null;
    IlrTaskJoinNodeExpression joinNode=null;
    Token opar=null;
    Token cpar=null;
}
{    
    (
     LOOKAHEAD(2) keyword = "while" opar="(" 
     |
     label = Identifier() ":" keyword = "while" opar="(" 
    )
	test=TestExpression() cpar=")"
	{
	    if (label == null)
	    {
		whileNode = new IlrTaskWhileNodeExpression(flow, keyword, opar, cpar); 
	    }
	    else
	    {
		whileNode = new IlrTaskWhileNodeExpression(flow, keyword, label, opar, cpar);
		flow.addNamedNode(whileNode);
	    }
	    whileNode.setFlowIndex(flowIndex++);
	    whileNode.setTestExpression(test);
	}
    Branch(flow, whileNode, null)
	{
	    whileNode.close(flow, keyword);
	    return whileNode;
	}
}

void BracedBranch(IlrFlowDefinition flow,
		  IlrSplitNodeExpression fatherNode,
		  IlrConstantValue value) :
{
    IlrFlowNodeExpression node=null;
    IlrFlowNodeExpression node1=null;
    IlrReflect reflect = rulesetParser.reflect;
    Token obrace;
    Token cbrace;
}
{
    obrace = "{" 
    (
     "}"
	{
	    flow.addPendingNode(fatherNode, fatherNode, value);
	}
     |
    (
     node = FlowStatement(flow)
	{ 
	    node.scope = fatherNode;
	    if (fatherNode.isIfNode())
	    {
		if (value == reflect.factory.TRUE)
		    ((IlrTaskIfNodeExpression)fatherNode).setTrueNode(node);
		else
		    ((IlrTaskIfNodeExpression)fatherNode).setFalseNode(node);
	    }
	    else if (fatherNode.isSwitchNode())
	    {
		if (value == null)
		((IlrTaskSwitchNodeExpression)fatherNode).setDefaultNode(node);
		else
		((IlrTaskSwitchNodeExpression)fatherNode).setCaseNode(value, node);
	    }
	    else
	    {
		fatherNode.addOutputNode(node);
	    }
	    if (node.isSplitNode())
	    {
		((IlrSplitNodeExpression)node).joinNode.scope = node.scope;
		node = ((IlrSplitNodeExpression)node).joinNode;
	    }
	}
     )
    (
     node1 = FlowStatement(flow)
	{ 
	    if (node1 != null)
	    {
		node1.scope = fatherNode;
		node.addOutputNode(node1);
		if (!node1.isSplitNode())
		  node = node1;
		else
		{
		    ((IlrSplitNodeExpression)node1).joinNode.scope = node1.scope;
		    node = ((IlrSplitNodeExpression)node1).joinNode;
		}
	    }
	}
     )*
	{
	    flow.addPendingNode(fatherNode, node, value);
	}
    cbrace = "}"
     )
}

void Branch(IlrFlowDefinition flow,
	    IlrSplitNodeExpression fatherNode,
	    IlrConstantValue value) :
{
    IlrFlowNodeExpression node=null;
    IlrFlowNodeExpression node1=null;
    IlrReflect reflect = rulesetParser.reflect;
    boolean gotoFound=false;
    Token obrace;
    Token cbrace;
}
{
    (
     node = FlowStatement(flow)
	{ 
	    node.scope = fatherNode;
	    if (fatherNode.isIfNode())
	    {
		if (value == reflect.factory.TRUE)
		    ((IlrTaskIfNodeExpression)fatherNode).setTrueNode(node);
		else
		    ((IlrTaskIfNodeExpression)fatherNode).setFalseNode(node);
	    }
	    else if (fatherNode.isSwitchNode())
	    {
		if (value == null)
		((IlrTaskSwitchNodeExpression)fatherNode).setDefaultNode(node); 
		else
		((IlrTaskSwitchNodeExpression)fatherNode).setCaseNode(value, node); 
	    }
	    else
	      fatherNode.addOutputNode(node);
	    if (node.isSplitNode())
  	      flow.addPendingNode(fatherNode,
			((IlrSplitNodeExpression)node).joinNode, value);
	    else
  	      flow.addPendingNode(fatherNode, node, value);
	}
     ) 
     |
    BracedBranch(flow, fatherNode, value)
}

IlrFlowNodeExpression ForkFlowStatement(IlrFlowDefinition flow) :
{
    Token keyword=null;
    Token label=null;
    IlrTaskForkNodeExpression forkNode=null;
    Token obrace=null;
    Token cbrace=null;
    IlrTaskJoinNodeExpression joinNode=null;
    IlrFlowNodeExpression node=null;
}
{
    [label = Identifier() ":" ]
    keyword = "fork" 
	{
	    if (label == null)
	      forkNode = new IlrTaskForkNodeExpression(flow, keyword);
	    else
	    {
		forkNode = new IlrTaskForkNodeExpression(flow, keyword, label);
		flow.addNamedNode(forkNode);
	    }
	    forkNode.setFlowIndex(flowIndex++);
	}
    BracedBranch(flow, forkNode, null)

    (LOOKAHEAD("&&") "&&" 
     BracedBranch(flow,forkNode,null)
     )*
	(";")?
	{
	    forkNode.close(flow, keyword);
	    return forkNode;
	}
}

void InitialFinalAction(IlrTaskDefinition task) :
{
    Token keyword;
    IlrTestExpression test;
    boolean initial=true;
    Vector actions;
}
{
    (keyword = "initialaction"
	{
	    if (!task.hasInitialActions())
	    {
		task.tinitialactions = keyword;
		initial = true; 
	    }
	    else
	    {
		String msg = IlrMessages.format("messages.Parsing.12", task.name);
		rulesetParser.reporter.insertException(rulesetParser, keyword,
						       msg);
		return;
	    }
	}
     |
     keyword = "finalaction"
	{
	    if (!task.hasFinalActions())
	    {
		task.tfinalactions = keyword;
		initial = false;
	    }
	    else
	    {
		String msg = IlrMessages.format("messages.Parsing.13", task.name);
		rulesetParser.reporter.insertException(rulesetParser, keyword,
						       msg);
		return;
	    }
	}
     )
	("=")?
	try {
	    (actions = TaskActions(task) (";")?
		{
		    IlrFunctionDefinition def =
		    new IlrFunctionDefinition(keyword,
					      new Token[0], null);
		    if (actions != null)
		    {
			for(int i=0; i<actions.size(); i++)
			    def.addAction((IlrActionExpression)actions.elementAt(i));
		    }
		    if (initial)
		    task.setInitialActions(def);
		    else
		    task.setFinalActions(def);
		}
	     )
	}
	catch(ParseException ex)
	    {
		lastCommonTaskToken = keyword;
		throw ex;
	    }
}
//---------------------------------------------------------------------------
// Conditions
//---------------------------------------------------------------------------

void RuleConditions(IlrRuleDefinition rule) :
{
    Token t,obrace,cbrace;
    IlrConditionExpression cond;
}
{
    t="when" { rule.whenToken = t; }
    obrace="{" { rule.whenObrace = obrace; }
    cond=FirstPattern() { rule.addCondition(cond); }
    (
     cond=LhsPattern() { rule.addCondition(cond); }
     )*
    cbrace="}" { rule.whenCbrace = cbrace; }
}

//---------------------------------------------------------------------------
// Condition part
//---------------------------------------------------------------------------

IlrConditionExpression FirstPattern() :
{
    IlrConditionExpression cond;
    Token t = null;
}
{
    cond=NotPattern() { return cond; }
    |
    cond=ExistsPattern() { return cond; }
    |
    (LOOKAHEAD(2) t=Variable() ":")?
      (
       cond=ClassPattern(t) { return cond; }
       |
       cond=CollectPattern(t) { return cond; }
       )
}

IlrConditionExpression LhsPattern() :
{
    IlrConditionExpression cond;
}
{
    LOOKAHEAD(4) cond=FirstPattern() { return cond; }
    | cond=EvaluatePattern() { return cond; }
    | cond=WaitPattern() { return cond; }
}

IlrConditionExpression ClassPattern(Token t) :
{
    IlrClassExpression expr;
}
{
    expr=ClassCondition(SimpleClassExpr) ";"
      {
	  IlrSimpleClassExpression cond = (IlrSimpleClassExpression)expr;
	  cond.setObjectBinding(t);
	  return cond;
      }
}

IlrConditionExpression CollectPattern(Token t) :
{
    IlrExpression container = null;
    IlrClassExpression element = null;
    IlrAndExpression tests = null;
    IlrCollectExpression cond;
}
{
    "collect" [ "(" [container=Expression()] ")" ]
    element=ClassCondition(CollectClassExpr)
    [ "where" "(" tests=TestAssignmentSuite() ")" ] ";"
      {
	  cond = new IlrCollectExpression(container, element, tests);
	  cond.setObjectBinding(t);
	  return cond;
      }
}

IlrConditionExpression NotPattern() :
{
    IlrClassExpression cond;
}
{
    "not" cond=ClassCondition(NotClassExpr) ";"
      {
	  return cond;
      }
}

IlrConditionExpression ExistsPattern() :
{
    IlrClassExpression cond;
}
{
    "exists" cond=ClassCondition(ExistsClassExpr) ";"
      {
	  return cond;
      }
}

IlrConditionExpression EvaluatePattern() :
{
  Token t;
    IlrAndExpression expr;
}
{
    t="evaluate" "(" expr=TestAssignmentSuite() ")" ";"
      {
	  return new IlrEvaluateExpression(t,expr);
      }
}

IlrConditionExpression WaitPattern() :
{
    Token keyword;
    Token label = null;
    Token logicalToken = null;
    boolean until = false;
    IlrExpression time;
    IlrTimeExpression cond;
    IlrConditionExpression element;
}
{
    (LOOKAHEAD(2) label=Variable() ":")?   // LOOKAHEAD to correct BR2003.816
     keyword="wait"
     (logicalToken="logical")?
     {
	 cond = new IlrTimeExpression(keyword,logicalToken);
	 if (label != null) cond.setObjectBinding(label);
     }
     (
      ("until" { until=true; } )?
      time=Expression()
      {
	  cond.setTime(until,time);
      }
      )?
     (
      ";"
      |
      "{"
      (
       element=FirstPattern() { cond.addCondition(element); }
       )*
      "}"
      )
       {
	   return cond;
       }
}

//---------------------------------------------------------------------------
// Class Condition
//---------------------------------------------------------------------------

IlrClassExpression ClassCondition(int kind) :
{
    Token event = null;
    IlrTypeExpression type;
    IlrAndExpression expr = null;
    IlrExpression enumerator = null;
    Token clause = null;
}
{
   [ event="event" ]
   type=TypeName() "(" [ expr=TestAssignmentSuite() ] ")"
   [
    (clause="from" | clause="in") enumerator=Expression()
   ]
     {
	 IlrClassExpression condition;
	 switch(kind)
	   {
	     case SimpleClassExpr:
	       condition = new IlrSimpleClassExpression(type,expr);
	       break;
	     case NotClassExpr:
	       condition = new IlrNotClassExpression(type,expr);
	       break;
	     case ExistsClassExpr:
	       condition = new IlrExistsClassExpression(type,expr);
	       break;
	     case CollectClassExpr:
	       condition = new IlrCollectElementExpression(type,expr);
	       break;
	     default:
	       condition = null;
	       break;
	   }
	 condition.eventKeyword = event;
	 condition.enumeratorClause = clause;
	 condition.enumerator = enumerator;
	 return condition;
     }
}

//---------------------------------------------------------------------------
// Tests
//---------------------------------------------------------------------------

IlrAndExpression TestAssignmentSuite() :
{
    IlrAndExpression expr = new IlrAndExpression();
    IlrOrExpression tmp;
}
{
    tmp=TestAssignmentSet() { expr.tests.addElement(tmp); }
    (LOOKAHEAD(2) ";" tmp=TestAssignmentSet() { expr.tests.addElement(tmp);})*
    [";"]
      { return expr; }
}

//---------------------------------------------------------------------------
// Decomposition of tests and assignment (combination of OR, AND)
//---------------------------------------------------------------------------

IlrOrExpression TestAssignmentSet() :
{
    IlrOrExpression expr;
}
{
    expr=OrTestAssignmentSet() { return expr; }
}

IlrOrExpression OrTestAssignmentSet() :
{
    IlrOrExpression expr = new IlrOrExpression();
    IlrAndExpression test;
}
{
    test=AndTestAssignmentSet() { expr.tests.addElement(test); }
   ("||" test=AndTestAssignmentSet() { expr.tests.addElement(test); } )*
     { return expr; }
}

IlrAndExpression AndTestAssignmentSet() :
{
    IlrAndExpression expr = new IlrAndExpression();
    IlrTestExpression test;
}
{
    test=TestAssignment() { expr.tests.addElement(test); }
   ("&&" test=TestAssignment() { expr.tests.addElement(test); } )*
     { return expr; }
}

IlrTestExpression TestAssignment() :
{
    IlrTestExpression expr;
}
{
    (
     LOOKAHEAD(Variable() ":") expr=VariableAssignment()
     |
     LOOKAHEAD(UnaryExpression()) expr=BooleanExpression()
     |
     "(" expr=TestAssignmentSet() ")"
     |
     "!" expr=TestAssignment() { expr = new IlrFalseTestExpression(expr); }
    )
    { return expr; }
}

//---------------------------------------------------------------------------
// Assignments
//---------------------------------------------------------------------------

IlrAndExpression VariableAssignment() :
{
    IlrAndExpression expr = new IlrAndExpression();
    IlrVariableExpression variable;
    IlrExpression value;
    Token t;
    IlrTestExpression test;
}
{
    t=Variable() ":" value=Expression()
      {
	  variable = new IlrVariableExpression(t);
	  expr.tests.addElement(new IlrBindingExpression(variable,value));
      }
    ("&" test=BooleanArguments(variable) { expr.tests.addElement(test); } )*
      {
	  return expr;
      }
}

//---------------------------------------------------------------------------
// Tests
//---------------------------------------------------------------------------

IlrAndExpression BooleanExpression() :
{
    IlrAndExpression expr = new IlrAndExpression();
    IlrExpression initial;
    IlrTestExpression test;
}
{
    initial=Expression()
    [
     test=BooleanArguments(initial) { expr.tests.addElement(test); }
    ("&" test=BooleanArguments(initial) { expr.tests.addElement(test); } )*
    ]
    {
	if (expr.tests.size() == 0)
	  expr.tests.addElement(new IlrTrueTestExpression(initial));
	return expr;
    }
}

IlrTestExpression BooleanArguments(IlrExpression e1) :
{
    IlrTestExpression test;
}
{
    (LOOKAHEAD(TypeTestArgumentsLookAhead()) test=TypeTestArguments(e1) |
     LOOKAHEAD(TemporalTestOperator()) test=TemporalTestArguments(e1) |
     test=ValueTestArguments(e1) |
     test=UnknownTestArguments(e1) |
     test=KnownTestArguments(e1))
      {
	  return test;
      }
}

IlrTestExpression UnknownTestArguments(IlrExpression e1) :
{
}
{
    "isunknown"
      {
	  return new IlrUnknownTestExpression(e1, true);
      }
}

IlrTestExpression KnownTestArguments(IlrExpression e1) :
{
}
{
    "isknown"
      {
	  return new IlrUnknownTestExpression(e1, false);
      }
}

void TypeTestArgumentsLookAhead() :
{
}
{
  ("instanceof" | "is") TypeName()
}

IlrTypeTestExpression TypeTestArguments(IlrExpression e1) :
{
    IlrTypeExpression type;
}
{
  ("instanceof" | "is") type=TypeName()
  {
    return new IlrTypeTestExpression(e1,type);
  }
}

// Modified for in and !in predicate
IlrBinaryTestExpression ValueTestArguments(IlrExpression e1) :
{
    IlrBinaryTestExpression expr=null;
}
{
    (LOOKAHEAD(3) expr = ValueTestArguments1(e1) | expr = ValueTestArguments2(e1))
	{
	    return expr;
	}
}
IlrExpression ListExpression() :
{
    IlrExpression expr = null;
    Vector values = new Vector();
    Token begin=null;
    Token end=null;
}
{
    begin = "{" 
	expr = Expression() { values.addElement(expr); }
    ("," expr = Expression() { values.addElement(expr); } )*
    end = "}" 
	{ return new IlrNewArrayInstanceExpression(begin, end, null, values); }
}
IlrBinaryTestExpression ValueTestArguments1(IlrExpression e1) :
{
    IlrExpression e2;
    Token t = null;
    Token t1 = null;
    boolean not=false;
    int kind = 0;
}
{
    [t = "!" { not = true; }] t1 = "in" e2=ListExpression()
	{
	    if (!not)
	    {
		kind = IlrBinaryTester.IN;
		return new IlrContainExpression(kind, e1, e2);
	    }
	    else 
	    {
		kind = IlrBinaryTester.NOT_IN;
		return new IlrContainExpression(kind, e1, e2);
	    }
	}

}

IlrBinaryTestExpression ValueTestArguments2(IlrExpression e1) :
{
    IlrExpression e2;
    Token t = null;
    Token t1 = null;
    int p = 0;
    int kind = 0;
}
{
    (p=PredefinedPredicate() | t1 = "!" t = "in" | t=Identifier()) e2=Expression()
      {
	  switch(p)
	    {
	      case PredEQ:
		kind = IlrBinaryTester.EQUAL;
		return new IlrComparativeExpression(kind,e1,e2);
	      case PredNE:
		kind = IlrBinaryTester.NOT_EQUAL;
		return new IlrComparativeExpression(kind,e1,e2);
	      case PredLT:
		kind = IlrBinaryTester.LESS_THAN;
		return new IlrComparativeExpression(kind,e1,e2);
	      case PredGT:
		kind = IlrBinaryTester.GREATER_THAN;
		return new IlrComparativeExpression(kind,e1,e2);
	      case PredLE:
		kind = IlrBinaryTester.LESS_OR_EQUAL;
		return new IlrComparativeExpression(kind,e1,e2);
	      case PredGE:
		kind = IlrBinaryTester.GREATER_OR_EQUAL;
		return new IlrComparativeExpression(kind,e1,e2);
	      default:
	      if (t.image.equals("in"))
	      {
		  if (t1 == null)
		      {
			  kind = IlrBinaryTester.IN;
			  return new IlrContainExpression(kind, e1, e2);
		      }
		  else 
		      {
			  kind = IlrBinaryTester.NOT_IN;
			  return new IlrContainExpression(kind, e1, e2);
		      }
	      }
	      else return new IlrPredicateExpression(t,e1,e2);
	    }
      }
}
// End - Modified for in and !in predicate

int PredefinedPredicate() :
{}
{
  "==" { return PredEQ; }
  | "!=" { return PredNE; }
  | "<"  { return PredLT; }
  | ">"  { return PredGT; }
  | "<=" { return PredLE; }
  | ">=" { return PredGE; }
}

void TemporalTestOperator() :
{
}
{
  "occursin" | "before" | "after"
}

IlrTemporalTestExpression TemporalTestArguments(IlrExpression e1) :
{
  IlrTemporalTestExpression test;
}
{
  (test = UnaryTemporalTestArguments(e1) |
   test = BinaryTemporalTestArguments(e1))
    {
      return test;
    }
}

IlrTemporalTestExpression UnaryTemporalTestArguments(IlrExpression e1) :
{
  IlrTimeInterval interval;
  Token keyword=null;
}
{
  keyword = "occursin" interval=TimeInterval()
    {
	return new IlrUnaryTemporalTestExpression(e1,interval, keyword);
    }
}

IlrTemporalTestExpression BinaryTemporalTestArguments(IlrExpression e1) :
{
  Token operator;
  IlrTimeInterval interval = null;
  IlrExpression e2;
}
{
  ( operator="before" | operator="after" )
  [ interval=TimeInterval() ]
  e2=Expression()
    {
      return new IlrBinaryTemporalTestExpression(operator,e1,e2,interval);
    }
}

IlrTimeInterval TimeInterval() :
{
  IlrExpression lo, hi;
}
{
  "["
    ( LOOKAHEAD("$") "$" { lo = null; } | lo = Expression() )
  ","
    ( LOOKAHEAD("$") "$" { hi = null; } | hi = Expression() )
  "]"
    {
      return new IlrTimeInterval(lo,hi);
    }
}



//---------------------------------------------------------------------------
// Expressions
//---------------------------------------------------------------------------

/*
IlrExpression Expression() :
{
    IlrExpression expr;
}
{
    expr=ConditionalExpression() { return expr; }
}

IlrExpression ConditionalExpression() :
{}
{
    AdditiveExpression() [ "?" Expression() ":" ConditionalExpression() ]
      {
	  return null;
      }
}
*/

IlrExpression ExpressionEof() :
{
    IlrExpression expr;
}
{
    expr=Expression() <EOF>	{ return expr; }
}

IlrExpression Expression() :
{
    IlrExpression expr;
}
{
    expr=AdditiveExpression() 	{ return expr; }
}

IlrExpression AdditiveExpression() :
{
    IlrExpression expr,e1,e2;
    Token t;
    int op;
}
{
    (
    expr=MultiplicativeExpression()
    (
     (t="+" | t="-") e2=MultiplicativeExpression()
     {
	 e1 = expr;
	 if (t.image.equals("+")) op = IlrBinaryOperator.ADD;
	 else op = IlrBinaryOperator.SUBTRACT;
	 expr = new IlrBinaryExpression(t,op,e1,e2);
     }
    )*
    )
    { return expr; }
}

IlrExpression MultiplicativeExpression() :
{
    IlrExpression expr,e1,e2;
    Token t;
    int op;
}
{
    (
    expr=UnaryExpression()
    (
     (t="*" | t="/" | t="%") e2=UnaryExpression()
     {
	 e1 = expr;
	 if (t.image.equals("*")) op = IlrBinaryOperator.MULTIPLY;
	 else if (t.image.equals("/")) op = IlrBinaryOperator.DIVIDE;
	 else op = IlrBinaryOperator.REMAINDER;
	 expr = new IlrBinaryExpression(t,op,e1,e2);
     }
    )*
    )
    { return expr; }
}

IlrExpression UnaryExpression() :
{
    IlrExpression expr;
    IlrExpression tmp;
    Token t;
}
{
    (
     LOOKAHEAD ( SignedNumberLookahead() ) expr=SignedNumberExpression ()
     |
     (t="+" | t="-" | t="!" | t="++" | t="--") expr=UnaryExpression()
       {
	 tmp = expr;
	 if (t.image.equals("!"))
	   expr = new IlrUnaryExpression(t,IlrUnaryOperator.NOT,tmp);
	 else if (t.image.equals("+"))
	   expr = new IlrUnaryExpression(t,IlrUnaryOperator.POSITIVE,tmp);
	 else if (t.image.equals("-"))
	   expr = new IlrUnaryExpression(t,IlrUnaryOperator.NEGATIVE,tmp);
	 else if (t.image.equals("++"))
	   expr = new IlrUnaryExpression(t,IlrUnaryOperator.PREFIX_INCR,tmp);
	 else
	   expr = new IlrUnaryExpression(t,IlrUnaryOperator.PREFIX_DECR,tmp);
       }
     | expr=UnaryExpressionNotPlusMinus()
    )
    { return expr; }
}

IlrExpression UnaryExpressionNotPlusMinus() :
{
    IlrExpression expr;
    Token t = null;
    int kind;
}
{
    (
     LOOKAHEAD(CastLookahead()) expr=CastExpression()
     |
     LOOKAHEAD(TimeofLookahead()) expr=TimeofExpression()
     |
     expr=PrimaryExpression() [ (t="++" | t="--") ]
     {
       if (t != null)
	 {
	   if (t.image.equals("++")) kind = IlrUnaryOperator.POSTFIX_INCR;
	   else kind = IlrUnaryOperator.POSTFIX_DECR;
	   expr = new IlrUnaryExpression(t,kind,expr);
	 }
     }
    )
    {
	return expr;
    }
}

void CastLookahead() :
{}
{
    "(" TypeName() ")"
     (
      "!" | "+" | "-" | "++" | "--"
      | "("

      | "new"
      | LiteralLookahead()
      | Name()
      )
}

IlrExpression CastExpression() :
{
    Token open;
    Token close;
    IlrTypeExpression type;
    IlrExpression expr;
}
{
    open="(" type=TypeName() close=")" expr=UnaryExpression()
      {
	  return new IlrCastExpression(open,close,type,expr);
      }
}

void TimeofLookahead() :
{
}
{
  "timeof"
}

IlrExpression TimeofExpression() :
{
  Token timeof, open, close;
  IlrExpression expr;
}
{
  timeof="timeof" open="(" expr=Expression() close=")"
    {
      return new IlrTimeofExpression(timeof, open, expr, close);
    }
}


IlrExpression PrimaryExpression() :
{
    IlrExpression expr;
}
{
    expr=PrimaryPrefix()
    (
     LOOKAHEAD(2)
     expr=PrimarySuffix(expr)
    )*
    { return expr; }
}

IlrExpression PrimaryPrefix() :
{
    IlrExpression expr;
}
{
    (
     expr=Literal()
     | expr=Name()
     | expr=AllocationExpression()
     | "(" expr=Expression() ")"
    )
    { return expr; }
}

IlrExpression AllocationExpression() :
{
  IlrSimpleTypeExpression type;
  IlrArgumentList arguments;
  Token t;
}
{
  t="new" type=SimpleTypeName()
  (
   arguments=Arguments()
    {
      return new IlrNewInstanceExpression(t,type,arguments);
    }
   |
   arguments=ArrayDims()
    {
      return new IlrNewArrayInstanceExpression(t,type,arguments);
    }
   )
}

IlrArgumentList ArrayDims() :
{
  IlrExpression expr;
  Token open;
  Token close;
  Vector vect = new Vector(5);
}
{
  open="[" expr = Expression() close="]" { vect.addElement(expr); }
  (LOOKAHEAD(2)
   "[" expr = Expression() close="]" { vect.addElement(expr); }
   )*
  {
    return new IlrArgumentList(open,close,vect);
  }
}

IlrExpression PrimarySuffix(IlrExpression expr) :
{
  IlrArgumentList args;
  Token t;
}
{
  (
   "." (t= Identifier()
	|
	// BR 2003.675
	t=<VARIABLE> { t.image = '?' + t.image; }
	)
    {
      return new IlrNameAccessExpression(expr,t);
    }
   |
   args=ArrayArguments()
    {
      return new IlrArrayElementExpression(expr,args);
    }
   |
   args=Arguments()
    {
      return new IlrFunctionCallExpression(expr,args);
    }
   )
}

IlrArgumentList ArrayArguments() :
{
  Token open;
  Token close;
  Vector v = new Vector(5);
}
{
  open="[" [ ArgumentList(v) ] close="]"
  {
    return new IlrArgumentList(open,close,v);
  }
}

IlrArgumentList Arguments() :
{
    Token open;
    Token close;
    Vector v = new Vector(5);
}
{
    open="(" [ ArgumentList(v) ] close=")"
      {
	  return new IlrArgumentList(open,close,v);
      }
}

void ArgumentList(Vector args) :
{
    IlrExpression expr;
}
{
    expr=Expression() { args.addElement(expr); }
    ( "," expr=Expression() { args.addElement(expr); } )*
}

//
// Warning: Here, a name is starting with an Identifier() or
// a Variable(). As Variable() is more generic, we use this form
// for desambiguiting the grammar. But the action should build
// objects of different classes. Thus, a form "?XXX" is never considered
// to be a name, while "XXX" can be processed as a variable.
//
IlrExpression Name() :
{
    Token t;
    IlrExpression expr;
}
{
    t=Variable()
     {
	 if (t.kind == VARIABLE) expr = new IlrVariableExpression(t);
	 else expr = new IlrIdentifierExpression(t);
     }
    (LOOKAHEAD(2) "." t=Identifier()
     {
	 expr = new IlrNameAccessExpression(expr,t);
     }
    )*
    {
	return expr;
    }
}

//---------------------------------------------------------------------------
// Rule Actions
//---------------------------------------------------------------------------

void RuleActions(IlrRuleDefinition rule) :
{
    Token t,obrace,cbrace;
    IlrActionExpression statement;
}
{
    t="then" { rule.thenToken = t; }
    obrace="{" { rule.thenObrace = obrace; }
      (statement=ActionStatement() { rule.addAction(statement); })*
      (statement=TimeOutStatement() { rule.addAction(statement); })*
    cbrace="}" { rule.thenCbrace = cbrace; }
   (
    t = "else" { rule.elseToken = t; }
    obrace="{" { rule.elseObrace = obrace; }
    (statement=ActionStatement() { rule.addElseAction(statement); })*
    (statement=TimeOutStatement() { rule.addElseAction(statement); })*
    cbrace="}" { rule.elseCbrace = cbrace; }
   )?
}

IlrActionExpression ActionStatement() :
{
    IlrActionExpression statement;
}
{
    (
     LOOKAHEAD(SimpleStatement()) statement=SimpleStatement()
   | LOOKAHEAD(3) statement=BindStatement()
   | LOOKAHEAD(3) statement=AssertStatement()
   | LOOKAHEAD(3) statement=RetractStatement()
   | LOOKAHEAD(3) statement=UpdateStatement()
   | LOOKAHEAD(3) statement=ModifyStatement()
   | LOOKAHEAD(3) statement=ApplyStatement()
   | LOOKAHEAD(3) statement=IfStatement()
   | LOOKAHEAD(3) statement=ExecuteStatement()
   | LOOKAHEAD(3) statement=WhileStatement()
   | LOOKAHEAD(3) statement=ForStatement()
   | LOOKAHEAD(3) statement=ReturnStatement()
   | LOOKAHEAD(3) statement=BreakStatement()
   | LOOKAHEAD(3) statement=ContinueStatement()
   | LOOKAHEAD(3) statement=ThrowStatement()
   | LOOKAHEAD(3) statement=TryStatement()
     )
      {
	  return statement;
      }
}

IlrActionExpression TryStatement() :
{
    Token keyword;
    Token obrace = null;
    Token cbrace = null;
    Vector actions = new Vector(5,5);
    IlrActionExpression action;
    IlrFinallyBlockExpression finallyExpr = null;
    IlrTryCatchFinallyExpression expr;
    Vector catches = null;
}
{
    keyword="try" obrace="{"
    (
     (action=ActionStatement() { actions.addElement(action); })*
    )
    cbrace="}"
    (
     finallyExpr = Finally()
     |
     (catches = Catches())+ (finallyExpr = Finally())?
    )

      {
	  expr = new IlrTryCatchFinallyExpression(keyword, obrace, cbrace,
						  null, actions);
	  if (catches != null)
   	    expr.setCatchPart(catches);
	  if (finallyExpr != null)
	    expr.setFinallyPart(finallyExpr);
	  return expr;
      }
}

Vector Catches() :
{
    IlrCatchBlockExpression catchClause = null;
    Vector catchExpressions = new Vector(5);
}
{
    catchClause = CatchClause() { catchExpressions.add(catchClause); }
     (
      LOOKAHEAD(2)
      catchClause = CatchClause() 
     { catchExpressions.addElement(catchClause); }
      )*
     {
	 return catchExpressions;	 
     }
}

IlrCatchBlockExpression CatchClause() :
{
    Token begin;
    Token variable;
    Token obrace = null;
    Token cbrace = null;
    Token opar;
    Token cpar;
    Vector actions = new Vector(5,5);
    IlrActionExpression action;
    IlrFunctionArgExpression arg;
    IlrCatchBlockExpression expr;
}
{
    begin="catch" opar = "(" (arg = FunctionArgDefinition()) cpar = ")"
    obrace="{"
    (
     (action=ActionStatement() { actions.addElement(action); })*
    )
    cbrace="}"
      {
	  expr = new IlrCatchBlockExpression(begin, obrace, cbrace, null,
					     actions, arg);
	  return expr;
      }
}

IlrFinallyBlockExpression Finally() :
{
    Token begin;
    Token variable;
    Token obrace = null;
    Token cbrace = null;
    Vector actions = new Vector(5,5);
    IlrActionExpression action;
    IlrFinallyBlockExpression expr;
}
{
    begin="finally" obrace="{"
    (
     (action=ActionStatement() { actions.addElement(action); })*
    )
    cbrace="}"
      {
	  expr = new IlrFinallyBlockExpression(begin,obrace,cbrace,
					       null, actions);
	  return expr;
      }
}

IlrActionExpression ThrowStatement() :
{
    Token begin;
    Token variable;
    IlrExpression expr=null;
    Token end;
}
{
    begin="throw" (expr=Expression()) end=";"
      {
	  return new IlrThrowExpression(begin, end, expr); 
      }
}

IlrActionExpression ReturnStatement() :
{
    Token begin;
    Token variable;
    IlrExpression expr=null;
    Token end;
}
{
    begin="return" (expr=Expression())? end=";"
      {
	  return new IlrReturnExpression(begin, end, expr);
      }
}

IlrActionExpression BreakStatement() :
{
    Token begin;
    Token end;
}
{
    begin="break" end=";"
      {
	  return new IlrBreakExpression(begin, end );
      }
}

IlrActionExpression ContinueStatement() :
{
    Token begin;
    Token end;
}
{
    begin="continue" end=";"
      {
	  return new IlrContinueExpression(begin, end );
      }
}

IlrActionExpression BindStatement() :
{
    Token keyword;
    Token variable;
    IlrExpression expr;
    Token end;
}
{
    ( keyword= "bind" | keyword = "var" ) variable=Variable() "=" expr=Expression() end=";"
      {
	  return new IlrBindExpression(keyword,end,variable,expr);
      }
}

IlrAssertExpression AssertStatement() :
{
  IlrAssertExpression.Sketch sketch = new IlrAssertExpression.Sketch();
}
{
  (sketch.keyword="assert" | sketch.keyword="insert")
    (
      [ "logical" { sketch.logical = true; } ]
      AssertedObjectAndInitStatements(sketch)
    |
       "event" { sketch.event = true; }
      AssertedEventAndInitStatements(sketch)
    )
    {
      return new IlrAssertExpression(sketch);
    }
}

void AssertedObjectAndInitStatements(IlrAssertExpression.Sketch sketch) :
{
    IlrSimpleTypeExpression type;
    IlrArgumentList args = null;
}
{
    (
      type=SimpleTypeName() [args=Arguments()]
      { sketch.object = new IlrNewInstanceExpression(null,type,args); }
    |
      "(" sketch.object=Expression() ")"
    )
    AssertInitStatements(sketch)
}

void AssertedEventAndInitStatements(IlrAssertExpression.Sketch sketch) :
{
    IlrSimpleTypeExpression type;
    IlrArgumentList args = null;
    IlrExpression expr = null;
}
{
    (
      type=SimpleTypeName() [args=Arguments()]
      { sketch.object = new IlrNewInstanceExpression(null,type,args); }
      AssertInitStatements(sketch)
    |
      "(" expr=Expression() ")"
      (
        AssertInitStatements(sketch) { sketch.object = expr; }
      |
        AssertedObjectAndInitStatements(sketch) { sketch.timeexpr = expr; }
      )
    )
}

void AssertInitStatements(IlrAssertExpression.Sketch sketch) :
{
}
{
    (
     sketch.obrace="{" SimpleStatementBlock(sketch.actions) sketch.cbrace="}"
     [ sketch.semiColon=";" ]
     |
     sketch.semiColon=";"
    )
}

IlrRetractExpression RetractStatement() :
{
    Token keyword;
    Token end;
    IlrExpression object;
}
{
    keyword="retract" object=PrimaryExpression() end=";"
      {
	  return new IlrRetractExpression(keyword,end,object);
      }
}

IlrUpdateExpression UpdateStatement() :
{
    Token keyword;
    Token end;
    IlrExpression object;
    boolean refresh = false;
}
{
    keyword="update"
    ["refresh" { refresh = true; } ]
    object=PrimaryExpression()
    end=";"
      {
	  return new IlrUpdateExpression(keyword,end,object,refresh);
      }
}

IlrModifyExpression ModifyStatement() :
{
    Token keyword;
    Token obrace = null;
    Token cbrace = null;
    Token end = null;
    IlrExpression object;
    Vector actions = new Vector(5,5);
    boolean refresh = false;
}
{
    keyword="modify"
    ["refresh" { refresh = true; } ]
    object=PrimaryExpression()
    obrace="{" SimpleStatementBlock(actions) cbrace="}"
    [end=";"]
      {
	  return new IlrModifyExpression(keyword,obrace,obrace,end,
					 object,actions,refresh);
      }
}

IlrApplyExpression ApplyStatement() :
{
    Token keyword;
    Token obrace = null;
    Token cbrace = null;
    Token end = null;
    IlrExpression object;
    Vector actions = new Vector(5,5);
}
{
    keyword="apply" object=PrimaryExpression()
    obrace="{" SimpleStatementBlock(actions) cbrace="}" [end=";"]
      {
	  return new IlrApplyExpression(keyword,obrace,obrace,end,
					object,actions);
      }
}

IlrExecuteExpression ExecuteStatement() :
{
    Token keyword;
    Token obrace = null;
    Token cbrace = null;
    Token end = null;
    Vector actions = new Vector(5,5);
    IlrActionExpression action;
}
{
    keyword="execute"
    (
     action=ActionStatement() { actions.addElement(action); }
     |
     obrace="{"
     (action=ActionStatement() { actions.addElement(action); })*
     cbrace="}"
     [end=";"]
    )
      {
	  return new IlrExecuteExpression(keyword,obrace,cbrace,end,actions);
      }
}

IlrActionExpression IfStatement() :
{
    IlrIfElseExpression expr;
    Token keyword;
    Token opar;
    Token cpar;
    Token obrace = null;
    Token cbrace = null;
    IlrTestExpression test;
    Vector ifStatements = new Vector(5,5);
    Token elseKeyword = null;
    Vector elseStatements = new Vector(5,5);
    IlrActionExpression stat;
}
{
    keyword="if" opar="(" test=TestExpression() cpar=")"
      (
       stat=ActionStatement() { ifStatements.addElement(stat); }
       |
       obrace="{"
       (
	stat=ActionStatement() { ifStatements.addElement(stat); }
       )*
       cbrace="}"
      )
      {
	  expr = new IlrIfElseExpression(keyword,obrace,cbrace,
					 opar,cpar,null,test,ifStatements);
      }
    [
     LOOKAHEAD(1) elseKeyword="else"
     (
      stat=ActionStatement() { elseStatements.addElement(stat); }
      |
      obrace="{"
      (
       stat=ActionStatement() { elseStatements.addElement(stat); }
      )*
      cbrace="}"
     )
     {
	 expr.setElsePart(elseKeyword,obrace,cbrace,elseStatements);
     }
    ]
      {
	  return expr;
      }
}

IlrActionExpression WhileStatement() :
{
    Token keyword;
    Token obrace = null;
    Token cbrace = null;
    Token opar;
    Token cpar;
    Token end = null;
    Vector actions = new Vector(5,5);
    IlrActionExpression action;
    IlrTestExpression test;
}
{
    keyword="while" opar="(" test=TestExpression() cpar=")"
    (
     action=ActionStatement() { actions.addElement(action); }
     |
     obrace="{"
     (action=ActionStatement() { actions.addElement(action); })*
     cbrace="}"
     [end=";"]
    )
      {
	  return new IlrWhileExpression(keyword,obrace,cbrace,opar,cpar,end,
					test,actions);
      }
}

IlrActionExpression ForStatement() :
{
    Token keyword;
    Token obrace = null;
    Token cbrace = null;
    Token opar;
    Token cpar;
    Token semiColonEnd = null;
    Token semiColon1;
    Token semiColon2;
    Vector actions = new Vector(5,5);
    IlrForBlockExpression init = null;
    IlrForBlockExpression next = null;
    IlrActionExpression action;
    IlrTestExpression test = null;
}
{
    keyword="for" opar="(" [init = ForBlockExpression()] semiColon1=";"
	[test=TestExpression()] semiColon2=";"
	[next = ForBlockExpression ()] cpar=")"
    (
     action=ActionStatement() { actions.addElement(action); }
     |
     obrace="{"
     (action=ActionStatement() { actions.addElement(action); })*
     cbrace="}"
     [semiColonEnd=";"]
    )
      {
	  return new IlrForExpression(keyword,obrace,cbrace,opar,cpar,
				      semiColon1, semiColon2, semiColonEnd,
				      init, test, next, actions);
      }
}

IlrForBlockExpression ForBlockExpression() :
{
    IlrActionExpression action;
    IlrForBlockExpression block = new IlrForBlockExpression ( getToken(1),
							      getToken(1) );
}
{
    ( action=ForSimpleStatement() | action=ForBindStatement() )
	{ block.addStatement( action ); }
    ( "," ( action=ForSimpleStatement() | action=ForBindStatement() )
      { block.addStatement( action ); } )*
    {
	return block;
    }
}

IlrActionStatement ForSimpleStatement() :
{
    IlrExpression expr;
    IlrExpression right = null;
    int kind = -1;
}
{
    expr=UnaryExpression()
    [kind=AssignmentOperator() right=Expression()]
      {
	  if (right == null) return new IlrActionStatement(expr,getToken(1));
	  else return new IlrActionAssignStatement(expr,kind,right,getToken(1));
      }
}

IlrActionExpression ForBindStatement() :
{
    Token keyword;
    Token variable;
    IlrExpression expr;
}
{
    ( keyword= "bind" | keyword = "var" ) variable=Variable() "=" expr=Expression()
      {
	  return new IlrBindExpression(keyword,getToken(1),variable,expr);
      }
}


IlrActionExpression TimeOutStatement() :
{
    Token keyword;
    Token obrace = null;
    Token cbrace = null;
    Token end = null;
    Vector actions = new Vector(5,5);
    IlrActionExpression action;
    Token label;
}
{
    keyword="timeout" label=Variable()
    (
     action=ActionStatement() { actions.addElement(action); }
     |
     obrace="{"
     (action=ActionStatement() { actions.addElement(action); })*
     cbrace="}"
     [end=";"]
    )
      {
	  return new IlrTimeOutExpression(keyword,obrace,cbrace,end,
					  label,actions);
      }
}

void StatementBlockEof(Vector vector) :
{
    IlrActionExpression stat;
}
{
    (
     ( stat=ActionStatement() )
     { vector.addElement(stat); }
    )*
    <EOF>
}

void SimpleStatementBlock(Vector vector) :
{
    IlrActionExpression stat;
}
{
    (
     (stat=SimpleStatement() | stat=BindStatement())
     { vector.addElement(stat); }
    )*
}


IlrActionStatement SimpleStatement() :
{
    IlrExpression expr;
    IlrExpression right = null;
    int kind = -1;
    Token end;
}
{
    expr=UnaryExpression()
    [kind=AssignmentOperator() right=Expression()] end=";"
      {
	  if (right == null) return new IlrActionStatement(expr,end);
	  else return new IlrActionAssignStatement(expr,kind,right,end);
      }
}

int AssignmentOperator() :
{}
{
    "=" { return IlrAssignment.SIMPLE_ASSIGN; }
 | "*=" { return IlrAssignment.MULTIPLY_ASSIGN; }
 | "/=" { return IlrAssignment.DIVIDE_ASSIGN; }
 | "%=" { return IlrAssignment.REMAINDER_ASSIGN; }
 | "+=" { return IlrAssignment.ADD_ASSIGN; }
 | "-=" { return IlrAssignment.SUBTRACT_ASSIGN; }
}

//---------------------------------------------------------------------------
// Conventional test expressions to be used in RHS
//---------------------------------------------------------------------------

IlrTestExpression TestExpression() :
{
    IlrOrExpression expr = new IlrOrExpression();
    IlrTestExpression test;
}
{
    test=AndTestExpression() { expr.tests.addElement(test); }
   ("||" test=AndTestExpression() { expr.tests.addElement(test); } )*
     {
	 if (expr.tests.size() == 1) return test;
	 else return expr;
     }
}

IlrTestExpression AndTestExpression() :
{
    IlrAndExpression expr = new IlrAndExpression();
    IlrTestExpression test;
}
{
    test=OtherTestExpression() { expr.tests.addElement(test); }
   ("&&" test=OtherTestExpression() { expr.tests.addElement(test); } )*
     {
	 if (expr.tests.size() == 1) return test;
	 else return expr;
     }
}

IlrTestExpression OtherTestExpression() :
{
    IlrTestExpression expr;
}
{
    (
     LOOKAHEAD(UnaryExpression()) expr=SimpleTestExpression()
     |
     "(" expr=TestExpression() ")"
     |
     "!" expr=OtherTestExpression() { expr = new IlrFalseTestExpression(expr); }
    )
    { return expr; }
}

IlrTestExpression SimpleTestExpression() :
{
    IlrExpression initial;
    IlrTestExpression test = null;
}
{
    initial=Expression() [ test=BooleanArguments(initial) ]
    {
	if (test == null) test = new IlrTrueTestExpression(initial);
	return test;
    }
}

//
// end of file
//


This file was generated on Wed Dec 10 14:24:53 PST 2003 from file parser.jj
by the ilog.language.tools.Hilite Java tool written by Hassan Aït-Kaci