001/* Generated By:JavaCC: Do not edit this line. MdxParserImpl.java */
002package mondrian.parser;
003
004import java.util.*;
005import java.io.StringReader;
006import java.math.BigDecimal;
007
008import mondrian.olap.*;
009import mondrian.mdx.*;
010import mondrian.parser.*;
011import mondrian.resource.MondrianResource;
012import mondrian.server.Statement;
013
014/**
015 * MDX parser, generated from MdxParser.jj.
016 *
017 * <p>The public wrapper for this parser is {@link JavaccParserValidatorImpl}.
018 *
019 * @author jhyde
020 * @since Dec 14, 2010
021 */
022@SuppressWarnings({
023    "ConstantIfStatement",
024    "UnnecessarySemicolon",
025    "UnnecessaryLabelOnBreakStatement",
026    "RedundantIfStatement"
027})
028public class MdxParserImpl implements MdxParserImplConstants {
029    private MdxParserValidator.QueryPartFactory factory;
030    private Statement statement;
031    private FunTable funTable;
032    private boolean strictValidation;
033
034    public MdxParserImpl(
035        MdxParserValidator.QueryPartFactory factory,
036        Statement statement,
037        String queryString,
038        boolean debug,
039        FunTable funTable,
040        boolean strictValidation)
041    {
042        this(new StringReader(term(queryString)));
043        this.factory = factory;
044        this.statement = statement;
045        this.funTable = funTable;
046        this.strictValidation = strictValidation;
047    }
048
049    private static String term(String s) {
050        return s.endsWith("\u005cn") ? s : (s + "\u005cn");
051    }
052
053    public void setTabSize(int tabSize) {
054        jj_input_stream.setTabSize(tabSize);
055    }
056
057    Exp recursivelyParseExp(String s) throws ParseException {
058        MdxParserImpl parser =
059            new MdxParserImpl(
060                factory,
061                statement,
062                s,
063                false,
064                funTable,
065                strictValidation);
066        return parser.expression();
067    }
068
069    static Id[] toIdArray(List<Id> idList) {
070        if (idList == null || idList.size() == 0) {
071            return EmptyIdArray;
072        } else {
073            return idList.toArray(new Id[idList.size()]);
074        }
075    }
076
077    static Exp[] toExpArray(List<Exp> expList) {
078        if (expList == null || expList.size() == 0) {
079            return EmptyExpArray;
080        } else {
081            return expList.toArray(new Exp[expList.size()]);
082        }
083    }
084
085    static Formula[] toFormulaArray(List<Formula> formulaList) {
086        if (formulaList == null || formulaList.size() == 0) {
087            return EmptyFormulaArray;
088        } else {
089            return formulaList.toArray(new Formula[formulaList.size()]);
090        }
091    }
092
093    static MemberProperty[] toMemberPropertyArray(List<MemberProperty> mpList) {
094        if (mpList == null || mpList.size() == 0) {
095            return EmptyMemberPropertyArray;
096        } else {
097            return mpList.toArray(new MemberProperty[mpList.size()]);
098        }
099    }
100
101    static QueryPart[] toQueryPartArray(List<QueryPart> qpList) {
102        if (qpList == null || qpList.size() == 0) {
103            return EmptyQueryPartArray;
104        } else {
105            return qpList.toArray(new QueryPart[qpList.size()]);
106        }
107    }
108
109    static QueryAxis[] toQueryAxisArray(List<QueryAxis> qpList) {
110        if (qpList == null || qpList.size() == 0) {
111            return EmptyQueryAxisArray;
112        } else {
113            return qpList.toArray(new QueryAxis[qpList.size()]);
114        }
115    }
116
117    private static final MemberProperty[] EmptyMemberPropertyArray =
118        new MemberProperty[0];
119    private static final Exp[] EmptyExpArray = new Exp[0];
120    private static final Formula[] EmptyFormulaArray = new Formula[0];
121    private static final Id[] EmptyIdArray = new Id[0];
122    private static final QueryPart[] EmptyQueryPartArray = new QueryPart[0];
123    private static final QueryAxis[] EmptyQueryAxisArray = new QueryAxis[0];
124
125    private static final String DQ = '"' + "";
126    private static final String DQDQ = DQ + DQ;
127
128    private static String stripQuotes(
129        String s, String prefix, String suffix, String quoted)
130    {
131        assert s.startsWith(prefix) && s.endsWith(suffix);
132        s = s.substring(prefix.length(), s.length() - suffix.length());
133        s = Util.replace(s, quoted, suffix);
134        return s;
135    }
136
137    private Exp createCall(
138        Exp left,
139        Id.Segment segment,
140        List<Exp> argList)
141    {
142        final String name = segment instanceof Id.NameSegment
143            ? ((Id.NameSegment) segment).name
144            : null;
145        if (argList != null) {
146            if (left != null) {
147                // Method syntax: "x.foo(arg1, arg2)" or "x.foo()"
148                argList.add(0, left);
149                return new UnresolvedFunCall(
150                    name, Syntax.Method, toExpArray(argList));
151            } else {
152                // Function syntax: "foo(arg1, arg2)" or "foo()"
153                return new UnresolvedFunCall(
154                    name, Syntax.Function, toExpArray(argList));
155            }
156        } else {
157            // Member syntax: "foo.bar"
158            // or property syntax: "foo.RESERVED_WORD"
159            Syntax syntax;
160            boolean call = false;
161            switch (segment.quoting) {
162            case UNQUOTED:
163                syntax = Syntax.Property;
164                call = funTable.isProperty(name);
165                break;
166            case QUOTED:
167                syntax = Syntax.QuotedProperty;
168                break;
169            default:
170                syntax = Syntax.AmpersandQuotedProperty;
171                break;
172            }
173            if (left instanceof Id && !call) {
174                return ((Id) left).append(segment);
175            } else if (left == null) {
176                return new Id(segment);
177            } else {
178                return new UnresolvedFunCall(
179                    name, syntax, new Exp[] {left});
180            }
181        }
182    }
183
184// ----------------------------------------------------------------------------
185// Entry points
186  final public QueryPart statementEof() throws ParseException {
187    QueryPart qp;
188    qp = statement();
189    jj_consume_token(0);
190        {if (true) return qp;}
191    throw new Error("Missing return statement in function");
192  }
193
194  final public Exp expressionEof() throws ParseException {
195    Exp e;
196    e = expression();
197    jj_consume_token(0);
198        {if (true) return e;}
199    throw new Error("Missing return statement in function");
200  }
201
202// ----------------------------------------------------------------------------
203// Elements
204//
205//
206// <identifier> ::= <regularIdentifier> | <delimitedIdentifier>
207  final public Id.Segment identifier() throws ParseException {
208    Id.Segment segment;
209    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
210    case DIMENSION:
211    case PROPERTIES:
212    case ID:
213    case QUOTED_ID:
214      segment = nameSegment();
215      break;
216    case AMP_QUOTED_ID:
217    case AMP_UNQUOTED_ID:
218      segment = keyIdentifier();
219      break;
220    default:
221      jj_la1[0] = jj_gen;
222      jj_consume_token(-1);
223      throw new ParseException();
224    }
225        {if (true) return segment;}
226    throw new Error("Missing return statement in function");
227  }
228
229  final public Id.NameSegment nameSegment() throws ParseException {
230    String id;
231    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
232    case DIMENSION:
233    case PROPERTIES:
234      id = keyword();
235        // Allow a non-reserved keyword to be converted back into an identifier
236        // if it is not in a context where it is meaningful.
237        {if (true) return new Id.NameSegment(id, Id.Quoting.UNQUOTED);}
238      break;
239    case ID:
240      jj_consume_token(ID);
241        {if (true) return new Id.NameSegment(token.image, Id.Quoting.UNQUOTED);}
242      break;
243    case QUOTED_ID:
244      jj_consume_token(QUOTED_ID);
245        {if (true) return new Id.NameSegment(
246            stripQuotes(token.image, "[", "]", "]]"),
247            Id.Quoting.QUOTED);}
248      break;
249    default:
250      jj_la1[1] = jj_gen;
251      jj_consume_token(-1);
252      throw new ParseException();
253    }
254    throw new Error("Missing return statement in function");
255  }
256
257// for example '&foo&[1]&bar' in '[x].&foo&[1]&bar.[y]'
258  final public Id.KeySegment keyIdentifier() throws ParseException {
259    List<Id.NameSegment> list = new ArrayList<Id.NameSegment>();
260    Id.NameSegment key;
261    label_1:
262    while (true) {
263      key = ampId();
264            list.add(key);
265      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
266      case AMP_QUOTED_ID:
267      case AMP_UNQUOTED_ID:
268        ;
269        break;
270      default:
271        jj_la1[2] = jj_gen;
272        break label_1;
273      }
274    }
275        {if (true) return new Id.KeySegment(list);}
276    throw new Error("Missing return statement in function");
277  }
278
279  final public Id.NameSegment ampId() throws ParseException {
280    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
281    case AMP_QUOTED_ID:
282      jj_consume_token(AMP_QUOTED_ID);
283        {if (true) return new Id.NameSegment(
284            stripQuotes(token.image, "&[", "]", "]]"),
285            Id.Quoting.QUOTED);}
286      break;
287    case AMP_UNQUOTED_ID:
288      jj_consume_token(AMP_UNQUOTED_ID);
289        {if (true) return new Id.NameSegment(
290            token.image.substring(1),
291            Id.Quoting.UNQUOTED);}
292      break;
293    default:
294      jj_la1[3] = jj_gen;
295      jj_consume_token(-1);
296      throw new ParseException();
297    }
298    throw new Error("Missing return statement in function");
299  }
300
301// a keyword (unlike a reserved word) can be converted back into an
302// identifier in some contexts
303  final public String keyword() throws ParseException {
304    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
305    case DIMENSION:
306      jj_consume_token(DIMENSION);
307        {if (true) return "Dimension";}
308      break;
309    case PROPERTIES:
310      jj_consume_token(PROPERTIES);
311        {if (true) return "Properties";}
312      break;
313    default:
314      jj_la1[4] = jj_gen;
315      jj_consume_token(-1);
316      throw new ParseException();
317    }
318    throw new Error("Missing return statement in function");
319  }
320
321  final public Id compoundId() throws ParseException {
322    Id.Segment i;
323    List<Id.Segment> list = new ArrayList<Id.Segment>();
324    i = identifier();
325        list.add(i);
326    label_2:
327    while (true) {
328      if (jj_2_1(2147483647)) {
329        ;
330      } else {
331        break label_2;
332      }
333      jj_consume_token(DOT);
334      i = identifier();
335            list.add(i);
336    }
337        {if (true) return new Id(list);}
338    throw new Error("Missing return statement in function");
339  }
340
341// ----------------------------------------------------------------------------
342// Expressions
343  final public Exp unaliasedExpression() throws ParseException {
344    Exp x, y;
345    x = term5();
346    label_3:
347    while (true) {
348      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
349      case OR:
350      case XOR:
351      case COLON:
352        ;
353        break;
354      default:
355        jj_la1[5] = jj_gen;
356        break label_3;
357      }
358      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
359      case OR:
360        jj_consume_token(OR);
361        y = term5();
362            x = new UnresolvedFunCall("OR", Syntax.Infix, new Exp[] {x, y});
363        break;
364      case XOR:
365        jj_consume_token(XOR);
366        y = term5();
367            x = new UnresolvedFunCall("XOR", Syntax.Infix, new Exp[] {x, y});
368        break;
369      case COLON:
370        jj_consume_token(COLON);
371        y = term5();
372            x = new UnresolvedFunCall(":", Syntax.Infix, new Exp[] {x, y});
373        break;
374      default:
375        jj_la1[6] = jj_gen;
376        jj_consume_token(-1);
377        throw new ParseException();
378      }
379    }
380        {if (true) return x;}
381    throw new Error("Missing return statement in function");
382  }
383
384  final public Exp term5() throws ParseException {
385    Exp x, y;
386    x = term4();
387    label_4:
388    while (true) {
389      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
390      case AND:
391        ;
392        break;
393      default:
394        jj_la1[7] = jj_gen;
395        break label_4;
396      }
397      jj_consume_token(AND);
398      y = term4();
399            x = new UnresolvedFunCall("AND", Syntax.Infix, new Exp[] {x, y});
400    }
401        {if (true) return x;}
402    throw new Error("Missing return statement in function");
403  }
404
405  final public Exp term4() throws ParseException {
406    Exp x;
407    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
408    case CASE:
409    case CAST:
410    case DIMENSION:
411    case NULL:
412    case PROPERTIES:
413    case LBRACE:
414    case LPAREN:
415    case MINUS:
416    case PLUS:
417    case UNSIGNED_INTEGER_LITERAL:
418    case APPROX_NUMERIC_LITERAL:
419    case DECIMAL_NUMERIC_LITERAL:
420    case SINGLE_QUOTED_STRING:
421    case DOUBLE_QUOTED_STRING:
422    case ID:
423    case QUOTED_ID:
424      x = term3();
425        {if (true) return x;}
426      break;
427    case NOT:
428      jj_consume_token(NOT);
429      x = term4();
430        {if (true) return new UnresolvedFunCall("NOT", Syntax.Prefix, new Exp[] {x});}
431      break;
432    default:
433      jj_la1[8] = jj_gen;
434      jj_consume_token(-1);
435      throw new ParseException();
436    }
437    throw new Error("Missing return statement in function");
438  }
439
440  final public Exp term3() throws ParseException {
441    Exp x, y;
442    Token op;
443    x = term2();
444    label_5:
445    while (true) {
446      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
447      case IN:
448      case IS:
449      case MATCHES:
450      case NOT:
451      case EQ:
452      case GE:
453      case GT:
454      case LE:
455      case LT:
456      case NE:
457        ;
458        break;
459      default:
460        jj_la1[9] = jj_gen;
461        break label_5;
462      }
463      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
464      case EQ:
465      case GE:
466      case GT:
467      case LE:
468      case LT:
469      case NE:
470        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
471        case EQ:
472          jj_consume_token(EQ);
473                   op = token;
474          break;
475        case NE:
476          jj_consume_token(NE);
477                    op = token;
478          break;
479        case LT:
480          jj_consume_token(LT);
481                    op = token;
482          break;
483        case GT:
484          jj_consume_token(GT);
485                    op = token;
486          break;
487        case LE:
488          jj_consume_token(LE);
489                    op = token;
490          break;
491        case GE:
492          jj_consume_token(GE);
493                    op = token;
494          break;
495        default:
496          jj_la1[10] = jj_gen;
497          jj_consume_token(-1);
498          throw new ParseException();
499        }
500        y = term2();
501            x = new UnresolvedFunCall(op.image, Syntax.Infix, new Exp[] {x, y});
502        break;
503      default:
504        jj_la1[11] = jj_gen;
505        if (jj_2_2(2)) {
506          jj_consume_token(IS);
507          jj_consume_token(NULL);
508            x = new UnresolvedFunCall("IS NULL", Syntax.Postfix, new Exp[] {x});
509        } else if (jj_2_3(2)) {
510          jj_consume_token(IS);
511          y = term2();
512            x = new UnresolvedFunCall("IS", Syntax.Infix, new Exp[] {x, y});
513        } else {
514          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
515          case IS:
516            jj_consume_token(IS);
517            jj_consume_token(EMPTY);
518            x = new UnresolvedFunCall(
519                "IS EMPTY", Syntax.Postfix, new Exp[] {x});
520            break;
521          case MATCHES:
522            jj_consume_token(MATCHES);
523            y = term2();
524            x = new UnresolvedFunCall("MATCHES", Syntax.Infix, new Exp[] {x, y});
525            break;
526          default:
527            jj_la1[12] = jj_gen;
528            if (jj_2_4(2)) {
529              jj_consume_token(NOT);
530              jj_consume_token(MATCHES);
531              y = term2();
532            x = new UnresolvedFunCall(
533                "NOT", Syntax.Prefix, new Exp[] {
534                    new UnresolvedFunCall(
535                        "MATCHES", Syntax.Infix, new Exp[] {x, y})});
536            } else {
537              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
538              case IN:
539                jj_consume_token(IN);
540                y = term2();
541            x = new UnresolvedFunCall("IN", Syntax.Infix, new Exp[] {x, y});
542                break;
543              case NOT:
544                jj_consume_token(NOT);
545                jj_consume_token(IN);
546                y = term2();
547            x = new UnresolvedFunCall(
548                "NOT", Syntax.Prefix, new Exp[] {
549                    new UnresolvedFunCall(
550                        "IN", Syntax.Infix, new Exp[] {x, y})});
551                break;
552              default:
553                jj_la1[13] = jj_gen;
554                jj_consume_token(-1);
555                throw new ParseException();
556              }
557            }
558          }
559        }
560      }
561    }
562        {if (true) return x;}
563    throw new Error("Missing return statement in function");
564  }
565
566  final public Exp term2() throws ParseException {
567    Exp x, y;
568    x = term();
569    label_6:
570    while (true) {
571      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
572      case CONCAT:
573      case MINUS:
574      case PLUS:
575        ;
576        break;
577      default:
578        jj_la1[14] = jj_gen;
579        break label_6;
580      }
581      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
582      case PLUS:
583        jj_consume_token(PLUS);
584        y = term();
585            x = new UnresolvedFunCall("+", Syntax.Infix, new Exp[] {x, y});
586        break;
587      case MINUS:
588        jj_consume_token(MINUS);
589        y = term();
590            x = new UnresolvedFunCall("-", Syntax.Infix, new Exp[] {x, y});
591        break;
592      case CONCAT:
593        jj_consume_token(CONCAT);
594        y = term();
595            x = new UnresolvedFunCall("||", Syntax.Infix, new Exp[] {x, y});
596        break;
597      default:
598        jj_la1[15] = jj_gen;
599        jj_consume_token(-1);
600        throw new ParseException();
601      }
602    }
603        {if (true) return x;}
604    throw new Error("Missing return statement in function");
605  }
606
607  final public Exp term() throws ParseException {
608    Exp x, y;
609    x = factor();
610    label_7:
611    while (true) {
612      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
613      case ASTERISK:
614      case SOLIDUS:
615        ;
616        break;
617      default:
618        jj_la1[16] = jj_gen;
619        break label_7;
620      }
621      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
622      case ASTERISK:
623        jj_consume_token(ASTERISK);
624        y = factor();
625            x = new UnresolvedFunCall("*", Syntax.Infix, new Exp[] {x, y});
626        break;
627      case SOLIDUS:
628        jj_consume_token(SOLIDUS);
629        y = factor();
630            x = new UnresolvedFunCall("/", Syntax.Infix, new Exp[] {x, y});
631        break;
632      default:
633        jj_la1[17] = jj_gen;
634        jj_consume_token(-1);
635        throw new ParseException();
636      }
637    }
638        {if (true) return x;}
639    throw new Error("Missing return statement in function");
640  }
641
642  final public Exp factor() throws ParseException {
643    Exp p;
644    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
645    case CASE:
646    case CAST:
647    case DIMENSION:
648    case NULL:
649    case PROPERTIES:
650    case LBRACE:
651    case LPAREN:
652    case UNSIGNED_INTEGER_LITERAL:
653    case APPROX_NUMERIC_LITERAL:
654    case DECIMAL_NUMERIC_LITERAL:
655    case SINGLE_QUOTED_STRING:
656    case DOUBLE_QUOTED_STRING:
657    case ID:
658    case QUOTED_ID:
659      p = primary();
660        {if (true) return p;}
661      break;
662    case PLUS:
663      jj_consume_token(PLUS);
664      p = primary();
665        {if (true) return p;}
666      break;
667    case MINUS:
668      jj_consume_token(MINUS);
669      p = primary();
670        {if (true) return new UnresolvedFunCall("-", Syntax.Prefix, new Exp[] {p});}
671      break;
672    default:
673      jj_la1[18] = jj_gen;
674      jj_consume_token(-1);
675      throw new ParseException();
676    }
677    throw new Error("Missing return statement in function");
678  }
679
680  final public Exp primary() throws ParseException {
681    Exp e;
682    e = atom();
683    label_8:
684    while (true) {
685      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
686      case DOT:
687        ;
688        break;
689      default:
690        jj_la1[19] = jj_gen;
691        break label_8;
692      }
693      jj_consume_token(DOT);
694      e = segmentOrFuncall(e);
695    }
696        {if (true) return e;}
697    throw new Error("Missing return statement in function");
698  }
699
700  final public Exp segmentOrFuncall(Exp left) throws ParseException {
701    Id.Segment segment;
702    List<Exp> argList = null;
703    segment = identifier();
704    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
705    case LPAREN:
706      jj_consume_token(LPAREN);
707      if (jj_2_5(2147483647)) {
708                argList = Collections.emptyList();
709      } else {
710        argList = expOrEmptyList();
711      }
712      jj_consume_token(RPAREN);
713      break;
714    default:
715      jj_la1[20] = jj_gen;
716      ;
717    }
718        {if (true) return createCall(left, segment, argList);}
719    throw new Error("Missing return statement in function");
720  }
721
722  final public Literal numericLiteral() throws ParseException {
723    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
724    case DECIMAL_NUMERIC_LITERAL:
725      jj_consume_token(DECIMAL_NUMERIC_LITERAL);
726        {if (true) return Literal.create(new BigDecimal(token.image));}
727      break;
728    case UNSIGNED_INTEGER_LITERAL:
729      jj_consume_token(UNSIGNED_INTEGER_LITERAL);
730        {if (true) return Literal.create(new BigDecimal(token.image));}
731      break;
732    case APPROX_NUMERIC_LITERAL:
733      jj_consume_token(APPROX_NUMERIC_LITERAL);
734        {if (true) return Literal.create(new BigDecimal(token.image));}
735      break;
736    default:
737      jj_la1[21] = jj_gen;
738      jj_consume_token(-1);
739      throw new ParseException();
740    }
741    throw new Error("Missing return statement in function");
742  }
743
744  final public Exp atom() throws ParseException {
745    Exp e;
746    Id.NameSegment segment;
747    List<Exp> lis;
748    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
749    case SINGLE_QUOTED_STRING:
750      jj_consume_token(SINGLE_QUOTED_STRING);
751        {if (true) return Literal.createString(stripQuotes(token.image, "'", "'", "''"));}
752      break;
753    case DOUBLE_QUOTED_STRING:
754      jj_consume_token(DOUBLE_QUOTED_STRING);
755        {if (true) return Literal.createString(stripQuotes(token.image, DQ, DQ, DQDQ));}
756      break;
757    case UNSIGNED_INTEGER_LITERAL:
758    case APPROX_NUMERIC_LITERAL:
759    case DECIMAL_NUMERIC_LITERAL:
760      e = numericLiteral();
761        {if (true) return e;}
762      break;
763    case NULL:
764      jj_consume_token(NULL);
765        {if (true) return Literal.nullValue;}
766      break;
767    case CAST:
768      jj_consume_token(CAST);
769      jj_consume_token(LPAREN);
770      e = unaliasedExpression();
771      jj_consume_token(AS);
772      segment = nameSegment();
773      jj_consume_token(RPAREN);
774        {if (true) return new UnresolvedFunCall(
775            "CAST", Syntax.Cast, new Exp[] {
776                e,
777                Literal.createSymbol(segment.name)});}
778      break;
779    case LPAREN:
780      jj_consume_token(LPAREN);
781      lis = expList();
782      jj_consume_token(RPAREN);
783        // Whereas ([Sales],[Time]) and () are tuples, ([Sales]) and (5)
784        // are just expressions.
785        {if (true) return new UnresolvedFunCall(
786            "()", Syntax.Parentheses, toExpArray(lis));}
787      break;
788    case LBRACE:
789      jj_consume_token(LBRACE);
790      if (jj_2_6(2147483647)) {
791            lis = Collections.emptyList();
792      } else {
793        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
794        case CASE:
795        case CAST:
796        case DIMENSION:
797        case NOT:
798        case NULL:
799        case PROPERTIES:
800        case LBRACE:
801        case LPAREN:
802        case MINUS:
803        case PLUS:
804        case UNSIGNED_INTEGER_LITERAL:
805        case APPROX_NUMERIC_LITERAL:
806        case DECIMAL_NUMERIC_LITERAL:
807        case SINGLE_QUOTED_STRING:
808        case DOUBLE_QUOTED_STRING:
809        case ID:
810        case QUOTED_ID:
811          lis = expList();
812          break;
813        default:
814          jj_la1[22] = jj_gen;
815          jj_consume_token(-1);
816          throw new ParseException();
817        }
818      }
819      jj_consume_token(RBRACE);
820        {if (true) return new UnresolvedFunCall(
821            "{}", Syntax.Braces, toExpArray(lis));}
822      break;
823    case CASE:
824      e = caseExpression();
825        {if (true) return e;}
826      break;
827    case DIMENSION:
828    case PROPERTIES:
829    case ID:
830    case QUOTED_ID:
831      // Function call "foo(a, b)" or "whiz!bang!foo(a, b)".
832          // Properties "x.PROP" and methods "exp.meth(a)" are in primary().
833          segment = nameSegment();
834      label_9:
835      while (true) {
836        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
837        case BANG:
838          ;
839          break;
840        default:
841          jj_la1[23] = jj_gen;
842          break label_9;
843        }
844        jj_consume_token(BANG);
845        segment = nameSegment();
846
847      }
848      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
849      case LPAREN:
850        jj_consume_token(LPAREN);
851        if (jj_2_7(2147483647)) {
852                lis = Collections.emptyList();
853        } else {
854          lis = expOrEmptyList();
855        }
856        jj_consume_token(RPAREN);
857        break;
858      default:
859        jj_la1[24] = jj_gen;
860                      lis = null;
861      }
862        {if (true) return createCall(null, segment, lis);}
863      break;
864    default:
865      jj_la1[25] = jj_gen;
866      jj_consume_token(-1);
867      throw new ParseException();
868    }
869    throw new Error("Missing return statement in function");
870  }
871
872  final public Exp caseExpression() throws ParseException {
873    Exp e, e2;
874    List<Exp> list = new ArrayList<Exp>();
875    boolean match = false;
876    jj_consume_token(CASE);
877    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
878    case CASE:
879    case CAST:
880    case DIMENSION:
881    case NOT:
882    case NULL:
883    case PROPERTIES:
884    case LBRACE:
885    case LPAREN:
886    case MINUS:
887    case PLUS:
888    case UNSIGNED_INTEGER_LITERAL:
889    case APPROX_NUMERIC_LITERAL:
890    case DECIMAL_NUMERIC_LITERAL:
891    case SINGLE_QUOTED_STRING:
892    case DOUBLE_QUOTED_STRING:
893    case ID:
894    case QUOTED_ID:
895      e = expression();
896            match = true;
897            list.add(e);
898      break;
899    default:
900      jj_la1[26] = jj_gen;
901      ;
902    }
903    label_10:
904    while (true) {
905      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
906      case WHEN:
907        ;
908        break;
909      default:
910        jj_la1[27] = jj_gen;
911        break label_10;
912      }
913      jj_consume_token(WHEN);
914      e = expression();
915      jj_consume_token(THEN);
916      e2 = expression();
917            list.add(e);
918            list.add(e2);
919    }
920    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
921    case ELSE:
922      jj_consume_token(ELSE);
923      e = expression();
924            list.add(e);
925      break;
926    default:
927      jj_la1[28] = jj_gen;
928      ;
929    }
930    jj_consume_token(END);
931        if (match) {
932            {if (true) return new UnresolvedFunCall(
933                "_CaseMatch", Syntax.Case, toExpArray(list));}
934        } else {
935            {if (true) return new UnresolvedFunCall(
936                "_CaseTest", Syntax.Case, toExpArray(list));}
937        }
938    throw new Error("Missing return statement in function");
939  }
940
941// ----------------------------------------------------------------------------
942// Member Value Expression
943  final public Exp expression() throws ParseException {
944    Exp e;
945    Id.Segment i;
946    e = unaliasedExpression();
947    label_11:
948    while (true) {
949      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
950      case AS:
951        ;
952        break;
953      default:
954        jj_la1[29] = jj_gen;
955        break label_11;
956      }
957      jj_consume_token(AS);
958      i = identifier();
959            Id id = new Id(i);
960            e = new UnresolvedFunCall("AS", Syntax.Infix, new Exp[] {e, id});
961    }
962        {if (true) return e;}
963    throw new Error("Missing return statement in function");
964  }
965
966  final public Exp expressionOrEmpty() throws ParseException {
967    Exp e;
968    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
969    case CASE:
970    case CAST:
971    case DIMENSION:
972    case NOT:
973    case NULL:
974    case PROPERTIES:
975    case LBRACE:
976    case LPAREN:
977    case MINUS:
978    case PLUS:
979    case UNSIGNED_INTEGER_LITERAL:
980    case APPROX_NUMERIC_LITERAL:
981    case DECIMAL_NUMERIC_LITERAL:
982    case SINGLE_QUOTED_STRING:
983    case DOUBLE_QUOTED_STRING:
984    case ID:
985    case QUOTED_ID:
986      e = expression();
987        {if (true) return e;}
988      break;
989    default:
990      jj_la1[30] = jj_gen;
991        {if (true) return new UnresolvedFunCall("", Syntax.Empty, new Exp[] {});}
992    }
993    throw new Error("Missing return statement in function");
994  }
995
996// Comma-separated list of expressions, some of which may be empty. Used
997// for functions.
998  final public List<Exp> expOrEmptyList() throws ParseException {
999    Exp e;
1000    List<Exp> list = new LinkedList<Exp>();
1001    e = expressionOrEmpty();
1002        list.add(e);
1003    label_12:
1004    while (true) {
1005      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1006      case COMMA:
1007        ;
1008        break;
1009      default:
1010        jj_la1[31] = jj_gen;
1011        break label_12;
1012      }
1013      jj_consume_token(COMMA);
1014      e = expressionOrEmpty();
1015            list.add(e);
1016    }
1017        {if (true) return list;}
1018    throw new Error("Missing return statement in function");
1019  }
1020
1021// List of expressions, none of which may be empty.
1022  final public List<Exp> expList() throws ParseException {
1023    Exp e;
1024    List<Exp> list = new LinkedList<Exp>();
1025    e = expression();
1026        list.add(e);
1027    label_13:
1028    while (true) {
1029      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1030      case COMMA:
1031        ;
1032        break;
1033      default:
1034        jj_la1[32] = jj_gen;
1035        break label_13;
1036      }
1037      jj_consume_token(COMMA);
1038      e = expression();
1039            list.add(e);
1040    }
1041        {if (true) return list;}
1042    throw new Error("Missing return statement in function");
1043  }
1044
1045// ----------------------------------------------------------------------------
1046// MDX Statement
1047//
1048// <statement> ::= <selectStatement>
1049//                   | <drillthroughStatement>
1050//                   | <explainStatement>
1051//
1052// <selectStatement> ::= [WITH <formulaSpecification>]
1053//                         SELECT [<axisSpecification>
1054//                                [, <axisSpecification>...]]
1055//                         FROM [<cubeSpecification>]
1056//                         [WHERE <slicerSpecification>]
1057//                         [<cellProps>]
1058//
1059// <drillthroughStatment> ::=
1060//     DRILLTHROUGH
1061//     [ MAXROWS <count> ]
1062//     [ FIRSTROWSET <count> ]
1063//     <selectStatement>
1064//     [ RETURN <memberOrAttribute> [, <memberOrAttribute>...] ]
1065//
1066// <explainStatement> ::=
1067//     EXPLAIN PLAN FOR ( <selectStatement> | <drillthroughStatement> )
1068//
1069  final public QueryPart statement() throws ParseException {
1070    QueryPart qp;
1071    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1072    case SELECT:
1073    case WITH:
1074      qp = selectStatement();
1075      break;
1076    case DRILLTHROUGH:
1077      qp = drillthroughStatement();
1078      break;
1079    case EXPLAIN:
1080      qp = explainStatement();
1081      break;
1082    default:
1083      jj_la1[33] = jj_gen;
1084      jj_consume_token(-1);
1085      throw new ParseException();
1086    }
1087        {if (true) return qp;}
1088    throw new Error("Missing return statement in function");
1089  }
1090
1091  final public QueryPart selectOrDrillthroughStatement() throws ParseException {
1092    QueryPart qp;
1093    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1094    case SELECT:
1095    case WITH:
1096      qp = selectStatement();
1097        {if (true) return qp;}
1098      break;
1099    case DRILLTHROUGH:
1100      qp = drillthroughStatement();
1101        {if (true) return qp;}
1102      break;
1103    default:
1104      jj_la1[34] = jj_gen;
1105      jj_consume_token(-1);
1106      throw new ParseException();
1107    }
1108    throw new Error("Missing return statement in function");
1109  }
1110
1111  final public Query selectStatement() throws ParseException {
1112     Formula e;
1113     List<Formula> f = new ArrayList<Formula>();
1114     Exp w = null;
1115     QueryAxis i;
1116     List<QueryAxis> a = new ArrayList<QueryAxis>();
1117     Id c, p;
1118     List<QueryPart> cellPropList = new ArrayList<QueryPart>();
1119    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1120    case WITH:
1121      jj_consume_token(WITH);
1122      label_14:
1123      while (true) {
1124        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1125        case MEMBER:
1126          e = memberSpecification();
1127               f.add(e);
1128          break;
1129        case SET:
1130          e = setSpecification();
1131               f.add(e);
1132          break;
1133        default:
1134          jj_la1[35] = jj_gen;
1135          jj_consume_token(-1);
1136          throw new ParseException();
1137        }
1138        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1139        case MEMBER:
1140        case SET:
1141          ;
1142          break;
1143        default:
1144          jj_la1[36] = jj_gen;
1145          break label_14;
1146        }
1147      }
1148      break;
1149    default:
1150      jj_la1[37] = jj_gen;
1151      ;
1152    }
1153    jj_consume_token(SELECT);
1154    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1155    case CASE:
1156    case CAST:
1157    case DIMENSION:
1158    case NON:
1159    case NOT:
1160    case NULL:
1161    case PROPERTIES:
1162    case LBRACE:
1163    case LPAREN:
1164    case MINUS:
1165    case PLUS:
1166    case UNSIGNED_INTEGER_LITERAL:
1167    case APPROX_NUMERIC_LITERAL:
1168    case DECIMAL_NUMERIC_LITERAL:
1169    case SINGLE_QUOTED_STRING:
1170    case DOUBLE_QUOTED_STRING:
1171    case ID:
1172    case QUOTED_ID:
1173      i = axisSpecification();
1174            a.add(i);
1175      label_15:
1176      while (true) {
1177        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1178        case COMMA:
1179          ;
1180          break;
1181        default:
1182          jj_la1[38] = jj_gen;
1183          break label_15;
1184        }
1185        jj_consume_token(COMMA);
1186        i = axisSpecification();
1187                a.add(i);
1188      }
1189      break;
1190    default:
1191      jj_la1[39] = jj_gen;
1192      ;
1193    }
1194    jj_consume_token(FROM);
1195    c = compoundId();
1196    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1197    case WHERE:
1198      jj_consume_token(WHERE);
1199      w = expression();
1200      break;
1201    default:
1202      jj_la1[40] = jj_gen;
1203      ;
1204    }
1205    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1206    case CELL:
1207    case PROPERTIES:
1208      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1209      case CELL:
1210        jj_consume_token(CELL);
1211        break;
1212      default:
1213        jj_la1[41] = jj_gen;
1214        ;
1215      }
1216      jj_consume_token(PROPERTIES);
1217      p = compoundId();
1218            cellPropList.add(new CellProperty(p.getSegments()));
1219      label_16:
1220      while (true) {
1221        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1222        case COMMA:
1223          ;
1224          break;
1225        default:
1226          jj_la1[42] = jj_gen;
1227          break label_16;
1228        }
1229        jj_consume_token(COMMA);
1230        p = compoundId();
1231                cellPropList.add(new CellProperty(p.getSegments()));
1232      }
1233      break;
1234    default:
1235      jj_la1[43] = jj_gen;
1236      ;
1237    }
1238        // We want 'Sales', not '[Sales]', and can't handle 'Schema.Sales'
1239        // yet.
1240        String cubeName = ((Id.NameSegment) c.getElement(0)).name;
1241        {if (true) return factory.makeQuery(
1242            statement,
1243            toFormulaArray(f),
1244            toQueryAxisArray(a),
1245            cubeName,
1246            w,
1247            toQueryPartArray(cellPropList),
1248            strictValidation);}
1249    throw new Error("Missing return statement in function");
1250  }
1251
1252//
1253// <memberSpecification> ::= MEMBER <member_name> AS <valueExpression>
1254//                                 [, <solveOrderSpecification>]
1255//                                 [, <memberPropertyDefinition>...]
1256  final public Formula memberSpecification() throws ParseException {
1257    Id m;
1258    Exp e;
1259    List<MemberProperty> l = new ArrayList<MemberProperty>();
1260    MemberProperty mp;
1261    jj_consume_token(MEMBER);
1262    m = compoundId();
1263    jj_consume_token(AS);
1264    e = formulaExpression();
1265    label_17:
1266    while (true) {
1267      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1268      case COMMA:
1269        ;
1270        break;
1271      default:
1272        jj_la1[44] = jj_gen;
1273        break label_17;
1274      }
1275      jj_consume_token(COMMA);
1276      mp = memberPropertyDefinition();
1277            l.add(mp);
1278    }
1279        {if (true) return new Formula(m, e, toMemberPropertyArray(l));}
1280    throw new Error("Missing return statement in function");
1281  }
1282
1283  final public Exp formulaExpression() throws ParseException {
1284    Exp e;
1285    if (jj_2_8(2147483647)) {
1286      jj_consume_token(SINGLE_QUOTED_STRING);
1287        // Support archaic syntax "WITH MEMBER m AS ' <expr> ' ...";
1288        // "WITH MEMBER m AS <expr>" is now preferred.
1289        {if (true) return recursivelyParseExp(stripQuotes(token.image, "'", "'", "''"));}
1290    } else {
1291      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1292      case CASE:
1293      case CAST:
1294      case DIMENSION:
1295      case NOT:
1296      case NULL:
1297      case PROPERTIES:
1298      case LBRACE:
1299      case LPAREN:
1300      case MINUS:
1301      case PLUS:
1302      case UNSIGNED_INTEGER_LITERAL:
1303      case APPROX_NUMERIC_LITERAL:
1304      case DECIMAL_NUMERIC_LITERAL:
1305      case SINGLE_QUOTED_STRING:
1306      case DOUBLE_QUOTED_STRING:
1307      case ID:
1308      case QUOTED_ID:
1309        e = unaliasedExpression();
1310        {if (true) return e;}
1311        break;
1312      default:
1313        jj_la1[45] = jj_gen;
1314        jj_consume_token(-1);
1315        throw new ParseException();
1316      }
1317    }
1318    throw new Error("Missing return statement in function");
1319  }
1320
1321  final public MemberProperty memberPropertyDefinition() throws ParseException {
1322    Id.NameSegment id;
1323    Exp e;
1324    id = nameSegment();
1325    jj_consume_token(EQ);
1326    e = expression();
1327        {if (true) return new MemberProperty(id.name, e);}
1328    throw new Error("Missing return statement in function");
1329  }
1330
1331  final public Formula setSpecification() throws ParseException {
1332    Id n;
1333    Exp e;
1334    jj_consume_token(SET);
1335    n = compoundId();
1336    jj_consume_token(AS);
1337    e = formulaExpression();
1338        {if (true) return new Formula(n, e);}
1339    throw new Error("Missing return statement in function");
1340  }
1341
1342// <axisSpecification> ::= [NON EMPTY] <set> [<dimProps>] ON <axis_name>
1343  final public QueryAxis axisSpecification() throws ParseException {
1344    boolean nonEmpty = false;
1345    Exp e;
1346    List<Id> dp = new ArrayList<Id>();
1347    AxisOrdinal axis;
1348    Literal n;
1349    Id p;
1350    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1351    case NON:
1352      jj_consume_token(NON);
1353      jj_consume_token(EMPTY);
1354            nonEmpty = true;
1355      break;
1356    default:
1357      jj_la1[46] = jj_gen;
1358      ;
1359    }
1360    e = expression();
1361    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1362    case DIMENSION:
1363    case PROPERTIES:
1364      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1365      case DIMENSION:
1366        jj_consume_token(DIMENSION);
1367        break;
1368      default:
1369        jj_la1[47] = jj_gen;
1370        ;
1371      }
1372      jj_consume_token(PROPERTIES);
1373      p = compoundId();
1374            dp.add(p);
1375      label_18:
1376      while (true) {
1377        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1378        case COMMA:
1379          ;
1380          break;
1381        default:
1382          jj_la1[48] = jj_gen;
1383          break label_18;
1384        }
1385        jj_consume_token(COMMA);
1386        p = compoundId();
1387                dp.add(p);
1388      }
1389      break;
1390    default:
1391      jj_la1[49] = jj_gen;
1392      ;
1393    }
1394    jj_consume_token(ON);
1395    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1396    case COLUMNS:
1397      jj_consume_token(COLUMNS);
1398            axis = AxisOrdinal.StandardAxisOrdinal.COLUMNS;
1399      break;
1400    case ROWS:
1401      jj_consume_token(ROWS);
1402            axis= AxisOrdinal.StandardAxisOrdinal.ROWS;
1403      break;
1404    case PAGES:
1405      jj_consume_token(PAGES);
1406            axis = AxisOrdinal.StandardAxisOrdinal.PAGES;
1407      break;
1408    case SECTIONS:
1409      jj_consume_token(SECTIONS);
1410            axis = AxisOrdinal.StandardAxisOrdinal.SECTIONS;
1411      break;
1412    case CHAPTERS:
1413      jj_consume_token(CHAPTERS);
1414            axis = AxisOrdinal.StandardAxisOrdinal.CHAPTERS;
1415      break;
1416    case AXIS:
1417    case UNSIGNED_INTEGER_LITERAL:
1418    case APPROX_NUMERIC_LITERAL:
1419    case DECIMAL_NUMERIC_LITERAL:
1420      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1421      case UNSIGNED_INTEGER_LITERAL:
1422      case APPROX_NUMERIC_LITERAL:
1423      case DECIMAL_NUMERIC_LITERAL:
1424        n = numericLiteral();
1425        break;
1426      case AXIS:
1427        jj_consume_token(AXIS);
1428        jj_consume_token(LPAREN);
1429        n = numericLiteral();
1430        jj_consume_token(RPAREN);
1431        break;
1432      default:
1433        jj_la1[50] = jj_gen;
1434        jj_consume_token(-1);
1435        throw new ParseException();
1436      }
1437            // AxisOrdinal values go from -2 to 4 for standard axis, but higher
1438            // ordinals are allowed. The negative values represent special
1439            // cases, so are ignored.
1440            Number number = (Number) n.getValue();
1441            if (number.doubleValue() < 0
1442                || number.doubleValue() != number.intValue())
1443            {
1444                {if (true) throw MondrianResource.instance().InvalidAxis.ex(
1445                    number.doubleValue());}
1446            }
1447
1448            axis = AxisOrdinal.StandardAxisOrdinal.forLogicalOrdinal(
1449                number.intValue());
1450      break;
1451    default:
1452      jj_la1[51] = jj_gen;
1453      jj_consume_token(-1);
1454      throw new ParseException();
1455    }
1456        {if (true) return new QueryAxis(
1457            nonEmpty, e, axis,
1458            QueryAxis.SubtotalVisibility.Undefined,
1459            toIdArray(dp));}
1460    throw new Error("Missing return statement in function");
1461  }
1462
1463  final public QueryPart drillthroughStatement() throws ParseException {
1464    int m = 0, f = 0;
1465    List<Exp> rl = null;
1466    Query s;
1467    jj_consume_token(DRILLTHROUGH);
1468    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1469    case MAXROWS:
1470      jj_consume_token(MAXROWS);
1471      jj_consume_token(UNSIGNED_INTEGER_LITERAL);
1472            m = Integer.valueOf(token.image);
1473      break;
1474    default:
1475      jj_la1[52] = jj_gen;
1476      ;
1477    }
1478    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1479    case FIRSTROWSET:
1480      jj_consume_token(FIRSTROWSET);
1481      jj_consume_token(UNSIGNED_INTEGER_LITERAL);
1482            f = Integer.valueOf(token.image);
1483      break;
1484    default:
1485      jj_la1[53] = jj_gen;
1486      ;
1487    }
1488    s = selectStatement();
1489    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1490    case RETURN:
1491      jj_consume_token(RETURN);
1492      rl = returnItemList();
1493      break;
1494    default:
1495      jj_la1[54] = jj_gen;
1496      ;
1497    }
1498        {if (true) return factory.makeDrillThrough(s, m, f, rl);}
1499    throw new Error("Missing return statement in function");
1500  }
1501
1502  final public List<Exp> returnItemList() throws ParseException {
1503    List<Exp> list = new ArrayList<Exp>();
1504    Id i;
1505    i = returnItem();
1506        list.add(i);
1507    label_19:
1508    while (true) {
1509      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1510      case COMMA:
1511        ;
1512        break;
1513      default:
1514        jj_la1[55] = jj_gen;
1515        break label_19;
1516      }
1517      jj_consume_token(COMMA);
1518      i = returnItem();
1519            list.add(i);
1520    }
1521        {if (true) return list;}
1522    throw new Error("Missing return statement in function");
1523  }
1524
1525  final public Id returnItem() throws ParseException {
1526    Id i;
1527    // TODO: allow NAME(id) etc.
1528        i = compoundId();
1529        {if (true) return i;}
1530    throw new Error("Missing return statement in function");
1531  }
1532
1533  final public QueryPart explainStatement() throws ParseException {
1534    QueryPart qp;
1535    jj_consume_token(EXPLAIN);
1536    jj_consume_token(PLAN);
1537    jj_consume_token(FOR);
1538    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1539    case SELECT:
1540    case WITH:
1541      qp = selectStatement();
1542      break;
1543    case DRILLTHROUGH:
1544      qp = drillthroughStatement();
1545      break;
1546    default:
1547      jj_la1[56] = jj_gen;
1548      jj_consume_token(-1);
1549      throw new ParseException();
1550    }
1551        {if (true) return factory.makeExplain(qp);}
1552    throw new Error("Missing return statement in function");
1553  }
1554
1555  private boolean jj_2_1(int xla) {
1556    jj_la = xla; jj_lastpos = jj_scanpos = token;
1557    try { return !jj_3_1(); }
1558    catch(LookaheadSuccess ls) { return true; }
1559    finally { jj_save(0, xla); }
1560  }
1561
1562  private boolean jj_2_2(int xla) {
1563    jj_la = xla; jj_lastpos = jj_scanpos = token;
1564    try { return !jj_3_2(); }
1565    catch(LookaheadSuccess ls) { return true; }
1566    finally { jj_save(1, xla); }
1567  }
1568
1569  private boolean jj_2_3(int xla) {
1570    jj_la = xla; jj_lastpos = jj_scanpos = token;
1571    try { return !jj_3_3(); }
1572    catch(LookaheadSuccess ls) { return true; }
1573    finally { jj_save(2, xla); }
1574  }
1575
1576  private boolean jj_2_4(int xla) {
1577    jj_la = xla; jj_lastpos = jj_scanpos = token;
1578    try { return !jj_3_4(); }
1579    catch(LookaheadSuccess ls) { return true; }
1580    finally { jj_save(3, xla); }
1581  }
1582
1583  private boolean jj_2_5(int xla) {
1584    jj_la = xla; jj_lastpos = jj_scanpos = token;
1585    try { return !jj_3_5(); }
1586    catch(LookaheadSuccess ls) { return true; }
1587    finally { jj_save(4, xla); }
1588  }
1589
1590  private boolean jj_2_6(int xla) {
1591    jj_la = xla; jj_lastpos = jj_scanpos = token;
1592    try { return !jj_3_6(); }
1593    catch(LookaheadSuccess ls) { return true; }
1594    finally { jj_save(5, xla); }
1595  }
1596
1597  private boolean jj_2_7(int xla) {
1598    jj_la = xla; jj_lastpos = jj_scanpos = token;
1599    try { return !jj_3_7(); }
1600    catch(LookaheadSuccess ls) { return true; }
1601    finally { jj_save(6, xla); }
1602  }
1603
1604  private boolean jj_2_8(int xla) {
1605    jj_la = xla; jj_lastpos = jj_scanpos = token;
1606    try { return !jj_3_8(); }
1607    catch(LookaheadSuccess ls) { return true; }
1608    finally { jj_save(7, xla); }
1609  }
1610
1611  private boolean jj_3R_37() {
1612    Token xsp;
1613    xsp = jj_scanpos;
1614    if (jj_3R_40()) {
1615    jj_scanpos = xsp;
1616    if (jj_3R_41()) {
1617    jj_scanpos = xsp;
1618    if (jj_3R_42()) return true;
1619    }
1620    }
1621    return false;
1622  }
1623
1624  private boolean jj_3R_40() {
1625    if (jj_scan_token(DECIMAL_NUMERIC_LITERAL)) return true;
1626    return false;
1627  }
1628
1629  private boolean jj_3_7() {
1630    if (jj_scan_token(RPAREN)) return true;
1631    return false;
1632  }
1633
1634  private boolean jj_3R_45() {
1635    if (jj_scan_token(QUOTED_ID)) return true;
1636    return false;
1637  }
1638
1639  private boolean jj_3R_44() {
1640    if (jj_scan_token(ID)) return true;
1641    return false;
1642  }
1643
1644  private boolean jj_3R_39() {
1645    Token xsp;
1646    xsp = jj_scanpos;
1647    if (jj_3R_43()) {
1648    jj_scanpos = xsp;
1649    if (jj_3R_44()) {
1650    jj_scanpos = xsp;
1651    if (jj_3R_45()) return true;
1652    }
1653    }
1654    return false;
1655  }
1656
1657  private boolean jj_3R_43() {
1658    if (jj_3R_46()) return true;
1659    return false;
1660  }
1661
1662  private boolean jj_3_8() {
1663    if (jj_scan_token(SINGLE_QUOTED_STRING)) return true;
1664    return false;
1665  }
1666
1667  private boolean jj_3_1() {
1668    if (jj_scan_token(DOT)) return true;
1669    return false;
1670  }
1671
1672  private boolean jj_3_4() {
1673    if (jj_scan_token(NOT)) return true;
1674    if (jj_scan_token(MATCHES)) return true;
1675    return false;
1676  }
1677
1678  private boolean jj_3R_36() {
1679    if (jj_3R_39()) return true;
1680    return false;
1681  }
1682
1683  private boolean jj_3_3() {
1684    if (jj_scan_token(IS)) return true;
1685    if (jj_3R_20()) return true;
1686    return false;
1687  }
1688
1689  private boolean jj_3_6() {
1690    if (jj_scan_token(RBRACE)) return true;
1691    return false;
1692  }
1693
1694  private boolean jj_3R_26() {
1695    if (jj_3R_27()) return true;
1696    return false;
1697  }
1698
1699  private boolean jj_3R_35() {
1700    if (jj_3R_38()) return true;
1701    return false;
1702  }
1703
1704  private boolean jj_3_2() {
1705    if (jj_scan_token(IS)) return true;
1706    if (jj_scan_token(NULL)) return true;
1707    return false;
1708  }
1709
1710  private boolean jj_3R_25() {
1711    if (jj_scan_token(MINUS)) return true;
1712    return false;
1713  }
1714
1715  private boolean jj_3R_24() {
1716    if (jj_scan_token(PLUS)) return true;
1717    return false;
1718  }
1719
1720  private boolean jj_3R_34() {
1721    if (jj_scan_token(LBRACE)) return true;
1722    return false;
1723  }
1724
1725  private boolean jj_3R_48() {
1726    if (jj_scan_token(PROPERTIES)) return true;
1727    return false;
1728  }
1729
1730  private boolean jj_3R_23() {
1731    if (jj_3R_26()) return true;
1732    return false;
1733  }
1734
1735  private boolean jj_3R_22() {
1736    Token xsp;
1737    xsp = jj_scanpos;
1738    if (jj_3R_23()) {
1739    jj_scanpos = xsp;
1740    if (jj_3R_24()) {
1741    jj_scanpos = xsp;
1742    if (jj_3R_25()) return true;
1743    }
1744    }
1745    return false;
1746  }
1747
1748  private boolean jj_3R_47() {
1749    if (jj_scan_token(DIMENSION)) return true;
1750    return false;
1751  }
1752
1753  private boolean jj_3R_46() {
1754    Token xsp;
1755    xsp = jj_scanpos;
1756    if (jj_3R_47()) {
1757    jj_scanpos = xsp;
1758    if (jj_3R_48()) return true;
1759    }
1760    return false;
1761  }
1762
1763  private boolean jj_3R_33() {
1764    if (jj_scan_token(LPAREN)) return true;
1765    return false;
1766  }
1767
1768  private boolean jj_3R_32() {
1769    if (jj_scan_token(CAST)) return true;
1770    return false;
1771  }
1772
1773  private boolean jj_3R_31() {
1774    if (jj_scan_token(NULL)) return true;
1775    return false;
1776  }
1777
1778  private boolean jj_3R_21() {
1779    if (jj_3R_22()) return true;
1780    return false;
1781  }
1782
1783  private boolean jj_3R_30() {
1784    if (jj_3R_37()) return true;
1785    return false;
1786  }
1787
1788  private boolean jj_3R_29() {
1789    if (jj_scan_token(DOUBLE_QUOTED_STRING)) return true;
1790    return false;
1791  }
1792
1793  private boolean jj_3R_28() {
1794    if (jj_scan_token(SINGLE_QUOTED_STRING)) return true;
1795    return false;
1796  }
1797
1798  private boolean jj_3R_27() {
1799    Token xsp;
1800    xsp = jj_scanpos;
1801    if (jj_3R_28()) {
1802    jj_scanpos = xsp;
1803    if (jj_3R_29()) {
1804    jj_scanpos = xsp;
1805    if (jj_3R_30()) {
1806    jj_scanpos = xsp;
1807    if (jj_3R_31()) {
1808    jj_scanpos = xsp;
1809    if (jj_3R_32()) {
1810    jj_scanpos = xsp;
1811    if (jj_3R_33()) {
1812    jj_scanpos = xsp;
1813    if (jj_3R_34()) {
1814    jj_scanpos = xsp;
1815    if (jj_3R_35()) {
1816    jj_scanpos = xsp;
1817    if (jj_3R_36()) return true;
1818    }
1819    }
1820    }
1821    }
1822    }
1823    }
1824    }
1825    }
1826    return false;
1827  }
1828
1829  private boolean jj_3R_42() {
1830    if (jj_scan_token(APPROX_NUMERIC_LITERAL)) return true;
1831    return false;
1832  }
1833
1834  private boolean jj_3R_41() {
1835    if (jj_scan_token(UNSIGNED_INTEGER_LITERAL)) return true;
1836    return false;
1837  }
1838
1839  private boolean jj_3R_38() {
1840    if (jj_scan_token(CASE)) return true;
1841    return false;
1842  }
1843
1844  private boolean jj_3R_20() {
1845    if (jj_3R_21()) return true;
1846    return false;
1847  }
1848
1849  private boolean jj_3_5() {
1850    if (jj_scan_token(RPAREN)) return true;
1851    return false;
1852  }
1853
1854  /** Generated Token Manager. */
1855  public MdxParserImplTokenManager token_source;
1856  SimpleCharStream jj_input_stream;
1857  /** Current token. */
1858  public Token token;
1859  /** Next token. */
1860  public Token jj_nt;
1861  private int jj_ntk;
1862  private Token jj_scanpos, jj_lastpos;
1863  private int jj_la;
1864  private int jj_gen;
1865  final private int[] jj_la1 = new int[57];
1866  static private int[] jj_la1_0;
1867  static private int[] jj_la1_1;
1868  static private int[] jj_la1_2;
1869  static {
1870      jj_la1_init_0();
1871      jj_la1_init_1();
1872      jj_la1_init_2();
1873   }
1874   private static void jj_la1_init_0() {
1875      jj_la1_0 = new int[] {0x40000200,0x40000200,0x0,0x0,0x40000200,0x8000000,0x8000000,0x2,0x43000230,0x11c0000,0x0,0x0,0x180000,0x1040000,0x0,0x0,0x0,0x0,0x42000230,0x0,0x0,0x0,0x43000230,0x0,0x0,0x42000230,0x43000230,0x0,0x800,0x4,0x43000230,0x0,0x0,0x4400,0x400,0x400000,0x400000,0x0,0x0,0x43800230,0x0,0x40,0x0,0x40000040,0x0,0x43000230,0x800000,0x200,0x0,0x40000200,0x8,0x10000188,0x200000,0x8000,0x80000000,0x0,0x400,};
1876   }
1877   private static void jj_la1_init_1() {
1878      jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x1000080,0x1000080,0x0,0x80000000,0x70000000,0x70000000,0x70000000,0x0,0x0,0x4000000,0x4000000,0x400000,0x400000,0x80000000,0x8000000,0x0,0x0,0x80000000,0x800000,0x0,0x80000000,0x80000000,0x20,0x0,0x0,0x80000000,0x2000000,0x2000000,0x104,0x104,0x8,0x8,0x100,0x2000000,0x80000000,0x40,0x0,0x2000000,0x0,0x2000000,0x80000000,0x0,0x0,0x2000000,0x0,0x0,0x3,0x0,0x0,0x0,0x2000000,0x104,};
1879   }
1880   private static void jj_la1_init_2() {
1881      jj_la1_2 = new int[] {0xf0000,0x30000,0xc0000,0xc0000,0x0,0x0,0x0,0x0,0x36e2a,0x15,0x15,0x15,0x0,0x0,0x28,0x28,0x100,0x100,0x36e2a,0x0,0x2,0xe00,0x36e2a,0x0,0x2,0x36e02,0x36e2a,0x0,0x0,0x0,0x36e2a,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x36e2a,0x0,0x0,0x0,0x0,0x0,0x36e2a,0x0,0x0,0x0,0x0,0xe00,0xe00,0x0,0x0,0x0,0x0,0x0,};
1882   }
1883  final private JJCalls[] jj_2_rtns = new JJCalls[8];
1884  private boolean jj_rescan = false;
1885  private int jj_gc = 0;
1886
1887  /** Constructor with InputStream. */
1888  public MdxParserImpl(java.io.InputStream stream) {
1889     this(stream, null);
1890  }
1891  /** Constructor with InputStream and supplied encoding */
1892  public MdxParserImpl(java.io.InputStream stream, String encoding) {
1893    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
1894    token_source = new MdxParserImplTokenManager(jj_input_stream);
1895    token = new Token();
1896    jj_ntk = -1;
1897    jj_gen = 0;
1898    for (int i = 0; i < 57; i++) jj_la1[i] = -1;
1899    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1900  }
1901
1902  /** Reinitialise. */
1903  public void ReInit(java.io.InputStream stream) {
1904     ReInit(stream, null);
1905  }
1906  /** Reinitialise. */
1907  public void ReInit(java.io.InputStream stream, String encoding) {
1908    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
1909    token_source.ReInit(jj_input_stream);
1910    token = new Token();
1911    jj_ntk = -1;
1912    jj_gen = 0;
1913    for (int i = 0; i < 57; i++) jj_la1[i] = -1;
1914    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1915  }
1916
1917  /** Constructor. */
1918  public MdxParserImpl(java.io.Reader stream) {
1919    jj_input_stream = new SimpleCharStream(stream, 1, 1);
1920    token_source = new MdxParserImplTokenManager(jj_input_stream);
1921    token = new Token();
1922    jj_ntk = -1;
1923    jj_gen = 0;
1924    for (int i = 0; i < 57; i++) jj_la1[i] = -1;
1925    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1926  }
1927
1928  /** Reinitialise. */
1929  public void ReInit(java.io.Reader stream) {
1930    jj_input_stream.ReInit(stream, 1, 1);
1931    token_source.ReInit(jj_input_stream);
1932    token = new Token();
1933    jj_ntk = -1;
1934    jj_gen = 0;
1935    for (int i = 0; i < 57; i++) jj_la1[i] = -1;
1936    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1937  }
1938
1939  /** Constructor with generated Token Manager. */
1940  public MdxParserImpl(MdxParserImplTokenManager tm) {
1941    token_source = tm;
1942    token = new Token();
1943    jj_ntk = -1;
1944    jj_gen = 0;
1945    for (int i = 0; i < 57; i++) jj_la1[i] = -1;
1946    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1947  }
1948
1949  /** Reinitialise. */
1950  public void ReInit(MdxParserImplTokenManager tm) {
1951    token_source = tm;
1952    token = new Token();
1953    jj_ntk = -1;
1954    jj_gen = 0;
1955    for (int i = 0; i < 57; i++) jj_la1[i] = -1;
1956    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1957  }
1958
1959  private Token jj_consume_token(int kind) throws ParseException {
1960    Token oldToken;
1961    if ((oldToken = token).next != null) token = token.next;
1962    else token = token.next = token_source.getNextToken();
1963    jj_ntk = -1;
1964    if (token.kind == kind) {
1965      jj_gen++;
1966      if (++jj_gc > 100) {
1967        jj_gc = 0;
1968        for (int i = 0; i < jj_2_rtns.length; i++) {
1969          JJCalls c = jj_2_rtns[i];
1970          while (c != null) {
1971            if (c.gen < jj_gen) c.first = null;
1972            c = c.next;
1973          }
1974        }
1975      }
1976      return token;
1977    }
1978    token = oldToken;
1979    jj_kind = kind;
1980    throw generateParseException();
1981  }
1982
1983  static private final class LookaheadSuccess extends java.lang.Error { }
1984  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
1985  private boolean jj_scan_token(int kind) {
1986    if (jj_scanpos == jj_lastpos) {
1987      jj_la--;
1988      if (jj_scanpos.next == null) {
1989        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
1990      } else {
1991        jj_lastpos = jj_scanpos = jj_scanpos.next;
1992      }
1993    } else {
1994      jj_scanpos = jj_scanpos.next;
1995    }
1996    if (jj_rescan) {
1997      int i = 0; Token tok = token;
1998      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
1999      if (tok != null) jj_add_error_token(kind, i);
2000    }
2001    if (jj_scanpos.kind != kind) return true;
2002    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
2003    return false;
2004  }
2005
2006
2007/** Get the next Token. */
2008  final public Token getNextToken() {
2009    if (token.next != null) token = token.next;
2010    else token = token.next = token_source.getNextToken();
2011    jj_ntk = -1;
2012    jj_gen++;
2013    return token;
2014  }
2015
2016/** Get the specific Token. */
2017  final public Token getToken(int index) {
2018    Token t = token;
2019    for (int i = 0; i < index; i++) {
2020      if (t.next != null) t = t.next;
2021      else t = t.next = token_source.getNextToken();
2022    }
2023    return t;
2024  }
2025
2026  private int jj_ntk() {
2027    if ((jj_nt=token.next) == null)
2028      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
2029    else
2030      return (jj_ntk = jj_nt.kind);
2031  }
2032
2033  private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
2034  private int[] jj_expentry;
2035  private int jj_kind = -1;
2036  private int[] jj_lasttokens = new int[100];
2037  private int jj_endpos;
2038
2039  private void jj_add_error_token(int kind, int pos) {
2040    if (pos >= 100) return;
2041    if (pos == jj_endpos + 1) {
2042      jj_lasttokens[jj_endpos++] = kind;
2043    } else if (jj_endpos != 0) {
2044      jj_expentry = new int[jj_endpos];
2045      for (int i = 0; i < jj_endpos; i++) {
2046        jj_expentry[i] = jj_lasttokens[i];
2047      }
2048      jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
2049        int[] oldentry = (int[])(it.next());
2050        if (oldentry.length == jj_expentry.length) {
2051          for (int i = 0; i < jj_expentry.length; i++) {
2052            if (oldentry[i] != jj_expentry[i]) {
2053              continue jj_entries_loop;
2054            }
2055          }
2056          jj_expentries.add(jj_expentry);
2057          break jj_entries_loop;
2058        }
2059      }
2060      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
2061    }
2062  }
2063
2064  /** Generate ParseException. */
2065  public ParseException generateParseException() {
2066    jj_expentries.clear();
2067    boolean[] la1tokens = new boolean[86];
2068    if (jj_kind >= 0) {
2069      la1tokens[jj_kind] = true;
2070      jj_kind = -1;
2071    }
2072    for (int i = 0; i < 57; i++) {
2073      if (jj_la1[i] == jj_gen) {
2074        for (int j = 0; j < 32; j++) {
2075          if ((jj_la1_0[i] & (1<<j)) != 0) {
2076            la1tokens[j] = true;
2077          }
2078          if ((jj_la1_1[i] & (1<<j)) != 0) {
2079            la1tokens[32+j] = true;
2080          }
2081          if ((jj_la1_2[i] & (1<<j)) != 0) {
2082            la1tokens[64+j] = true;
2083          }
2084        }
2085      }
2086    }
2087    for (int i = 0; i < 86; i++) {
2088      if (la1tokens[i]) {
2089        jj_expentry = new int[1];
2090        jj_expentry[0] = i;
2091        jj_expentries.add(jj_expentry);
2092      }
2093    }
2094    jj_endpos = 0;
2095    jj_rescan_token();
2096    jj_add_error_token(0, 0);
2097    int[][] exptokseq = new int[jj_expentries.size()][];
2098    for (int i = 0; i < jj_expentries.size(); i++) {
2099      exptokseq[i] = jj_expentries.get(i);
2100    }
2101    return new ParseException(token, exptokseq, tokenImage);
2102  }
2103
2104  /** Enable tracing. */
2105  final public void enable_tracing() {
2106  }
2107
2108  /** Disable tracing. */
2109  final public void disable_tracing() {
2110  }
2111
2112  private void jj_rescan_token() {
2113    jj_rescan = true;
2114    for (int i = 0; i < 8; i++) {
2115    try {
2116      JJCalls p = jj_2_rtns[i];
2117      do {
2118        if (p.gen > jj_gen) {
2119          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
2120          switch (i) {
2121            case 0: jj_3_1(); break;
2122            case 1: jj_3_2(); break;
2123            case 2: jj_3_3(); break;
2124            case 3: jj_3_4(); break;
2125            case 4: jj_3_5(); break;
2126            case 5: jj_3_6(); break;
2127            case 6: jj_3_7(); break;
2128            case 7: jj_3_8(); break;
2129          }
2130        }
2131        p = p.next;
2132      } while (p != null);
2133      } catch(LookaheadSuccess ls) { }
2134    }
2135    jj_rescan = false;
2136  }
2137
2138  private void jj_save(int index, int xla) {
2139    JJCalls p = jj_2_rtns[index];
2140    while (p.gen > jj_gen) {
2141      if (p.next == null) { p = p.next = new JJCalls(); break; }
2142      p = p.next;
2143    }
2144    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
2145  }
2146
2147  static final class JJCalls {
2148    int gen;
2149    Token first;
2150    int arg;
2151    JJCalls next;
2152  }
2153
2154}