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