![JAR search and dependency download from the Maven repository](/logo.png)
src.it.unimi.dsi.big.mg4j.query.parser.SimpleParser Maven / Gradle / Ivy
Show all versions of mg4j-big Show documentation
/* Generated By:JavaCC: Do not edit this line. SimpleParser.java */
package it.unimi.dsi.big.mg4j.query.parser;
import it.unimi.dsi.lang.*;
import it.unimi.dsi.big.mg4j.index.*;
import it.unimi.dsi.big.mg4j.query.nodes.*;
import it.unimi.dsi.fastutil.objects.*;
import it.unimi.dsi.fastutil.ints.*;
import java.util.*;
/*
* MG4J: Managing Gigabytes for Java (big)
*
* Copyright (C) 2006-2011 Paolo Boldi and Sebastiano Vigna
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see .
*
*/
/** A simple parser that transform a query string into a {@linkplain it.unimi.dsi.mg4j.query.nodes query}.
*
* The parser supports multiple indices. You must provide a set of
* index aliases that the user will use to select indices, and the name of the default index
* alias to be used. After that, you parse a query by using the {@link #parse(String)} method.
*
*
The parser generated by JavaCC for this class will break terms using operators and
* nonspace-to-space transitions. Operators can be included in terms, if needed, using
* the backslash, which acts as an escape character, and makes the next character
* (usually an operator) a standard character. The syntax of the parser can be seen in action
* in the documentation of the package {@link it.unimi.dsi.mg4j.search}.
*
*
The parser returns a {@link it.unimi.dsi.mg4j.query.nodes.Query}—an abstract
* representation of the query string that can be turned later into a
* {@link it.unimi.dsi.mg4j.search.DocumentIterator}.
*
*
If a {@link TermProcessor} is specified, it will be applied to the terms found in the
* query string. This can lead to transformations (e.g., downcasing) or generate an exception
* if the query string contains terms filtered by the term processor.
*
* @author Sebastiano Vigna
* @author Paolo Boldi
* @since 1.0.1
*
*/
@SuppressWarnings("unused")
public class SimpleParser implements QueryParser, SimpleParserConstants {
/** The set of index aliases. */
public Set indices;
/** The default index alias. */
public String defaultIndex;
/** The term processor for each index. */
public Map termProcessors;
/** The query visitor used to check for Select nodes. */
private CheckForSelectQueryVisitor visitor;
private final static boolean DEBUG = false;
/** Creates a parser.
*
* @param indices the set of index aliases.
* @param defaultIndex the default index alias to be used when parsing the query.
* @param termProcessors a map from index aliases to the corresponding term processor, or null
* for no term processing.
*/
public SimpleParser( final Set indices, final String defaultIndex, final Map termProcessors ) {
this( new java.io.StringReader( "" ) ); // Just for initialization purposes...
this.indices = indices;
this.defaultIndex = defaultIndex;
this.termProcessors = termProcessors;
this.visitor = new CheckForSelectQueryVisitor( defaultIndex );
}
/** Creates a parser with no term processing.
*
* @param indices the set of index aliases.
* @param defaultIndex the default index alias to be used when parsing the query.
*/
public SimpleParser( final Set indices, final String defaultIndex ) {
this( indices, defaultIndex, null );
}
/** Creates a parser for a single nameless index with no term processing.
*
* Parsers created by this constructor allow only nameless access,
* both in the query and in the interval-iterator methods.
*/
public SimpleParser() {
this( ObjectSets.singleton( "" ), "" );
}
/** Creates a parser for a single nameless index with a given term processor.
*
*
Parsers created by this constructor allow only nameless access,
* both in the query and in the interval-iterator methods.
*/
public SimpleParser( final TermProcessor termProcessor ) {
this( ObjectSets.singleton( "" ), "", Object2ObjectMaps.singleton( "", termProcessor ) );
}
public SimpleParser copy() {
return new SimpleParser( indices, defaultIndex, termProcessors );
}
// WARNING: these arrays must be kept in sync with the grammar!
private final char[] SPECIAL_CHARACTER =
new char[] { ' ', '&', '$', '<', '|', '!', '(', ')', '{', '}', '[', ']', ',', '\"', ':', '~', '#', '-', '+', '*', '\\', '^', '\u2227', '\u2228', '\u22a4', '\u22a5', };
private final String[] SPECIAL_CHARACTER_REPLACEMENT =
new String[] { "\\ ", "\\&", "\\$", "\\<", "\\|", "\\!", "\\(", "\\)", "\\{", "\\}", "\\[", "\\]", "\\,", "\\\"", "\\:", "\\~", "\\#", "\\-", "\\+", "\\*", "\\\\", "\\^", "\\\u2227", "\\\u2228", "\\\u22a4", "\\\u22a5", };
public String escape( final String token ) {
return new MutableString( token ).replace( SPECIAL_CHARACTER, SPECIAL_CHARACTER_REPLACEMENT ).toString();
}
public MutableString escape( final MutableString token ) {
return token.replace( SPECIAL_CHARACTER, SPECIAL_CHARACTER_REPLACEMENT );
}
public Query parse( final String text ) throws QueryParserException {
ReInit( new java.io.StringReader( text ) );
try {
final Query query = query( defaultIndex );
try {
visitor.prepare();
if ( query.accept( visitor ) == null ) throw new ParseException( visitor.errorMessage );
}
catch( QueryBuilderVisitorException e ) {}
return query;
}
catch( ParseException e ) {
throw new QueryParserException( e );
}
}
public Query parse( final MutableString text ) throws QueryParserException {
ReInit( new it.unimi.dsi.io.FastBufferedReader( text ) );
try {
final Query query = query( defaultIndex );
try {
visitor.prepare();
if ( query.accept( visitor ) == null ) throw new ParseException( visitor.errorMessage );
}
catch( QueryBuilderVisitorException e ) {}
return query;
}
catch( ParseException e ) {
throw new QueryParserException( e );
}
}
/** Parser. */
final public Query query(String indexAlias) throws ParseException {
Query query;
query = remappedQuery(indexAlias);
jj_consume_token(0);
{if (true) return query;}
throw new Error("Missing return statement in function");
}
/** Starting rule for a remapped query.
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query remappedQuery(String indexAlias) throws ParseException {
Query query;
Token external, internal;
ArrayList externalIndices = new ArrayList(), internalIndices = new ArrayList();
query = differenceQuery(indexAlias);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OPEN_REMAP:
jj_consume_token(OPEN_REMAP);
if ( DEBUG ) System.err.println( "Building remapped query" );
internal = jj_consume_token(WORD);
jj_consume_token(REMAP);
external = jj_consume_token(WORD);
internalIndices.add( internal.toString() );
externalIndices.add( external.toString() );
label_1:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case SEMICOLON:
;
break;
default:
jj_la1[0] = jj_gen;
break label_1;
}
jj_consume_token(SEMICOLON);
internal = jj_consume_token(WORD);
jj_consume_token(REMAP);
external = jj_consume_token(WORD);
internalIndices.add( internal.toString() );
externalIndices.add( external.toString() );
}
jj_consume_token(CLOSE_REMAP);
break;
default:
jj_la1[1] = jj_gen;
;
}
if ( externalIndices.isEmpty() ) {if (true) return query;}
{if (true) return new Remap( query, internalIndices.toArray( new String[ internalIndices.size() ] ), externalIndices.toArray( new String[ externalIndices.size() ] ) );}
throw new Error("Missing return statement in function");
}
/** Starting rule for a difference query.
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query differenceQuery(String indexAlias) throws ParseException {
Query minuend, subtrahend = null;
Token leftMargin = null, rightMargin = null;
minuend = orQuery(indexAlias);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case MINUS:
jj_consume_token(MINUS);
if ( DEBUG ) System.err.println( "Building difference query" );
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OPEN_ENLARGE:
jj_consume_token(OPEN_ENLARGE);
leftMargin = jj_consume_token(WORD);
jj_consume_token(COLON);
rightMargin = jj_consume_token(WORD);
jj_consume_token(CLOSE_ENLARGE);
break;
default:
jj_la1[2] = jj_gen;
;
}
subtrahend = orQuery( indexAlias );
break;
default:
jj_la1[3] = jj_gen;
;
}
if ( subtrahend == null ) {if (true) return minuend;}
{if (true) return new Difference( minuend, subtrahend, leftMargin == null ? 0 : Integer.parseInt( leftMargin.image ), rightMargin == null ? 0 : Integer.parseInt( rightMargin.image ) );}
throw new Error("Missing return statement in function");
}
/** Starting rule for a OR-query.
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query orQuery(String indexAlias) throws ParseException {
Query res;
ObjectArrayList qrm = new ObjectArrayList();
res = orderedAndQuery(indexAlias);
qrm.add( res );
label_2:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OR:
;
break;
default:
jj_la1[4] = jj_gen;
break label_2;
}
jj_consume_token(OR);
if ( DEBUG ) System.err.println( "Building OR query" );
res = orderedAndQuery(indexAlias);
qrm.add( res );
}
if ( qrm.size() == 1 ) {if (true) return res;}
{if (true) return new Or( qrm.toArray( Queries.EMPTY_ARRAY ) );}
throw new Error("Missing return statement in function");
}
/** Starting rule for an AND-query (the AND token is optional).
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query andQuery(String indexAlias) throws ParseException {
Query res;
ObjectArrayList qrm = new ObjectArrayList();
res = multiTermQuery(indexAlias);
if ( DEBUG ) System.err.println( "Building AND query: " + res );
qrm.add( res );
label_3:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case AND:
case NOT:
case OPEN_PAREN:
case OPEN_RANGE:
case QUOTE:
case SHARP:
case TRUE:
case FALSE:
case WORD:
;
break;
default:
jj_la1[5] = jj_gen;
break label_3;
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case AND:
jj_consume_token(AND);
break;
default:
jj_la1[6] = jj_gen;
;
}
res = multiTermQuery(indexAlias);
if ( DEBUG ) System.err.println( "Building AND query: " + res );
qrm.add( res );
}
if ( qrm.size() == 1 ) {if (true) return res;}
{if (true) return new And( qrm.toArray( Queries.EMPTY_ARRAY ) );}
throw new Error("Missing return statement in function");
}
/** Starting rule for an AND<-query.
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query orderedAndQuery(String indexAlias) throws ParseException {
Query res;
ObjectArrayList qrm = new ObjectArrayList();
res = alignQuery(indexAlias);
if ( DEBUG ) System.err.println( "Building AND< query: " + res );
qrm.add( res );
label_4:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OAND:
;
break;
default:
jj_la1[7] = jj_gen;
break label_4;
}
jj_consume_token(OAND);
res = alignQuery(indexAlias);
if ( DEBUG ) System.err.println( "Building AND< query: " + res );
qrm.add( res );
}
if ( qrm.size() == 1 ) {if (true) return res;}
{if (true) return new OrderedAnd( qrm.toArray( Queries.EMPTY_ARRAY ) );}
throw new Error("Missing return statement in function");
}
/** Starting rule for an alignment query.
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query alignQuery(String indexAlias) throws ParseException {
Query alignee, aligner = null;
alignee = andQuery(indexAlias);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case ALIGN:
jj_consume_token(ALIGN);
if ( DEBUG ) System.err.println( "Building aligned query: " + alignee );
aligner = andQuery(indexAlias);
break;
default:
jj_la1[8] = jj_gen;
;
}
if ( aligner == null ) {if (true) return alignee;}
{if (true) return new Align( alignee, aligner );}
throw new Error("Missing return statement in function");
}
/** Starting rule for a multiterm query.
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query multiTermQuery(String indexAlias) throws ParseException {
Query res;
ObjectArrayList qrm = new ObjectArrayList();
res = atomicQuery(indexAlias);
if ( DEBUG ) System.err.println( "Building multiterm query: " + res );
qrm.add( res );
label_5:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case PLUS:
;
break;
default:
jj_la1[9] = jj_gen;
break label_5;
}
jj_consume_token(PLUS);
if ( qrm.size() == 1 && ! ( res instanceof Term ) && ! ( ( res instanceof Weight ) && ( ((Weight)res).query instanceof Term ) ) ) {if (true) throw new ParseException("Expecting a term instead of " + res );}
res = atomicQuery(indexAlias);
if ( DEBUG ) System.err.println( "Building multiterm query: " + res );
if ( ! ( res instanceof Term ) && ! ( ( res instanceof Weight ) && ( ((Weight)res).query instanceof Term ) ) ) {if (true) throw new ParseException("Expecting a term instead of " + res );} qrm.add( res );
}
if ( qrm.size() == 1 ) {if (true) return res;}
{if (true) return new MultiTerm( qrm.toArray( new Query[ qrm.size() ] ) );}
throw new Error("Missing return statement in function");
}
/** Starting rule for a quoted query. Subqueries cannot change index.
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query quotedQuery(String indexAlias) throws ParseException {
Query res = null;
ObjectArrayList qrm = new ObjectArrayList();
IntArrayList gaps = new IntArrayList();
int gap = 0; boolean holeSeen = false;
jj_consume_token(QUOTE);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OPEN_PAREN:
case OPEN_RANGE:
case SHARP:
case TRUE:
case FALSE:
case WORD:
res = atomicSimpleQuery(indexAlias);
qrm.add( res ); gaps.add( gap ); gap = 0;
break;
case HOLE:
jj_consume_token(HOLE);
gap++; holeSeen = true;
break;
default:
jj_la1[10] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
label_6:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OPEN_PAREN:
case OPEN_RANGE:
case SHARP:
case TRUE:
case FALSE:
case HOLE:
case WORD:
;
break;
default:
jj_la1[11] = jj_gen;
break label_6;
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OPEN_PAREN:
case OPEN_RANGE:
case SHARP:
case TRUE:
case FALSE:
case WORD:
res = atomicSimpleQuery(indexAlias);
qrm.add( res ); gaps.add( gap ); gap = 0;
break;
case HOLE:
jj_consume_token(HOLE);
gap++; holeSeen = true;
break;
default:
jj_la1[12] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
}
jj_consume_token(QUOTE);
if ( qrm.size() == 1 ) {
if ( res == null ) {if (true) throw new ParseException( "You must specify at least one term within quotes" );}
{if (true) return res;}
}
if ( gap > 0 ) gaps.add( gap );
{if (true) return new Consecutive( qrm.toArray( Queries.EMPTY_ARRAY ), holeSeen ? gaps.toIntArray() : null );}
throw new Error("Missing return statement in function");
}
/** Starting rule for an atomic query. May be either an atomic simple query or a
* quoted query. It can optionally contain an index selector and
* a low-pass limit.
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query atomicQuery(String indexAlias) throws ParseException {
Query res;
Token t;
String newIndexAlias = indexAlias;
boolean negative = false;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case NOT:
jj_consume_token(NOT);
negative = true;
break;
default:
jj_la1[13] = jj_gen;
;
}
if (jj_2_1(2)) {
t = jj_consume_token(WORD);
newIndexAlias = t.image;
jj_consume_token(COLON);
} else {
;
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OPEN_PAREN:
case OPEN_RANGE:
case SHARP:
case TRUE:
case FALSE:
case WORD:
res = atomicSimpleQuery(newIndexAlias);
break;
case QUOTE:
res = quotedQuery(newIndexAlias);
break;
default:
jj_la1[14] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
if ( negative ) res = new Not( res );
if ( newIndexAlias != indexAlias ) res = new Select( newIndexAlias, res );
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case TILDA:
jj_consume_token(TILDA);
t = jj_consume_token(WORD);
int limit = 0;
try {
limit = Integer.parseInt( t.image );
if ( limit <= 0 ) {if (true) throw new NumberFormatException();}
} catch ( NumberFormatException e ) {
{if (true) throw new ParseException( "Expecting a positive number, found " + t.image + " instead" );}
}
if ( DEBUG ) System.err.println( "Building low-pass filter with threshold " + limit );
res = new LowPass( res, limit );
break;
default:
jj_la1[15] = jj_gen;
;
}
{if (true) return res;}
throw new Error("Missing return statement in function");
}
/** Starting rule for an atomic simple query. May be either a word or a query
* enclosed within parentheses.
* @param indexAlias the index alias for the default index to be used for the query that is going to be parsed.
* @return the result of the query.
*/
final public Query atomicSimpleQuery(String indexAlias) throws ParseException {
Query res;
Token t = null, s = null, p = null;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case TRUE:
jj_consume_token(TRUE);
res = new True();
break;
case FALSE:
jj_consume_token(FALSE);
res = new False();
break;
case SHARP:
case WORD:
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case SHARP:
s = jj_consume_token(SHARP);
break;
default:
jj_la1[16] = jj_gen;
;
}
t = jj_consume_token(WORD);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case PREFIX:
p = jj_consume_token(PREFIX);
break;
default:
jj_la1[17] = jj_gen;
;
}
String word = t.image;
if ( ! indices.contains( indexAlias ) ) {if (true) throw new ParseException( "Index \"" + indexAlias + "\" does not exist" );}
if ( s != null && p != null ) {if (true) throw new ParseException( s + " and " + p + " cannot be used at the same time" );}
final MutableString term = new MutableString();
if ( s == null ) {
// Before passing the word to anyone, we pass it through the index term processor.
for( int i = 0; i < word.length(); i++ ) {
if ( word.charAt( i ) == '\\' ) i++;
term.append( word.charAt( i ) );
}
if ( p != null ) {
if ( termProcessors != null && ! termProcessors.get( indexAlias ).processPrefix( term ) ) {if (true) throw new ParseException( "Prefix " + term + " has not been indexed" );}
}
else {
if ( termProcessors != null && ! termProcessors.get( indexAlias ).processTerm( term ) ) {if (true) throw new ParseException( "Term " + term + " has not been indexed" );}
}
}
if ( p == null ) {
if ( s != null ) {
try {
res = new Term( Integer.parseInt( word ) );
}
catch( NumberFormatException e ) {
{if (true) throw new ParseException( "Malformed number: " + word );}
}
}
else res = new Term( term );
}
else {
res = new Prefix( term );
}
break;
case OPEN_RANGE:
jj_consume_token(OPEN_RANGE);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case WORD:
s = jj_consume_token(WORD);
break;
default:
jj_la1[18] = jj_gen;
;
}
jj_consume_token(INTERVAL_SEPARATOR);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case WORD:
t = jj_consume_token(WORD);
break;
default:
jj_la1[19] = jj_gen;
;
}
jj_consume_token(CLOSE_RANGE);
res = new Range( s != null ? s.toString() : null, t != null ? t.toString() : null );
break;
case OPEN_PAREN:
jj_consume_token(OPEN_PAREN);
res = remappedQuery(indexAlias);
jj_consume_token(CLOSE_PAREN);
break;
default:
jj_la1[20] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case OPEN_WEIGHT:
jj_consume_token(OPEN_WEIGHT);
t = jj_consume_token(WORD);
jj_consume_token(CLOSE_WEIGHT);
double weight;
try {
weight = Double.parseDouble( t.image );
if ( weight < 0 ) {if (true) throw new NumberFormatException();}
} catch ( NumberFormatException e ) {
{if (true) throw new ParseException( "Expecting a nonnegative number, found " + t.image + " instead" );}
}
if ( DEBUG ) System.err.println( "Building weight: " + weight );
res = new Weight( weight, res );
break;
default:
jj_la1[21] = jj_gen;
;
}
{if (true) return res;}
throw new Error("Missing return statement in function");
}
final private boolean jj_2_1(int xla) {
jj_la = xla; jj_lastpos = jj_scanpos = token;
try { return !jj_3_1(); }
catch(LookaheadSuccess ls) { return true; }
finally { jj_save(0, xla); }
}
final private boolean jj_3_1() {
if (jj_scan_token(WORD)) return true;
if (jj_scan_token(COLON)) return true;
return false;
}
public SimpleParserTokenManager token_source;
SimpleCharStream jj_input_stream;
public Token token, jj_nt;
private int jj_ntk;
private Token jj_scanpos, jj_lastpos;
private int jj_la;
public boolean lookingAhead = false;
private boolean jj_semLA;
private int jj_gen;
final private int[] jj_la1 = new int[22];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
jj_la1_0();
jj_la1_1();
}
private static void jj_la1_0() {
jj_la1_0 = new int[] {0x800000,0x10000,0x80000,0x4000000,0x80,0x38201520,0x20,0x40,0x200,0x2000000,0xb8001400,0xb8001400,0xb8001400,0x100,0x38201400,0x1000000,0x8000000,0x40000000,0x0,0x0,0x38001400,0x4000,};
}
private static void jj_la1_1() {
jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x0,0x2,0x0,0x0,0x0,0x2,0x2,0x2,0x0,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[1];
private boolean jj_rescan = false;
private int jj_gc = 0;
public SimpleParser(java.io.InputStream stream) {
this(stream, null);
}
public SimpleParser(java.io.InputStream stream, String encoding) {
try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source = new SimpleParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 22; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
public void ReInit(java.io.InputStream stream) {
ReInit(stream, null);
}
public void ReInit(java.io.InputStream stream, String encoding) {
try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 22; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
public SimpleParser(java.io.Reader stream) {
jj_input_stream = new SimpleCharStream(stream, 1, 1);
token_source = new SimpleParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 22; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
public void ReInit(java.io.Reader stream) {
jj_input_stream.ReInit(stream, 1, 1);
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 22; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
public SimpleParser(SimpleParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 22; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
public void ReInit(SimpleParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 22; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
final private Token jj_consume_token(int kind) throws ParseException {
Token oldToken;
if ((oldToken = token).next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
if (token.kind == kind) {
jj_gen++;
if (++jj_gc > 100) {
jj_gc = 0;
for (int i = 0; i < jj_2_rtns.length; i++) {
JJCalls c = jj_2_rtns[i];
while (c != null) {
if (c.gen < jj_gen) c.first = null;
c = c.next;
}
}
}
return token;
}
token = oldToken;
jj_kind = kind;
throw generateParseException();
}
static private final class LookaheadSuccess extends java.lang.Error { }
final private LookaheadSuccess jj_ls = new LookaheadSuccess();
final private boolean jj_scan_token(int kind) {
if (jj_scanpos == jj_lastpos) {
jj_la--;
if (jj_scanpos.next == null) {
jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
} else {
jj_lastpos = jj_scanpos = jj_scanpos.next;
}
} else {
jj_scanpos = jj_scanpos.next;
}
if (jj_rescan) {
int i = 0; Token tok = token;
while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
if (tok != null) jj_add_error_token(kind, i);
}
if (jj_scanpos.kind != kind) return true;
if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
return false;
}
final public Token getNextToken() {
if (token.next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
jj_gen++;
return token;
}
final public Token getToken(int index) {
Token t = lookingAhead ? jj_scanpos : token;
for (int i = 0; i < index; i++) {
if (t.next != null) t = t.next;
else t = t.next = token_source.getNextToken();
}
return t;
}
final private int jj_ntk() {
if ((jj_nt=token.next) == null)
return (jj_ntk = (token.next=token_source.getNextToken()).kind);
else
return (jj_ntk = jj_nt.kind);
}
private java.util.Vector jj_expentries = new java.util.Vector();
private int[] jj_expentry;
private int jj_kind = -1;
private int[] jj_lasttokens = new int[100];
private int jj_endpos;
private void jj_add_error_token(int kind, int pos) {
if (pos >= 100) return;
if (pos == jj_endpos + 1) {
jj_lasttokens[jj_endpos++] = kind;
} else if (jj_endpos != 0) {
jj_expentry = new int[jj_endpos];
for (int i = 0; i < jj_endpos; i++) {
jj_expentry[i] = jj_lasttokens[i];
}
boolean exists = false;
for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) {
int[] oldentry = (int[])(e.nextElement());
if (oldentry.length == jj_expentry.length) {
exists = true;
for (int i = 0; i < jj_expentry.length; i++) {
if (oldentry[i] != jj_expentry[i]) {
exists = false;
break;
}
}
if (exists) break;
}
}
if (!exists) jj_expentries.addElement(jj_expentry);
if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
}
}
public ParseException generateParseException() {
jj_expentries.removeAllElements();
boolean[] la1tokens = new boolean[34];
for (int i = 0; i < 34; i++) {
la1tokens[i] = false;
}
if (jj_kind >= 0) {
la1tokens[jj_kind] = true;
jj_kind = -1;
}
for (int i = 0; i < 22; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1< jj_gen) {
jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
switch (i) {
case 0: jj_3_1(); break;
}
}
p = p.next;
} while (p != null);
} catch(LookaheadSuccess ls) { }
}
jj_rescan = false;
}
final private void jj_save(int index, int xla) {
JJCalls p = jj_2_rtns[index];
while (p.gen > jj_gen) {
if (p.next == null) { p = p.next = new JJCalls(); break; }
p = p.next;
}
p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
}
static final class JJCalls {
int gen;
Token first;
int arg;
JJCalls next;
}
}