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