1   /* Generated By:JavaCC: Do not edit this line. ParseCpsl.java */
2   package gate.jape.parser;
3   
4   import java.io.*;
5   import java.net.*;
6   import java.util.*;
7   import gate.util.*;
8   import gate.jape.*;
9   import gate.event.*;
10  
11  
12  /**
13    * A parser for the CPSL language. Generated using JavaCC.
14    * @author Hamish Cunningham
15    */
16  public class ParseCpsl implements JapeConstants, ParseCpslConstants {
17  
18    /** Construct from a URL and an encoding
19      */
20    public ParseCpsl(URL url, String encoding) throws IOException {
21      this(url, encoding, new HashMap());
22    }
23  
24    /** Construct from a URL and an encoding
25      */
26    public ParseCpsl(URL url, String encoding, HashMap existingMacros) throws IOException {
27      this(new InputStreamReader(
28             new BufferedInputStream(url.openStream()),
29             encoding), existingMacros);
30      baseURL = url;
31      this.encoding = encoding;
32    }
33  
34    public ParseCpsl(java.io.Reader stream, HashMap existingMacros) {
35      this(stream);
36      macrosMap = existingMacros;
37    }
38  
39    //StatusReporter Implementation
40    public void addStatusListener(StatusListener listener){
41      myStatusListeners.add(listener);
42    }
43    public void removeStatusListener(StatusListener listener){
44      myStatusListeners.remove(listener);
45    }
46    protected void fireStatusChangedEvent(String text){
47      java.util.Iterator listenersIter = myStatusListeners.iterator();
48      while(listenersIter.hasNext())
49        ((StatusListener)listenersIter.next()).statusChanged(text);
50    }
51  
52    protected SinglePhaseTransducer createSinglePhaseTransducer(String name){
53      return new SinglePhaseTransducer(name);
54    }
55  
56    protected ParseCpsl spawn(URL sptURL) throws IOException{
57      return new ParseCpsl(sptURL, encoding, macrosMap);
58    }
59  
60    protected void finishSPT(SinglePhaseTransducer t) throws ParseException {
61      if(ruleNumber == 0)
62        throw(new ParseException("no rules defined in transducer " + t.getName()));
63      t.setBaseURL(baseURL);
64    }
65  
66    protected void finishBPE(BasicPatternElement bpe) {
67    }
68  
69    protected void appendAnnotationAdd(StringBuffer blockBuffer, String newAnnotType, String annotSetName)
70    {
71        String nl = Strings.getNl();
72        blockBuffer.append("      annotations.add(" + nl);
73        blockBuffer.append("        " + annotSetName + ".firstNode(), ");
74        blockBuffer.append(annotSetName + ".lastNode(), " + nl);
75        blockBuffer.append("        \"" + newAnnotType + "\", features" + nl);
76        blockBuffer.append("      );" + nl);
77        blockBuffer.append("      // end of RHS assignment block");
78    }
79  
80    public void setBaseURL (URL newURL) {
81      baseURL = newURL;
82    }
83  
84    public void setEncoding (String newEncoding) {
85      encoding = newEncoding;
86    }
87  
88    private transient java.util.List myStatusListeners = new java.util.LinkedList();
89  
90    /** Position of the current rule */
91    private int ruleNumber;
92  
93    /** A list of all the bindings we made this time, for checking
94      * the RHS during parsing.
95      */
96    private HashSet bindingNameSet = null;
97  
98    /** A table of macro definitions. */
99    protected HashMap macrosMap;
100 
101   protected URL baseURL;
102   protected String encoding;
103 
104 //////////////
105 // the grammar
106 //////////////
107   final public MultiPhaseTransducer MultiPhaseTransducer() throws ParseException {
108   // macrosMap = new HashMap();
109   SinglePhaseTransducer s = null;
110   MultiPhaseTransducer m = new MultiPhaseTransducer();
111   m.setBaseURL(baseURL);
112   Token mptNameTok = null;
113   Token phaseNameTok = null;
114     switch (jj_nt.kind) {
115     case multiphase:
116       jj_consume_token(multiphase);
117       mptNameTok = jj_consume_token(ident);
118       m.setName(mptNameTok.image);
119       break;
120     default:
121       jj_la1[0] = jj_gen;
122       ;
123     }
124     switch (jj_nt.kind) {
125     case phase:
126       label_1:
127       while (true) {
128         s = SinglePhaseTransducer();
129       m.addPhase(s.getName(), s);
130       s.setBaseURL(baseURL);
131         switch (jj_nt.kind) {
132         case phase:
133           ;
134           break;
135         default:
136           jj_la1[1] = jj_gen;
137           break label_1;
138         }
139       }
140       break;
141     case phases:
142       jj_consume_token(phases);
143       label_2:
144       while (true) {
145         phaseNameTok = jj_consume_token(path);
146           ParseCpsl parser = null;
147 
148             // check file exists
149             String sptPath = phaseNameTok.image + ".jape";
150             URL sptURL = null;
151             try{
152               sptURL = new URL(baseURL, sptPath);
153             }catch(MalformedURLException mue){
154               {if (true) throw(new ParseException("Read error " + mue.toString()));}
155             }
156 
157             if(sptURL == null){
158               {if (true) throw(new ParseException(
159                 "Resource not found: base = " + baseURL.toString() +
160                 " path = " + sptPath
161               ));}
162             }
163 
164             // construct a parser and parse it
165             fireStatusChangedEvent("Reading " + phaseNameTok.image + "...");
166             try {
167               parser = spawn(sptURL);
168             } catch (IOException e) {
169               {if (true) throw(
170                 new ParseException(
171                   "Cannot open URL " + sptURL.toExternalForm()
172                 )
173               );}
174             }
175 
176           // adding the resultant spt to m
177           if(parser != null) {
178             s = parser.SinglePhaseTransducer();
179             if(s != null)
180               m.addPhase(s.getName(), s);
181           }
182         switch (jj_nt.kind) {
183         case path:
184           ;
185           break;
186         default:
187           jj_la1[2] = jj_gen;
188           break label_2;
189         }
190       }
191       break;
192     default:
193       jj_la1[3] = jj_gen;
194       jj_consume_token(-1);
195       throw new ParseException();
196     }
197     jj_consume_token(0);
198 //move this out of here so the input file gets closed properly
199 //    m.finish(); // swap the various JGL types for Java arrays
200     {if (true) return m;}
201     throw new Error("Missing return statement in function");
202   }
203 
204   // MultiPhaseTransducer
205   final public SinglePhaseTransducer SinglePhaseTransducer() throws ParseException {
206   ruleNumber = 0;
207   Token phaseNameTok = null;
208   Token inputTok = null;
209   SinglePhaseTransducer t = null;
210   Rule newRule = null;
211   bindingNameSet = new HashSet();
212   Token optionNameTok = null;
213   Token optionValueTok = null;
214     jj_consume_token(phase);
215     phaseNameTok = jj_consume_token(ident);
216     t = createSinglePhaseTransducer(phaseNameTok.image);
217     switch (jj_nt.kind) {
218     case input:
219       jj_consume_token(input);
220       label_3:
221       while (true) {
222         switch (jj_nt.kind) {
223         case ident:
224           ;
225           break;
226         default:
227           jj_la1[4] = jj_gen;
228           break label_3;
229         }
230         inputTok = jj_consume_token(ident);
231                          t.addInput(inputTok.image);
232       }
233       break;
234     default:
235       jj_la1[5] = jj_gen;
236       ;
237     }
238     switch (jj_nt.kind) {
239     case option:
240       jj_consume_token(option);
241       label_4:
242       while (true) {
243         switch (jj_nt.kind) {
244         case ident:
245           ;
246           break;
247         default:
248           jj_la1[6] = jj_gen;
249           break label_4;
250         }
251         optionNameTok = jj_consume_token(ident);
252         jj_consume_token(assign);
253         switch (jj_nt.kind) {
254         case ident:
255           optionValueTok = jj_consume_token(ident);
256           break;
257         case bool:
258           optionValueTok = jj_consume_token(bool);
259           break;
260         default:
261           jj_la1[7] = jj_gen;
262           jj_consume_token(-1);
263           throw new ParseException();
264         }
265         t.setOption(optionNameTok.image, optionValueTok.image);
266 
267         // control
268         if(optionNameTok.image.equalsIgnoreCase("control")) {
269           if(optionValueTok.image.equalsIgnoreCase("appelt"))
270             t.setRuleApplicationStyle(APPELT_STYLE);
271           else if(optionValueTok.image.equalsIgnoreCase("first"))
272             t.setRuleApplicationStyle(FIRST_STYLE);
273           else if(optionValueTok.image.equalsIgnoreCase("brill"))
274             t.setRuleApplicationStyle(BRILL_STYLE);
275           else if(optionValueTok.image.equalsIgnoreCase("once"))
276             t.setRuleApplicationStyle(ONCE_STYLE);
277           else if(optionValueTok.image.equalsIgnoreCase("all"))
278             t.setRuleApplicationStyle(ALL_STYLE);
279           else
280             System.err.println(
281               "ignoring unknown control strategy " + option +
282               " (should be brill, appelt, first, once or all)"
283             );
284         } // control
285         else if(optionNameTok.image.equalsIgnoreCase("debug")) {
286           if(optionValueTok.image.equalsIgnoreCase("true") ||
287              optionValueTok.image.equalsIgnoreCase("yes") ||
288              optionValueTok.image.equalsIgnoreCase("y"))
289             t.setDebugMode(true);
290           else t.setDebugMode(false);
291         }
292         else if(optionNameTok.image.equalsIgnoreCase("matchGroup")) {
293           if(optionValueTok.image.equalsIgnoreCase("true") ||
294              optionValueTok.image.equalsIgnoreCase("yes") ||
295              optionValueTok.image.equalsIgnoreCase("y"))
296             t.setMatchGroupMode(true);
297           else t.setMatchGroupMode(false);
298         }
299       }
300       break;
301     default:
302       jj_la1[8] = jj_gen;
303       ;
304     }
305     label_5:
306     while (true) {
307       switch (jj_nt.kind) {
308       case rule:
309       case macro:
310         ;
311         break;
312       default:
313         jj_la1[9] = jj_gen;
314         break label_5;
315       }
316       switch (jj_nt.kind) {
317       case rule:
318         newRule = Rule(phaseNameTok.image);
319                                          t.addRule(newRule);
320         break;
321       case macro:
322         MacroDef();
323         break;
324       default:
325         jj_la1[10] = jj_gen;
326         jj_consume_token(-1);
327         throw new ParseException();
328       }
329     }
330     finishSPT(t);
331     {if (true) return t;}
332     throw new Error("Missing return statement in function");
333   }
334 
335   // SinglePhaseTransducer
336   final public Rule Rule(String phaseName) throws ParseException {
337   Token ruleNameTok = null;
338   String ruleName = null;
339   Token priorityTok = null;
340   int rulePriority = 0;
341   LeftHandSide lhs = null;
342   RightHandSide rhs = null;
343   Rule newRule = null;
344     jj_consume_token(rule);
345     ruleNameTok = jj_consume_token(ident);
346                                ruleName=ruleNameTok.image;
347     switch (jj_nt.kind) {
348     case priority:
349       jj_consume_token(priority);
350       priorityTok = jj_consume_token(integer);
351       try { rulePriority=Integer.parseInt(priorityTok.image); }
352       catch(NumberFormatException e) {
353         System.err.println("bad priority spec(" + priorityTok.image +
354                            "), rule(" + ruleName + ") - treating as 0");
355         rulePriority=0;
356       }
357       break;
358     default:
359       jj_la1[11] = jj_gen;
360       ;
361     }
362     lhs = LeftHandSide();
363     jj_consume_token(58);
364     rhs = RightHandSide(phaseName, ruleName, lhs);
365     try { rhs.createActionClass(); } catch(JapeException e)
366     {
367       /*Debug.pr(
368         this, "ParseCpsl.Rule, FAILED rhs: " + rhs.getActionClassString()
369       );*/
370       {if (true) throw new ParseException("couldn't create rule RHS: " + e.toString());}
371     }
372     /*Debug.pr(this, "ParseCpsl.Rule, done rhs: " + rhs.getActionClassString());*/
373     newRule = new Rule(ruleName, ruleNumber, rulePriority, lhs, rhs);
374     ruleNumber++;
375     {if (true) return newRule;}
376     throw new Error("Missing return statement in function");
377   }
378 
379   // Rule
380   final public void MacroDef() throws ParseException {
381   Token macroNameTok = null;
382   Object body = null;
383     jj_consume_token(macro);
384     macroNameTok = jj_consume_token(ident);
385     if (jj_2_1(2)) {
386       // both blocks and PEs may start with "{"
387           body = PatternElement(null);
388     } else {
389       switch (jj_nt.kind) {
390       case ident:
391       case colon:
392       case leftBrace:
393       case colonplus:
394         body = Action();
395         break;
396       default:
397         jj_la1[12] = jj_gen;
398         jj_consume_token(-1);
399         throw new ParseException();
400       }
401     }
402     macrosMap.put(macroNameTok.image, body);
403   }
404 
405   // MacroDef
406   final public LeftHandSide LeftHandSide() throws ParseException {
407   ConstraintGroup cg = new ConstraintGroup();
408   LeftHandSide lhs = new LeftHandSide(cg);
409     ConstraintGroup(lhs, cg);
410     {if (true) return lhs;}
411     throw new Error("Missing return statement in function");
412   }
413 
414   // LeftHandSide
415 
416 
417 // we pass the lhs down so we can add bindings in CPEs, and the cg
418 // so we can add PEs and create disjunctions here
419   final public void ConstraintGroup(LeftHandSide lhs, ConstraintGroup cg) throws ParseException {
420   PatternElement pat = null;
421     label_6:
422     while (true) {
423       pat = PatternElement(lhs);
424                               cg.addPatternElement(pat);
425       switch (jj_nt.kind) {
426       case string:
427       case ident:
428       case leftBrace:
429       case leftBracket:
430         ;
431         break;
432       default:
433         jj_la1[13] = jj_gen;
434         break label_6;
435       }
436     }
437     label_7:
438     while (true) {
439       switch (jj_nt.kind) {
440       case bar:
441         ;
442         break;
443       default:
444         jj_la1[14] = jj_gen;
445         break label_7;
446       }
447       jj_consume_token(bar);
448             cg.createDisjunction();
449       label_8:
450       while (true) {
451         pat = PatternElement(lhs);
452                                 cg.addPatternElement(pat);
453         switch (jj_nt.kind) {
454         case string:
455         case ident:
456         case leftBrace:
457         case leftBracket:
458           ;
459           break;
460         default:
461           jj_la1[15] = jj_gen;
462           break label_8;
463         }
464       }
465     }
466   }
467 
468   // ConstraintGroup
469   final public PatternElement PatternElement(LeftHandSide lhs) throws ParseException {
470   PatternElement pat = null;
471   Token macroRefTok = null;
472   boolean macroRef = false;
473     switch (jj_nt.kind) {
474     case ident:
475       macroRefTok = jj_consume_token(ident);
476       macroRef = true;
477       Object macro = macrosMap.get(macroRefTok.image);
478       if(macro == null)
479         {if (true) throw(new ParseException("unknown macro name " + macroRefTok.image));}
480       else if(macro instanceof String[])
481         {if (true) throw(
482           new ParseException(
483             "macro " + macroRefTok.image +
484             " references an Action, not a PatternElement"
485           )
486         );}
487       else if(! (macro instanceof PatternElement)) // this should never happen
488         {if (true) throw(
489           new ParseException(
490             "macro " + macroRefTok.image +
491             " doesn't reference a PatternElement!"
492           )
493         );}
494       else { // macro is a pattern element
495         pat = (PatternElement) ((PatternElement) macro).clone();
496       }
497       break;
498     case string:
499     case leftBrace:
500       pat = BasicPatternElement();
501       break;
502     case leftBracket:
503       pat = ComplexPatternElement(lhs);
504       break;
505     default:
506       jj_la1[16] = jj_gen;
507       jj_consume_token(-1);
508       throw new ParseException();
509     }
510     // if its a CPE, make binding into the LHS
511     if(pat instanceof ComplexPatternElement) {
512 
513       String bindingName = ((ComplexPatternElement) pat).getBindingName();
514 
515       if(bindingName != null && lhs != null) {
516 
517         try {
518           lhs.addBinding(
519             bindingName, (ComplexPatternElement) pat, bindingNameSet, macroRef
520           );
521         } catch(JapeException e) {
522           System.err.println(
523             "duplicate binding name " + bindingName +
524             " - ignoring this binding! exception was: " + e.toString()
525           );
526         }
527 
528       } // not null binding or lhs
529     } // its a CPE
530 
531     {if (true) return pat;}
532     throw new Error("Missing return statement in function");
533   }
534 
535   // PatternElement
536   final public BasicPatternElement BasicPatternElement() throws ParseException {
537   Token shortTok = null; // string shorthand token
538   Constraint c = null;
539   BasicPatternElement bpe = new BasicPatternElement();
540     switch (jj_nt.kind) {
541     case leftBrace:
542       jj_consume_token(leftBrace);
543       c = Constraint();
544                                    bpe.addConstraint(c);
545       label_9:
546       while (true) {
547         switch (jj_nt.kind) {
548         case comma:
549           ;
550           break;
551         default:
552           jj_la1[17] = jj_gen;
553           break label_9;
554         }
555         jj_consume_token(comma);
556         c = Constraint();
557                                  bpe.addConstraint(c);
558       }
559       jj_consume_token(rightBrace);
560       break;
561     case string:
562       // string shorthand
563             shortTok = jj_consume_token(string);
564       System.err.println(
565         "string shorthand not supported yet, ignoring: " + shortTok.image
566       );
567       break;
568     default:
569       jj_la1[18] = jj_gen;
570       jj_consume_token(-1);
571       throw new ParseException();
572     }
573     finishBPE(bpe);
574     {if (true) return bpe;}
575     throw new Error("Missing return statement in function");
576   }
577 
578   // BasicPatternElement
579   final public ComplexPatternElement ComplexPatternElement(LeftHandSide lhs) throws ParseException {
580   Token kleeneOpTok = null;
581   Token bindingNameTok = null;
582   ConstraintGroup cg = new ConstraintGroup();
583     jj_consume_token(leftBracket);
584     ConstraintGroup(lhs, cg);
585     jj_consume_token(rightBracket);
586     switch (jj_nt.kind) {
587     case kleeneOp:
588       kleeneOpTok = jj_consume_token(kleeneOp);
589       break;
590     default:
591       jj_la1[19] = jj_gen;
592       ;
593     }
594     switch (jj_nt.kind) {
595     case colon:
596       jj_consume_token(colon);
597       switch (jj_nt.kind) {
598       case ident:
599         bindingNameTok = jj_consume_token(ident);
600         break;
601       case integer:
602         bindingNameTok = jj_consume_token(integer);
603         break;
604       default:
605         jj_la1[20] = jj_gen;
606         jj_consume_token(-1);
607         throw new ParseException();
608       }
609       break;
610     default:
611       jj_la1[21] = jj_gen;
612       ;
613     }
614     int kleeneOp = NO_KLEENE_OP;
615     if(kleeneOpTok != null) {
616       String k = kleeneOpTok.image;
617       if(k.equals("*"))         kleeneOp = KLEENE_STAR;
618       else if(k.equals("?"))    kleeneOp = KLEENE_QUERY;
619       else if(k.equals("+"))    kleeneOp = KLEENE_PLUS;
620       else
621         System.err.println("ignoring uninterpretable Kleene op " + k);
622     }
623 
624     String bindingName = null;
625     if(bindingNameTok != null)
626       bindingName = bindingNameTok.image;
627     {if (true) return new ComplexPatternElement(cg, kleeneOp, bindingName);}
628     throw new Error("Missing return statement in function");
629   }
630 
631   // ComplexPatternElement
632   final public Constraint Constraint() throws ParseException {
633   Token annotTypeTok = null;
634   Token attrNameTok = null;
635   Object attrValObj = null;
636   Pair attrValPair = null;
637   boolean negate = false;
638   Constraint c = null;
639     switch (jj_nt.kind) {
640     case pling:
641       jj_consume_token(pling);
642              negate = true;
643       break;
644     default:
645       jj_la1[22] = jj_gen;
646       ;
647     }
648     // the annotation type
649       annotTypeTok = jj_consume_token(ident);
650     c = new Constraint(annotTypeTok.image);
651     if(negate) c.negate();
652     switch (jj_nt.kind) {
653     case period:
654       jj_consume_token(period);
655       attrNameTok = jj_consume_token(ident);
656       jj_consume_token(equals);
657       attrValPair = AttrVal();
658       attrValObj = attrValPair.second;
659       c.addAttribute(
660         new JdmAttribute(attrNameTok.image, attrValObj)
661       );
662       break;
663     default:
664       jj_la1[23] = jj_gen;
665       ;
666     }
667     {if (true) return c;}
668     throw new Error("Missing return statement in function");
669   }
670 
671   // Constraint
672 
673 
674 // attribute values: strings, identifers (=strings), integers, floats,
675 //                   booleans
676   final public Pair AttrVal() throws ParseException {
677   Token attrValTok = null;
678   Pair val = new Pair();
679     switch (jj_nt.kind) {
680     case string:
681       attrValTok = jj_consume_token(string);
682       break;
683     case ident:
684       attrValTok = jj_consume_token(ident);
685       break;
686     case integer:
687       attrValTok = jj_consume_token(integer);
688       break;
689     case floatingPoint:
690       attrValTok = jj_consume_token(floatingPoint);
691       break;
692     case bool:
693       attrValTok = jj_consume_token(bool);
694       break;
695     default:
696       jj_la1[24] = jj_gen;
697       jj_consume_token(-1);
698       throw new ParseException();
699     }
700     val.first = new Integer(attrValTok.kind);
701 
702     switch(attrValTok.kind) {
703       case string:
704         // strip the quotes
705         val.second
706           = attrValTok.image.substring(1, attrValTok.image.length() - 1);
707         break;
708       case integer:
709         try {
710           val.second = Long.valueOf(attrValTok.image);
711         } catch(NumberFormatException e) {
712           System.err.println("couldn't parse integer " +
713                              attrValTok.image + " - treating as 0");
714           val.second = new Long(0);
715         }
716         break;
717       case ident:
718         val.second = new String(attrValTok.image);
719         break;
720       case bool:
721         val.second = Boolean.valueOf(attrValTok.image);
722         break;
723       case floatingPoint:
724         try {
725           val.second = Double.valueOf(attrValTok.image);
726         } catch(NumberFormatException e) {
727           System.err.println("couldn't parse float " +
728                              attrValTok.image + " - treating as 0.0");
729           val.second = new Double(0.0);
730         }
731         break;
732       default:
733         System.err.println(
734           "didn't understand type of " + attrValTok.image + ": ignoring"
735         );
736         val.second = new String("");
737         break;
738     } // switch
739 
740     {if (true) return val;}
741     throw new Error("Missing return statement in function");
742   }
743 
744   final public RightHandSide RightHandSide(String phaseName, String ruleName, LeftHandSide lhs) throws ParseException {
745   String[] block = new String[2];
746   RightHandSide rhs = new RightHandSide(phaseName, ruleName, lhs);
747     block = Action();
748     // did we get a non-existent block name?
749     if(block[0] != null)
750       if(! bindingNameSet.contains(block[0])) {
751         {if (true) throw(new ParseException("unknown label in RHS action: " + block[0]));}
752       }
753     rhs.addBlock(block[0], block[1]);
754     label_10:
755     while (true) {
756       switch (jj_nt.kind) {
757       case comma:
758         ;
759         break;
760       default:
761         jj_la1[25] = jj_gen;
762         break label_10;
763       }
764       jj_consume_token(comma);
765       block = Action();
766       // did we get a non-existent block name?
767       if(block[0] != null)
768         if(! bindingNameSet.contains(block[0])) {
769           {if (true) throw(new ParseException("unknown label in RHS action: " + block[0]));}
770         }
771       rhs.addBlock(block[0], block[1]);
772     }
773     {if (true) return rhs;} /* action class not created yet */
774 
775     throw new Error("Missing return statement in function");
776   }
777 
778   // RightHandSide
779 
780 
781 // actions return 2 strings, one for the name of the block, and
782 // one for the block itself. if the name is null, it is an anonymous block
783   final public String[] Action() throws ParseException {
784   String[] block = new String[2];
785   Token macroRefTok = null;
786     if (jj_2_2(3)) {
787       block = NamedJavaBlock();
788     } else {
789       switch (jj_nt.kind) {
790       case leftBrace:
791         block = AnonymousJavaBlock();
792         break;
793       case colon:
794       case colonplus:
795         block = AssignmentExpression();
796         break;
797       case ident:
798         macroRefTok = jj_consume_token(ident);
799       Object macro = macrosMap.get(macroRefTok.image);
800       if(macro == null)
801         {if (true) throw(new ParseException("unknown macro name " + macroRefTok.image));}
802       else if(macro instanceof PatternElement)
803         {if (true) throw(
804           new ParseException(
805             "macro " + macroRefTok.image +
806             " references a PatternElement, not an Action"
807           )
808         );}
809       else if(! (macro instanceof String[])) // this should never happen
810         {if (true) throw(
811           new ParseException(
812             "macro " + macroRefTok.image + " doesn't reference an Action!"
813           )
814         );}
815       else { // macro is an action
816         block = (String[]) macro;
817       }
818         break;
819       default:
820         jj_la1[26] = jj_gen;
821         jj_consume_token(-1);
822         throw new ParseException();
823       }
824     }
825     {if (true) return block;}
826     throw new Error("Missing return statement in function");
827   }
828 
829   // Action
830   final public String[] NamedJavaBlock() throws ParseException {
831   String[] block = new String[2];
832   Token nameTok = null;
833     jj_consume_token(colon);
834     nameTok = jj_consume_token(ident);
835                             block[0] = nameTok.image;
836     jj_consume_token(leftBrace);
837     block[1] = ConsumeBlock();
838     {if (true) return block;}
839     throw new Error("Missing return statement in function");
840   }
841 
842   // NamedJavaBlock
843   final public String[] AnonymousJavaBlock() throws ParseException {
844   String[] block = new String[2];
845   block[0] = null;
846     jj_consume_token(leftBrace);
847     block[1] = ConsumeBlock();
848     {if (true) return block;}
849     throw new Error("Missing return statement in function");
850   }
851 
852   // AnonymousJavaBlock
853   final public String[] AssignmentExpression() throws ParseException {
854   String[] block = new String[2];
855   StringBuffer blockBuffer = new StringBuffer();
856   Token nameTok = null;
857   String newAnnotType = null;
858   String newAttrName = null;
859   String nl = Strings.getNl();
860   String annotSetName = null;
861   Pair attrVal = null;
862   String existingAnnotSetName = null;
863   String existingAnnotType = null;
864   String existingAttrName = null;
865 
866   blockBuffer.append("// RHS assignment block" + nl);
867   blockBuffer.append(
868     "      FeatureMap features = Factory.newFeatureMap();" + nl
869   );
870     switch (jj_nt.kind) {
871     case colon:
872       jj_consume_token(colon);
873       break;
874     case colonplus:
875       jj_consume_token(colonplus);
876       {if (true) throw new
877         ParseException(":+ not a legal operator (no multi-span annots)");}
878       break;
879     default:
880       jj_la1[27] = jj_gen;
881       jj_consume_token(-1);
882       throw new ParseException();
883     }
884     // the name of the bound annotation set we're referencing
885       nameTok = jj_consume_token(ident);
886     block[0] = nameTok.image;
887     annotSetName = block[0] + "Annots";
888     jj_consume_token(period);
889     nameTok = jj_consume_token(ident);
890     newAnnotType = nameTok.image;
891 
892     // start of the attribute stuff
893     blockBuffer.append("      Object val = null;" + nl);
894     jj_consume_token(assign);
895     jj_consume_token(leftBrace);
896     label_11:
897     while (true) {
898       switch (jj_nt.kind) {
899       case ident:
900         ;
901         break;
902       default:
903         jj_la1[28] = jj_gen;
904         break label_11;
905       }
906       // the name of the attribute, and equals sign
907           nameTok = jj_consume_token(ident);
908       jj_consume_token(assign);
909                                newAttrName = nameTok.image;
910       switch (jj_nt.kind) {
911       case integer:
912       case string:
913       case bool:
914       case ident:
915       case floatingPoint:
916         // a static attribute value
917               attrVal = AttrVal();
918         switch(((Integer) attrVal.first).intValue()) {
919           case string:
920             blockBuffer.append(
921               "      val = new String(\"" + attrVal.second.toString() +
922               "\");" + nl
923             );
924             break;
925           case integer:
926             blockBuffer.append("      try { " +
927               "val = new Long(" + attrVal.second.toString() + "); }" +
928               nl + "      catch(NumberFormatException e) { }" + nl
929             );
930             break;
931           case ident:
932             blockBuffer.append(
933               "      val = new String(\"" + attrVal.second.toString() +
934               "\");" + nl
935             );
936             break;
937           case bool:
938             blockBuffer.append(
939               "      val = new Boolean(\"" +
940               attrVal.second.toString() + "\");" + nl
941             );
942             break;
943           case floatingPoint:
944             blockBuffer.append("      try { " +
945               "val = new Double(" + attrVal.second.toString() + "); }" + nl +
946               "      catch(NumberFormatException e) { }" + nl
947             );
948             break;
949           default:
950             blockBuffer.append(
951               "      val = new String(\"\");" + nl
952             );
953             break;
954         } // switch
955 
956         blockBuffer.append("      features.put(\"" + newAttrName + "\", val);");
957         blockBuffer.append(nl);
958         break;
959       case colon:
960         jj_consume_token(colon);
961         nameTok = jj_consume_token(ident);
962           existingAnnotSetName = nameTok.image + "ExistingAnnots";
963           if(! bindingNameSet.contains(nameTok.image))
964             {if (true) throw(
965               new ParseException(
966                 "unknown label in RHS action(2): " + nameTok.image
967               )
968             );}
969 
970           blockBuffer.append(
971             "      { // need a block for the existing annot set" + nl +
972             "        AnnotationSet " + existingAnnotSetName +
973             " = (AnnotationSet)bindings.get(\"" + nameTok.image + "\"); " + nl
974           );
975         jj_consume_token(period);
976         nameTok = jj_consume_token(ident);
977                                    existingAnnotType = nameTok.image;
978         jj_consume_token(period);
979         nameTok = jj_consume_token(ident);
980                                    existingAttrName = nameTok.image;
981           blockBuffer.append(
982 "        if (" + existingAnnotSetName + " != null) {" + nl +
983 "          AnnotationSet existingAnnots = " + nl +
984 "          " + existingAnnotSetName + ".get(\"" + existingAnnotType + "\");" + nl +
985 "          if (existingAnnots != null) {" + nl +
986 "            Iterator iter = existingAnnots.iterator();" + nl +
987 "            while(iter.hasNext()) {" + nl +
988 "              Annotation existingA = (Annotation) iter.next();" + nl +
989 "              Object existingFeatureValue = existingA.getFeatures().get(\"" +
990 existingAttrName + "\");" + nl +
991 "              if(existingFeatureValue != null) {" + nl +
992 "                features.put(\"" + newAttrName + "\", existingFeatureValue);" + nl +
993 "                break;" + nl +
994 "              }" + nl + "        } // while" + nl +
995 "            } // if not null" + nl +
996 "          } // if not null" + nl +
997 "        } // block for existing annots" + nl
998           );
999         break;
1000      default:
1001        jj_la1[29] = jj_gen;
1002        jj_consume_token(-1);
1003        throw new ParseException();
1004      }
1005      switch (jj_nt.kind) {
1006      case comma:
1007        jj_consume_token(comma);
1008        break;
1009      default:
1010        jj_la1[30] = jj_gen;
1011        ;
1012      }
1013    }
1014    jj_consume_token(rightBrace);
1015    appendAnnotationAdd(blockBuffer, newAnnotType, annotSetName);
1016    block[1] = blockBuffer.toString();
1017    {if (true) return block;}
1018    throw new Error("Missing return statement in function");
1019  }
1020
1021  String ConsumeBlock() throws ParseException {
1022  StringBuffer block = new StringBuffer(); // to collect the block in
1023  int nesting = 1; // the first "{" was consumed before we were called
1024
1025  // step through the code until the final brace
1026  while(nesting != 0) {
1027    Token nextTok = getNextToken();
1028
1029    // add in any preceding spaces and comments
1030    // for some bizzare reason, this misses the comments...
1031    if(nextTok.specialToken != null) {
1032      Token special = nextTok.specialToken;
1033      while(special != null) {
1034        /*Debug.pr(
1035          this, "ParseCpsl.ConsumeBlock: special.image = " + special.image
1036        );*/
1037        block.append(special.image);
1038        special = special.next;
1039      }
1040    }
1041
1042    // adjust nesting
1043    if(nextTok.image.equals("{")) {
1044      nesting++;
1045      /*Debug.pr(this, "ParseCpsl.ConsumeBlock: nesting = " + nesting);*/
1046    } else if(nextTok.image.equals("}")) {
1047      nesting--;
1048      /*Debug.pr(this, "ParseCpsl.ConsumeBlock: nesting = " + nesting);*/
1049    }
1050
1051    // add the image to the block string (but not the final "}")
1052    if(nesting > 0)
1053      block.append(nextTok.image);
1054    /*Debug.pr(this, "ParseCpsl.ConsumeBlock: nextTok.image = ^" +
1055             nextTok.image + "^");*/
1056
1057  } // while
1058
1059  /*Debug.pr(this, "ParseCpsl.ConsumeBlock: block = " + block.toString());*/
1060  return block.toString();
1061  }
1062
1063  final private boolean jj_2_1(int xla) {
1064    jj_la = xla; jj_lastpos = jj_scanpos = token;
1065    try { return !jj_3_1(); }
1066    catch(LookaheadSuccess ls) { return true; }
1067    finally { jj_save(0, xla); }
1068  }
1069
1070  final private boolean jj_2_2(int xla) {
1071    jj_la = xla; jj_lastpos = jj_scanpos = token;
1072    try { return !jj_3_2(); }
1073    catch(LookaheadSuccess ls) { return true; }
1074    finally { jj_save(1, xla); }
1075  }
1076
1077  final private boolean jj_3_2() {
1078    if (jj_3R_13()) return true;
1079    return false;
1080  }
1081
1082  final private boolean jj_3R_23() {
1083    if (jj_3R_12()) return true;
1084    return false;
1085  }
1086
1087  final private boolean jj_3R_20() {
1088    if (jj_scan_token(string)) return true;
1089    return false;
1090  }
1091
1092  final private boolean jj_3R_18() {
1093    if (jj_scan_token(leftBracket)) return true;
1094    if (jj_3R_21()) return true;
1095    return false;
1096  }
1097
1098  final private boolean jj_3R_21() {
1099    Token xsp;
1100    if (jj_3R_23()) return true;
1101    while (true) {
1102      xsp = jj_scanpos;
1103      if (jj_3R_23()) { jj_scanpos = xsp; break; }
1104    }
1105    return false;
1106  }
1107
1108  final private boolean jj_3R_16() {
1109    if (jj_3R_18()) return true;
1110    return false;
1111  }
1112
1113  final private boolean jj_3R_13() {
1114    if (jj_scan_token(colon)) return true;
1115    if (jj_scan_token(ident)) return true;
1116    if (jj_scan_token(leftBrace)) return true;
1117    return false;
1118  }
1119
1120  final private boolean jj_3R_15() {
1121    if (jj_3R_17()) return true;
1122    return false;
1123  }
1124
1125  final private boolean jj_3R_14() {
1126    if (jj_scan_token(ident)) return true;
1127    return false;
1128  }
1129
1130  final private boolean jj_3_1() {
1131    if (jj_3R_12()) return true;
1132    return false;
1133  }
1134
1135  final private boolean jj_3R_19() {
1136    if (jj_scan_token(leftBrace)) return true;
1137    if (jj_3R_22()) return true;
1138    return false;
1139  }
1140
1141  final private boolean jj_3R_12() {
1142    Token xsp;
1143    xsp = jj_scanpos;
1144    if (jj_3R_14()) {
1145    jj_scanpos = xsp;
1146    if (jj_3R_15()) {
1147    jj_scanpos = xsp;
1148    if (jj_3R_16()) return true;
1149    }
1150    }
1151    return false;
1152  }
1153
1154  final private boolean jj_3R_24() {
1155    if (jj_scan_token(pling)) return true;
1156    return false;
1157  }
1158
1159  final private boolean jj_3R_17() {
1160    Token xsp;
1161    xsp = jj_scanpos;
1162    if (jj_3R_19()) {
1163    jj_scanpos = xsp;
1164    if (jj_3R_20()) return true;
1165    }
1166    return false;
1167  }
1168
1169  final private boolean jj_3R_22() {
1170    Token xsp;
1171    xsp = jj_scanpos;
1172    if (jj_3R_24()) jj_scanpos = xsp;
1173    if (jj_scan_token(ident)) return true;
1174    return false;
1175  }
1176
1177  public ParseCpslTokenManager token_source;
1178  SimpleCharStream jj_input_stream;
1179  public Token token, jj_nt;
1180  private Token jj_scanpos, jj_lastpos;
1181  private int jj_la;
1182  public boolean lookingAhead = false;
1183  private boolean jj_semLA;
1184  private int jj_gen;
1185  final private int[] jj_la1 = new int[31];
1186  static private int[] jj_la1_0;
1187  static private int[] jj_la1_1;
1188  static {
1189      jj_la1_0();
1190      jj_la1_1();
1191   }
1192   private static void jj_la1_0() {
1193      jj_la1_0 = new int[] {0x400,0x80000,0x1000,0x80800,0x0,0x100000,0x0,0x0,0x200000,0xc00000,0xc00000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000000,0x8000000,0x0,0x2000000,0x0,0x8000000,0x0,0x0,0x0,0x0,0x8000000,0x0,};
1194   }
1195   private static void jj_la1_1() {
1196      jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x10,0x0,0x10,0x18,0x0,0x0,0x0,0x0,0x41090,0x5014,0x400,0x5014,0x5014,0x800,0x1004,0x0,0x10,0x80,0x0,0x200,0x3c,0x800,0x41090,0x40080,0x10,0xbc,0x800,};
1197   }
1198  final private JJCalls[] jj_2_rtns = new JJCalls[2];
1199  private boolean jj_rescan = false;
1200  private int jj_gc = 0;
1201
1202  public ParseCpsl(java.io.InputStream stream) {
1203    jj_input_stream = new SimpleCharStream(stream, 1, 1);
1204    token_source = new ParseCpslTokenManager(jj_input_stream);
1205    token = new Token();
1206    token.next = jj_nt = token_source.getNextToken();
1207    jj_gen = 0;
1208    for (int i = 0; i < 31; i++) jj_la1[i] = -1;
1209    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1210  }
1211
1212  public void ReInit(java.io.InputStream stream) {
1213    jj_input_stream.ReInit(stream, 1, 1);
1214    token_source.ReInit(jj_input_stream);
1215    token = new Token();
1216    token.next = jj_nt = token_source.getNextToken();
1217    jj_gen = 0;
1218    for (int i = 0; i < 31; i++) jj_la1[i] = -1;
1219    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1220  }
1221
1222  public ParseCpsl(java.io.Reader stream) {
1223    jj_input_stream = new SimpleCharStream(stream, 1, 1);
1224    token_source = new ParseCpslTokenManager(jj_input_stream);
1225    token = new Token();
1226    token.next = jj_nt = token_source.getNextToken();
1227    jj_gen = 0;
1228    for (int i = 0; i < 31; i++) jj_la1[i] = -1;
1229    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1230  }
1231
1232  public void ReInit(java.io.Reader stream) {
1233    jj_input_stream.ReInit(stream, 1, 1);
1234    token_source.ReInit(jj_input_stream);
1235    token = new Token();
1236    token.next = jj_nt = token_source.getNextToken();
1237    jj_gen = 0;
1238    for (int i = 0; i < 31; i++) jj_la1[i] = -1;
1239    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1240  }
1241
1242  public ParseCpsl(ParseCpslTokenManager tm) {
1243    token_source = tm;
1244    token = new Token();
1245    token.next = jj_nt = token_source.getNextToken();
1246    jj_gen = 0;
1247    for (int i = 0; i < 31; i++) jj_la1[i] = -1;
1248    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1249  }
1250
1251  public void ReInit(ParseCpslTokenManager tm) {
1252    token_source = tm;
1253    token = new Token();
1254    token.next = jj_nt = token_source.getNextToken();
1255    jj_gen = 0;
1256    for (int i = 0; i < 31; i++) jj_la1[i] = -1;
1257    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1258  }
1259
1260  final private Token jj_consume_token(int kind) throws ParseException {
1261    Token oldToken = token;
1262    if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
1263    else jj_nt = jj_nt.next = token_source.getNextToken();
1264    if (token.kind == kind) {
1265      jj_gen++;
1266      if (++jj_gc > 100) {
1267        jj_gc = 0;
1268        for (int i = 0; i < jj_2_rtns.length; i++) {
1269          JJCalls c = jj_2_rtns[i];
1270          while (c != null) {
1271            if (c.gen < jj_gen) c.first = null;
1272            c = c.next;
1273          }
1274        }
1275      }
1276      return token;
1277    }
1278    jj_nt = token;
1279    token = oldToken;
1280    jj_kind = kind;
1281    throw generateParseException();
1282  }
1283
1284  static private final class LookaheadSuccess extends java.lang.Error { }
1285  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
1286  final private boolean jj_scan_token(int kind) {
1287    if (jj_scanpos == jj_lastpos) {
1288      jj_la--;
1289      if (jj_scanpos.next == null) {
1290        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
1291      } else {
1292        jj_lastpos = jj_scanpos = jj_scanpos.next;
1293      }
1294    } else {
1295      jj_scanpos = jj_scanpos.next;
1296    }
1297    if (jj_rescan) {
1298      int i = 0; Token tok = token;
1299      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
1300      if (tok != null) jj_add_error_token(kind, i);
1301    }
1302    if (jj_scanpos.kind != kind) return true;
1303    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
1304    return false;
1305  }
1306
1307  final public Token getNextToken() {
1308    if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
1309    else jj_nt = jj_nt.next = token_source.getNextToken();
1310    jj_gen++;
1311    return token;
1312  }
1313
1314  final public Token getToken(int index) {
1315    Token t = lookingAhead ? jj_scanpos : token;
1316    for (int i = 0; i < index; i++) {
1317      if (t.next != null) t = t.next;
1318      else t = t.next = token_source.getNextToken();
1319    }
1320    return t;
1321  }
1322
1323  private java.util.Vector jj_expentries = new java.util.Vector();
1324  private int[] jj_expentry;
1325  private int jj_kind = -1;
1326  private int[] jj_lasttokens = new int[100];
1327  private int jj_endpos;
1328
1329  private void jj_add_error_token(int kind, int pos) {
1330    if (pos >= 100) return;
1331    if (pos == jj_endpos + 1) {
1332      jj_lasttokens[jj_endpos++] = kind;
1333    } else if (jj_endpos != 0) {
1334      jj_expentry = new int[jj_endpos];
1335      for (int i = 0; i < jj_endpos; i++) {
1336        jj_expentry[i] = jj_lasttokens[i];
1337      }
1338      boolean exists = false;
1339      for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) {
1340        int[] oldentry = (int[])(e.nextElement());
1341        if (oldentry.length == jj_expentry.length) {
1342          exists = true;
1343          for (int i = 0; i < jj_expentry.length; i++) {
1344            if (oldentry[i] != jj_expentry[i]) {
1345              exists = false;
1346              break;
1347            }
1348          }
1349          if (exists) break;
1350        }
1351      }
1352      if (!exists) jj_expentries.addElement(jj_expentry);
1353      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
1354    }
1355  }
1356
1357  public ParseException generateParseException() {
1358    jj_expentries.removeAllElements();
1359    boolean[] la1tokens = new boolean[59];
1360    for (int i = 0; i < 59; i++) {
1361      la1tokens[i] = false;
1362    }
1363    if (jj_kind >= 0) {
1364      la1tokens[jj_kind] = true;
1365      jj_kind = -1;
1366    }
1367    for (int i = 0; i < 31; i++) {
1368      if (jj_la1[i] == jj_gen) {
1369        for (int j = 0; j < 32; j++) {
1370          if ((jj_la1_0[i] & (1<<j)) != 0) {
1371            la1tokens[j] = true;
1372          }
1373          if ((jj_la1_1[i] & (1<<j)) != 0) {
1374            la1tokens[32+j] = true;
1375          }
1376        }
1377      }
1378    }
1379    for (int i = 0; i < 59; i++) {
1380      if (la1tokens[i]) {
1381        jj_expentry = new int[1];
1382        jj_expentry[0] = i;
1383        jj_expentries.addElement(jj_expentry);
1384      }
1385    }
1386    jj_endpos = 0;
1387    jj_rescan_token();
1388    jj_add_error_token(0, 0);
1389    int[][] exptokseq = new int[jj_expentries.size()][];
1390    for (int i = 0; i < jj_expentries.size(); i++) {
1391      exptokseq[i] = (int[])jj_expentries.elementAt(i);
1392    }
1393    return new ParseException(token, exptokseq, tokenImage);
1394  }
1395
1396  final public void enable_tracing() {
1397  }
1398
1399  final public void disable_tracing() {
1400  }
1401
1402  final private void jj_rescan_token() {
1403    jj_rescan = true;
1404    for (int i = 0; i < 2; i++) {
1405      JJCalls p = jj_2_rtns[i];
1406      do {
1407        if (p.gen > jj_gen) {
1408          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
1409          switch (i) {
1410            case 0: jj_3_1(); break;
1411            case 1: jj_3_2(); break;
1412          }
1413        }
1414        p = p.next;
1415      } while (p != null);
1416    }
1417    jj_rescan = false;
1418  }
1419
1420  final private void jj_save(int index, int xla) {
1421    JJCalls p = jj_2_rtns[index];
1422    while (p.gen > jj_gen) {
1423      if (p.next == null) { p = p.next = new JJCalls(); break; }
1424      p = p.next;
1425    }
1426    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
1427  }
1428
1429  static final class JJCalls {
1430    int gen;
1431    Token first;
1432    int arg;
1433    JJCalls next;
1434  }
1435
1436}
1437