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