001    /* Generated By:JavaCC: Do not edit this line. Parser.java */
002            package edu.upenn.gloDB.parser;
003            import edu.upenn.gloDB.*;
004            import java.io.StringReader;
005            import java.util.HashMap;
006            import java.util.HashSet;
007            import java.util.ArrayList;
008            import java.util.Iterator;
009    
010    
011            /**
012             * The parser is created using javacc.  To make changes to the parser,
013             * the files Parser.jj, Operation.java, Operator.java, and
014             * ParserUtils.java are the only files that should be edited.  All
015             * other files are recreated by javacc from Parser.jj.
016             * After Parser.jj is edited, makeParser.bat should be run.  This will 
017             * update the relevant parser java files.  After makeParser is run, then
018             * this file should be run to add the parser changes into gloDB.jar.
019             *
020             */
021            public class Parser implements ParserConstants {
022                    /** The String to be parsed. */
023    //              public String parse = "";
024    
025                    /** An ArrayList containing the parsed Tracks. */
026                    private ArrayList parsed = new ArrayList();
027    
028                    /** The set of Tracks to be used. */
029                    private HashMap trackPool;
030    
031                    /** The set of Sequences to be used. */
032                    private HashMap sequencePool;
033    
034                    /** 
035                     * The ID of the new Track object.
036                     */
037                    private String id;
038    
039                    /** 
040                     * The list of Operations defined by 'parse'.
041                     */
042    //              public ArrayList ops = new ArrayList();
043    
044                    /**
045                     * Construct a new Parser using trackPool
046                     * as the set Tracks to search.
047                     */
048                    public Parser(String parse) throws ParseException {
049                            this(new StringReader(parse));
050                    }
051    
052                    //--------------------------------------------------------------------------
053                    // Getters and Setters
054    
055                    public String getId() { return id; }
056    
057                    //--------------------------------------------------------------------------
058                    // Miscellaneous Methods
059    
060                    /** 
061                     * Performs the parsing.  Returns the ops ArrayList
062                     * which is a list of operations to perform.  The first object
063                     * in the ArrayList is the ID of the new Track.
064                     */
065                    public ArrayList run(HashMap trackPool, HashMap sequencePool) throws ParseException {
066                            this.trackPool = trackPool;
067                            this.sequencePool = sequencePool;
068                            ArrayList ops = parseLine();
069    
070                            // if the next token is a valid token (ie an object or track) then the 
071                            // parser will finish but not complain, ignoring the valid token.
072                            // Here we test to see if there is any valid token following the last
073                            // token parsed and if so then we know there was an error.
074                            // For example, the parser won't complain about "t = t1 t2",
075                            // but will stop parsing after "t1" and finish without an
076                            // error.  Since this is an invalid computation, we check for
077                            // it here and throw an error.  In this example, 'token'
078                            // will represent "t1" and 'token.next' will contain the token "t2".
079                            if (token.next.kind != 0) {
080                                    Token tn = token.next;
081                                    String msg = "Lexical error at line " + tn.beginLine + ", column " + tn.beginColumn + ".";
082                                    msg += "  Encountered: \"" + tn.image + "\".";
083                                    throw new ParseException(msg);
084                            }
085    
086    //                      GloDBUtils.printMsg("Parse table: " + ops);
087    
088                            // if there is an Edge without any Features, then return 'null'
089                            // because "ops" can not be matched.
090                            // XXX this currently only tests the top level 'group'
091                            if (! validOperation(ops)) {
092                                    String out = "This expression has at least one empty element.\n";
093                                    out += "Make sure that the qualifiers (ie sequence\n";
094                                    out += "specifications, width, etc) are valid.";
095                                    GloDBUtils.printWarning(out);
096    //                              return null;
097                            }
098    
099                            return ops;
100                    }
101    
102                    /**
103                     * Test if 'ops' contains any Operations that lack a Feature.
104                     */
105                    private boolean validOperation(ArrayList ops) {
106                            boolean valid = true;  // flag if valid operation
107                            Iterator i = ops.iterator();
108                            while (i.hasNext() && valid) {
109                                    Operation operation = (Operation) i.next();
110                                    if (operation.track == null) {
111                                            // Recursively test any groups
112                                            valid = validOperation(operation.getGroup());
113                                    } else if (operation.track.numFeatures() == 0) {
114                                            valid = false;
115                                    }
116                            }
117                            return valid;
118                    }
119    
120                    /** 
121                     * Returns the string to be parsed and the same string 
122                     * having been parsed information. 
123                     */
124                    public String toString() {
125                            String out = "";
126    
127    //                      out += "Parser operation table: " + ops + "\n";
128                            out += "Parser operation table: " + parsed + "\n";
129    
130                            return out;
131                    }
132    
133    
134                    //--------------------------------------------------------------------------
135                    // Parsing Related Methods
136    
137                    /** Deal with length/from values. */
138                    private void addLength(int a, int b, int c, int d) {
139                            if (a == -1) {  // has 'from', no 'length'.
140                                    parsed.add("from");
141                                    if (d > -1) { parsed.add(Integer.toString(c) + ", " + Integer.toString(d)); }
142                                    else { parsed.add(Integer.toString(c)); }
143    
144                            } else {  // has 'length'
145                                    parsed.add("len");
146                                    if (b > -1) { parsed.add(Integer.toString(a) + ", " + Integer.toString(b)); }
147                                    else { parsed.add(Integer.toString(a)); }
148    
149                                    if (c > -1) {  // has 'from'
150                                            parsed.add("from");
151                                            if (d > -1) { parsed.add(Integer.toString(c) + ", " + Integer.toString(d)); }
152                                            else { parsed.add(Integer.toString(c)); }
153                                    }
154                            }
155                    }
156    
157                    /** Deal with repeat/within values. */
158                    private void addRepeat(int a, int b, int c, int d) {
159                            parsed.add("repeated");
160                            if (b > -1) { parsed.add(Integer.toString(a) + ", " + Integer.toString(b)); }
161                            else { parsed.add(Integer.toString(a)); }
162    
163                            if (c > -1) { // test for 'within'
164                                    parsed.add("within");
165                                    if (d > -1) { parsed.add(Integer.toString(c) + ", " + Integer.toString(d)); }
166                                    else { parsed.add(Integer.toString(c)); }
167                            }
168                    }
169    
170                    /** Chop off preceeding descriptor. */
171                    private String stripDescriptor(String a) {
172                            if (a.startsWith(" followed by")) { a = a.substring(12); }
173                            if (a.startsWith(" then")) { a = a.substring(5); }
174                            return a;
175                    }
176    
177                    public String formatParsed() {
178                            if (parsed.isEmpty()) { return ""; }
179    
180                            Iterator i = parsed.iterator();
181                            String out = (String) i.next();
182    
183                            while (i.hasNext()) {
184                                    String track = (String) i.next();
185                                    out += " " + track;
186                            }
187    
188                            return out;
189                    }
190    
191      final public ArrayList parseLine() throws ParseException {
192            String assign;
193            ArrayList ops = new ArrayList();
194        assign = trackAssign();
195                                                      this.id = assign;
196        expr(ops);
197                                      {if (true) return ops;}
198        throw new Error("Missing return statement in function");
199      }
200    
201      final public String trackAssign() throws ParseException {
202            Token t;
203        t = jj_consume_token(ASSIGN);
204                                    String id = (t.toString()).trim();
205                                    // return id without the "="
206                                    {if (true) return (id.substring(0, id.length()-1)).trim();}
207        throw new Error("Missing return statement in function");
208      }
209    
210      final public void expr(ArrayList ops) throws ParseException {
211            Operation operation;
212        operation = track(-1);
213                                                      ops.add(operation);
214        label_1:
215        while (true) {
216          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
217          case POS:
218          case AND:
219          case sAND:
220          case OR:
221          case MINUS:
222          case sMINUS:
223          case bAND:
224          case bOR:
225          case bMINUS:
226            ;
227            break;
228          default:
229            jj_la1[0] = jj_gen;
230            break label_1;
231          }
232          operation = opExpr();
233                                                      ops.add(operation);
234        }
235      }
236    
237      final public Operation opExpr() throws ParseException {
238            int a = 0;
239            int b = Integer.MIN_VALUE;
240            int flag = -1;
241            int type;
242            int minPos = 0;  // default to 0 space
243            int maxPos = 0;  // default to 0 space
244    
245            Operation operation = null;
246        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
247        case AND:
248        case sAND:
249        case OR:
250        case MINUS:
251        case sMINUS:
252        case bAND:
253        case bOR:
254        case bMINUS:
255          type = operator();
256          break;
257        case POS:
258          type = position();
259          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
260          case lREPEAT:
261          case HOOK:
262          case PLUS:
263          case STAR:
264            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
265            case lREPEAT:
266              jj_consume_token(lREPEAT);
267              a = nValue();
268              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
269              case SEPARATOR:
270                jj_consume_token(SEPARATOR);
271                b = nValue();
272                break;
273              default:
274                jj_la1[1] = jj_gen;
275                ;
276              }
277              jj_consume_token(rREPEAT);
278              break;
279            case HOOK:
280            case PLUS:
281            case STAR:
282              flag = oRepeat();
283              break;
284            default:
285              jj_la1[2] = jj_gen;
286              jj_consume_token(-1);
287              throw new ParseException();
288            }
289            break;
290          default:
291            jj_la1[3] = jj_gen;
292            ;
293          }
294          break;
295        default:
296          jj_la1[4] = jj_gen;
297          jj_consume_token(-1);
298          throw new ParseException();
299        }
300        operation = track(type);
301                                    // if POS or '.', then compute minPos and maxPos
302                                    if ((type == 0) || (type == 10)) {
303                                            if (flag == 0) {                        // <HOOK>
304                                                    minPos = 0;
305                                                    maxPos = 1;
306                                            } else if (flag == 1) { // <PLUS>
307                                                    minPos = 1;
308                                                    maxPos = -1;
309                                            } else if (flag == 2) { // <STAR>
310                                                    minPos = 0;
311                                                    maxPos = -1;
312                                            } else {
313                                                    minPos = a;
314                                                    // make sure max => min
315                                                    if (b < a) { maxPos = a; }
316                                                    else { maxPos = b; }
317                                            }
318                                    }
319    
320                                    // update OPERATOR (type) info for the current Operation
321                                    operation.setType(type);
322    
323                                    // add positional info
324                                    operation.minPos = minPos;
325                                    operation.maxPos = maxPos;
326    
327                                    {if (true) return operation;}
328        throw new Error("Missing return statement in function");
329      }
330    
331      final public Operation track(int type) throws ParseException {
332            boolean ignore = false;
333            boolean negate = false;
334            Operation operation;
335        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
336        case IGNORE:
337          ignore();
338                                              ignore = true;
339          break;
340        default:
341          jj_la1[5] = jj_gen;
342          ;
343        }
344        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
345        case bNOT:
346          negate();
347                                  negate = true;
348          break;
349        default:
350          jj_la1[6] = jj_gen;
351          ;
352        }
353        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
354        case lGROUP:
355          operation = group();
356          break;
357        case allTRACKS:
358        case OBJECT:
359        case TRACK:
360          operation = feature();
361          break;
362        default:
363          jj_la1[7] = jj_gen;
364          jj_consume_token(-1);
365          throw new ParseException();
366        }
367                                    if (ignore) { operation.setIgnore(ignore); }            // set ignore flag
368                                    if (negate) { operation.setNegate(negate); }    // set negate flag
369    
370        label_2:
371        while (true) {
372          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
373          case lLENGTH:
374          case lLENGTH2:
375          case LENGTH:
376          case FROM:
377          case lREPEAT:
378          case HOOK:
379          case PLUS:
380          case STAR:
381          case REPEATED:
382          case SEQUENCE:
383            ;
384            break;
385          default:
386            jj_la1[8] = jj_gen;
387            break label_2;
388          }
389          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
390          case lREPEAT:
391          case REPEATED:
392            operation = densityRepeat(operation);
393    
394            break;
395          case HOOK:
396          case PLUS:
397          case STAR:
398            operation = operatorRepeat(operation);
399                                    if ((type != 0) && (type != 10)) {
400                                            GloDBUtils.printWarning("Repeat is invalid following a \"" + Operator.getType(type) + "\" operator and will be ignored.");
401                                    }
402            break;
403          case lLENGTH:
404          case lLENGTH2:
405          case LENGTH:
406          case FROM:
407            operation = length(operation);
408            break;
409          case SEQUENCE:
410            operation = sequence(operation);
411            break;
412          default:
413            jj_la1[9] = jj_gen;
414            jj_consume_token(-1);
415            throw new ParseException();
416          }
417        }
418                              {if (true) return operation;}
419        throw new Error("Missing return statement in function");
420      }
421    
422      final public Operation group() throws ParseException {
423            ArrayList ops = new ArrayList();
424        jj_consume_token(lGROUP);
425                                                      parsed.add("(");
426        expr(ops);
427        jj_consume_token(rGROUP);
428                                                      parsed.add(")");
429                              {if (true) return new Operation(ops);}
430        throw new Error("Missing return statement in function");
431      }
432    
433    /*
434    Operation setTracks():
435    {
436            Operation operation;
437            HashSet tracks = new HashSet();
438            Track track;
439    }
440    {
441            <lSET>                                    { parsed.add("["); }
442            (
443                    track=trackRef()        { tracks.add(track); }
444            )*
445            <rSET>                                    { parsed.add("]"); }
446                            { return new Operation(tracks); }
447    }
448    */
449      final public Operation feature() throws ParseException {
450            Operation operation;
451            Track track;
452        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
453        case allTRACKS:
454          allTracks();
455                                    HashSet tracks = new HashSet();
456                                    for (Iterator i = trackPool.keySet().iterator(); i.hasNext();) {
457                                            String key = (String) i.next();
458                                            tracks.add(trackPool.get(key));
459                                    }
460                                    operation = new Operation(tracks);
461          break;
462        case OBJECT:
463        case TRACK:
464          track = trackRef();
465                              operation = new Operation(track);
466          break;
467        default:
468          jj_la1[10] = jj_gen;
469          jj_consume_token(-1);
470          throw new ParseException();
471        }
472                              {if (true) return operation;}
473        throw new Error("Missing return statement in function");
474      }
475    
476      final public Operation densityRepeat(Operation operation) throws ParseException {
477            int a = -1;
478            int b = -1;
479            int c = -1;
480            int d = -1;
481        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
482        case lREPEAT:
483          jj_consume_token(lREPEAT);
484          a = value();
485          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
486          case SEPARATOR:
487            jj_consume_token(SEPARATOR);
488            b = value();
489            break;
490          default:
491            jj_la1[11] = jj_gen;
492            ;
493          }
494          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
495          case 47:
496            jj_consume_token(47);
497            c = value();
498            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
499            case SEPARATOR:
500              jj_consume_token(SEPARATOR);
501              d = value();
502              break;
503            default:
504              jj_la1[12] = jj_gen;
505              ;
506            }
507            break;
508          default:
509            jj_la1[13] = jj_gen;
510            ;
511          }
512          jj_consume_token(rREPEAT);
513          break;
514        case REPEATED:
515          jj_consume_token(REPEATED);
516          a = value();
517          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
518          case SEPARATOR:
519            jj_consume_token(SEPARATOR);
520            b = value();
521            break;
522          default:
523            jj_la1[14] = jj_gen;
524            ;
525          }
526          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
527          case TIMES:
528            jj_consume_token(TIMES);
529            break;
530          default:
531            jj_la1[15] = jj_gen;
532            ;
533          }
534          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
535          case WITHIN:
536            jj_consume_token(WITHIN);
537            c = value();
538            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
539            case SEPARATOR:
540              jj_consume_token(SEPARATOR);
541              d = value();
542              break;
543            default:
544              jj_la1[16] = jj_gen;
545              ;
546            }
547            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
548            case POSITIONS:
549              jj_consume_token(POSITIONS);
550              break;
551            default:
552              jj_la1[17] = jj_gen;
553              ;
554            }
555            break;
556          default:
557            jj_la1[18] = jj_gen;
558            ;
559          }
560          break;
561        default:
562          jj_la1[19] = jj_gen;
563          jj_consume_token(-1);
564          throw new ParseException();
565        }
566                                    // add items to 'parsed'
567                                    addRepeat(a, b, c, d);
568    
569                                    // add repeat info.  Only add info that was actually set.
570                                    if (b == -1) {
571                                            // if 'b' not set but 'a' is, then set 'b' equal to 'a'
572                                            b = a;
573                                    }
574                                    if (c > -1) {
575                                            if (d == -1) {
576                                                    // if 'd' not set but 'c' is, then set 'd' equal to 'c'
577                                                    operation.setRepeat(a, b, c, c);
578                                            } else {
579                                                    operation.setRepeat(a, b, c, d);
580                                            }
581                                    } else {
582                                            operation.setRepeat(a, b);
583                                    }
584    
585                                    {if (true) return operation;}
586        throw new Error("Missing return statement in function");
587      }
588    
589      final public Operation operatorRepeat(Operation operation) throws ParseException {
590            int flag = -1;
591            int minRepeat;
592            int maxRepeat;
593        flag = oRepeat();
594                                    if (flag == 0) {                        // <HOOK>
595                                            minRepeat = 0;
596                                            maxRepeat = 1;
597                                    } else if (flag == 1) { // <PLUS>
598                                            minRepeat = 1;
599                                            maxRepeat = -1;
600                                    } else {                                                // <STAR>
601                                            minRepeat = 0;
602                                            maxRepeat = -1;
603                                    }
604    
605                                    // add repeat info
606                                    operation.setRepeat(minRepeat, maxRepeat);
607    
608                                    {if (true) return operation;}
609        throw new Error("Missing return statement in function");
610      }
611    
612      final public Operation length(Operation operation) throws ParseException {
613            int a = -1;
614            int b = -1;
615            int c = -1;
616            int d = -1;
617        if (jj_2_1(3)) {
618          jj_consume_token(lLENGTH2);
619          c = value();
620          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
621          case SEPARATOR:
622            jj_consume_token(SEPARATOR);
623            d = value();
624            break;
625          default:
626            jj_la1[20] = jj_gen;
627            ;
628          }
629          jj_consume_token(rLENGTH);
630                              addLength(a, b, c, d);
631        } else {
632          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
633          case lLENGTH:
634            jj_consume_token(lLENGTH);
635            a = value();
636            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
637            case SEPARATOR:
638              jj_consume_token(SEPARATOR);
639              b = value();
640              break;
641            default:
642              jj_la1[21] = jj_gen;
643              ;
644            }
645            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
646            case 47:
647              jj_consume_token(47);
648              c = value();
649              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
650              case SEPARATOR:
651                jj_consume_token(SEPARATOR);
652                d = value();
653                break;
654              default:
655                jj_la1[22] = jj_gen;
656                ;
657              }
658              break;
659            default:
660              jj_la1[23] = jj_gen;
661              ;
662            }
663            jj_consume_token(rLENGTH);
664                              addLength(a, b, c, d);
665            break;
666          case LENGTH:
667            jj_consume_token(LENGTH);
668            a = value();
669            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
670            case SEPARATOR:
671              jj_consume_token(SEPARATOR);
672              b = value();
673              break;
674            default:
675              jj_la1[24] = jj_gen;
676              ;
677            }
678            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
679            case FROM:
680              jj_consume_token(FROM);
681              c = value();
682              switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
683              case SEPARATOR:
684                jj_consume_token(SEPARATOR);
685                d = value();
686                break;
687              default:
688                jj_la1[25] = jj_gen;
689                ;
690              }
691              break;
692            default:
693              jj_la1[26] = jj_gen;
694              ;
695            }
696                              addLength(a, b, c, d);
697            break;
698          case FROM:
699            jj_consume_token(FROM);
700            c = value();
701            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
702            case SEPARATOR:
703              jj_consume_token(SEPARATOR);
704              d = value();
705              break;
706            default:
707              jj_la1[27] = jj_gen;
708              ;
709            }
710                              addLength(a, b, c, d);
711            break;
712          default:
713            jj_la1[28] = jj_gen;
714            jj_consume_token(-1);
715            throw new ParseException();
716          }
717        }
718                                    // setLength() and setSeqPos() will propogate to inner groups
719                                    if (a > -1) {
720                                            if (b > -1) { operation.setLength(a, b); }
721                                            else { operation.setLength(a, a); }
722                                    }
723                                    if (c > -1) {
724                                            // if no 'd' then flag that max is sequence length
725                                            if (d > -1) { operation.setSeqPos(c, d); }
726                                            else { operation.setSeqPos(c, -1); }
727                                    }
728                                    {if (true) return operation;}
729        throw new Error("Missing return statement in function");
730      }
731    
732      final public Operation sequence(Operation operation) throws ParseException {
733            Sequence seq;
734        seq = sequenceRef();
735                                    // add Sequence info to the Operation.  This will propogate to
736                                    // all inner groups.
737                                    operation.setSequence(seq);
738    
739                                    {if (true) return operation;}
740        throw new Error("Missing return statement in function");
741      }
742    
743      final public void allTracks() throws ParseException {
744            Token t;
745        t = jj_consume_token(allTRACKS);
746                                                      parsed.add("T");
747      }
748    
749      final public Track trackRef() throws ParseException {
750            Token t;
751        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
752        case TRACK:
753          jj_consume_token(TRACK);
754          break;
755        default:
756          jj_la1[29] = jj_gen;
757          ;
758        }
759        t = jj_consume_token(OBJECT);
760                                    String a = t.toString();
761    //                              if (a.startsWith("feature")) { a = a.substring(4);      }
762                                    if (a.startsWith("a feature in")) { a = a.substring(14);        }
763                                    if (a.startsWith("track")) { a = a.substring(8);        }
764    
765                                    parsed.add(a);
766                                    if (a.startsWith("T:") || a.startsWith("t:")) {
767                                            a = a.substring(2);   // chop off the "T:"
768                                    }
769                                    a = a.trim();
770    
771                                    Track track = (Track) trackPool.get(a);
772    
773                                    if (track == null) {
774                                            String msg = "Track \"" + a + "\" not found.";
775    //                                      GloDBUtils.printError(msg);
776                                            {if (true) throw new ParseException(msg);}
777                                    }
778    
779                                    {if (true) return track;}
780        throw new Error("Missing return statement in function");
781      }
782    
783      final public int position() throws ParseException {
784            Token t;
785            int flag;
786        t = jj_consume_token(POS);
787                                              flag = 0;
788                                    parsed.add(t.toString());
789                                    {if (true) return flag;}
790        throw new Error("Missing return statement in function");
791      }
792    
793      final public Sequence sequenceRef() throws ParseException {
794            Token t;
795            String a;
796        jj_consume_token(SEQUENCE);
797        t = jj_consume_token(OBJECT);
798                                    a = t.toString();
799                                    if (a.startsWith("seq")) { a = a.substring(4); }
800                                    if (a.startsWith("on sequence")) { a = a.substring(12); }
801    
802                                    parsed.add(a);
803                                    if (a.startsWith("S:") || a.startsWith("s:")) {
804                                            a = a.substring(2);   // chop off the "S:"
805                                    }
806                                    a = a.trim();
807    
808                                    Sequence s = (Sequence) sequencePool.get(a);
809                                    if (s == null) {
810                                            String msg = "Sequence \"" + a + "\" not found.";
811    //                                      GloDBUtils.printError(msg);
812                                            {if (true) throw new ParseException(msg);}
813                                    }
814    
815                                    {if (true) return s;}
816        throw new Error("Missing return statement in function");
817      }
818    
819      final public void ignore() throws ParseException {
820            Token t;
821        t = jj_consume_token(IGNORE);
822                                              parsed.add(t.toString());
823      }
824    
825      final public void negate() throws ParseException {
826            Token t;
827        t = jj_consume_token(bNOT);
828                                                      parsed.add(t.toString());
829      }
830    
831      final public int operator() throws ParseException {
832            Token t;
833            int flag;
834        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
835        case AND:
836          t = jj_consume_token(AND);
837                                              flag = 1;
838          break;
839        case OR:
840          t = jj_consume_token(OR);
841                                              flag = 2;
842          break;
843        case MINUS:
844          t = jj_consume_token(MINUS);
845                                              flag = 3;
846          break;
847        case sAND:
848          t = jj_consume_token(sAND);
849                                                      flag = 4;
850          break;
851        case sMINUS:
852          t = jj_consume_token(sMINUS);
853                                              flag = 5;
854          break;
855        case bAND:
856          t = jj_consume_token(bAND);
857                                                      flag = 11;
858          break;
859        case bOR:
860          t = jj_consume_token(bOR);
861                                              flag = 12;
862          break;
863        case bMINUS:
864          t = jj_consume_token(bMINUS);
865                                              flag = 13;
866          break;
867        default:
868          jj_la1[30] = jj_gen;
869          jj_consume_token(-1);
870          throw new ParseException();
871        }
872                                    parsed.add(t.toString());
873                                    {if (true) return flag;}
874        throw new Error("Missing return statement in function");
875      }
876    
877      final public int oRepeat() throws ParseException {
878            Token t;
879            int flag;
880        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
881        case HOOK:
882          t = jj_consume_token(HOOK);
883                                                      flag = 0;
884          break;
885        case PLUS:
886          t = jj_consume_token(PLUS);
887                                                      flag = 1;
888          break;
889        case STAR:
890          t = jj_consume_token(STAR);
891                                                      flag = 2;
892          break;
893        default:
894          jj_la1[31] = jj_gen;
895          jj_consume_token(-1);
896          throw new ParseException();
897        }
898                                    parsed.add(t.toString());
899                                    {if (true) return flag;}
900        throw new Error("Missing return statement in function");
901      }
902    
903      final public int value() throws ParseException {
904            Token t;
905        t = jj_consume_token(INTEGER);
906                                              {if (true) return Integer.parseInt(t.toString());}
907        throw new Error("Missing return statement in function");
908      }
909    
910      final public int nValue() throws ParseException {
911            Token t;
912        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
913        case INTEGER:
914          t = jj_consume_token(INTEGER);
915                                                      {if (true) return Integer.parseInt(t.toString());}
916          break;
917        case nINTEGER:
918          t = jj_consume_token(nINTEGER);
919                                              {if (true) return Integer.parseInt(t.toString());}
920          break;
921        default:
922          jj_la1[32] = jj_gen;
923          jj_consume_token(-1);
924          throw new ParseException();
925        }
926        throw new Error("Missing return statement in function");
927      }
928    
929      final private boolean jj_2_1(int xla) {
930        jj_la = xla; jj_lastpos = jj_scanpos = token;
931        try { return !jj_3_1(); }
932        catch(LookaheadSuccess ls) { return true; }
933        finally { jj_save(0, xla); }
934      }
935    
936      final private boolean jj_3R_4() {
937        if (jj_scan_token(SEPARATOR)) return true;
938        return false;
939      }
940    
941      final private boolean jj_3R_3() {
942        if (jj_scan_token(INTEGER)) return true;
943        return false;
944      }
945    
946      final private boolean jj_3_1() {
947        if (jj_scan_token(lLENGTH2)) return true;
948        if (jj_3R_3()) return true;
949        Token xsp;
950        xsp = jj_scanpos;
951        if (jj_3R_4()) jj_scanpos = xsp;
952        if (jj_scan_token(rLENGTH)) return true;
953        return false;
954      }
955    
956      public ParserTokenManager token_source;
957      SimpleCharStream jj_input_stream;
958      public Token token, jj_nt;
959      private int jj_ntk;
960      private Token jj_scanpos, jj_lastpos;
961      private int jj_la;
962      public boolean lookingAhead = false;
963      private boolean jj_semLA;
964      private int jj_gen;
965      final private int[] jj_la1 = new int[33];
966      static private int[] jj_la1_0;
967      static private int[] jj_la1_1;
968      static {
969          jj_la1_0();
970          jj_la1_1();
971       }
972       private static void jj_la1_0() {
973          jj_la1_0 = new int[] {0xff000000,0x200,0x20000,0x20000,0xff000000,0x800000,0x0,0x80000,0x3b000,0x3b000,0x0,0x200,0x200,0x0,0x200,0x0,0x200,0x0,0x0,0x20000,0x200,0x200,0x200,0x0,0x200,0x200,0x10000,0x200,0x19000,0x0,0xfe000000,0x0,0xc00,};
974       }
975       private static void jj_la1_1() {
976          jj_la1_1 = new int[] {0x1,0x0,0x1c,0x1c,0x1,0x0,0x2,0x2c00,0x411c,0x411c,0x2c00,0x0,0x0,0x8000,0x0,0x80,0x0,0x200,0x40,0x100,0x0,0x0,0x0,0x8000,0x0,0x0,0x0,0x0,0x0,0x2000,0x1,0x1c,0x0,};
977       }
978      final private JJCalls[] jj_2_rtns = new JJCalls[1];
979      private boolean jj_rescan = false;
980      private int jj_gc = 0;
981    
982      public Parser(java.io.InputStream stream) {
983        jj_input_stream = new SimpleCharStream(stream, 1, 1);
984        token_source = new ParserTokenManager(jj_input_stream);
985        token = new Token();
986        jj_ntk = -1;
987        jj_gen = 0;
988        for (int i = 0; i < 33; i++) jj_la1[i] = -1;
989        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
990      }
991    
992      public void ReInit(java.io.InputStream stream) {
993        jj_input_stream.ReInit(stream, 1, 1);
994        token_source.ReInit(jj_input_stream);
995        token = new Token();
996        jj_ntk = -1;
997        jj_gen = 0;
998        for (int i = 0; i < 33; i++) jj_la1[i] = -1;
999        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1000      }
1001    
1002      public Parser(java.io.Reader stream) {
1003        jj_input_stream = new SimpleCharStream(stream, 1, 1);
1004        token_source = new ParserTokenManager(jj_input_stream);
1005        token = new Token();
1006        jj_ntk = -1;
1007        jj_gen = 0;
1008        for (int i = 0; i < 33; i++) jj_la1[i] = -1;
1009        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1010      }
1011    
1012      public void ReInit(java.io.Reader stream) {
1013        jj_input_stream.ReInit(stream, 1, 1);
1014        token_source.ReInit(jj_input_stream);
1015        token = new Token();
1016        jj_ntk = -1;
1017        jj_gen = 0;
1018        for (int i = 0; i < 33; i++) jj_la1[i] = -1;
1019        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1020      }
1021    
1022      public Parser(ParserTokenManager tm) {
1023        token_source = tm;
1024        token = new Token();
1025        jj_ntk = -1;
1026        jj_gen = 0;
1027        for (int i = 0; i < 33; i++) jj_la1[i] = -1;
1028        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1029      }
1030    
1031      public void ReInit(ParserTokenManager tm) {
1032        token_source = tm;
1033        token = new Token();
1034        jj_ntk = -1;
1035        jj_gen = 0;
1036        for (int i = 0; i < 33; i++) jj_la1[i] = -1;
1037        for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1038      }
1039    
1040      final private Token jj_consume_token(int kind) throws ParseException {
1041        Token oldToken;
1042        if ((oldToken = token).next != null) token = token.next;
1043        else token = token.next = token_source.getNextToken();
1044        jj_ntk = -1;
1045        if (token.kind == kind) {
1046          jj_gen++;
1047          if (++jj_gc > 100) {
1048            jj_gc = 0;
1049            for (int i = 0; i < jj_2_rtns.length; i++) {
1050              JJCalls c = jj_2_rtns[i];
1051              while (c != null) {
1052                if (c.gen < jj_gen) c.first = null;
1053                c = c.next;
1054              }
1055            }
1056          }
1057          return token;
1058        }
1059        token = oldToken;
1060        jj_kind = kind;
1061        throw generateParseException();
1062      }
1063    
1064      static private final class LookaheadSuccess extends java.lang.Error { }
1065      final private LookaheadSuccess jj_ls = new LookaheadSuccess();
1066      final private boolean jj_scan_token(int kind) {
1067        if (jj_scanpos == jj_lastpos) {
1068          jj_la--;
1069          if (jj_scanpos.next == null) {
1070            jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
1071          } else {
1072            jj_lastpos = jj_scanpos = jj_scanpos.next;
1073          }
1074        } else {
1075          jj_scanpos = jj_scanpos.next;
1076        }
1077        if (jj_rescan) {
1078          int i = 0; Token tok = token;
1079          while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
1080          if (tok != null) jj_add_error_token(kind, i);
1081        }
1082        if (jj_scanpos.kind != kind) return true;
1083        if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
1084        return false;
1085      }
1086    
1087      final public Token getNextToken() {
1088        if (token.next != null) token = token.next;
1089        else token = token.next = token_source.getNextToken();
1090        jj_ntk = -1;
1091        jj_gen++;
1092        return token;
1093      }
1094    
1095      final public Token getToken(int index) {
1096        Token t = lookingAhead ? jj_scanpos : token;
1097        for (int i = 0; i < index; i++) {
1098          if (t.next != null) t = t.next;
1099          else t = t.next = token_source.getNextToken();
1100        }
1101        return t;
1102      }
1103    
1104      final private int jj_ntk() {
1105        if ((jj_nt=token.next) == null)
1106          return (jj_ntk = (token.next=token_source.getNextToken()).kind);
1107        else
1108          return (jj_ntk = jj_nt.kind);
1109      }
1110    
1111      private java.util.Vector jj_expentries = new java.util.Vector();
1112      private int[] jj_expentry;
1113      private int jj_kind = -1;
1114      private int[] jj_lasttokens = new int[100];
1115      private int jj_endpos;
1116    
1117      private void jj_add_error_token(int kind, int pos) {
1118        if (pos >= 100) return;
1119        if (pos == jj_endpos + 1) {
1120          jj_lasttokens[jj_endpos++] = kind;
1121        } else if (jj_endpos != 0) {
1122          jj_expentry = new int[jj_endpos];
1123          for (int i = 0; i < jj_endpos; i++) {
1124            jj_expentry[i] = jj_lasttokens[i];
1125          }
1126          boolean exists = false;
1127          for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) {
1128            int[] oldentry = (int[])(e.nextElement());
1129            if (oldentry.length == jj_expentry.length) {
1130              exists = true;
1131              for (int i = 0; i < jj_expentry.length; i++) {
1132                if (oldentry[i] != jj_expentry[i]) {
1133                  exists = false;
1134                  break;
1135                }
1136              }
1137              if (exists) break;
1138            }
1139          }
1140          if (!exists) jj_expentries.addElement(jj_expentry);
1141          if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
1142        }
1143      }
1144    
1145      public ParseException generateParseException() {
1146        jj_expentries.removeAllElements();
1147        boolean[] la1tokens = new boolean[48];
1148        for (int i = 0; i < 48; i++) {
1149          la1tokens[i] = false;
1150        }
1151        if (jj_kind >= 0) {
1152          la1tokens[jj_kind] = true;
1153          jj_kind = -1;
1154        }
1155        for (int i = 0; i < 33; i++) {
1156          if (jj_la1[i] == jj_gen) {
1157            for (int j = 0; j < 32; j++) {
1158              if ((jj_la1_0[i] & (1<<j)) != 0) {
1159                la1tokens[j] = true;
1160              }
1161              if ((jj_la1_1[i] & (1<<j)) != 0) {
1162                la1tokens[32+j] = true;
1163              }
1164            }
1165          }
1166        }
1167        for (int i = 0; i < 48; i++) {
1168          if (la1tokens[i]) {
1169            jj_expentry = new int[1];
1170            jj_expentry[0] = i;
1171            jj_expentries.addElement(jj_expentry);
1172          }
1173        }
1174        jj_endpos = 0;
1175        jj_rescan_token();
1176        jj_add_error_token(0, 0);
1177        int[][] exptokseq = new int[jj_expentries.size()][];
1178        for (int i = 0; i < jj_expentries.size(); i++) {
1179          exptokseq[i] = (int[])jj_expentries.elementAt(i);
1180        }
1181        return new ParseException(token, exptokseq, tokenImage);
1182      }
1183    
1184      final public void enable_tracing() {
1185      }
1186    
1187      final public void disable_tracing() {
1188      }
1189    
1190      final private void jj_rescan_token() {
1191        jj_rescan = true;
1192        for (int i = 0; i < 1; i++) {
1193          JJCalls p = jj_2_rtns[i];
1194          do {
1195            if (p.gen > jj_gen) {
1196              jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
1197              switch (i) {
1198                case 0: jj_3_1(); break;
1199              }
1200            }
1201            p = p.next;
1202          } while (p != null);
1203        }
1204        jj_rescan = false;
1205      }
1206    
1207      final private void jj_save(int index, int xla) {
1208        JJCalls p = jj_2_rtns[index];
1209        while (p.gen > jj_gen) {
1210          if (p.next == null) { p = p.next = new JJCalls(); break; }
1211          p = p.next;
1212        }
1213        p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
1214      }
1215    
1216      static final class JJCalls {
1217        int gen;
1218        Token first;
1219        int arg;
1220        JJCalls next;
1221      }
1222    
1223            }