QueryParser.java

  1. /* Generated By:JavaCC: Do not edit this line. QueryParser.java */
  2. package gate.mimir.search.query.parser;

  3. import gate.Annotation;
  4. import gate.Corpus;
  5. import gate.Document;
  6. import gate.Factory;
  7. import gate.Gate;
  8. import gate.LanguageAnalyser;
  9. import gate.creole.ANNIEConstants;
  10. import gate.creole.ExecutionException;
  11. import gate.creole.ResourceInstantiationException;
  12. import gate.util.OffsetComparator;

  13. import gate.mimir.search.query.QueryNode;
  14. import gate.mimir.search.query.SequenceQuery.Gap;
  15. import gate.mimir.ConstraintType;
  16. import gate.mimir.Constraint;

  17. import java.io.StringReader;
  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.List;

  21. /**
  22.  * QueryParser. Given a text query, this parser returns a QueryNode object
  23.  * that can be used for querying the Mimir index.
  24.  */
  25. public class QueryParser implements QueryParserConstants {

  26.   // keeping track of row and column for gap queries
  27.   // please note that this variable is updated only on certain occassions
  28.   int column;
  29.   int row;
  30.   boolean debug = false;

  31.   private static final OffsetComparator OFFSET_COMPARATOR = new OffsetComparator();

  32.   /**
  33.    * The GATE LanguageAnalyser used to tokenise plain term queries and quoted
  34.    * strings.  Typically this will just be a tokeniser PR but we allow any
  35.    * LanguageAnalyser so more complex processing can be injected if required.
  36.    * The only requirement is that the LA can take an un-annotated document and
  37.    * return one with {@link ANNIEConstants#TOKEN_ANNOTATION_TYPE} annotations
  38.    * in the default annotation set.
  39.    */
  40.   private LanguageAnalyser queryTokeniser;

  41.   /**
  42.    * Set the GATE LanguageAnalyser used to parse quoted strings in queries.
  43.    * This allows clients to override the default tokeniser if required, and
  44.    * should be called before the first use of {@link #parse}.
  45.    */
  46.   public void setQueryTokeniser(LanguageAnalyser tok) {
  47.     queryTokeniser = tok;
  48.   }

  49.   /**
  50.    * Default query tokeniser, used if no specific tokeniser has been passed to
  51.    * a particular parser instance.  Initialized lazily on first use.
  52.    */
  53.   private static LanguageAnalyser defaultQueryTokeniser;

  54.   public static final String DEFAULT_TOKENISER_CLASS_NAME =
  55.     "gate.creole.tokeniser.DefaultTokeniser";

  56.   /**
  57.    * Returns the default query tokeniser, initializing it if necessary.
  58.    */
  59.   private static synchronized LanguageAnalyser getDefaultQueryTokeniser() throws ParseException {
  60.     if(defaultQueryTokeniser == null) {
  61.       try {
  62.         defaultQueryTokeniser = (LanguageAnalyser)Factory.createResource(
  63.             DEFAULT_TOKENISER_CLASS_NAME);
  64.       }
  65.       catch(ResourceInstantiationException e) {
  66.         throw (ParseException)new ParseException("Couldn't create query tokeniser")
  67.           .initCause(e);
  68.       }
  69.     }

  70.     return defaultQueryTokeniser;
  71.   }

  72.   public static void main(String[] args) throws Exception {
  73.     String query = args[0];
  74.     Gate.init();
  75.     QueryNode node = QueryParser.parse(query);
  76.     System.out.println(query);
  77.     System.out.println(node.getClass().getName());
  78.   }

  79.   /**
  80.    * Parses the query and returns a top level QueryNode object.
  81.    * @param query the query to parse
  82.    * @return instance of the QueryNode
  83.    */
  84.   public static QueryNode parse(String query) throws ParseException {
  85.     return parse(query, getDefaultQueryTokeniser());
  86.   }

  87.   /**
  88.    * Parses the query and returns a top level QueryNode object.
  89.    * @param query the query to parse
  90.    * @param tokeniser the GATE {@link LanguageAnalyser} used to parse strings
  91.    *         in the query.
  92.    * @return instance of the QueryNode
  93.    */
  94.   public static QueryNode parse(String query, LanguageAnalyser tokeniser) throws ParseException {
  95.       // start parsing
  96.       QueryParser parser = new QueryParser(new StringReader(query));
  97.       parser.setQueryTokeniser(tokeniser);
  98.       Query queryInst = parser.start();
  99.       return parser.convert(queryInst, "");
  100.   }

  101.   /**
  102.    * converts the given query object into an appropriate QueryNode.
  103.    * @param queryInst
  104.    * @return instance of QueryNode
  105.    */
  106.   private QueryNode convert(Query queryInst, String space)
  107.                                              throws ParseException {
  108.     // need to convert queryInst into appropriate query objects
  109.     // TermQuery, AnnotationQuery, GapQuery, InQuery, OverQuery, KleneQuery
  110.     // OrQuery, AndQuery, SequenceQuery
  111.     if(queryInst instanceof TermQuery) {
  112.       return toTermQuery((TermQuery)queryInst, space);
  113.     } else if(queryInst instanceof AnnotationQuery) {
  114.       return toAnnotationQuery((AnnotationQuery) queryInst, space);
  115.     } else if(queryInst instanceof GapQuery) {
  116.       throw new ParseException(
  117.            "Gap cannot be specified as a first or last element in the query");
  118.     } else if(queryInst instanceof InQuery) {
  119.       return toWithinQuery((InQuery)queryInst, space);
  120.     } else if(queryInst instanceof OverQuery) {
  121.       return toContainsQuery((OverQuery)queryInst, space);
  122.     } else if(queryInst instanceof KleneQuery) {
  123.       return toRepeatsQuery((KleneQuery)queryInst, space);
  124.     } else if(queryInst instanceof ORQuery) {
  125.       return toOrQuery((ORQuery)queryInst, space);
  126.     } else if(queryInst instanceof ANDQuery) {
  127.       return toAndQuery((ANDQuery)queryInst, space);
  128.     } else if(queryInst instanceof MinusQuery) {
  129.       return toMinusQuery((MinusQuery)queryInst, space);
  130.     } else if(queryInst instanceof SequenceQuery) {
  131.       return toSequenceQuery((SequenceQuery)queryInst, space);
  132.     }
  133.     else {
  134.       throw new ParseException("Invalid query type:" +
  135.                                  queryInst.getClass().getName());
  136.     }
  137.   }

  138.   /**
  139.    * Conversion of the TermQuery
  140.    * @param query
  141.    * @return
  142.    */
  143.   private QueryNode toTermQuery(TermQuery query, String space) {
  144.     if(debug) System.out.println(space + "Term="+query.index+":"+query.term);
  145.     return new gate.mimir.search.query.TermQuery(query.index, query.term);
  146.   }

  147.   /**
  148.    * Conversion of the AnnotationQuery
  149.    * @param query
  150.    * @return
  151.    */
  152.   private QueryNode toAnnotationQuery(AnnotationQuery query, String space) {
  153.     if(debug) System.out.println(space + "Annotation="+query.type);
  154.     List<Constraint> featureConstraints = new ArrayList<Constraint>();
  155.     for(FeatureValuePair fvp : query.pairs) {
  156.       Constraint c = null;
  157.       if(fvp.constraintType == FeatureValuePair.EQ) {
  158.         if(debug)
  159.           System.out.println("\t"+fvp.feature+"="+fvp.value);
  160.         c = new Constraint(ConstraintType.EQ, fvp.feature, fvp.value);
  161.       } else if(fvp.constraintType == FeatureValuePair.REGEX) {
  162.         if(fvp.value instanceof String[]) {
  163.           if(debug) {
  164.             String[] values = (String[]) fvp.value;
  165.             System.out.println("\t"+fvp.feature+".REGEX("+values[0]+"," +
  166.                                values[1]+")");
  167.           }
  168.         } else {
  169.           if(debug) System.out.println("\t"+fvp.feature+".REGEX("
  170.                                         +fvp.value+")");
  171.         }
  172.         c = new Constraint(ConstraintType.REGEX, fvp.feature, fvp.value);
  173.       } else if(fvp.constraintType == FeatureValuePair.LT) {
  174.         if(debug)
  175.           System.out.println("\t"+fvp.feature+"<"+fvp.value);
  176.         c = new Constraint(ConstraintType.LT, fvp.feature, fvp.value);
  177.       } else if(fvp.constraintType == FeatureValuePair.GT) {
  178.         if(debug)
  179.           System.out.println("\t"+fvp.feature+">"+fvp.value);
  180.         c = new Constraint(ConstraintType.GT, fvp.feature, fvp.value);
  181.       } else if(fvp.constraintType == FeatureValuePair.LE) {
  182.         if(debug)
  183.           System.out.println("\t"+fvp.feature+"<="+fvp.value);
  184.         c = new Constraint(ConstraintType.LE, fvp.feature, fvp.value);
  185.       } else {
  186.         if(debug)
  187.           System.out.println("\t"+fvp.feature+">="+fvp.value);
  188.         c = new Constraint(ConstraintType.GE, fvp.feature, fvp.value);
  189.       }
  190.       featureConstraints.add(c);
  191.     }
  192.     return new gate.mimir.search.query.AnnotationQuery(query.type,
  193.                                                           featureConstraints);
  194.   }

  195.   /**
  196.    * Conversion of the InQuery into WithinQuery
  197.    * @param query
  198.    * @return
  199.    * @throws ParseException
  200.    */
  201.   private QueryNode toWithinQuery(InQuery query, String space)
  202.                                                  throws ParseException {
  203.     if(debug) System.out.println(space + "WithinQuery:");
  204.     QueryNode targetQuery = convert(query.innerQuery, space + " ");
  205.     QueryNode surroundingQuery = convert(query.outerQuery, space + " ");
  206.     return new gate.mimir.search.query.WithinQuery(targetQuery,
  207.                                                     surroundingQuery);
  208.   }

  209.   /**
  210.    * Conversion of the OverQuery into ContainsQuery
  211.    * @param query
  212.    * @return
  213.    * @throws ParseException
  214.    */
  215.   private QueryNode toContainsQuery(OverQuery query, String space)
  216.                                                      throws ParseException {
  217.     if(debug) System.out.println(space + "ContainsQuery");
  218.     QueryNode targetQuery = convert(query.overQuery, space + " ");
  219.     QueryNode nestedQuery = convert(query.innerQuery, space + " ");
  220.     return new gate.mimir.search.query.ContainsQuery(targetQuery, nestedQuery);
  221.   }

  222.   /**
  223.    * Conversion of the KleneQuery into RepeatsQuery
  224.    * @param query
  225.    * @return
  226.    * @throws ParseException
  227.    */
  228.   private QueryNode toRepeatsQuery(KleneQuery query, String space)
  229.                                                      throws ParseException {
  230.     if(debug) System.out.println(space + "Repeats:"+query.min+".."+query.max);
  231.     QueryNode queryNode = convert(query.query, space + " ");
  232.     return new gate.mimir.search.query.RepeatsQuery(queryNode, query.min,
  233.                                                                    query.max);
  234.   }

  235.   /**
  236.    * Conversion of the ORQuery
  237.    * @param query
  238.    * @return
  239.    * @throws ParseException
  240.    */
  241.   private QueryNode toOrQuery(ORQuery query, String space)
  242.                                              throws ParseException {
  243.     int totalQueries = query.queriesToOr.size();
  244.     if(debug) System.out.println(space + "OrQuery:"+totalQueries);
  245.     QueryNode [] orQueries = new QueryNode[totalQueries];
  246.     for(int i=0;i<totalQueries;i++) {
  247.       orQueries[i] = convert(query.queriesToOr.get(i), space + " ");
  248.     }
  249.     return new gate.mimir.search.query.OrQuery(orQueries);
  250.   }

  251.   /**
  252.    * Conversion of the ANDQuery
  253.    * @param query
  254.    * @return
  255.    * @throws ParseException
  256.    */
  257.   private QueryNode toAndQuery(ANDQuery query, String space)
  258.                                              throws ParseException {
  259.     int totalQueries = query.queriesToAnd.size();
  260.     if(debug) System.out.println(space + "AndQuery:"+totalQueries);
  261.     QueryNode [] andQueries = new QueryNode[totalQueries];
  262.     for(int i=0;i<totalQueries;i++) {
  263.       andQueries[i] = convert(query.queriesToAnd.get(i), space + " ");
  264.     }
  265.     return new gate.mimir.search.query.AndQuery(andQueries);
  266.   }

  267.   /**
  268.    * Conversion of the MinusQuery
  269.    * @param query
  270.    * @return
  271.    * @throws ParseException
  272.    */
  273.   private QueryNode toMinusQuery(MinusQuery query, String space)
  274.                                              throws ParseException {
  275.     if(debug) System.out.println(space + "MinusQuery:");
  276.     QueryNode leftQuery = convert(query.leftQuery, space + " ");
  277.     QueryNode rightQuery = convert(query.rightQuery, space + " ");
  278.     return new gate.mimir.search.query.MinusQuery(leftQuery,
  279.                                                     rightQuery);
  280.   }

  281.   /**
  282.    * Conversion of the SequenceQuery
  283.    * @param query
  284.    * @return
  285.    * @throws ParseException
  286.    */
  287.   private QueryNode toSequenceQuery(SequenceQuery query, String space)
  288.                                                          throws ParseException {
  289.     if(query.queriesInOrder.size() > 1) {
  290.       if(debug) System.out.println(space +
  291.                                  "SequenceQuery:"+query.queriesInOrder.size());
  292.     }
  293.     List<QueryNode> queries = new ArrayList<QueryNode>();
  294.     List<Gap> queryGaps = new ArrayList<Gap>();

  295.     boolean canBeGapQuery = false;

  296.     for(int i=0;i<query.queriesInOrder.size();i++) {
  297.       Query q = query.queriesInOrder.get(i);
  298.       if(q instanceof GapQuery) {
  299.         if(!canBeGapQuery) {
  300.           throw new ParseException("Improper use of the Gap");
  301.         }

  302.         if(i == query.queriesInOrder.size()-1) {
  303.           throw new ParseException(
  304.                          "Last element in the SequenceQuery cannot be gap");
  305.         }

  306.         GapQuery gq = (GapQuery) q;
  307.         Gap gap =
  308.            gate.mimir.search.query.SequenceQuery.getGap(gq.minGap, gq.maxGap);
  309.         if(debug) System.out.println(space +
  310.                                      " GapQuery:"+gq.minGap+".."+gq.maxGap);
  311.         queryGaps.add(gap);
  312.         // next element cannot be a gap query
  313.         canBeGapQuery = false;
  314.         continue;
  315.       }

  316.       // expecting a gap?
  317.       if(canBeGapQuery) {
  318.         // yes but this is not a gap, so add an empty gap
  319.         queryGaps.add(gate.mimir.search.query.SequenceQuery.getGap(0, 0));
  320.       }
  321.       queries.add(convert(q, query.queriesInOrder.size() > 1 ? space + " " : space));
  322.       canBeGapQuery = true;
  323.     }

  324.     if(queries.size() == 1) {
  325.       return queries.get(0);
  326.     } else {
  327.       return new gate.mimir.search.query.SequenceQuery(
  328.             queryGaps.toArray(new Gap[0]), queries.toArray(new QueryNode[0]));
  329.     }
  330.   }

  331.   /** converts escape sequences into normal sequences */
  332.   public String unescape(String s) {
  333.     return s.replaceAll("\\\"IN\\\"","IN")
  334.                       .replaceAll("\\\"OVER\\\"","OVER")
  335.                       .replaceAll("\\\"AND\\\"","AND")
  336.                       .replaceAll("\\\"OR\\\"","OR")
  337.                       .replaceAll("\\\"REGEX\\\"","REGEX")
  338.                       .replaceAll("\\\\\\{","{").replaceAll("\\\\\\}","}")
  339.                       .replaceAll("\\\\\\<","<").replaceAll("\\\\\\>",">")
  340.                       .replaceAll("\\\\\\-","-")
  341.                       .replaceAll("\\\\\\[","[").replaceAll("\\\\\\]","]")
  342.                       .replaceAll("\\\\\\(","(").replaceAll("\\\\\\)",")")
  343.                       .replaceAll("\\\\\\:",":").replaceAll("\\\\\\+","+")
  344.                       .replaceAll("\\\\\\|","|").replaceAll("\\\\\\?","?")
  345.                       .replaceAll("\\\\\\&","&")
  346.                       .replaceAll("\\\\\\.",".").replaceAll("\\\\\"","\"")
  347.                       .replaceAll("\\\\\\=","=").replaceAll("(\\\\){2}","\\\\");
  348.   }

  349.   // parse string and obtain the appropriate query object
  350.   public Query parseString(String s) throws ParseException {
  351.     Document document = null;
  352.     Corpus corpus = null;
  353.     synchronized(queryTokeniser) {
  354.       try {
  355.         document = Factory.newDocument(s);
  356.         corpus = Factory.newCorpus("QueryParser corpus");
  357.         corpus.add(document);
  358.         queryTokeniser.setCorpus(corpus);
  359.         queryTokeniser.setDocument(document);
  360.         queryTokeniser.execute();

  361.         List<Annotation> tokens = new ArrayList<Annotation>(
  362.             document.getAnnotations().get(ANNIEConstants.TOKEN_ANNOTATION_TYPE));
  363.         Collections.sort(tokens, OFFSET_COMPARATOR);

  364.         if(tokens.size() > 1) {
  365.           SequenceQuery sq = new SequenceQuery();
  366.           for(Annotation term : tokens) {
  367.             TermQuery tq = new TermQuery();
  368.             tq.term = (String)term.getFeatures()
  369.                         .get(ANNIEConstants.TOKEN_STRING_FEATURE_NAME);
  370.             tq.index = null;  // as valy suggested using null instead of "string";
  371.             sq.add(tq);
  372.           }
  373.           return sq;
  374.         }
  375.         else {
  376.           TermQuery tq = new TermQuery();
  377.           tq.term = (String)tokens.get(0).getFeatures()
  378.                       .get(ANNIEConstants.TOKEN_STRING_FEATURE_NAME);
  379.           tq.index = null;  // as valy suggested using null instead of "string";
  380.           return tq;
  381.         }
  382.       }
  383.       catch(ResourceInstantiationException e) {
  384.         throw (ParseException)new ParseException(
  385.             "Error creating GATE document for string parser").initCause(e);
  386.       }
  387.       catch(ExecutionException e) {
  388.         throw (ParseException)new ParseException(
  389.             "Error tokenising string").initCause(e);
  390.       }
  391.       finally {
  392.         queryTokeniser.setCorpus(null);
  393.         queryTokeniser.setDocument(null);
  394.         if(corpus != null) {
  395.           corpus.clear();
  396.           Factory.deleteResource(corpus);
  397.         }
  398.         if(document != null) {
  399.           Factory.deleteResource(document);
  400.         }
  401.       }
  402.     }
  403.   }

  404. // lexical analyser

  405. // starting method with EOF
  406.   final public Query start() throws ParseException {
  407.   Query q;
  408.     q = QueryPlus();
  409.     {if (true) return q;}
  410.     jj_consume_token(0);
  411.     throw new Error("Missing return statement in function");
  412.   }

  413. /**
  414.  * Query+
  415.  * If more than one query detected, an object of sequence query is returned.
  416.  * If there is only one query, that particular instance of query is returned.
  417.  */
  418.   final public Query QueryPlus() throws ParseException {
  419.   Query q;
  420.   Query q1;
  421.   SequenceQuery sq = new SequenceQuery();
  422.     q = Query(null);
  423.     sq.add(q);
  424.     label_1:
  425.     while (true) {
  426.       if (jj_2_1(2147483647)) {
  427.         ;
  428.       } else {
  429.         break label_1;
  430.       }
  431.       q1 = Query(q);
  432.       if(q1 instanceof InQuery ||
  433.          q1 instanceof OverQuery ||
  434.          q1 instanceof MinusQuery ||
  435.          q1 instanceof ORQuery ||
  436.          q1 instanceof ANDQuery ||
  437.          q1 instanceof KleneQuery) {
  438.         sq.removeLastElement();
  439.       }

  440.       q = q1;
  441.       sq.add(q);
  442.     }
  443.     if(q instanceof GapQuery)
  444.       {if (true) throw new ParseException(
  445.       "Gap cannot be the first/last element. See line:"+row+", column:"+column);}

  446.     if(sq.size() == 1 && !(q instanceof InQuery ||
  447.          q instanceof OverQuery || q instanceof ORQuery ||
  448.          q instanceof ANDQuery || q instanceof KleneQuery ||
  449.          q instanceof MinusQuery))
  450.       {if (true) return q;}
  451.     else
  452.       {if (true) return sq;}
  453.     throw new Error("Missing return statement in function");
  454.   }

  455. /**
  456.  * Returns true if the next token in the stream is a reserved word
  457.  */
  458.   final public boolean reserved() throws ParseException {
  459.     switch (jj_nt.kind) {
  460.     case string:
  461.       jj_consume_token(string);
  462.       break;
  463.     case leftbrace:
  464.       jj_consume_token(leftbrace);
  465.       break;
  466.     case leftbracket:
  467.       jj_consume_token(leftbracket);
  468.       break;
  469.     case or:
  470.       jj_consume_token(or);
  471.       break;
  472.     case and:
  473.       jj_consume_token(and);
  474.       break;
  475.     case in:
  476.       jj_consume_token(in);
  477.       break;
  478.     case over:
  479.       jj_consume_token(over);
  480.       break;
  481.     case minus:
  482.       jj_consume_token(minus);
  483.       break;
  484.     case plus:
  485.       jj_consume_token(plus);
  486.       break;
  487.     case tok:
  488.       jj_consume_token(tok);
  489.       break;
  490.     case leftsquarebracket:
  491.       jj_consume_token(leftsquarebracket);
  492.       break;
  493.     case hyphen:
  494.       jj_consume_token(hyphen);
  495.       break;
  496.     case number:
  497.       jj_consume_token(number);
  498.    {if (true) return true;}
  499.       break;
  500.     default:
  501.       jj_la1[0] = jj_gen;
  502.       jj_consume_token(-1);
  503.       throw new ParseException();
  504.     }
  505.     throw new Error("Missing return statement in function");
  506.   }

  507. /**
  508.  * parse a single query.
  509.  */
  510.   final public Query Query(Query previousQuery) throws ParseException {
  511.   Query q;
  512.   Query[] qs = new Query[2];
  513.     switch (jj_nt.kind) {
  514.     case leftbracket:
  515.       jj_consume_token(leftbracket);
  516.       // a query can be surrounded by ( and )
  517.               q = QueryPlus();
  518.       jj_consume_token(rightbracket);
  519.       break;
  520.     case leftbrace:
  521.       q = AnnotationQuery();
  522.       break;
  523.     case number:
  524.     case hyphen:
  525.     case tok:
  526.       q = TermOrNamedIndexQuery();
  527.       break;
  528.     case string:
  529.       q = QuotedTextQuery();
  530.       break;
  531.     case leftsquarebracket:
  532.       q = GapQuery();
  533.       break;
  534.     case in:
  535.       q = InQuery(previousQuery);
  536.       break;
  537.     case over:
  538.       q = OverQuery(previousQuery);
  539.       break;
  540.     case minus:
  541.       q = MinusQuery(previousQuery);
  542.       break;
  543.     default:
  544.       jj_la1[1] = jj_gen;
  545.       if (jj_2_2(2147483647)) {
  546.         q = OrQuery(previousQuery);
  547.       } else if (jj_2_3(2147483647)) {
  548.         q = AndQuery(previousQuery);
  549.       } else {
  550.         switch (jj_nt.kind) {
  551.         case plus:
  552.           q = KleneQuery(previousQuery);
  553.           break;
  554.         default:
  555.           jj_la1[2] = jj_gen;
  556.           jj_consume_token(-1);
  557.           throw new ParseException();
  558.         }
  559.       }
  560.     }
  561.     {if (true) return q;}
  562.     throw new Error("Missing return statement in function");
  563.   }

  564. /**
  565.  * Gap. Only valid if it is a part of a sequence query.
  566.  * Cannot appear at the start or at the end of a query
  567.  */
  568.   final public Query GapQuery() throws ParseException {
  569.   GapQuery gq = new GapQuery();
  570.   Token t;
  571.     t = jj_consume_token(leftsquarebracket);
  572.     column = t.beginColumn;
  573.     row = t.beginLine;
  574.     t = jj_consume_token(number);
  575.    gq.maxGap = Integer.parseInt(t.image);
  576.     switch (jj_nt.kind) {
  577.     case period:
  578.       jj_consume_token(period);
  579.       jj_consume_token(period);
  580.       t = jj_consume_token(number);
  581.      gq.minGap = gq.maxGap; gq.maxGap = Integer.parseInt(t.image);
  582.       break;
  583.     default:
  584.       jj_la1[3] = jj_gen;
  585.       ;
  586.     }
  587.     jj_consume_token(rightsquarebracket);
  588.     {if (true) return gq;}
  589.     throw new Error("Missing return statement in function");
  590.   }

  591. /**
  592.  * Returns true if the next token in the stream is a regex word
  593.  */
  594.   final public boolean regex() throws ParseException {
  595.     jj_consume_token(period);
  596.     jj_consume_token(regex);
  597.    {if (true) return true;}
  598.     throw new Error("Missing return statement in function");
  599.   }

  600. /**
  601.  * Returns true if the next token in the stream is a double number
  602.  */
  603.   final public String number() throws ParseException {
  604.   StringBuffer sb = new StringBuffer();
  605.   Token t;
  606.     switch (jj_nt.kind) {
  607.     case hyphen:
  608.       t = jj_consume_token(hyphen);
  609.     sb.append(t.image);
  610.       break;
  611.     default:
  612.       jj_la1[4] = jj_gen;
  613.       ;
  614.     }
  615.     t = jj_consume_token(number);
  616.     sb.append(t.image);
  617.     switch (jj_nt.kind) {
  618.     case period:
  619.       t = jj_consume_token(period);
  620.       sb.append(t.image);
  621.       t = jj_consume_token(number);
  622.       sb.append(t.image);
  623.       break;
  624.     default:
  625.       jj_la1[5] = jj_gen;
  626.       ;
  627.     }
  628.    {if (true) return sb.toString();}
  629.     throw new Error("Missing return statement in function");
  630.   }

  631. // Regext Query
  632.   final public void RegexQuery(AnnotationQuery aq, String feature) throws ParseException {
  633.   Token t;
  634.   String flags = null;
  635.   Object value;
  636.   int constraintType = 0;
  637.     jj_consume_token(period);
  638.     jj_consume_token(regex);
  639.     jj_consume_token(leftbracket);
  640.     t = jj_consume_token(string);
  641.     value = t.image.substring(1, t.image.length()-1);
  642.     constraintType = FeatureValuePair.REGEX;
  643.     switch (jj_nt.kind) {
  644.     case comma:
  645.       jj_consume_token(comma);
  646.       t = jj_consume_token(string);
  647.       flags = t.image.substring(1, t.image.length()-1);
  648.       value = new String[]{value.toString(), flags};
  649.       break;
  650.     default:
  651.       jj_la1[6] = jj_gen;
  652.       ;
  653.     }
  654.     jj_consume_token(rightbracket);
  655.    aq.add(constraintType, feature, value, flags);
  656.   }

  657. /**
  658.  * Annotation Query
  659.  * e.g. {AnnotationType featureName=featureValue}
  660.  * e.g. featureValue can be a quoted value
  661.  */
  662.   final public Query AnnotationQuery() throws ParseException {
  663.   AnnotationQuery aq = new AnnotationQuery();
  664.   Token t;
  665.   String feature = null;
  666.   Object value = null;
  667.   String flags = null;
  668.   String numberStr = "";
  669.   int constraintType = 0;
  670.     jj_consume_token(leftbrace);
  671.     t = jj_consume_token(tok);
  672.     aq.type = unescape(t.image);
  673.     label_2:
  674.     while (true) {
  675.       switch (jj_nt.kind) {
  676.       case tok:
  677.         ;
  678.         break;
  679.       default:
  680.         jj_la1[7] = jj_gen;
  681.         break label_2;
  682.       }
  683.       // feature name
  684.           t = jj_consume_token(tok);
  685.      feature = unescape(t.image);
  686.       if (jj_2_4(2147483647)) {
  687.         RegexQuery(aq, feature);
  688.       } else {
  689.         switch (jj_nt.kind) {
  690.         case le:
  691.         case ge:
  692.         case lt:
  693.         case gt:
  694.         case equals:
  695.           switch (jj_nt.kind) {
  696.           case equals:
  697.             t = jj_consume_token(equals);
  698.                 constraintType = FeatureValuePair.EQ;
  699.             break;
  700.           case le:
  701.             t = jj_consume_token(le);
  702.                 constraintType = FeatureValuePair.LE;
  703.             break;
  704.           case ge:
  705.             t = jj_consume_token(ge);
  706.                 constraintType = FeatureValuePair.GE;
  707.             break;
  708.           case gt:
  709.             t = jj_consume_token(gt);
  710.                 constraintType = FeatureValuePair.GT;
  711.             break;
  712.           case lt:
  713.             t = jj_consume_token(lt);
  714.                 constraintType = FeatureValuePair.LT;
  715.             break;
  716.           default:
  717.             jj_la1[8] = jj_gen;
  718.             jj_consume_token(-1);
  719.             throw new ParseException();
  720.           }
  721.           switch (jj_nt.kind) {
  722.           case string:
  723.             t = jj_consume_token(string);
  724.                 value = t.image.substring(1, t.image.length()-1);
  725.             break;
  726.           case tok:
  727.             t = jj_consume_token(tok);
  728.                 value = unescape(t.image);
  729.             break;
  730.           case number:
  731.           case hyphen:
  732.             numberStr = number();
  733.                 try {
  734.                   value = new Double(Double.parseDouble(numberStr));
  735.                 } catch(NumberFormatException nfe) {
  736.                   {if (true) throw new ParseException("Invalid Number :" + numberStr);}
  737.                 }
  738.             break;
  739.           default:
  740.             jj_la1[9] = jj_gen;
  741.             jj_consume_token(-1);
  742.             throw new ParseException();
  743.           }
  744.          aq.add(constraintType, feature, value);
  745.           break;
  746.         default:
  747.           jj_la1[10] = jj_gen;
  748.           jj_consume_token(-1);
  749.           throw new ParseException();
  750.         }
  751.       }
  752.     }
  753.     jj_consume_token(rightbrace);
  754.    {if (true) return aq;}
  755.     throw new Error("Missing return statement in function");
  756.   }

  757. /**
  758.  * UnQuotedText or NamedIndexQuery
  759.  * e.g. microsoft corporation
  760.  * e.g. root:value
  761.  */
  762.   final public Query TermOrNamedIndexQuery() throws ParseException {
  763.   Token t;
  764.   Token t1;
  765.   String n;
  766.   TermQuery tq;
  767.     if (jj_2_5(2)) {
  768.       t = jj_consume_token(tok);
  769.       jj_consume_token(colon);
  770.           tq = new TermQuery();
  771.           tq.index = unescape(t.image);
  772.       switch (jj_nt.kind) {
  773.       case tok:
  774.         t1 = jj_consume_token(tok);
  775.             tq.term = unescape(t1.image);
  776.         break;
  777.       case string:
  778.         t1 = jj_consume_token(string);
  779.             tq.term = t1.image.substring(1, t1.image.length()-1);
  780.         break;
  781.       default:
  782.         jj_la1[11] = jj_gen;
  783.         jj_consume_token(-1);
  784.         throw new ParseException();
  785.       }
  786.         {if (true) return tq;}
  787.     } else {
  788.       switch (jj_nt.kind) {
  789.       case tok:
  790.         t = jj_consume_token(tok);
  791.         // if no index name is specified, parse the token like a quoted
  792.         // string.
  793.         {if (true) return parseString(unescape(t.image));}
  794.         break;
  795.       case number:
  796.       case hyphen:
  797.         // bare number is treated as a query for that number as a string
  798.               n = number();
  799.         {if (true) return parseString(unescape(n));}
  800.         break;
  801.       default:
  802.         jj_la1[12] = jj_gen;
  803.         jj_consume_token(-1);
  804.         throw new ParseException();
  805.       }
  806.     }
  807.     throw new Error("Missing return statement in function");
  808.   }

  809. /**
  810.  * obtaining a term or sequence query with all terms in it.
  811.  * e.g. "amazing videos"
  812.  */
  813.   final public Query QuotedTextQuery() throws ParseException {
  814.   String s;
  815.   Token t;
  816.     t = jj_consume_token(string);
  817.     s= t.image.substring(1, t.image.length()-1);
  818.    {if (true) return parseString(s);}
  819.     throw new Error("Missing return statement in function");
  820.   }

  821. /**
  822.  * OrQuery
  823.  * e.g. Query | Query
  824.  * In the example above, first "Query" is supplied in the previousQuery parameter.
  825.  * This method starts parsing tokens after the previousQuery has ended.
  826.  * i.e. first character after the previous query must be "|"
  827.  */
  828.   final public Query OrQuery(Query previousQuery) throws ParseException {
  829.   ORQuery orQuery = new ORQuery();
  830.   Query q;
  831.   Token t;
  832.     t = jj_consume_token(or);
  833.     if(previousQuery instanceof GapQuery)
  834.       {if (true) throw new ParseException("First element cannot be Gap. See line:"+row+", column:"+column);}

  835.     column = t.beginColumn;
  836.     row = t.beginLine;

  837.     if(previousQuery == null)
  838.       {if (true) throw new ParseException(
  839.          "Use of OR at the start of a query is not permitted. See line:"+row+", column:"+column);}

  840.     orQuery.add(previousQuery);
  841.     q = QueryPlus();
  842.     // merging all ORQueries into one
  843.     // i.e. ORQuery { query1, ORQuery {query2, query3}}
  844.     // will become ORQuery {query1, query2, query3}
  845.     if(q instanceof ORQuery) {
  846.       ORQuery oq = (ORQuery) q;
  847.       for(Query qq : oq.getQueries()) {
  848.         orQuery.add(qq);
  849.       }
  850.     } else {
  851.       orQuery.add(q);
  852.     }
  853.     {if (true) return orQuery;}
  854.     throw new Error("Missing return statement in function");
  855.   }

  856. /**
  857.  * AndQuery
  858.  * e.g. Query & Query
  859.  * In the example above, first "Query" is supplied in the previousQuery parameter.
  860.  * This method starts parsing tokens after the previousQuery has ended.
  861.  * i.e. first character after the previous query must be "&" Or AND
  862.  */
  863.   final public Query AndQuery(Query previousQuery) throws ParseException {
  864.   ANDQuery andQuery = new ANDQuery();
  865.   Query q;
  866.   Token t;
  867.     t = jj_consume_token(and);
  868.     if(previousQuery instanceof GapQuery)
  869.       {if (true) throw new ParseException("First element cannot be Gap. See line:"+row+", column:"+column);}

  870.     column = t.beginColumn;
  871.     row = t.beginLine;

  872.     if(previousQuery == null)
  873.       {if (true) throw new ParseException(
  874.          "Use of AND at the start of a query is not permitted. See line:"+row+", column:"+column);}

  875.     andQuery.add(previousQuery);
  876.     q = QueryPlus();
  877.     // merging all ANDQueries into one
  878.     // i.e. ANDQuery { query1, ANDQuery {query2, query3}}
  879.     // will become ANDQuery {query1, query2, query3}
  880.     if(q instanceof ANDQuery) {
  881.       ANDQuery aq = (ANDQuery) q;
  882.       for(Query qq : aq.getQueries()) {
  883.         andQuery.add(qq);
  884.       }
  885.     } else {
  886.       andQuery.add(q);
  887.     }
  888.     {if (true) return andQuery;}
  889.     throw new Error("Missing return statement in function");
  890.   }

  891. /**
  892.  * InQuery
  893.  * e.g. Query IN Query
  894.  * In the example above, first "Query" is supplied in the previousQuery parameter.
  895.  * This method starts parsing tokens after the previousQuery has ended.
  896.  * i.e. first character after the previous query must be "IN"
  897.  */
  898.   final public Query InQuery(Query previousQuery) throws ParseException {
  899.   InQuery inQuery = new InQuery();
  900.   Query q;
  901.   Token t;
  902.     t = jj_consume_token(in);
  903.     if(previousQuery instanceof GapQuery)
  904.       {if (true) throw new ParseException("First element cannot be Gap. See line:"+row+", column:"+column);}

  905.     column = t.beginColumn;
  906.     row = t.beginLine;

  907.     if(previousQuery == null)
  908.       {if (true) throw new ParseException(
  909.          "Use of IN at the start of a query is not permitted. See line:"+row+", column:"+column);}

  910.     inQuery.innerQuery = previousQuery;
  911.     q = QueryPlus();
  912.     inQuery.outerQuery = q;
  913.     {if (true) return inQuery;}
  914.     throw new Error("Missing return statement in function");
  915.   }

  916. /**
  917.  * OverQuery
  918.  * e.g. Query OVER Query
  919.  * In the example above, first "Query" is supplied in the previousQuery parameter.
  920.  * This method starts parsing tokens after the previousQuery has ended.
  921.  * i.e. first character after the previous query must be "OVER"
  922.  */
  923.   final public Query OverQuery(Query previousQuery) throws ParseException {
  924.   OverQuery overQuery = new OverQuery();
  925.   Query q;
  926.   Token t;
  927.     t = jj_consume_token(over);
  928.     if(previousQuery instanceof GapQuery)
  929.       {if (true) throw new ParseException(
  930.         "First element cannot be Gap. See line:"+row+", column:"+column);}

  931.     column = t.beginColumn;
  932.     row = t.beginLine;

  933.     if(previousQuery == null)
  934.       {if (true) throw new ParseException(
  935.          "Use of Over at the start of a query is not permitted. " +
  936.          "See line:"+row+", column:"+column);}

  937.     overQuery.overQuery = previousQuery;
  938.     q = QueryPlus();
  939.     overQuery.innerQuery = q;
  940.     {if (true) return overQuery;}
  941.     throw new Error("Missing return statement in function");
  942.   }

  943. /**
  944.  * MinusQuery
  945.  * e.g. Query MINUS Query
  946.  * In the example above, first "Query" is supplied in the previousQuery parameter.
  947.  * This method starts parsing tokens after the previousQuery has ended.
  948.  * i.e. first character after the previous query must be "MINUS" or "-"
  949.  */
  950.   final public Query MinusQuery(Query previousQuery) throws ParseException {
  951.   MinusQuery minusQuery = new MinusQuery();
  952.   Query q;
  953.   Token t;
  954.     t = jj_consume_token(minus);
  955.     if(previousQuery instanceof GapQuery)
  956.       {if (true) throw new ParseException(
  957.         "First element cannot be Gap. See line:"+row+", column:"+column);}

  958.     column = t.beginColumn;
  959.     row = t.beginLine;

  960.     if(previousQuery == null)
  961.       {if (true) throw new ParseException(
  962.          "Use of MINUS at the start of a query is not permitted. " +
  963.          "See line:"+row+", column:"+column);}

  964.     minusQuery.leftQuery = previousQuery;
  965.     q = QueryPlus();
  966.     minusQuery.rightQuery = q;
  967.     {if (true) return minusQuery;}
  968.     throw new Error("Missing return statement in function");
  969.   }

  970. /**
  971.  * KleneQuery
  972.  * e.g. Query+3, Query+3..5
  973.  * In all the above examples, "Query" is supplied in the previousQuery parameter.
  974.  * This method starts parsing tokens after the previousQuery has ended.
  975.  * i.e. first character after the previous query must be "+"
  976.  */
  977.   final public Query KleneQuery(Query previousQuery) throws ParseException {
  978.   KleneQuery kq = new KleneQuery();
  979.   Token t;
  980.   Query q;
  981.     t = jj_consume_token(plus);
  982.     if(previousQuery instanceof GapQuery)
  983.       {if (true) throw new ParseException("First element cannot be Gap." +
  984.       " See line:"+row+", column:"+column);}

  985.     column = t.beginColumn;
  986.     row = t.beginLine;

  987.     if(previousQuery == null)
  988.       {if (true) throw new ParseException(
  989.          "Use of KleneOperator + at the start of a query is not permitted." +
  990.          " See line:"+row+", column:"+column);}

  991.     q = previousQuery;
  992.     kq.query = q;
  993.     kq.min = 1;
  994.     kq.max = 1;
  995.     t = jj_consume_token(number);
  996.       kq.max = Integer.parseInt(t.image);
  997.     switch (jj_nt.kind) {
  998.     case period:
  999.       jj_consume_token(period);
  1000.       jj_consume_token(period);
  1001.       t = jj_consume_token(number);
  1002.         kq.min = kq.max;
  1003.         kq.max = Integer.parseInt(t.image);
  1004.       break;
  1005.     default:
  1006.       jj_la1[13] = jj_gen;
  1007.       ;
  1008.     }
  1009.    {if (true) return kq;}
  1010.     throw new Error("Missing return statement in function");
  1011.   }

  1012.   final private boolean jj_2_1(int xla) {
  1013.     jj_la = xla; jj_lastpos = jj_scanpos = token;
  1014.     try { return !jj_3_1(); }
  1015.     catch(LookaheadSuccess ls) { return true; }
  1016.     finally { jj_save(0, xla); }
  1017.   }

  1018.   final private boolean jj_2_2(int xla) {
  1019.     jj_la = xla; jj_lastpos = jj_scanpos = token;
  1020.     try { return !jj_3_2(); }
  1021.     catch(LookaheadSuccess ls) { return true; }
  1022.     finally { jj_save(1, xla); }
  1023.   }

  1024.   final private boolean jj_2_3(int xla) {
  1025.     jj_la = xla; jj_lastpos = jj_scanpos = token;
  1026.     try { return !jj_3_3(); }
  1027.     catch(LookaheadSuccess ls) { return true; }
  1028.     finally { jj_save(2, xla); }
  1029.   }

  1030.   final private boolean jj_2_4(int xla) {
  1031.     jj_la = xla; jj_lastpos = jj_scanpos = token;
  1032.     try { return !jj_3_4(); }
  1033.     catch(LookaheadSuccess ls) { return true; }
  1034.     finally { jj_save(3, xla); }
  1035.   }

  1036.   final private boolean jj_2_5(int xla) {
  1037.     jj_la = xla; jj_lastpos = jj_scanpos = token;
  1038.     try { return !jj_3_5(); }
  1039.     catch(LookaheadSuccess ls) { return true; }
  1040.     finally { jj_save(4, xla); }
  1041.   }

  1042.   final private boolean jj_3R_4() {
  1043.     if (jj_scan_token(period)) return true;
  1044.     if (jj_scan_token(regex)) return true;
  1045.     return false;
  1046.   }

  1047.   final private boolean jj_3_2() {
  1048.     if (jj_scan_token(or)) return true;
  1049.     return false;
  1050.   }

  1051.   final private boolean jj_3R_3() {
  1052.     Token xsp;
  1053.     xsp = jj_scanpos;
  1054.     if (jj_scan_token(17)) {
  1055.     jj_scanpos = xsp;
  1056.     if (jj_scan_token(25)) {
  1057.     jj_scanpos = xsp;
  1058.     if (jj_scan_token(27)) {
  1059.     jj_scanpos = xsp;
  1060.     if (jj_scan_token(33)) {
  1061.     jj_scanpos = xsp;
  1062.     if (jj_scan_token(34)) {
  1063.     jj_scanpos = xsp;
  1064.     if (jj_scan_token(38)) {
  1065.     jj_scanpos = xsp;
  1066.     if (jj_scan_token(40)) {
  1067.     jj_scanpos = xsp;
  1068.     if (jj_scan_token(35)) {
  1069.     jj_scanpos = xsp;
  1070.     if (jj_scan_token(36)) {
  1071.     jj_scanpos = xsp;
  1072.     if (jj_scan_token(44)) {
  1073.     jj_scanpos = xsp;
  1074.     if (jj_scan_token(41)) {
  1075.     jj_scanpos = xsp;
  1076.     if (jj_scan_token(39)) {
  1077.     jj_scanpos = xsp;
  1078.     if (jj_3R_5()) return true;
  1079.     }
  1080.     }
  1081.     }
  1082.     }
  1083.     }
  1084.     }
  1085.     }
  1086.     }
  1087.     }
  1088.     }
  1089.     }
  1090.     }
  1091.     return false;
  1092.   }

  1093.   final private boolean jj_3_4() {
  1094.     if (jj_3R_4()) return true;
  1095.     return false;
  1096.   }

  1097.   final private boolean jj_3_5() {
  1098.     if (jj_scan_token(tok)) return true;
  1099.     if (jj_scan_token(colon)) return true;
  1100.     return false;
  1101.   }

  1102.   final private boolean jj_3_3() {
  1103.     if (jj_scan_token(and)) return true;
  1104.     return false;
  1105.   }

  1106.   final private boolean jj_3_1() {
  1107.     if (jj_3R_3()) return true;
  1108.     return false;
  1109.   }

  1110.   final private boolean jj_3R_5() {
  1111.     if (jj_scan_token(number)) return true;
  1112.     return false;
  1113.   }

  1114.   public QueryParserTokenManager token_source;
  1115.   SimpleCharStream jj_input_stream;
  1116.   public Token token, jj_nt;
  1117.   private Token jj_scanpos, jj_lastpos;
  1118.   private int jj_la;
  1119.   public boolean lookingAhead = false;
  1120.   private boolean jj_semLA;
  1121.   private int jj_gen;
  1122.   final private int[] jj_la1 = new int[14];
  1123.   static private int[] jj_la1_0;
  1124.   static private int[] jj_la1_1;
  1125.   static {
  1126.       jj_la1_0();
  1127.       jj_la1_1();
  1128.    }
  1129.    private static void jj_la1_0() {
  1130.       jj_la1_0 = new int[] {0xa060000,0xa060000,0x0,0x20000000,0x0,0x20000000,0x0,0x0,0x41e00000,0x60000,0x41e00000,0x20000,0x40000,0x20000000,};
  1131.    }
  1132.    private static void jj_la1_1() {
  1133.       jj_la1_1 = new int[] {0x13de,0x13c8,0x10,0x0,0x80,0x0,0x1,0x1000,0x0,0x1080,0x0,0x1000,0x1080,0x0,};
  1134.    }
  1135.   final private JJCalls[] jj_2_rtns = new JJCalls[5];
  1136.   private boolean jj_rescan = false;
  1137.   private int jj_gc = 0;

  1138.   public QueryParser(java.io.InputStream stream) {
  1139.      this(stream, null);
  1140.   }
  1141.   public QueryParser(java.io.InputStream stream, String encoding) {
  1142.     try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
  1143.     token_source = new QueryParserTokenManager(jj_input_stream);
  1144.     token = new Token();
  1145.     token.next = jj_nt = token_source.getNextToken();
  1146.     jj_gen = 0;
  1147.     for (int i = 0; i < 14; i++) jj_la1[i] = -1;
  1148.     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  1149.   }

  1150.   public void ReInit(java.io.InputStream stream) {
  1151.      ReInit(stream, null);
  1152.   }
  1153.   public void ReInit(java.io.InputStream stream, String encoding) {
  1154.     try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
  1155.     token_source.ReInit(jj_input_stream);
  1156.     token = new Token();
  1157.     token.next = jj_nt = token_source.getNextToken();
  1158.     jj_gen = 0;
  1159.     for (int i = 0; i < 14; i++) jj_la1[i] = -1;
  1160.     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  1161.   }

  1162.   public QueryParser(java.io.Reader stream) {
  1163.     jj_input_stream = new SimpleCharStream(stream, 1, 1);
  1164.     token_source = new QueryParserTokenManager(jj_input_stream);
  1165.     token = new Token();
  1166.     token.next = jj_nt = token_source.getNextToken();
  1167.     jj_gen = 0;
  1168.     for (int i = 0; i < 14; i++) jj_la1[i] = -1;
  1169.     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  1170.   }

  1171.   public void ReInit(java.io.Reader stream) {
  1172.     jj_input_stream.ReInit(stream, 1, 1);
  1173.     token_source.ReInit(jj_input_stream);
  1174.     token = new Token();
  1175.     token.next = jj_nt = token_source.getNextToken();
  1176.     jj_gen = 0;
  1177.     for (int i = 0; i < 14; i++) jj_la1[i] = -1;
  1178.     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  1179.   }

  1180.   public QueryParser(QueryParserTokenManager tm) {
  1181.     token_source = tm;
  1182.     token = new Token();
  1183.     token.next = jj_nt = token_source.getNextToken();
  1184.     jj_gen = 0;
  1185.     for (int i = 0; i < 14; i++) jj_la1[i] = -1;
  1186.     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  1187.   }

  1188.   public void ReInit(QueryParserTokenManager tm) {
  1189.     token_source = tm;
  1190.     token = new Token();
  1191.     token.next = jj_nt = token_source.getNextToken();
  1192.     jj_gen = 0;
  1193.     for (int i = 0; i < 14; i++) jj_la1[i] = -1;
  1194.     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  1195.   }

  1196.   final private Token jj_consume_token(int kind) throws ParseException {
  1197.     Token oldToken = token;
  1198.     if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
  1199.     else jj_nt = jj_nt.next = token_source.getNextToken();
  1200.     if (token.kind == kind) {
  1201.       jj_gen++;
  1202.       if (++jj_gc > 100) {
  1203.         jj_gc = 0;
  1204.         for (int i = 0; i < jj_2_rtns.length; i++) {
  1205.           JJCalls c = jj_2_rtns[i];
  1206.           while (c != null) {
  1207.             if (c.gen < jj_gen) c.first = null;
  1208.             c = c.next;
  1209.           }
  1210.         }
  1211.       }
  1212.       return token;
  1213.     }
  1214.     jj_nt = token;
  1215.     token = oldToken;
  1216.     jj_kind = kind;
  1217.     throw generateParseException();
  1218.   }

  1219.   static private final class LookaheadSuccess extends java.lang.Error { }
  1220.   final private LookaheadSuccess jj_ls = new LookaheadSuccess();
  1221.   final private boolean jj_scan_token(int kind) {
  1222.     if (jj_scanpos == jj_lastpos) {
  1223.       jj_la--;
  1224.       if (jj_scanpos.next == null) {
  1225.         jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
  1226.       } else {
  1227.         jj_lastpos = jj_scanpos = jj_scanpos.next;
  1228.       }
  1229.     } else {
  1230.       jj_scanpos = jj_scanpos.next;
  1231.     }
  1232.     if (jj_rescan) {
  1233.       int i = 0; Token tok = token;
  1234.       while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
  1235.       if (tok != null) jj_add_error_token(kind, i);
  1236.     }
  1237.     if (jj_scanpos.kind != kind) return true;
  1238.     if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
  1239.     return false;
  1240.   }

  1241.   final public Token getNextToken() {
  1242.     if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
  1243.     else jj_nt = jj_nt.next = token_source.getNextToken();
  1244.     jj_gen++;
  1245.     return token;
  1246.   }

  1247.   final public Token getToken(int index) {
  1248.     Token t = lookingAhead ? jj_scanpos : token;
  1249.     for (int i = 0; i < index; i++) {
  1250.       if (t.next != null) t = t.next;
  1251.       else t = t.next = token_source.getNextToken();
  1252.     }
  1253.     return t;
  1254.   }

  1255.   private java.util.Vector jj_expentries = new java.util.Vector();
  1256.   private int[] jj_expentry;
  1257.   private int jj_kind = -1;
  1258.   private int[] jj_lasttokens = new int[100];
  1259.   private int jj_endpos;

  1260.   private void jj_add_error_token(int kind, int pos) {
  1261.     if (pos >= 100) return;
  1262.     if (pos == jj_endpos + 1) {
  1263.       jj_lasttokens[jj_endpos++] = kind;
  1264.     } else if (jj_endpos != 0) {
  1265.       jj_expentry = new int[jj_endpos];
  1266.       for (int i = 0; i < jj_endpos; i++) {
  1267.         jj_expentry[i] = jj_lasttokens[i];
  1268.       }
  1269.       boolean exists = false;
  1270.       for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) {
  1271.         int[] oldentry = (int[])(e.nextElement());
  1272.         if (oldentry.length == jj_expentry.length) {
  1273.           exists = true;
  1274.           for (int i = 0; i < jj_expentry.length; i++) {
  1275.             if (oldentry[i] != jj_expentry[i]) {
  1276.               exists = false;
  1277.               break;
  1278.             }
  1279.           }
  1280.           if (exists) break;
  1281.         }
  1282.       }
  1283.       if (!exists) jj_expentries.addElement(jj_expentry);
  1284.       if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
  1285.     }
  1286.   }

  1287.   public ParseException generateParseException() {
  1288.     jj_expentries.removeAllElements();
  1289.     boolean[] la1tokens = new boolean[47];
  1290.     for (int i = 0; i < 47; i++) {
  1291.       la1tokens[i] = false;
  1292.     }
  1293.     if (jj_kind >= 0) {
  1294.       la1tokens[jj_kind] = true;
  1295.       jj_kind = -1;
  1296.     }
  1297.     for (int i = 0; i < 14; i++) {
  1298.       if (jj_la1[i] == jj_gen) {
  1299.         for (int j = 0; j < 32; j++) {
  1300.           if ((jj_la1_0[i] & (1<<j)) != 0) {
  1301.             la1tokens[j] = true;
  1302.           }
  1303.           if ((jj_la1_1[i] & (1<<j)) != 0) {
  1304.             la1tokens[32+j] = true;
  1305.           }
  1306.         }
  1307.       }
  1308.     }
  1309.     for (int i = 0; i < 47; i++) {
  1310.       if (la1tokens[i]) {
  1311.         jj_expentry = new int[1];
  1312.         jj_expentry[0] = i;
  1313.         jj_expentries.addElement(jj_expentry);
  1314.       }
  1315.     }
  1316.     jj_endpos = 0;
  1317.     jj_rescan_token();
  1318.     jj_add_error_token(0, 0);
  1319.     int[][] exptokseq = new int[jj_expentries.size()][];
  1320.     for (int i = 0; i < jj_expentries.size(); i++) {
  1321.       exptokseq[i] = (int[])jj_expentries.elementAt(i);
  1322.     }
  1323.     return new ParseException(token, exptokseq, tokenImage);
  1324.   }

  1325.   final public void enable_tracing() {
  1326.   }

  1327.   final public void disable_tracing() {
  1328.   }

  1329.   final private void jj_rescan_token() {
  1330.     jj_rescan = true;
  1331.     for (int i = 0; i < 5; i++) {
  1332.     try {
  1333.       JJCalls p = jj_2_rtns[i];
  1334.       do {
  1335.         if (p.gen > jj_gen) {
  1336.           jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
  1337.           switch (i) {
  1338.             case 0: jj_3_1(); break;
  1339.             case 1: jj_3_2(); break;
  1340.             case 2: jj_3_3(); break;
  1341.             case 3: jj_3_4(); break;
  1342.             case 4: jj_3_5(); break;
  1343.           }
  1344.         }
  1345.         p = p.next;
  1346.       } while (p != null);
  1347.       } catch(LookaheadSuccess ls) { }
  1348.     }
  1349.     jj_rescan = false;
  1350.   }

  1351.   final private void jj_save(int index, int xla) {
  1352.     JJCalls p = jj_2_rtns[index];
  1353.     while (p.gen > jj_gen) {
  1354.       if (p.next == null) { p = p.next = new JJCalls(); break; }
  1355.       p = p.next;
  1356.     }
  1357.     p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
  1358.   }

  1359.   static final class JJCalls {
  1360.     int gen;
  1361.     Token first;
  1362.     int arg;
  1363.     JJCalls next;
  1364.   }

  1365. }