ParseCpsl.java
0001 /* ParseCpsl.java */
0002 /* Generated By:JavaCC: Do not edit this line. ParseCpsl.java */
0003 package gate.jape.parser;
0004 
0005 import java.io.*;
0006 import java.net.*;
0007 import java.util.*;
0008 import java.util.regex.*;
0009 import java.lang.reflect.Constructor;
0010 import java.lang.reflect.InvocationTargetException;
0011 
0012 import gate.Factory;
0013 import gate.util.*;
0014 import gate.jape.*;
0015 import gate.jape.constraint.*;
0016 import gate.event.*;
0017 
0018 import org.apache.log4j.Logger;
0019 
0020 
0021 /**
0022   * A parser for the CPSL language. Generated using JavaCC.
0023   @author Hamish Cunningham
0024   */
0025 public class ParseCpsl implements JapeConstants, ParseCpslConstants {
0026 
0027   private static final long serialVersionUID = -2754817550046808372L;
0028 
0029   private static final Logger log = Logger.getLogger(ParseCpsl.class);
0030 
0031   /** Construct from a URL and an encoding
0032     */
0033   public ParseCpsl(URL url, String encodingthrows IOException {
0034     this(url, encoding, new HashMap<String,Object>());
0035   }
0036 
0037   /** Construct from a URL and an encoding
0038     */
0039   public ParseCpsl(URL url, String encoding, Map<String,Object> existingMacrosthrows IOException {
0040     this(url, encoding, existingMacros, new HashMap<String,Pair>());
0041   }
0042 
0043   public ParseCpsl(URL url, String encoding, Map<String,Object> existingMacros, Map<String,Pair> existingTemplatesthrows IOException {
0044     this(new BomStrippingInputStreamReader(url.openStream(), encoding),
0045          existingMacros, existingTemplates);
0046     baseURL = url;
0047     this.encoding = encoding;
0048   }
0049 
0050   public ParseCpsl(java.io.Reader stream, Map<String,Object> existingMacros) {
0051     this(stream, existingMacros, new HashMap<String,Pair>());
0052   }
0053 
0054   public ParseCpsl(java.io.Reader stream, Map<String,Object> existingMacros, Map<String,Pair> existingTemplates) {
0055     this(stream);
0056     macrosMap = existingMacros;
0057     templatesMap = existingTemplates;
0058   }
0059 
0060   //StatusReporter Implementation
0061   public void addStatusListener(StatusListener listener){
0062     myStatusListeners.add(listener);
0063   }
0064   public void removeStatusListener(StatusListener listener){
0065     myStatusListeners.remove(listener);
0066   }
0067   protected void fireStatusChangedEvent(String text){
0068     Iterator<StatusListener> listenersIter = myStatusListeners.iterator();
0069     while(listenersIter.hasNext())
0070       listenersIter.next().statusChanged(text);
0071   }
0072 
0073   protected SinglePhaseTransducer createSinglePhaseTransducer(String name){
0074     try {
0075       Constructor<? extends SinglePhaseTransducer> c = sptClass.getConstructor
0076           (String.class);
0077       return c.newInstance(name);
0078     catch (NoSuchMethodException e) { // Shouldn't happen
0079       throw new RuntimeException(e);
0080     catch (IllegalArgumentException e) { // Shouldn't happen
0081       throw new RuntimeException(e);
0082     catch (InstantiationException e) { // Shouldn't happen
0083       throw new RuntimeException(e);
0084     catch (IllegalAccessException e) { // Shouldn't happen
0085       throw new RuntimeException(e);
0086     catch (InvocationTargetException e) { // Happens if the constructor throws an exception
0087       throw new RuntimeException(e);
0088     }
0089   }
0090 
0091   protected ParseCpsl spawn(URL sptURLthrows IOException{
0092     ParseCpsl newParser = new ParseCpsl(sptURL, encoding, macrosMap, templatesMap);
0093     newParser.setSptClass(this.sptClass);
0094     return newParser;
0095   }
0096 
0097   protected void finishSPT(SinglePhaseTransducer tthrows ParseException {
0098     if(ruleNumber == 0)
0099       throw(new ParseException("no rules defined in transducer " + t.getName()));
0100     t.setBaseURL(baseURL);
0101   }
0102 
0103   protected void finishBPE(BasicPatternElement bpe) {
0104   }
0105 
0106   /**
0107    * Attempt to parse a multi phase transducer from the current file.  This
0108    * method ensures that the JAPE file reader is properly closed when the
0109    * method completes, whether it completes successfully or throws an
0110    * exception.
0111    */
0112   public MultiPhaseTransducer MultiPhaseTransducer() throws ParseException {
0113     try {
0114       return _MultiPhaseTransducer();
0115     }
0116     finally {
0117       // this is a bit nasty but I couldn't find a better way to get at the
0118       // underlying Reader
0119       if(jj_input_stream.inputStream != null) {
0120         try {
0121           jj_input_stream.inputStream.close();
0122         }
0123         catch(IOException e) {
0124           log.warn("Couldn't close input stream while parsing " + baseURL, e);
0125         }
0126       }
0127     }
0128   }
0129 
0130   protected String toJavaIdentifier(String japeIdentifier) {
0131     return japeIdentifier.replace("-""_");
0132   }
0133 
0134   /**
0135    * Normalise for quoted and unquoted strings - if the token is a string,
0136    * strip the quotes off its image, otherwise return the image as-is.
0137    */
0138   protected String stringValueOf(Token tok) {
0139     if(tok.kind == string) {
0140       // quoted string - strip the quotes
0141       return tok.image.substring(1, tok.image.length() 1);
0142     else {
0143       return tok.image;
0144     }
0145   }
0146 
0147   /**
0148    * Append the given string to the end of the given buffer as a Java string
0149    * literal.  If <code>str</code> is <code>null</code>, we append the four
0150    * characters n, u, l, l.  Otherwise, we append the contents of str surrounded
0151    * by double quotes, except that characters in str are escaped as necessary
0152    * to be a legal Java string literal: backspace, formfeed, tab, newline and
0153    * return are replaced by their escape sequences \b, \f, etc.; single and double
0154    * quote and backslash are preceded by an extra backslash; other non-ASCII
0155    * and non-printing characters are rendered as Unicode escapes (backslash-u
0156    * followed by four hex digits).
0157    */
0158   protected void appendJavaStringLiteral(StringBuffer buf, String str) {
0159         if(str == null) {
0160           buf.append("null");
0161         }
0162         else {
0163           Formatter formatter = null;
0164           buf.append("\u005c"");
0165           for(int i = 0; i < str.length(); i++) {
0166             char c = str.charAt(i);
0167             switch(c) {
0168               case '\u005cb':
0169                 buf.append("\u005c\u005cb");
0170                 break;
0171               case '\u005cf':
0172                 buf.append("\u005c\u005cf");
0173                 break;
0174               case '\u005cn':
0175                 buf.append("\u005c\u005cn");
0176                 break;
0177               case '\u005cr':
0178                 buf.append("\u005c\u005cr");
0179                 break;
0180               case '\u005ct':
0181                 buf.append("\u005c\u005ct");
0182                 break;
0183               case '\u005c"':
0184                 buf.append("\u005c\u005c\u005c"");
0185                 break;
0186               case '\u005c'':
0187                 buf.append("\u005c\u005c\u005c'");
0188                 break;
0189               case '\u005c\u005c':
0190                 buf.append("\u005c\u005c\u005c\u005c");
0191                 break;
0192 
0193               default:
0194                 if(c < 32 || c > 127) {
0195                   if(formatter == nullformatter = new Formatter(buf);
0196                   formatter.format("\u005c\u005cu%04X", Integer.valueOf(c));
0197                 }
0198                 else {
0199                   buf.append(c);
0200                 }
0201                 break;
0202             }
0203           }
0204           buf.append("\u005c"");
0205         }
0206   }
0207 
0208   protected void appendAnnotationAdd(StringBuffer blockBuffer, String newAnnotType, String annotSetName)
0209   {
0210       String nl = Strings.getNl();
0211       blockBuffer.append("      if(outputAS == inputAS) { // use nodes directly" + nl);
0212       blockBuffer.append("        outputAS.add(" + nl);
0213       blockBuffer.append("          " + annotSetName + ".firstNode(), ");
0214       blockBuffer.append(annotSetName + ".lastNode(), " + nl);
0215       blockBuffer.append("          ");
0216       appendJavaStringLiteral(blockBuffer, newAnnotType);
0217       blockBuffer.append(", features" + nl);
0218       blockBuffer.append("        );" + nl);
0219       blockBuffer.append("      }" + nl);
0220       blockBuffer.append("      else { // use offsets" + nl);
0221       blockBuffer.append("        try {" + nl);
0222       blockBuffer.append("          outputAS.add(" + nl);
0223       blockBuffer.append("            " + annotSetName + ".firstNode().getOffset(), ");
0224       blockBuffer.append(annotSetName + ".lastNode().getOffset(), " + nl);
0225       blockBuffer.append("            ");
0226       appendJavaStringLiteral(blockBuffer, newAnnotType);
0227       blockBuffer.append(", features" + nl);
0228       blockBuffer.append("          );" + nl);
0229       blockBuffer.append("        }" + nl);
0230       blockBuffer.append("        catch(gate.util.InvalidOffsetException ioe) {" + nl);
0231       blockBuffer.append("          throw new gate.util.LuckyException(\u005c"Invalid offset exception generated \u005c" +" + nl);
0232       blockBuffer.append("               \u005c"from offsets taken from same document!\u005c");" + nl);
0233       blockBuffer.append("        }" + nl);
0234       blockBuffer.append("      }" + nl);
0235       blockBuffer.append("      // end of RHS assignment block");
0236   }
0237 
0238   /**
0239    * Takes a string containing ${key} placeholders and substitutes
0240    * in the corresponding values from the given map.  If there is
0241    * no value in the map for a particular placeholder it is left
0242    * un-resolved, i.e. given a template of "${key1}/${key2}" and
0243    * a values map of just [key1: "hello"], this method would return
0244    * "hello/${key2}".
0245    */
0246   protected Pair substituteTemplate(Token templateNameTok,
0247           Map<String, Object> valuesthrows ParseException {
0248     Pair template = templatesMap.get(templateNameTok.image);
0249     if(template == null) {
0250       throw new ParseException(errorMsgPrefix(templateNameTok+
0251               "unknown template name " + templateNameTok.image);
0252     }
0253     Pair returnVal = null;
0254     Set<String> unusedParams = new HashSet<String>(values.keySet());
0255     if(((Integer)template.first).intValue() == string) {
0256       log.debug("Substituting template " + templateNameTok.image + " with map "
0257               + values + ". Template is " + template);
0258       StringBuffer buf = new StringBuffer();
0259       Matcher mat = Pattern.compile("\u005c\u005c$\u005c\u005c{([^\u005c\u005c}]+)\u005c\u005c}")
0260               .matcher((String)template.second);
0261       while(mat.find()) {
0262         String key = mat.group(1);
0263         if(values.containsKey(key)) {
0264           mat.appendReplacement(buf,
0265                   Matcher.quoteReplacement(String.valueOf(values.get(key))));
0266           unusedParams.remove(key);
0267         }
0268         else {
0269           mat.appendReplacement(buf, "\u005c\u005c${");
0270           buf.append(key);
0271           buf.append("}");
0272         }
0273       }
0274       mat.appendTail(buf);
0275 
0276       returnVal = new Pair();
0277       returnVal.first = Integer.valueOf(string);
0278       returnVal.second = buf.toString();
0279       log.debug("Template substitution produced " + returnVal.second);
0280     }
0281     else {
0282       returnVal = template;
0283     }
0284 
0285     // check that there were no invalid parameters
0286     if(!unusedParams.isEmpty()) {
0287       throw new ParseException(errorMsgPrefix(templateNameTok+
0288               "invalid parameters " + unusedParams +
0289               " for template " + templateNameTok.image);
0290     }
0291     else {
0292       return returnVal;
0293     }
0294   }
0295 
0296   public void setBaseURL (URL newURL) {
0297     baseURL = newURL;
0298   }
0299 
0300   public void setEncoding (String newEncoding) {
0301     encoding = newEncoding;
0302   }
0303 
0304   public void setSptClass(Class<? extends SinglePhaseTransducer> sptClass) {
0305     this.sptClass = sptClass;
0306   }
0307 
0308   private String errorMsgPrefix(Token t) {
0309     return ((baseURL != null? baseURL.toExternalForm() "(No URL)")+
0310       ( (t == null" " :
0311           ":"+t.beginLine+":"+t.beginColumn+": ");
0312    }
0313 
0314   private transient List<StatusListener> myStatusListeners = new LinkedList<StatusListener>();
0315 
0316   /** Position of the current rule */
0317   private int ruleNumber;
0318 
0319   /** A list of all the bindings we made this time, for checking
0320     * the RHS during parsing.
0321     */
0322   private Set<String> bindingNameSet = null;
0323 
0324   /** A table of macro definitions. */
0325   protected Map<String,Object> macrosMap;
0326 
0327   /**
0328    * A table of template definitions. Keys are template names,
0329    * values are Pairs of token kind and value, as returned by
0330    * AttrVal.
0331    */
0332   protected Map<String,Pair> templatesMap;
0333 
0334   protected URL baseURL;
0335   protected String encoding;
0336 
0337   protected Class<? extends SinglePhaseTransducer> sptClass =
0338       SinglePhaseTransducer.class;
0339 
0340   protected SinglePhaseTransducer curSPT;
0341 
0342 //////////////
0343 // the grammar
0344 //////////////
0345   final public 
0346 MultiPhaseTransducer _MultiPhaseTransducer() throws ParseException {// macrosMap = new HashMap();
0347   SinglePhaseTransducer s = null;
0348   MultiPhaseTransducer m = new MultiPhaseTransducer();
0349   m.setBaseURL(baseURL);
0350   Token mptNameTok = null;
0351   Token phaseNameTok = null;
0352   String javaimportblock = null;
0353   String controllerstartedblock = null;
0354   String controllerfinishedblock = null;
0355   String controllerabortedblock = null;
0356   boolean haveControllerStartedBlock = false;
0357   boolean haveControllerFinishedBlock = false;
0358   boolean haveControllerAbortedBlock = false;
0359     switch (jj_nt.kind) {
0360     case multiphase:{
0361       jj_consume_token(multiphase);
0362       mptNameTok = jj_consume_token(ident);
0363 m.setName(mptNameTok.image);
0364       break;
0365       }
0366     default:
0367       jj_la1[0= jj_gen;
0368       ;
0369     }
0370     switch (jj_nt.kind) {
0371     case javaimport:
0372     case controllerstarted:
0373     case controllerfinished:
0374     case controlleraborted:
0375     case phase:{
0376       javaimportblock = JavaImportBlock();
0377       label_1:
0378       while (true) {
0379         switch (jj_nt.kind) {
0380         case controllerstarted:
0381         case controllerfinished:
0382         case controlleraborted:{
0383           ;
0384           break;
0385           }
0386         default:
0387           jj_la1[1= jj_gen;
0388           break label_1;
0389         }
0390         switch (jj_nt.kind) {
0391         case controllerstarted:{
0392           controllerstartedblock = ControllerStartedBlock();
0393 if(haveControllerStartedBlock)
0394                {if (truethrow new ParseException("Only one ControllerStarted block allowed");}
0395              else
0396                haveControllerStartedBlock = true;
0397           break;
0398           }
0399         case controllerfinished:{
0400           controllerfinishedblock = ControllerFinishedBlock();
0401 if(haveControllerFinishedBlock)
0402                {if (truethrow new ParseException("Only one ControllerFinished block allowed");}
0403              else
0404                haveControllerFinishedBlock = true;
0405           break;
0406           }
0407         case controlleraborted:{
0408           controllerabortedblock = ControllerAbortedBlock();
0409 if(haveControllerAbortedBlock)
0410                {if (truethrow new ParseException("Only one ControllerAborted block allowed");}
0411              else
0412                haveControllerAbortedBlock = true;
0413           break;
0414           }
0415         default:
0416           jj_la1[2= jj_gen;
0417           jj_consume_token(-1);
0418           throw new ParseException();
0419         }
0420       }
0421       label_2:
0422       while (true) {
0423         try {
0424           s = SinglePhaseTransducer(javaimportblock);
0425 m.addPhase(s.getName(), s);
0426                 s.setBaseURL(baseURL);
0427                 s.setControllerEventBlocks(controllerstartedblock,
0428                   controllerfinishedblock,controllerabortedblock,javaimportblock);
0429               // only the first SPT in a MPT file should define/execute the blocks
0430               controllerstartedblock = null;
0431               controllerfinishedblock = null;
0432               controllerabortedblock = null;
0433         catch (Throwable e) {
0434 // try to wrap the exception with info about what file/resource
0435             // it occurred in.
0436             {if (truethrow(
0437               new ParseException("Cannot parse a phase in " +
0438                   baseURL + ": " + e.getMessage()
0439               ));}
0440         }
0441         switch (jj_nt.kind) {
0442         case phase:{
0443           ;
0444           break;
0445           }
0446         default:
0447           jj_la1[3= jj_gen;
0448           break label_2;
0449         }
0450       }
0451       break;
0452       }
0453     case phases:{
0454       jj_consume_token(phases);
0455       label_3:
0456       while (true) {
0457         phaseNameTok = jj_consume_token(path);
0458 ParseCpsl parser = null;
0459 
0460             // check file exists
0461             String sptPath = phaseNameTok.image + ".jape";
0462             URL sptURL = null;
0463             try{
0464               sptURL = new URL(baseURL, sptPath);
0465             }catch(MalformedURLException mue){
0466               {if (truethrow(new ParseException(errorMsgPrefix(phaseNameTok)+
0467                 "Read error " + mue.toString()));}
0468             }
0469 
0470             // sptURL can never be null at this point because the only way that could
0471             // happen would be if an exception occurred above, but that would trigger
0472             // the ParserException above
0473             if(sptURL == null){
0474               {if (truethrow(new ParseException(errorMsgPrefix(phaseNameTok)+
0475                 "Resource not found: base = " + baseURL.toString() +
0476                 " path = " + sptPath
0477               ));}
0478             }
0479 
0480             // construct a parser and parse it
0481             fireStatusChangedEvent("Reading " + phaseNameTok.image + "...");
0482             try {
0483               parser = spawn(sptURL);
0484             catch (IOException e) {
0485               {if (truethrow(
0486                 new ParseException(errorMsgPrefix(phaseNameTok)+
0487                   "Cannot open URL " + sptURL.toExternalForm()
0488                 )
0489               );}
0490             }
0491 
0492           // adding the resultant spt to m
0493           if(parser != null) {
0494                 List<Transducer> phases = parser.MultiPhaseTransducer().getPhases();
0495 
0496             //s = parser.SinglePhaseTransducer();
0497             //if(s != null)
0498             //  m.addPhase(s.getName(), s);
0499 
0500             if(phases != null) {
0501               for(int i=0; i < phases.size(); i++) {
0502                 m.addPhase(
0503                   phases.get(i).getName(),
0504                   phases.get(i)
0505                   );
0506               }
0507             }
0508           }
0509         switch (jj_nt.kind) {
0510         case path:{
0511           ;
0512           break;
0513           }
0514         default:
0515           jj_la1[4= jj_gen;
0516           break label_3;
0517         }
0518       }
0519       break;
0520       }
0521     default:
0522       jj_la1[5= jj_gen;
0523       jj_consume_token(-1);
0524       throw new ParseException();
0525     }
0526     jj_consume_token(0);
0527 //move this out of here so the input file gets closed properly
0528 //    m.finish(); // swap the various JGL types for Java arrays
0529     {if ("" != nullreturn m;}
0530     throw new Error("Missing return statement in function");
0531   }
0532 
0533 // _MultiPhaseTransducer
0534   final public 
0535 
0536 SinglePhaseTransducer SinglePhaseTransducer(String javaimportblockthrows ParseException {ruleNumber = 0;
0537   Token phaseNameTok = null;
0538   String phaseName = null;
0539   Token inputTok = null;
0540   SinglePhaseTransducer t = null;
0541   Rule newRule = null;
0542   bindingNameSet = new HashSet<String>();
0543   Token optionNameTok = null;
0544   Token optionValueTok = null;
0545     jj_consume_token(phase);
0546     phaseNameTok = jj_consume_token(ident);
0547 phaseName = toJavaIdentifier(phaseNameTok.image);
0548     t = createSinglePhaseTransducer(phaseName); curSPT = t;
0549     label_4:
0550     while (true) {
0551       switch (jj_nt.kind) {
0552       case input:
0553       case option:{
0554         ;
0555         break;
0556         }
0557       default:
0558         jj_la1[6= jj_gen;
0559         break label_4;
0560       }
0561       switch (jj_nt.kind) {
0562       case input:{
0563         jj_consume_token(input);
0564         label_5:
0565         while (true) {
0566           switch (jj_nt.kind) {
0567           case string:
0568           case ident:{
0569             ;
0570             break;
0571             }
0572           default:
0573             jj_la1[7= jj_gen;
0574             break label_5;
0575           }
0576           switch (jj_nt.kind) {
0577           case ident:{
0578             inputTok = jj_consume_token(ident);
0579             break;
0580             }
0581           case string:{
0582             inputTok = jj_consume_token(string);
0583             break;
0584             }
0585           default:
0586             jj_la1[8= jj_gen;
0587             jj_consume_token(-1);
0588             throw new ParseException();
0589           }
0590 t.addInput(stringValueOf(inputTok));
0591         }
0592         break;
0593         }
0594       case option:{
0595         jj_consume_token(option);
0596         label_6:
0597         while (true) {
0598           switch (jj_nt.kind) {
0599           case ident:{
0600             ;
0601             break;
0602             }
0603           default:
0604             jj_la1[9= jj_gen;
0605             break label_6;
0606           }
0607           optionNameTok = jj_consume_token(ident);
0608           jj_consume_token(assign);
0609           switch (jj_nt.kind) {
0610           case ident:{
0611             optionValueTok = jj_consume_token(ident);
0612             break;
0613             }
0614           case bool:{
0615             optionValueTok = jj_consume_token(bool);
0616             break;
0617             }
0618           default:
0619             jj_la1[10= jj_gen;
0620             jj_consume_token(-1);
0621             throw new ParseException();
0622           }
0623 t.setOption(optionNameTok.image, optionValueTok.image);
0624 
0625           // control
0626           if(optionNameTok.image.equalsIgnoreCase("control")) {
0627             if(optionValueTok.image.equalsIgnoreCase("appelt"))
0628               t.setRuleApplicationStyle(APPELT_STYLE);
0629             else if(optionValueTok.image.equalsIgnoreCase("first"))
0630               t.setRuleApplicationStyle(FIRST_STYLE);
0631             else if(optionValueTok.image.equalsIgnoreCase("brill"))
0632               t.setRuleApplicationStyle(BRILL_STYLE);
0633             else if(optionValueTok.image.equalsIgnoreCase("once"))
0634               t.setRuleApplicationStyle(ONCE_STYLE);
0635             else if(optionValueTok.image.equalsIgnoreCase("all"))
0636               t.setRuleApplicationStyle(ALL_STYLE);
0637             else
0638               System.err.println(errorMsgPrefix(optionValueTok)+
0639                 "ignoring unknown control strategy " + option +
0640                 " (should be brill, appelt, first, once or all)"
0641               );
0642           // control
0643           else if(optionNameTok.image.equalsIgnoreCase("debug")) {
0644             if(optionValueTok.image.equalsIgnoreCase("true"||
0645                optionValueTok.image.equalsIgnoreCase("yes"||
0646                optionValueTok.image.equalsIgnoreCase("y"))
0647               t.setDebugMode(true);
0648             else t.setDebugMode(false);
0649           }
0650           else if(optionNameTok.image.equalsIgnoreCase("matchGroup")) {
0651             if(optionValueTok.image.equalsIgnoreCase("true"||
0652                optionValueTok.image.equalsIgnoreCase("yes"||
0653                optionValueTok.image.equalsIgnoreCase("y"))
0654               t.setMatchGroupMode(true);
0655             else t.setMatchGroupMode(false);
0656           }
0657           else if(optionNameTok.image.equalsIgnoreCase("negationGrouping")) {
0658             if(optionValueTok.image.equalsIgnoreCase("false"||
0659                optionValueTok.image.equalsIgnoreCase("no"||
0660                optionValueTok.image.equalsIgnoreCase("n"))
0661               t.setNegationCompatMode(true);
0662             else t.setNegationCompatMode(false);
0663           }
0664         }
0665         break;
0666         }
0667       default:
0668         jj_la1[11= jj_gen;
0669         jj_consume_token(-1);
0670         throw new ParseException();
0671       }
0672     }
0673     label_7:
0674     while (true) {
0675       switch (jj_nt.kind) {
0676       case rule:
0677       case macro:
0678       case template:{
0679         ;
0680         break;
0681         }
0682       default:
0683         jj_la1[12= jj_gen;
0684         break label_7;
0685       }
0686       switch (jj_nt.kind) {
0687       case rule:{
0688         newRule = Rule(phaseName,javaimportblock);
0689 t.addRule(newRule);
0690         break;
0691         }
0692       case macro:{
0693         MacroDef();
0694         break;
0695         }
0696       case template:{
0697         TemplateDef();
0698         break;
0699         }
0700       default:
0701         jj_la1[13= jj_gen;
0702         jj_consume_token(-1);
0703         throw new ParseException();
0704       }
0705     }
0706 finishSPT(t);
0707     {if ("" != nullreturn t;}
0708     throw new Error("Missing return statement in function");
0709   }
0710 
0711 // SinglePhaseTransducer
0712 
0713 // if there is a block, set the javaimports to the java block specified,
0714 // otherwise set it to the default block
0715   final public String JavaImportBlock() throws ParseException {// default java imports
0716   String defaultimportblock =
0717       "import gate.*;\u005cn" +
0718       "import java.io.*;\u005cn" +
0719       "import java.util.*;\u005cn" +
0720       "import gate.util.*;\u005cn" +
0721       "import gate.jape.*;\u005cn" +
0722       "import gate.creole.ontology.*;\u005cn";
0723   String importblock = null;
0724     switch (jj_nt.kind) {
0725     case javaimport:{
0726       jj_consume_token(javaimport);
0727       jj_consume_token(leftBrace);
0728       importblock = ConsumeBlock();
0729       break;
0730       }
0731     default:
0732       jj_la1[14= jj_gen;
0733       ;
0734     }
0735 if(importblock != null) {
0736       {if ("" != nullreturn defaultimportblock+importblock;}
0737     else  {
0738       {if ("" != nullreturn defaultimportblock;}
0739     }
0740     throw new Error("Missing return statement in function");
0741   }
0742 
0743   final public String ControllerStartedBlock() throws ParseException {String block = null;
0744     jj_consume_token(controllerstarted);
0745     jj_consume_token(leftBrace);
0746     block = ConsumeBlock();
0747 {if ("" != nullreturn block;}
0748     throw new Error("Missing return statement in function");
0749   }
0750 
0751   final public String ControllerFinishedBlock() throws ParseException {String block = null;
0752     jj_consume_token(controllerfinished);
0753     jj_consume_token(leftBrace);
0754     block = ConsumeBlock();
0755 {if ("" != nullreturn block;}
0756     throw new Error("Missing return statement in function");
0757   }
0758 
0759   final public String ControllerAbortedBlock() throws ParseException {String block = null;
0760     jj_consume_token(controlleraborted);
0761     jj_consume_token(leftBrace);
0762     block = ConsumeBlock();
0763 {if ("" != nullreturn block;}
0764     throw new Error("Missing return statement in function");
0765   }
0766 
0767   final public Rule Rule(String phaseName, String currentImportsthrows ParseException {Token ruleNameTok = null;
0768   String ruleName = null;
0769   Token priorityTok = null;
0770   int rulePriority = 0;
0771   LeftHandSide lhs = null;
0772   RightHandSide rhs = null;
0773   Rule newRule = null;
0774   // forget the labels we saw in the previous rule
0775   bindingNameSet.clear();
0776     jj_consume_token(rule);
0777     ruleNameTok = jj_consume_token(ident);
0778 ruleName=toJavaIdentifier(ruleNameTok.image);
0779     switch (jj_nt.kind) {
0780     case priority:{
0781       jj_consume_token(priority);
0782       priorityTok = jj_consume_token(integer);
0783 try rulePriority=Integer.parseInt(priorityTok.image)}
0784       catch(NumberFormatException e) {
0785         System.err.println(errorMsgPrefix(priorityTok)+
0786           "bad priority spec(" + priorityTok.image +
0787           "), rule(" + ruleName + ") - treating as 0");
0788         rulePriority=0;
0789       }
0790       break;
0791       }
0792     default:
0793       jj_la1[15= jj_gen;
0794       ;
0795     }
0796     lhs = LeftHandSide();
0797     jj_consume_token(72);
0798     rhs = RightHandSide(phaseName, ruleName, lhs, currentImports);
0799 try {
0800       rhs.createActionClass();
0801     catch(JapeException e) {
0802       /*Debug.pr(
0803         this, "ParseCpsl.Rule, FAILED rhs: " + rhs.getActionClassString()
0804       );*/
0805       {if (truethrow new ParseException(errorMsgPrefix(null)+
0806         "couldn't create rule RHS: " + e.toString());}
0807     }
0808     /*Debug.pr(this, "ParseCpsl.Rule, done rhs: " + rhs.getActionClassString());*/
0809     newRule = new Rule(ruleName, ruleNumber, rulePriority, lhs, rhs);
0810         // if there were "Input:" annotation types specified ...
0811         if(curSPT.isInputRestricted()) {
0812       // find all the different annotation types used in the
0813       // LHS of the rule
0814       HashSet<String> set = new HashSet<String>();
0815           lhs.getConstraintGroup().getContainedAnnotationTypes(set);
0816           // and check if each of them is mentioned in the list
0817           for (String type : set) {
0818                 if(!curSPT.hasInput(type)) {
0819                   System.err.println(errorMsgPrefix(null)+
0820                     "Rule "+ruleNameTok.image+" contains unlisted annotation type " + type);
0821                 }
0822           }
0823         }
0824     ruleNumber++;
0825     {if ("" != nullreturn newRule;}
0826     throw new Error("Missing return statement in function");
0827   }
0828 
0829 // Rule
0830   final public 
0831 
0832 void MacroDef() throws ParseException {Token macroNameTok = null;
0833   Object body = null;
0834     jj_consume_token(macro);
0835     macroNameTok = jj_consume_token(ident);
0836     if (jj_2_1(2)) {
0837       // both blocks and PEs may start with "{"
0838           body = PatternElement();
0839     else {
0840       switch (jj_nt.kind) {
0841       case ident:
0842       case colon:
0843       case leftBrace:
0844       case colonplus:{
0845         body = Action(false);
0846         break;
0847         }
0848       default:
0849         jj_la1[16= jj_gen;
0850         jj_consume_token(-1);
0851         throw new ParseException();
0852       }
0853     }
0854 macrosMap.put(macroNameTok.image, body);
0855   }
0856 
0857 // MacroDef
0858   final public 
0859 void TemplateDef() throws ParseException {Token templateNameTok = null;
0860   Pair value = null;
0861     jj_consume_token(template);
0862     templateNameTok = jj_consume_token(ident);
0863     jj_consume_token(assign);
0864     value = AttrVal();
0865 templatesMap.put(templateNameTok.image, value);
0866   }
0867 
0868 // TemplateDef
0869   final public 
0870 
0871 LeftHandSide LeftHandSide() throws ParseException {ConstraintGroup cg = new ConstraintGroup();
0872     ConstraintGroup(cg);
0873 LeftHandSide lhs = new LeftHandSide(cg);
0874     // pull out all bindings (including nested ones) and add them to the LHS
0875     Iterator<ComplexPatternElement> boundCPEs = cg.getCPEs();
0876     while(boundCPEs.hasNext()) {
0877       ComplexPatternElement cpe = boundCPEs.next();
0878       String bindingName = cpe.getBindingName();
0879       if(bindingName != null) {
0880         try {
0881           lhs.addBinding(bindingName, cpe, bindingNameSet);
0882         catch(JapeException e) {
0883           System.err.println(errorMsgPrefix(null)+
0884             "duplicate binding name " + bindingName +
0885             " - ignoring this binding! exception was: " + e.toString()
0886           );
0887         }
0888 
0889       }
0890     }
0891     {if ("" != nullreturn lhs;}
0892     throw new Error("Missing return statement in function");
0893   }
0894 
0895 // LeftHandSide
0896 
0897 
0898 // we pass the lhs down so we can add bindings in CPEs, and the cg
0899 // so we can add PEs and create disjunctions here
0900   final public void ConstraintGroup(ConstraintGroup cgthrows ParseException {PatternElement pat = null;
0901     label_8:
0902     while (true) {
0903       pat = PatternElement();
0904 cg.addPatternElement(pat);
0905       switch (jj_nt.kind) {
0906       case string:
0907       case ident:
0908       case leftBrace:
0909       case leftBracket:{
0910         ;
0911         break;
0912         }
0913       default:
0914         jj_la1[17= jj_gen;
0915         break label_8;
0916       }
0917     }
0918     label_9:
0919     while (true) {
0920       switch (jj_nt.kind) {
0921       case bar:{
0922         ;
0923         break;
0924         }
0925       default:
0926         jj_la1[18= jj_gen;
0927         break label_9;
0928       }
0929       jj_consume_token(bar);
0930 cg.createDisjunction();
0931       label_10:
0932       while (true) {
0933         pat = PatternElement();
0934 cg.addPatternElement(pat);
0935         switch (jj_nt.kind) {
0936         case string:
0937         case ident:
0938         case leftBrace:
0939         case leftBracket:{
0940           ;
0941           break;
0942           }
0943         default:
0944           jj_la1[19= jj_gen;
0945           break label_10;
0946         }
0947       }
0948     }
0949   }
0950 
0951 // ConstraintGroup
0952   final public 
0953 
0954 PatternElement PatternElement() throws ParseException {PatternElement pat = null;
0955   Token macroRefTok = null;
0956     switch (jj_nt.kind) {
0957     case ident:{
0958       macroRefTok = jj_consume_token(ident);
0959 Object macro = macrosMap.get(macroRefTok.image);
0960       if(macro == null)
0961         {if (truethrow(new ParseException(errorMsgPrefix(macroRefTok)+
0962           "unknown macro name " + macroRefTok.image));}
0963       else if(macro instanceof String[])
0964         {if (truethrow(
0965           new ParseException(errorMsgPrefix(macroRefTok)+
0966             "macro " + macroRefTok.image +
0967             " references an Action, not a PatternElement"
0968           )
0969         );}
0970       else if((macro instanceof PatternElement)) // this should never happen
0971         {if (truethrow(
0972           new ParseException(errorMsgPrefix(macroRefTok)+
0973             "macro " + macroRefTok.image +
0974             " doesn't reference a PatternElement!"
0975           )
0976         );}
0977       else // macro is a pattern element
0978         pat = (PatternElement) ((PatternElementmacro).clone();
0979       }
0980       break;
0981       }
0982     case string:
0983     case leftBrace:{
0984       pat = BasicPatternElement();
0985       break;
0986       }
0987     case leftBracket:{
0988       pat = ComplexPatternElement();
0989       break;
0990       }
0991     default:
0992       jj_la1[20= jj_gen;
0993       jj_consume_token(-1);
0994       throw new ParseException();
0995     }
0996 {if ("" != nullreturn pat;}
0997     throw new Error("Missing return statement in function");
0998   }
0999 
1000 // PatternElement
1001   final public 
1002 
1003 BasicPatternElement BasicPatternElement() throws ParseException {Token shortTok = null// string shorthand token
1004   Constraint c = null;
1005   BasicPatternElement bpe = new BasicPatternElement(curSPT);
1006     switch (jj_nt.kind) {
1007     case leftBrace:{
1008       jj_consume_token(leftBrace);
1009       c = Constraint();
1010 bpe.addConstraint(c);
1011       label_11:
1012       while (true) {
1013         switch (jj_nt.kind) {
1014         case comma:{
1015           ;
1016           break;
1017           }
1018         default:
1019           jj_la1[21= jj_gen;
1020           break label_11;
1021         }
1022         jj_consume_token(comma);
1023         c = Constraint();
1024 bpe.addConstraint(c);
1025       }
1026       jj_consume_token(rightBrace);
1027       break;
1028       }
1029     case string:{
1030       // string shorthand
1031             shortTok = jj_consume_token(string);
1032 System.err.println(errorMsgPrefix(shortTok)+
1033         "string shorthand not supported yet, ignoring: " + shortTok.image
1034       );
1035       break;
1036       }
1037     default:
1038       jj_la1[22= jj_gen;
1039       jj_consume_token(-1);
1040       throw new ParseException();
1041     }
1042 finishBPE(bpe);
1043     {if ("" != nullreturn bpe;}
1044     throw new Error("Missing return statement in function");
1045   }
1046 
1047 // BasicPatternElement
1048   final public 
1049 
1050 ComplexPatternElement ComplexPatternElement() throws ParseException {KleeneOperator kleeneOperator = null;
1051   Token bindingNameTok = null;
1052   ConstraintGroup cg = new ConstraintGroup();
1053     jj_consume_token(leftBracket);
1054     ConstraintGroup(cg);
1055     jj_consume_token(rightBracket);
1056     switch (jj_nt.kind) {
1057     case kleeneOp:
1058     case leftSquare:{
1059       kleeneOperator = KleeneOperator();
1060       break;
1061       }
1062     default:
1063       jj_la1[23= jj_gen;
1064       ;
1065     }
1066     switch (jj_nt.kind) {
1067     case colon:{
1068       jj_consume_token(colon);
1069       switch (jj_nt.kind) {
1070       case ident:{
1071         bindingNameTok = jj_consume_token(ident);
1072         break;
1073         }
1074       case integer:{
1075         bindingNameTok = jj_consume_token(integer);
1076         break;
1077         }
1078       default:
1079         jj_la1[24= jj_gen;
1080         jj_consume_token(-1);
1081         throw new ParseException();
1082       }
1083       break;
1084       }
1085     default:
1086       jj_la1[25= jj_gen;
1087       ;
1088     }
1089 String bindingName = null;
1090     if(bindingNameTok != null)
1091       bindingName = bindingNameTok.image;
1092     {if ("" != nullreturn new ComplexPatternElement(cg, kleeneOperator, bindingName);}
1093     throw new Error("Missing return statement in function");
1094   }
1095 
1096 // ComplexPatternElement
1097   final public 
1098 KleeneOperator KleeneOperator() throws ParseException {Token kleeneOpTok = null;
1099   Token minTok = null;
1100   Token maxTok = null;
1101   Integer min = null;
1102   Integer max = null;
1103     switch (jj_nt.kind) {
1104     case kleeneOp:{
1105       kleeneOpTok = jj_consume_token(kleeneOp);
1106 if (kleeneOpTok == null) {
1107           {if ("" != nullreturn new KleeneOperator(KleeneOperator.Type.SINGLE);}
1108         }
1109 
1110         KleeneOperator.Type type = KleeneOperator.Type.getFromSymbol(kleeneOpTok.image);
1111         if (type != null)
1112             {if ("" != nullreturn new KleeneOperator(type);}
1113         else {
1114           System.err.println(errorMsgPrefix(kleeneOpTok)+
1115               "ignoring uninterpretable Kleene op " + kleeneOpTok.image);
1116           {if ("" != nullreturn new KleeneOperator(KleeneOperator.Type.SINGLE);}
1117         }
1118       break;
1119       }
1120     case leftSquare:{
1121       jj_consume_token(leftSquare);
1122       minTok = jj_consume_token(integer);
1123       switch (jj_nt.kind) {
1124       case comma:{
1125         jj_consume_token(comma);
1126         maxTok = jj_consume_token(integer);
1127         break;
1128         }
1129       default:
1130         jj_la1[26= jj_gen;
1131         ;
1132       }
1133       jj_consume_token(rightSquare);
1134 if (minTok != null)
1135               min = new Integer(minTok.image);
1136           if (maxTok != null)
1137               max = new Integer(maxTok.image);
1138           else
1139               max = min;
1140           {if ("" != nullreturn new KleeneOperator(min, max);}
1141       break;
1142       }
1143     default:
1144       jj_la1[27= jj_gen;
1145       jj_consume_token(-1);
1146       throw new ParseException();
1147     }
1148     throw new Error("Missing return statement in function");
1149   }
1150 
1151 // KleeneOperator
1152   final public 
1153 Constraint Constraint() throws ParseException {Token annotTypeTok = null;
1154   Token metaPropertyTok = null;
1155   AnnotationAccessor accessor = null;
1156   Token opTok = null;
1157   Pair attrValPair = null;
1158   boolean negate = false;
1159   Constraint c = null;
1160   Constraint embeddedConstraint = null;
1161   String opString = null;
1162     switch (jj_nt.kind) {
1163     case pling:{
1164       jj_consume_token(pling);
1165 negate = true;
1166       break;
1167       }
1168     default:
1169       jj_la1[28= jj_gen;
1170       ;
1171     }
1172     switch (jj_nt.kind) {
1173     case ident:{
1174       annotTypeTok = jj_consume_token(ident);
1175       break;
1176       }
1177     case string:{
1178       annotTypeTok = jj_consume_token(string);
1179       break;
1180       }
1181     default:
1182       jj_la1[29= jj_gen;
1183       jj_consume_token(-1);
1184       throw new ParseException();
1185     }
1186 c = Factory.getConstraintFactory().createConstraint(stringValueOf(annotTypeTok));
1187     if(negatec.negate();
1188     switch (jj_nt.kind) {
1189     case metaPropOp:
1190     case ident:
1191     case period:{
1192       switch (jj_nt.kind) {
1193       case period:{
1194         accessor = FeatureAccessor();
1195         opTok = jj_consume_token(attrOp);
1196         attrValPair = AttrVal();
1197 opString = opTok.image;
1198         c.addAttribute(Factory.getConstraintFactory().createPredicate(opString, accessor, attrValPair.second));
1199         break;
1200         }
1201       case metaPropOp:{
1202         jj_consume_token(metaPropOp);
1203         metaPropertyTok = jj_consume_token(ident);
1204         opTok = jj_consume_token(attrOp);
1205         attrValPair = AttrVal();
1206 accessor = Factory.getConstraintFactory().createMetaPropertyAccessor(metaPropertyTok.image);
1207         opString = opTok.image;
1208         c.addAttribute(Factory.getConstraintFactory().createPredicate(opString, accessor, attrValPair.second));
1209         break;
1210         }
1211       case ident:{
1212         // custom string operator name with value
1213               opTok = jj_consume_token(ident);
1214         switch (jj_nt.kind) {
1215         case leftBrace:{
1216           jj_consume_token(leftBrace);
1217           embeddedConstraint = Constraint();
1218           jj_consume_token(rightBrace);
1219           break;
1220           }
1221         case pling:
1222         case string:
1223         case ident:{
1224           embeddedConstraint = Constraint();
1225           break;
1226           }
1227         default:
1228           jj_la1[30= jj_gen;
1229           jj_consume_token(-1);
1230           throw new ParseException();
1231         }
1232 opString = opTok.image;
1233         accessor = new SimpleAnnotationAccessor();
1234         c.addAttribute(Factory.getConstraintFactory().createPredicate(opString, accessor, embeddedConstraint));
1235         break;
1236         }
1237       default:
1238         jj_la1[31= jj_gen;
1239         jj_consume_token(-1);
1240         throw new ParseException();
1241       }
1242       break;
1243       }
1244     default:
1245       jj_la1[32= jj_gen;
1246       ;
1247     }
1248 {if ("" != nullreturn c;}
1249     throw new Error("Missing return statement in function");
1250   }
1251 
1252 // Constraint
1253 
1254 //attribute values: strings, identifers (=strings), integers, floats,
1255 //booleans
1256   final public AnnotationAccessor FeatureAccessor() throws ParseException {Token attrNameTok = null;
1257 AnnotationAccessor accessor = null;
1258     jj_consume_token(period);
1259     switch (jj_nt.kind) {
1260     case ident:{
1261       attrNameTok = jj_consume_token(ident);
1262       break;
1263       }
1264     case string:{
1265       attrNameTok = jj_consume_token(string);
1266       break;
1267       }
1268     default:
1269       jj_la1[33= jj_gen;
1270       jj_consume_token(-1);
1271       throw new ParseException();
1272     }
1273 accessor = Factory.getConstraintFactory().createDefaultAccessor(stringValueOf(attrNameTok));
1274     {if ("" != nullreturn accessor;}
1275     throw new Error("Missing return statement in function");
1276   }
1277 
1278 // attribute values: strings, identifers (=strings), integers, floats,
1279 //                   booleans
1280   final public Pair AttrVal() throws ParseException {Token attrValTok = null;
1281   Pair val = new Pair();
1282     switch (jj_nt.kind) {
1283     case integer:
1284     case string:
1285     case bool:
1286     case ident:
1287     case floatingPoint:{
1288       switch (jj_nt.kind) {
1289       case string:{
1290         attrValTok = jj_consume_token(string);
1291         break;
1292         }
1293       case ident:{
1294         attrValTok = jj_consume_token(ident);
1295         break;
1296         }
1297       case integer:{
1298         attrValTok = jj_consume_token(integer);
1299         break;
1300         }
1301       case floatingPoint:{
1302         attrValTok = jj_consume_token(floatingPoint);
1303         break;
1304         }
1305       case bool:{
1306         attrValTok = jj_consume_token(bool);
1307         break;
1308         }
1309       default:
1310         jj_la1[34= jj_gen;
1311         jj_consume_token(-1);
1312         throw new ParseException();
1313       }
1314 val.first = new Integer(attrValTok.kind);
1315 
1316       switch(attrValTok.kind) {
1317         case string:
1318           // strip the quotes
1319           val.second
1320             = attrValTok.image.substring(1, attrValTok.image.length() 1);
1321           break;
1322         case integer:
1323           try {
1324             val.second = Long.valueOf(attrValTok.image);
1325           catch(NumberFormatException e) {
1326             System.err.println(errorMsgPrefix(attrValTok)+
1327               "couldn't parse integer " +
1328               attrValTok.image + " - treating as 0");
1329             val.second = new Long(0);
1330           }
1331           break;
1332         case ident:
1333           val.second = new String(attrValTok.image);
1334           break;
1335         case bool:
1336           val.second = Boolean.valueOf(attrValTok.image);
1337           break;
1338         case floatingPoint:
1339           try {
1340             val.second = Double.valueOf(attrValTok.image);
1341           catch(NumberFormatException e) {
1342             System.err.println(errorMsgPrefix(attrValTok)+
1343               "couldn't parse float " +
1344               attrValTok.image + " - treating as 0.0");
1345             val.second = new Double(0.0);
1346           }
1347           break;
1348         default:
1349           System.err.println(errorMsgPrefix(attrValTok)+
1350             "didn't understand type of " + attrValTok.image + ": ignoring"
1351           );
1352           val.second = new String("");
1353           break;
1354       // switch
1355 
1356       {if ("" != nullreturn val;}
1357       break;
1358       }
1359     case leftSquare:{
1360       val = TemplateCall();
1361 {if ("" != nullreturn val;}
1362       break;
1363       }
1364     default:
1365       jj_la1[35= jj_gen;
1366       jj_consume_token(-1);
1367       throw new ParseException();
1368     }
1369     throw new Error("Missing return statement in function");
1370   }
1371 
1372   final public Pair TemplateCall() throws ParseException {Token templateNameTok = null;
1373   Token attrNameTok = null;
1374   Pair attrVal = null;
1375   Map<String, Object> placeholders = new HashMap<String, Object>();
1376     jj_consume_token(leftSquare);
1377     templateNameTok = jj_consume_token(ident);
1378     label_12:
1379     while (true) {
1380       switch (jj_nt.kind) {
1381       case ident:{
1382         ;
1383         break;
1384         }
1385       default:
1386         jj_la1[36= jj_gen;
1387         break label_12;
1388       }
1389       attrNameTok = jj_consume_token(ident);
1390       jj_consume_token(assign);
1391       attrVal = AttrVal();
1392 placeholders.put(attrNameTok.image, attrVal.second);
1393       switch (jj_nt.kind) {
1394       case comma:{
1395         jj_consume_token(comma);
1396         break;
1397         }
1398       default:
1399         jj_la1[37= jj_gen;
1400         ;
1401       }
1402     }
1403     jj_consume_token(rightSquare);
1404 {if ("" != nullreturn substituteTemplate(templateNameTok, placeholders);}
1405     throw new Error("Missing return statement in function");
1406   }
1407 
1408   final public RightHandSide RightHandSide(String phaseName, String ruleName, LeftHandSide lhs, String importsthrows ParseException {String[] block = new String[2];
1409   RightHandSide rhs = new RightHandSide(phaseName, ruleName, lhs, imports);
1410     block = Action(true);
1411 rhs.addBlock(block[0], block[1]);
1412     label_13:
1413     while (true) {
1414       switch (jj_nt.kind) {
1415       case comma:{
1416         ;
1417         break;
1418         }
1419       default:
1420         jj_la1[38= jj_gen;
1421         break label_13;
1422       }
1423       jj_consume_token(comma);
1424       block = Action(true);
1425 rhs.addBlock(block[0], block[1]);
1426     }
1427 {if ("" != nullreturn rhs;/* action class not created yet */
1428 
1429     throw new Error("Missing return statement in function");
1430   }
1431 
1432 // RightHandSide
1433 
1434 
1435 // actions return 2 strings, one for the name of the block, and
1436 // one for the block itself. if the name is null, it is an anonymous block.
1437 // The checkLabel parameter indicates whether named blocks should check
1438 // at parse time that the label they refer to is bound.  Actions in
1439 // a MacroDef can't make this check at parse time, but instead the
1440 // check is done when the macro is referenced.
1441   final public String[] Action(boolean checkLabelthrows ParseException {String[] block = new String[2];
1442   Token macroRefTok = null;
1443     if (jj_2_2(3)) {
1444       block = NamedJavaBlock(checkLabel);
1445     else {
1446       switch (jj_nt.kind) {
1447       case leftBrace:{
1448         block = AnonymousJavaBlock();
1449         break;
1450         }
1451       case colon:
1452       case colonplus:{
1453         block = AssignmentExpression(checkLabel);
1454         break;
1455         }
1456       case ident:{
1457         macroRefTok = jj_consume_token(ident);
1458 Object macro = macrosMap.get(macroRefTok.image);
1459       if(macro == null)
1460         {if (truethrow(new ParseException(errorMsgPrefix(macroRefTok)+
1461           "unknown macro name " + macroRefTok.image));}
1462       else if(macro instanceof PatternElement)
1463         {if (truethrow(
1464           new ParseException(errorMsgPrefix(macroRefTok)+
1465             "macro " + macroRefTok.image +
1466             " references a PatternElement, not an Action"
1467           )
1468         );}
1469       else if((macro instanceof String[])) // this should never happen
1470         {if (truethrow(
1471           new ParseException(errorMsgPrefix(macroRefTok)+
1472             "macro " + macroRefTok.image + " doesn't reference an Action!"
1473           )
1474         );}
1475       else // macro is an action
1476         block = (String[]) macro;
1477         // if the macro is a named block or assignment, check that
1478         // the label is valid
1479         if(block[0!= null && !bindingNameSet.contains(block[0])) {
1480           {if (truethrow(new ParseException(errorMsgPrefix(macroRefTok)+
1481             "RHS macro reference " + macroRefTok.image +
1482             " refers to unknown label: " + block[0]));}
1483         }
1484       }
1485         break;
1486         }
1487       default:
1488         jj_la1[39= jj_gen;
1489         jj_consume_token(-1);
1490         throw new ParseException();
1491       }
1492     }
1493 {if ("" != nullreturn block;}
1494     throw new Error("Missing return statement in function");
1495   }
1496 
1497 // Action
1498 
1499 
1500 // A :bind { ... } code block.  The checkLabel parameter
1501 // indicates whether or not we should check *at parse time* that the
1502 // :bind label is valid.  Assignments that are the body of a MacroDef
1503 // can't check this at parse time but will be checked at reference time
1504   final public String[] NamedJavaBlock(boolean checkLabelthrows ParseException {String[] block = new String[2];
1505   Token nameTok = null;
1506     jj_consume_token(colon);
1507     nameTok = jj_consume_token(ident);
1508 block[0= nameTok.image;
1509     // did we get a non-existent block name?
1510     if(checkLabel && block[0!= null)
1511       if(! bindingNameSet.contains(block[0])) {
1512         {if (truethrow(new ParseException(errorMsgPrefix(nameTok)+
1513           "unknown label in RHS action: " + block[0]));}
1514       }
1515     jj_consume_token(leftBrace);
1516     block[1= ConsumeBlock();
1517 {if ("" != nullreturn block;}
1518     throw new Error("Missing return statement in function");
1519   }
1520 
1521 // NamedJavaBlock
1522   final public 
1523 
1524 String[] AnonymousJavaBlock() throws ParseException {String[] block = new String[2];
1525   block[0null// no name
1526 
1527     jj_consume_token(leftBrace);
1528     block[1= ConsumeBlock();
1529 {if ("" != nullreturn block;}
1530     throw new Error("Missing return statement in function");
1531   }
1532 
1533 // AnonymousJavaBlock
1534 
1535 
1536 // A :bind.Type = {features} assignment.  The checkLabel parameter
1537 // indicates whether or not we should check *at parse time* that the
1538 // :bind label is valid.  Assignments that are the body of a MacroDef
1539 // can't check this at parse time but will be checked at reference time
1540   final public String[] AssignmentExpression(boolean checkLabelthrows ParseException {String[] block = new String[2];
1541   StringBuffer blockBuffer = new StringBuffer();
1542   Token nameTok = null;
1543   Token opTok = null;
1544   String newAnnotType = null;
1545   String newAttrName = null;
1546   String nl = Strings.getNl();
1547   String annotSetName = null;
1548   Pair attrVal = null;
1549   String existingAnnotSetName = null;
1550   String existingAnnotType = null;
1551   String existingAttrName = null;
1552   String opName = null;
1553 
1554   blockBuffer.append("// RHS assignment block" + nl);
1555   blockBuffer.append(
1556     "      gate.FeatureMap features = gate.Factory.newFeatureMap();" + nl
1557   );
1558     switch (jj_nt.kind) {
1559     case colon:{
1560       jj_consume_token(colon);
1561       break;
1562       }
1563     case colonplus:{
1564       jj_consume_token(colonplus);
1565 {if (truethrow new
1566         ParseException(":+ not a legal operator (no multi-span annots)");}
1567       break;
1568       }
1569     default:
1570       jj_la1[40= jj_gen;
1571       jj_consume_token(-1);
1572       throw new ParseException();
1573     }
1574     // the name of the bound annotation set we're referencing
1575       nameTok = jj_consume_token(ident);
1576 block[0= nameTok.image;
1577     // did we get a non-existent block name?
1578     if(checkLabel && block[0!= null)
1579       if(! bindingNameSet.contains(block[0])) {
1580         {if (truethrow(new ParseException(errorMsgPrefix(nameTok)+
1581           "unknown label in RHS action: " + block[0]));}
1582       }
1583 
1584     annotSetName = block[0"Annots";
1585     jj_consume_token(period);
1586     switch (jj_nt.kind) {
1587     case ident:{
1588       nameTok = jj_consume_token(ident);
1589       break;
1590       }
1591     case string:{
1592       nameTok = jj_consume_token(string);
1593       break;
1594       }
1595     default:
1596       jj_la1[41= jj_gen;
1597       jj_consume_token(-1);
1598       throw new ParseException();
1599     }
1600 newAnnotType = stringValueOf(nameTok);
1601 
1602     // start of the attribute stuff
1603     blockBuffer.append("      java.lang.Object val = null;" + nl);
1604     jj_consume_token(assign);
1605     jj_consume_token(leftBrace);
1606     label_14:
1607     while (true) {
1608       switch (jj_nt.kind) {
1609       case string:
1610       case ident:{
1611         ;
1612         break;
1613         }
1614       default:
1615         jj_la1[42= jj_gen;
1616         break label_14;
1617       }
1618       switch (jj_nt.kind) {
1619       case ident:{
1620         nameTok = jj_consume_token(ident);
1621         break;
1622         }
1623       case string:{
1624         nameTok = jj_consume_token(string);
1625         break;
1626         }
1627       default:
1628         jj_la1[43= jj_gen;
1629         jj_consume_token(-1);
1630         throw new ParseException();
1631       }
1632       jj_consume_token(assign);
1633 newAttrName = stringValueOf(nameTok);
1634       switch (jj_nt.kind) {
1635       case integer:
1636       case string:
1637       case bool:
1638       case ident:
1639       case floatingPoint:
1640       case leftSquare:{
1641         // a static attribute value
1642               attrVal = AttrVal();
1643 switch(((IntegerattrVal.first).intValue()) {
1644           case string:
1645             blockBuffer.append(
1646               "      val = ");
1647             appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
1648             blockBuffer.append(";" + nl);
1649             break;
1650           case integer:
1651             blockBuffer.append("      try { " +
1652               "val = java.lang.Long.valueOf(");
1653             appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
1654             blockBuffer.append("); }" +
1655               nl + "      catch(java.lang.NumberFormatException e) { }" + nl
1656             );
1657             break;
1658           case ident:
1659             blockBuffer.append(
1660               "      val = ");
1661             appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
1662             blockBuffer.append(";" + nl);
1663             break;
1664           case bool:
1665             blockBuffer.append(
1666               "      val = java.lang.Boolean.valueOf(");
1667             appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
1668             blockBuffer.append(");" + nl);
1669             break;
1670           case floatingPoint:
1671             blockBuffer.append("      try { " +
1672               "val = java.lang.Double.valueOf(");
1673             appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
1674             blockBuffer.append("); }" +
1675               nl + "      catch(java.lang.NumberFormatException e) { }" + nl
1676             );
1677             break;
1678           default:
1679             blockBuffer.append(
1680               "      val = \u005c"\u005c";" + nl
1681             );
1682             break;
1683         // switch
1684 
1685         blockBuffer.append("      features.put(");
1686         appendJavaStringLiteral(blockBuffer, newAttrName);
1687         blockBuffer.append(", val);");
1688         blockBuffer.append(nl);
1689         break;
1690         }
1691       case colon:{
1692         jj_consume_token(colon);
1693         nameTok = jj_consume_token(ident);
1694 existingAnnotSetName = nameTok.image + "ExistingAnnots";
1695           if(checkLabel && ! bindingNameSet.contains(nameTok.image))
1696             {if (truethrow(
1697               new ParseException(errorMsgPrefix(nameTok)+
1698                 "unknown label in RHS action(2): " + nameTok.image
1699               )
1700             );}
1701 
1702           blockBuffer.append(
1703             "      { // need a block for the existing annot set" + nl +
1704             "        gate.AnnotationSet " + existingAnnotSetName +
1705             " = (gate.AnnotationSet)bindings.get(");
1706           appendJavaStringLiteral(blockBuffer, nameTok.image);
1707           blockBuffer.append("); " + nl +
1708             "        java.lang.Object existingFeatureValue;" + nl);
1709         switch (jj_nt.kind) {
1710         case period:{
1711           jj_consume_token(period);
1712           switch (jj_nt.kind) {
1713           case ident:{
1714             nameTok = jj_consume_token(ident);
1715             break;
1716             }
1717           case string:{
1718             nameTok = jj_consume_token(string);
1719             break;
1720             }
1721           default:
1722             jj_la1[44= jj_gen;
1723             jj_consume_token(-1);
1724             throw new ParseException();
1725           }
1726 existingAnnotType = stringValueOf(nameTok);
1727           switch (jj_nt.kind) {
1728           case period:{
1729             opTok = jj_consume_token(period);
1730             break;
1731             }
1732           case metaPropOp:{
1733             opTok = jj_consume_token(metaPropOp);
1734             break;
1735             }
1736           default:
1737             jj_la1[45= jj_gen;
1738             jj_consume_token(-1);
1739             throw new ParseException();
1740           }
1741           switch (jj_nt.kind) {
1742           case ident:{
1743             nameTok = jj_consume_token(ident);
1744             break;
1745             }
1746           case string:{
1747             nameTok = jj_consume_token(string);
1748             break;
1749             }
1750           default:
1751             jj_la1[46= jj_gen;
1752             jj_consume_token(-1);
1753             throw new ParseException();
1754           }
1755 opName = opTok.image; existingAttrName = stringValueOf(nameTok);
1756 blockBuffer.append(
1757     "        if (" + existingAnnotSetName + " != null) {" + nl +
1758     "          gate.AnnotationSet existingAnnots = " + nl +
1759     "          " + existingAnnotSetName + ".get(");
1760               appendJavaStringLiteral(blockBuffer, existingAnnotType);
1761               blockBuffer.append(");" + nl +
1762     "          if (existingAnnots != null) {" + nl +
1763     "            java.util.Iterator iter = existingAnnots.iterator();" + nl +
1764     "            while(iter.hasNext()) {" + nl +
1765     "              gate.Annotation existingA = (gate.Annotation) iter.next();" + nl);
1766 
1767               // handle :bind.Type@string, :bind.Type@cleanString and :bind.Type@length
1768               if(opName.equals("@"&& existingAttrName.equals("string"|| existingAttrName.equals("cleanString"|| existingAttrName.equals("length") ) ) {
1769                 blockBuffer.append(
1770     "              int from = existingA.getStartNode().getOffset().intValue();" + nl +
1771     "              int to   = existingA.getEndNode().getOffset().intValue();" + nl +
1772     "              existingFeatureValue = doc.getContent().toString().substring(from,to);" + nl
1773                 );
1774                 if existingAttrName.equals("cleanString") ) {
1775                   blockBuffer.append(
1776     "                 existingFeatureValue = gate.Utils.cleanString((String)existingFeatureValue);" + nl
1777                   );
1778                 }
1779                 if existingAttrName.equals("length") ) {
1780                   blockBuffer.append(
1781     "                 existingFeatureValue = (long)to - (long)from;" + nl
1782                   );
1783                 }
1784               else {
1785                 blockBuffer.append("existingFeatureValue = existingA.getFeatures().get(");
1786                 appendJavaStringLiteral(blockBuffer, existingAttrName);
1787                 blockBuffer.append(");" + nl);
1788               }
1789 
1790               blockBuffer.append(
1791     "              if(existingFeatureValue != null) {" + nl +
1792     "                features.put(");
1793               appendJavaStringLiteral(blockBuffer, newAttrName);
1794               blockBuffer.append(", existingFeatureValue);" + nl +
1795     "                break;" + nl +
1796     "              }" + nl +
1797     "            } // while" + nl +
1798     "          } // if not null" + nl +
1799     "        } // if not null" + nl);
1800           break;
1801           }
1802         case metaPropOp:{
1803           opTok = jj_consume_token(metaPropOp);
1804           nameTok = jj_consume_token(ident);
1805 opName = opTok.image; existingAttrName = nameTok.image;
1806 if(opName.equals("@"&& existingAttrName.equals("string"|| existingAttrName.equals("cleanString"|| existingAttrName.equals("length") ) ) {
1807                 blockBuffer.append(
1808     "        if (" + existingAnnotSetName + " != null) {" + nl +
1809     "          int from = " + existingAnnotSetName +".firstNode().getOffset().intValue();" + nl +
1810     "          int to   = " + existingAnnotSetName +".lastNode().getOffset().intValue();" + nl +
1811     "          existingFeatureValue = doc.getContent().toString().substring(from,to);" + nl
1812                 );
1813                 if existingAttrName.equals("cleanString") ) {
1814                   blockBuffer.append(
1815     "                 existingFeatureValue = ((String)existingFeatureValue).replaceAll(\u005c"\u005c\u005c\u005c\u005cs+\u005c", \u005c" \u005c").trim();" + nl
1816                   );
1817                 }
1818                 if existingAttrName.equals("length") ) {
1819                   blockBuffer.append(
1820     "                 existingFeatureValue = (long)to - (long)from;" + nl
1821                   );
1822                 }
1823                 blockBuffer.append(
1824     "          if(existingFeatureValue != null) {" + nl +
1825     "            features.put(");
1826                 appendJavaStringLiteral(blockBuffer, newAttrName);
1827                 blockBuffer.append(", existingFeatureValue);" + nl +
1828     "          }" + nl +
1829     "        } // if not null" + nl);
1830               }
1831               else {
1832                 {if (truethrow new ParseException(errorMsgPrefix(nameTok+
1833                         "Unsupported RHS meta-property " + nameTok.image);}
1834               }
1835           break;
1836           }
1837         default:
1838           jj_la1[47= jj_gen;
1839           jj_consume_token(-1);
1840           throw new ParseException();
1841         }
1842 blockBuffer.append(
1843   "      } // block for existing annots" + nl
1844           );
1845         break;
1846         }
1847       default:
1848         jj_la1[48= jj_gen;
1849         jj_consume_token(-1);
1850         throw new ParseException();
1851       }
1852       switch (jj_nt.kind) {
1853       case comma:{
1854         jj_consume_token(comma);
1855         break;
1856         }
1857       default:
1858         jj_la1[49= jj_gen;
1859         ;
1860       }
1861     }
1862     jj_consume_token(rightBrace);
1863 appendAnnotationAdd(blockBuffer, newAnnotType, annotSetName);
1864     block[1= blockBuffer.toString();
1865     {if ("" != nullreturn block;}
1866     throw new Error("Missing return statement in function");
1867   }
1868 
1869   void appendSpecials(Token tok, StringBuffer blockthrows ParseException {if(tok != null) {
1870     // each specialToken points to its *preceding* one, so we must recursively
1871     // append the previous special (which will recursively append its
1872     // predecessor, etc.) before appending the current one.
1873     appendSpecials(tok.specialToken, block);
1874     block.append(tok.image);
1875   }
1876   }
1877 
1878   String ConsumeBlock() throws ParseException, ParseException {StringBuffer block = new StringBuffer()// to collect the block in
1879   int nesting = 1// the first "{" was consumed before we were called
1880 
1881   // this is the first 'proper' token in the block
1882   Token nextTok = getNextToken();
1883   if(nextTok.kind == EOF) {
1884     throw new ParseException(errorMsgPrefix(nextTok)
1885             "Unexpected EOF in Java block");
1886   }
1887 
1888   // for line numbers in the original Jape we want the first
1889   // token, normal or special (i.e. comments) so look back from
1890   // the first 'proper' token until we get back to the token
1891   // after the opening brace 
1892   Token blockStart = nextTok;
1893   while (blockStart.specialToken != null) {
1894     blockStart = blockStart.specialToken;
1895   }
1896 
1897   // append the info about the source Jape to the beginning
1898   // of the loaded source Java block
1899   block.append("  // JAPE Source: " + baseURL+":" + blockStart.beginLine + "\u005cn");
1900 
1901   // step through the code until the final brace
1902   while(nesting != 0) {
1903 
1904     // add in any preceding spaces and comments
1905     appendSpecials(nextTok.specialToken, block);
1906 
1907     // adjust nesting
1908     if(nextTok.image.equals("{")) {
1909       nesting++;
1910       /*Debug.pr(this, "ParseCpsl.ConsumeBlock: nesting = " + nesting);*/
1911     else if(nextTok.image.equals("}")) {
1912       nesting--;
1913       /*Debug.pr(this, "ParseCpsl.ConsumeBlock: nesting = " + nesting);*/
1914     }
1915 
1916     // add the image to the block string (but not the final "}")
1917     if(nesting > 0) {
1918       if(nextTok.kind == string) {
1919         // deal with escapes in string literals
1920         appendJavaStringLiteral(block,
1921             nextTok.image.substring(1, nextTok.image.length() 1));
1922       }
1923       else {
1924         block.append(nextTok.image);
1925       }
1926     }
1927     /*Debug.pr(this, "ParseCpsl.ConsumeBlock: nextTok.image = ^" +
1928              nextTok.image + "^");*/
1929 
1930         // if we haven't worked all the way out of the nesting
1931         // then get the next token
1932         if (nesting != 0) {
1933           nextTok = getNextToken();
1934           if(nextTok.kind == EOF) {
1935             throw new ParseException(errorMsgPrefix(nextTok)
1936                     "Unexpected EOF in Java block");
1937           }
1938         }
1939 
1940   // while
1941 
1942   /*Debug.pr(this, "ParseCpsl.ConsumeBlock: block = " + block.toString());*/
1943 
1944   return block.toString();
1945   }
1946 
1947   private boolean jj_2_1(int xla)
1948  {
1949     jj_la = xla; jj_lastpos = jj_scanpos = token;
1950     try return !jj_3_1()}
1951     catch(LookaheadSuccess ls) { return true}
1952     finally jj_save(0, xla)}
1953   }
1954 
1955   private boolean jj_2_2(int xla)
1956  {
1957     jj_la = xla; jj_lastpos = jj_scanpos = token;
1958     try return !jj_3_2()}
1959     catch(LookaheadSuccess ls) { return true}
1960     finally jj_save(1, xla)}
1961   }
1962 
1963   private boolean jj_3R_27()
1964  {
1965     if (jj_scan_token(pling)) return true;
1966     return false;
1967   }
1968 
1969   private boolean jj_3R_26()
1970  {
1971     if (jj_3R_15()) return true;
1972     return false;
1973   }
1974 
1975   private boolean jj_3R_25()
1976  {
1977     Token xsp;
1978     xsp = jj_scanpos;
1979     if (jj_3R_27()) jj_scanpos = xsp;
1980     xsp = jj_scanpos;
1981     if (jj_scan_token(49)) {
1982     jj_scanpos = xsp;
1983     if (jj_scan_token(47)) return true;
1984     }
1985     return false;
1986   }
1987 
1988   private boolean jj_3R_23()
1989  {
1990     if (jj_scan_token(string)) return true;
1991     return false;
1992   }
1993 
1994   private boolean jj_3R_21()
1995  {
1996     if (jj_scan_token(leftBracket)) return true;
1997     if (jj_3R_24()) return true;
1998     return false;
1999   }
2000 
2001   private boolean jj_3R_24()
2002  {
2003     Token xsp;
2004     if (jj_3R_26()) return true;
2005     while (true) {
2006       xsp = jj_scanpos;
2007       if (jj_3R_26()) { jj_scanpos = xsp; break}
2008     }
2009     return false;
2010   }
2011 
2012   private boolean jj_3R_19()
2013  {
2014     if (jj_3R_21()) return true;
2015     return false;
2016   }
2017 
2018   private boolean jj_3R_18()
2019  {
2020     if (jj_3R_20()) return true;
2021     return false;
2022   }
2023 
2024   private boolean jj_3R_16()
2025  {
2026     if (jj_scan_token(colon)) return true;
2027     if (jj_scan_token(ident)) return true;
2028     if (jj_scan_token(leftBrace)) return true;
2029     return false;
2030   }
2031 
2032   private boolean jj_3R_17()
2033  {
2034     if (jj_scan_token(ident)) return true;
2035     return false;
2036   }
2037 
2038   private boolean jj_3R_22()
2039  {
2040     if (jj_scan_token(leftBrace)) return true;
2041     if (jj_3R_25()) return true;
2042     return false;
2043   }
2044 
2045   private boolean jj_3R_15()
2046  {
2047     Token xsp;
2048     xsp = jj_scanpos;
2049     if (jj_3R_17()) {
2050     jj_scanpos = xsp;
2051     if (jj_3R_18()) {
2052     jj_scanpos = xsp;
2053     if (jj_3R_19()) return true;
2054     }
2055     }
2056     return false;
2057   }
2058 
2059   private boolean jj_3_2()
2060  {
2061     if (jj_3R_16()) return true;
2062     return false;
2063   }
2064 
2065   private boolean jj_3R_20()
2066  {
2067     Token xsp;
2068     xsp = jj_scanpos;
2069     if (jj_3R_22()) {
2070     jj_scanpos = xsp;
2071     if (jj_3R_23()) return true;
2072     }
2073     return false;
2074   }
2075 
2076   private boolean jj_3_1()
2077  {
2078     if (jj_3R_15()) return true;
2079     return false;
2080   }
2081 
2082   /** Generated Token Manager. */
2083   public ParseCpslTokenManager token_source;
2084   SimpleCharStream jj_input_stream;
2085   /** Current token. */
2086   public Token token;
2087   /** Next token. */
2088   public Token jj_nt;
2089   private Token jj_scanpos, jj_lastpos;
2090   private int jj_la;
2091   private int jj_gen;
2092   final private int[] jj_la1 = new int[50];
2093   static private int[] jj_la1_0;
2094   static private int[] jj_la1_1;
2095   static private int[] jj_la1_2;
2096   static {
2097       jj_la1_init_0();
2098       jj_la1_init_1();
2099       jj_la1_init_2();
2100    }
2101    private static void jj_la1_init_0() {
2102       jj_la1_0 = new int[] {0x800,0xe00000,0xe00000,0x1000000,0x2000,0x1f01000,0x6000000,0x0,0x0,0x0,0x0,0x6000000,0x38000000,0x38000000,0x100000,0x40000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000,0x0,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
2103    }
2104    private static void jj_la1_init_1() {
2105       jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x28000,0x28000,0x20000,0x30000,0x0,0x0,0x0,0x0,0x0,0x2120000,0xa028000,0x800000,0xa028000,0xa028000,0x1000000,0x2008000,0x20000001,0x20008,0x100000,0x1000000,0x20000001,0x0,0x28000,0x2028000,0x420004,0x420004,0x28000,0x78008,0x20078008,0x20000,0x1000000,0x1000000,0x2120000,0x100000,0x28000,0x28000,0x28000,0x28000,0x400004,0x28000,0x400004,0x20178008,0x1000000,};
2106    }
2107    private static void jj_la1_init_2() {
2108       jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
2109    }
2110   final private JJCalls[] jj_2_rtns = new JJCalls[2];
2111   private boolean jj_rescan = false;
2112   private int jj_gc = 0;
2113 
2114   /** Constructor with InputStream. */
2115   public ParseCpsl(java.io.InputStream stream) {
2116      this(stream, null);
2117   }
2118   /** Constructor with InputStream and supplied encoding */
2119   public ParseCpsl(java.io.InputStream stream, String encoding) {
2120     try jj_input_stream = new SimpleCharStream(stream, encoding, 11)catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e)}
2121     token_source = new ParseCpslTokenManager(jj_input_stream);
2122     token = new Token();
2123     token.next = jj_nt = token_source.getNextToken();
2124     jj_gen = 0;
2125     for (int i = 0; i < 50; i++jj_la1[i= -1;
2126     for (int i = 0; i < jj_2_rtns.length; i++jj_2_rtns[inew JJCalls();
2127   }
2128 
2129   /** Reinitialise. */
2130   public void ReInit(java.io.InputStream stream) {
2131      ReInit(stream, null);
2132   }
2133   /** Reinitialise. */
2134   public void ReInit(java.io.InputStream stream, String encoding) {
2135     try jj_input_stream.ReInit(stream, encoding, 11)catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e)}
2136     token_source.ReInit(jj_input_stream);
2137     token = new Token();
2138     token.next = jj_nt = token_source.getNextToken();
2139     jj_gen = 0;
2140     for (int i = 0; i < 50; i++jj_la1[i= -1;
2141     for (int i = 0; i < jj_2_rtns.length; i++jj_2_rtns[inew JJCalls();
2142   }
2143 
2144   /** Constructor. */
2145   public ParseCpsl(java.io.Reader stream) {
2146     jj_input_stream = new SimpleCharStream(stream, 11);
2147     token_source = new ParseCpslTokenManager(jj_input_stream);
2148     token = new Token();
2149     token.next = jj_nt = token_source.getNextToken();
2150     jj_gen = 0;
2151     for (int i = 0; i < 50; i++jj_la1[i= -1;
2152     for (int i = 0; i < jj_2_rtns.length; i++jj_2_rtns[inew JJCalls();
2153   }
2154 
2155   /** Reinitialise. */
2156   public void ReInit(java.io.Reader stream) {
2157     jj_input_stream.ReInit(stream, 11);
2158     token_source.ReInit(jj_input_stream);
2159     token = new Token();
2160     token.next = jj_nt = token_source.getNextToken();
2161     jj_gen = 0;
2162     for (int i = 0; i < 50; i++jj_la1[i= -1;
2163     for (int i = 0; i < jj_2_rtns.length; i++jj_2_rtns[inew JJCalls();
2164   }
2165 
2166   /** Constructor with generated Token Manager. */
2167   public ParseCpsl(ParseCpslTokenManager tm) {
2168     token_source = tm;
2169     token = new Token();
2170     token.next = jj_nt = token_source.getNextToken();
2171     jj_gen = 0;
2172     for (int i = 0; i < 50; i++jj_la1[i= -1;
2173     for (int i = 0; i < jj_2_rtns.length; i++jj_2_rtns[inew JJCalls();
2174   }
2175 
2176   /** Reinitialise. */
2177   public void ReInit(ParseCpslTokenManager tm) {
2178     token_source = tm;
2179     token = new Token();
2180     token.next = jj_nt = token_source.getNextToken();
2181     jj_gen = 0;
2182     for (int i = 0; i < 50; i++jj_la1[i= -1;
2183     for (int i = 0; i < jj_2_rtns.length; i++jj_2_rtns[inew JJCalls();
2184   }
2185 
2186   private Token jj_consume_token(int kindthrows ParseException {
2187     Token oldToken = token;
2188     if ((token = jj_nt).next != nulljj_nt = jj_nt.next;
2189     else jj_nt = jj_nt.next = token_source.getNextToken();
2190     if (token.kind == kind) {
2191       jj_gen++;
2192       if (++jj_gc > 100) {
2193         jj_gc = 0;
2194         for (int i = 0; i < jj_2_rtns.length; i++) {
2195           JJCalls c = jj_2_rtns[i];
2196           while (c != null) {
2197             if (c.gen < jj_genc.first = null;
2198             c = c.next;
2199           }
2200         }
2201       }
2202       return token;
2203     }
2204     jj_nt = token;
2205     token = oldToken;
2206     jj_kind = kind;
2207     throw generateParseException();
2208   }
2209 
2210   @SuppressWarnings("serial")
2211   static private final class LookaheadSuccess extends java.lang.Error { }
2212   final private LookaheadSuccess jj_ls = new LookaheadSuccess();
2213   private boolean jj_scan_token(int kind) {
2214     if (jj_scanpos == jj_lastpos) {
2215       jj_la--;
2216       if (jj_scanpos.next == null) {
2217         jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
2218       else {
2219         jj_lastpos = jj_scanpos = jj_scanpos.next;
2220       }
2221     else {
2222       jj_scanpos = jj_scanpos.next;
2223     }
2224     if (jj_rescan) {
2225       int i = 0; Token tok = token;
2226       while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
2227       if (tok != nulljj_add_error_token(kind, i);
2228     }
2229     if (jj_scanpos.kind != kindreturn true;
2230     if (jj_la == && jj_scanpos == jj_lastposthrow jj_ls;
2231     return false;
2232   }
2233 
2234 
2235 /** Get the next Token. */
2236   final public Token getNextToken() {
2237     if ((token = jj_nt).next != nulljj_nt = jj_nt.next;
2238     else jj_nt = jj_nt.next = token_source.getNextToken();
2239     jj_gen++;
2240     return token;
2241   }
2242 
2243 /** Get the specific Token. */
2244   final public Token getToken(int index) {
2245     Token t = token;
2246     for (int i = 0; i < index; i++) {
2247       if (t.next != nullt = t.next;
2248       else t = t.next = token_source.getNextToken();
2249     }
2250     return t;
2251   }
2252 
2253   private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
2254   private int[] jj_expentry;
2255   private int jj_kind = -1;
2256   private int[] jj_lasttokens = new int[100];
2257   private int jj_endpos;
2258 
2259   private void jj_add_error_token(int kind, int pos) {
2260     if (pos >= 100return;
2261     if (pos == jj_endpos + 1) {
2262       jj_lasttokens[jj_endpos++= kind;
2263     else if (jj_endpos != 0) {
2264       jj_expentry = new int[jj_endpos];
2265       for (int i = 0; i < jj_endpos; i++) {
2266         jj_expentry[i= jj_lasttokens[i];
2267       }
2268       jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
2269         int[] oldentry = (int[])(it.next());
2270         if (oldentry.length == jj_expentry.length) {
2271           for (int i = 0; i < jj_expentry.length; i++) {
2272             if (oldentry[i!= jj_expentry[i]) {
2273               continue jj_entries_loop;
2274             }
2275           }
2276           jj_expentries.add(jj_expentry);
2277           break jj_entries_loop;
2278         }
2279       }
2280       if (pos != 0jj_lasttokens[(jj_endpos = pos1= kind;
2281     }
2282   }
2283 
2284   /** Generate ParseException. */
2285   public ParseException generateParseException() {
2286     jj_expentries.clear();
2287     boolean[] la1tokens = new boolean[73];
2288     if (jj_kind >= 0) {
2289       la1tokens[jj_kindtrue;
2290       jj_kind = -1;
2291     }
2292     for (int i = 0; i < 50; i++) {
2293       if (jj_la1[i== jj_gen) {
2294         for (int j = 0; j < 32; j++) {
2295           if ((jj_la1_0[i(1<<j)) != 0) {
2296             la1tokens[jtrue;
2297           }
2298           if ((jj_la1_1[i(1<<j)) != 0) {
2299             la1tokens[32+jtrue;
2300           }
2301           if ((jj_la1_2[i(1<<j)) != 0) {
2302             la1tokens[64+jtrue;
2303           }
2304         }
2305       }
2306     }
2307     for (int i = 0; i < 73; i++) {
2308       if (la1tokens[i]) {
2309         jj_expentry = new int[1];
2310         jj_expentry[0= i;
2311         jj_expentries.add(jj_expentry);
2312       }
2313     }
2314     jj_endpos = 0;
2315     jj_rescan_token();
2316     jj_add_error_token(00);
2317     int[][] exptokseq = new int[jj_expentries.size()][];
2318     for (int i = 0; i < jj_expentries.size(); i++) {
2319       exptokseq[i= jj_expentries.get(i);
2320     }
2321     return new ParseException(token, exptokseq, tokenImage);
2322   }
2323 
2324   /** Enable tracing. */
2325   final public void enable_tracing() {
2326   }
2327 
2328   /** Disable tracing. */
2329   final public void disable_tracing() {
2330   }
2331 
2332   private void jj_rescan_token() {
2333     jj_rescan = true;
2334     for (int i = 0; i < 2; i++) {
2335     try {
2336       JJCalls p = jj_2_rtns[i];
2337       do {
2338         if (p.gen > jj_gen) {
2339           jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
2340           switch (i) {
2341             case 0: jj_3_1()break;
2342             case 1: jj_3_2()break;
2343           }
2344         }
2345         p = p.next;
2346       while (p != null);
2347       catch(LookaheadSuccess ls) { }
2348     }
2349     jj_rescan = false;
2350   }
2351 
2352   private void jj_save(int index, int xla) {
2353     JJCalls p = jj_2_rtns[index];
2354     while (p.gen > jj_gen) {
2355       if (p.next == null) { p = p.next = new JJCalls()break}
2356       p = p.next;
2357     }
2358     p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
2359   }
2360 
2361   static final class JJCalls {
2362     int gen;
2363     Token first;
2364     int arg;
2365     JJCalls next;
2366   }
2367 
2368 // class ParseCpsl