All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gate.jape.parser.ParseCpsl Maven / Gradle / Ivy

Go to download

ANNIE is a general purpose information extraction system that provides the building blocks of many other GATE applications.

There is a newer version: 9.1
Show newest version
/* ParseCpsl.java */
/* Generated By:JavaCC: Do not edit this line. ParseCpsl.java */
package gate.jape.parser;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import gate.Factory;
import gate.util.*;
import gate.jape.*;
import gate.jape.constraint.*;
import gate.event.*;

import org.apache.log4j.Logger;


/**
  * A parser for the CPSL language. Generated using JavaCC.
  * @author Hamish Cunningham
  */
public class ParseCpsl implements JapeConstants, ParseCpslConstants {

  private static final long serialVersionUID = -2754817550046808372L;

  private static final Logger log = Logger.getLogger(ParseCpsl.class);

  /** Construct from a URL and an encoding
    */
  public ParseCpsl(URL url, String encoding) throws IOException {
    this(url, encoding, new HashMap());
  }

  /** Construct from a URL and an encoding
    */
  public ParseCpsl(URL url, String encoding, Map existingMacros) throws IOException {
    this(url, encoding, existingMacros, new HashMap());
  }

  public ParseCpsl(URL url, String encoding, Map existingMacros, Map existingTemplates) throws IOException {
    this(new BomStrippingInputStreamReader(url.openStream(), encoding),
         existingMacros, existingTemplates);
    baseURL = url;
    this.encoding = encoding;
  }

  public ParseCpsl(java.io.Reader stream, Map existingMacros) {
    this(stream, existingMacros, new HashMap());
  }

  public ParseCpsl(java.io.Reader stream, Map existingMacros, Map existingTemplates) {
    this(stream);
    macrosMap = existingMacros;
    templatesMap = existingTemplates;
  }

  //StatusReporter Implementation
  public void addStatusListener(StatusListener listener){
    myStatusListeners.add(listener);
  }
  public void removeStatusListener(StatusListener listener){
    myStatusListeners.remove(listener);
  }
  protected void fireStatusChangedEvent(String text){
    Iterator listenersIter = myStatusListeners.iterator();
    while(listenersIter.hasNext())
      listenersIter.next().statusChanged(text);
  }

  protected SinglePhaseTransducer createSinglePhaseTransducer(String name){
    try {
      Constructor c = sptClass.getConstructor
          (String.class);
      return c.newInstance(name);
    } catch (NoSuchMethodException e) { // Shouldn't happen
      throw new RuntimeException(e);
    } catch (IllegalArgumentException e) { // Shouldn't happen
      throw new RuntimeException(e);
    } catch (InstantiationException e) { // Shouldn't happen
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) { // Shouldn't happen
      throw new RuntimeException(e);
    } catch (InvocationTargetException e) { // Happens if the constructor throws an exception
      throw new RuntimeException(e);
    }
  }

  protected ParseCpsl spawn(URL sptURL) throws IOException{
    ParseCpsl newParser = new ParseCpsl(sptURL, encoding, macrosMap, templatesMap);
    newParser.setSptClass(this.sptClass);
    return newParser;
  }

  protected void finishSPT(SinglePhaseTransducer t) throws ParseException {
    if(ruleNumber == 0)
      throw(new ParseException("no rules defined in transducer " + t.getName()));
    t.setBaseURL(baseURL);
  }

  protected void finishBPE(BasicPatternElement bpe) {
  }

  /**
   * Attempt to parse a multi phase transducer from the current file.  This
   * method ensures that the JAPE file reader is properly closed when the
   * method completes, whether it completes successfully or throws an
   * exception.
   */
  public MultiPhaseTransducer MultiPhaseTransducer() throws ParseException {
    try {
      return _MultiPhaseTransducer();
    }
    finally {
      // this is a bit nasty but I couldn't find a better way to get at the
      // underlying Reader
      if(jj_input_stream.inputStream != null) {
        try {
          jj_input_stream.inputStream.close();
        }
        catch(IOException e) {
          log.warn("Couldn't close input stream while parsing " + baseURL, e);
        }
      }
    }
  }

  protected String toJavaIdentifier(String japeIdentifier) {
    return japeIdentifier.replace("-", "_");
  }

  /**
   * Normalise for quoted and unquoted strings - if the token is a string,
   * strip the quotes off its image, otherwise return the image as-is.
   */
  protected String stringValueOf(Token tok) {
    if(tok.kind == string) {
      // quoted string - strip the quotes
      return tok.image.substring(1, tok.image.length() - 1);
    } else {
      return tok.image;
    }
  }

  /**
   * Append the given string to the end of the given buffer as a Java string
   * literal.  If str is null, we append the four
   * characters n, u, l, l.  Otherwise, we append the contents of str surrounded
   * by double quotes, except that characters in str are escaped as necessary
   * to be a legal Java string literal: backspace, formfeed, tab, newline and
   * return are replaced by their escape sequences \b, \f, etc.; single and double
   * quote and backslash are preceded by an extra backslash; other non-ASCII
   * and non-printing characters are rendered as Unicode escapes (backslash-u
   * followed by four hex digits).
   */
  protected void appendJavaStringLiteral(StringBuffer buf, String str) {
   if(str == null) {
     buf.append("null");
   }
   else {
     Formatter formatter = null;
     buf.append("\"");
     for(int i = 0; i < str.length(); i++) {
       char c = str.charAt(i);
       switch(c) {
         case '\b':
           buf.append("\\b");
           break;
         case '\f':
           buf.append("\\f");
           break;
         case '\n':
           buf.append("\\n");
           break;
         case '\r':
           buf.append("\\r");
           break;
         case '\t':
           buf.append("\\t");
           break;
         case '\"':
           buf.append("\\\"");
           break;
         case '\'':
           buf.append("\\\'");
           break;
         case '\\':
           buf.append("\\\\");
           break;

         default:
           if(c < 32 || c > 127) {
             if(formatter == null) formatter = new Formatter(buf);
             formatter.format("\\u%04X", Integer.valueOf(c));
           }
           else {
             buf.append(c);
           }
           break;
       }
     }
     buf.append("\"");
   }
  }

  protected void appendAnnotationAdd(StringBuffer blockBuffer, String newAnnotType, String annotSetName)
  {
      String nl = Strings.getNl();
      blockBuffer.append("      if(outputAS == inputAS) { // use nodes directly" + nl);
      blockBuffer.append("        outputAS.add(" + nl);
      blockBuffer.append("          " + annotSetName + ".firstNode(), ");
      blockBuffer.append(annotSetName + ".lastNode(), " + nl);
      blockBuffer.append("          ");
      appendJavaStringLiteral(blockBuffer, newAnnotType);
      blockBuffer.append(", features" + nl);
      blockBuffer.append("        );" + nl);
      blockBuffer.append("      }" + nl);
      blockBuffer.append("      else { // use offsets" + nl);
      blockBuffer.append("        try {" + nl);
      blockBuffer.append("          outputAS.add(" + nl);
      blockBuffer.append("            " + annotSetName + ".firstNode().getOffset(), ");
      blockBuffer.append(annotSetName + ".lastNode().getOffset(), " + nl);
      blockBuffer.append("            ");
      appendJavaStringLiteral(blockBuffer, newAnnotType);
      blockBuffer.append(", features" + nl);
      blockBuffer.append("          );" + nl);
      blockBuffer.append("        }" + nl);
      blockBuffer.append("        catch(gate.util.InvalidOffsetException ioe) {" + nl);
      blockBuffer.append("          throw new gate.util.GateRuntimeException(\"Invalid offset exception generated \" +" + nl);
      blockBuffer.append("               \"from offsets taken from same document!\");" + nl);
      blockBuffer.append("        }" + nl);
      blockBuffer.append("      }" + nl);
      blockBuffer.append("      // end of RHS assignment block");
  }

  /**
   * Takes a string containing ${key} placeholders and substitutes
   * in the corresponding values from the given map.  If there is
   * no value in the map for a particular placeholder it is left
   * un-resolved, i.e. given a template of "${key1}/${key2}" and
   * a values map of just [key1: "hello"], this method would return
   * "hello/${key2}".
   */
  protected Pair substituteTemplate(Token templateNameTok,
          Map values) throws ParseException {
    Pair template = templatesMap.get(templateNameTok.image);
    if(template == null) {
      throw new ParseException(errorMsgPrefix(templateNameTok) +
              "unknown template name " + templateNameTok.image);
    }
    Pair returnVal = null;
    Set unusedParams = new HashSet(values.keySet());
    if(((Integer)template.first).intValue() == string) {
      log.debug("Substituting template " + templateNameTok.image + " with map "
              + values + ". Template is " + template);
      StringBuffer buf = new StringBuffer();
      Matcher mat = Pattern.compile("\\$\\{([^\\}]+)\\}")
              .matcher((String)template.second);
      while(mat.find()) {
        String key = mat.group(1);
        if(values.containsKey(key)) {
          mat.appendReplacement(buf,
                  Matcher.quoteReplacement(String.valueOf(values.get(key))));
          unusedParams.remove(key);
        }
        else {
          mat.appendReplacement(buf, "\\${");
          buf.append(key);
          buf.append("}");
        }
      }
      mat.appendTail(buf);

      returnVal = new Pair();
      returnVal.first = Integer.valueOf(string);
      returnVal.second = buf.toString();
      log.debug("Template substitution produced " + returnVal.second);
    }
    else {
      returnVal = template;
    }

    // check that there were no invalid parameters
    if(!unusedParams.isEmpty()) {
      throw new ParseException(errorMsgPrefix(templateNameTok) +
              "invalid parameters " + unusedParams +
              " for template " + templateNameTok.image);
    }
    else {
      return returnVal;
    }
  }

  public void setBaseURL (URL newURL) {
    baseURL = newURL;
  }

  public void setEncoding (String newEncoding) {
    encoding = newEncoding;
  }

  public void setSptClass(Class sptClass) {
    this.sptClass = sptClass;
  }

  private String errorMsgPrefix(Token t) {
    return ((baseURL != null) ? baseURL.toExternalForm() : "(No URL)")+
      ( (t == null) ? " " :
          ":"+t.beginLine+":"+t.beginColumn+": ");
   }

  private transient List myStatusListeners = new LinkedList();

  /** Position of the current rule */
  private int ruleNumber;

  /** A list of all the bindings we made this time, for checking
    * the RHS during parsing.
    */
  private Set bindingNameSet = null;

  /** A table of macro definitions. */
  protected Map macrosMap;

  /**
   * A table of template definitions. Keys are template names,
   * values are Pairs of token kind and value, as returned by
   * AttrVal.
   */
  protected Map templatesMap;

  protected URL baseURL;
  protected String encoding;

  protected Class sptClass =
      SinglePhaseTransducer.class;

  protected SinglePhaseTransducer curSPT;

//////////////
// the grammar
//////////////
  final public 
MultiPhaseTransducer _MultiPhaseTransducer() throws ParseException {// macrosMap = new HashMap();
  SinglePhaseTransducer s = null;
  MultiPhaseTransducer m = new MultiPhaseTransducer();
  m.setBaseURL(baseURL);
  Token mptNameTok = null;
  Token phaseNameTok = null;
  String javaimportblock = null;
  String controllerstartedblock = null;
  String controllerfinishedblock = null;
  String controllerabortedblock = null;
  boolean haveControllerStartedBlock = false;
  boolean haveControllerFinishedBlock = false;
  boolean haveControllerAbortedBlock = false;
    switch (jj_nt.kind) {
    case multiphase:{
      jj_consume_token(multiphase);
      mptNameTok = jj_consume_token(ident);
m.setName(mptNameTok.image);
      break;
      }
    default:
      jj_la1[0] = jj_gen;
      ;
    }
    switch (jj_nt.kind) {
    case javaimport:
    case controllerstarted:
    case controllerfinished:
    case controlleraborted:
    case phase:{
      javaimportblock = JavaImportBlock();
      label_1:
      while (true) {
        switch (jj_nt.kind) {
        case controllerstarted:
        case controllerfinished:
        case controlleraborted:{
          ;
          break;
          }
        default:
          jj_la1[1] = jj_gen;
          break label_1;
        }
        switch (jj_nt.kind) {
        case controllerstarted:{
          controllerstartedblock = ControllerStartedBlock();
if(haveControllerStartedBlock)
               {if (true) throw new ParseException("Only one ControllerStarted block allowed");}
             else
               haveControllerStartedBlock = true;
          break;
          }
        case controllerfinished:{
          controllerfinishedblock = ControllerFinishedBlock();
if(haveControllerFinishedBlock)
               {if (true) throw new ParseException("Only one ControllerFinished block allowed");}
             else
               haveControllerFinishedBlock = true;
          break;
          }
        case controlleraborted:{
          controllerabortedblock = ControllerAbortedBlock();
if(haveControllerAbortedBlock)
               {if (true) throw new ParseException("Only one ControllerAborted block allowed");}
             else
               haveControllerAbortedBlock = true;
          break;
          }
        default:
          jj_la1[2] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
      }
      label_2:
      while (true) {
        try {
          s = SinglePhaseTransducer(javaimportblock);
m.addPhase(s.getName(), s);
                s.setBaseURL(baseURL);
                s.setControllerEventBlocks(controllerstartedblock,
                  controllerfinishedblock,controllerabortedblock,javaimportblock);
              // only the first SPT in a MPT file should define/execute the blocks
              controllerstartedblock = null;
              controllerfinishedblock = null;
              controllerabortedblock = null;
        } catch (Throwable e) {
// try to wrap the exception with info about what file/resource
            // it occurred in.
            {if (true) throw(
              new ParseException("Cannot parse a phase in " +
                  baseURL + ": " + e.getMessage()
              ));}
        }
        switch (jj_nt.kind) {
        case phase:{
          ;
          break;
          }
        default:
          jj_la1[3] = jj_gen;
          break label_2;
        }
      }
      break;
      }
    case phases:{
      jj_consume_token(phases);
      label_3:
      while (true) {
        phaseNameTok = jj_consume_token(path);
ParseCpsl parser = null;

            // check file exists
            String sptPath = phaseNameTok.image + ".jape";
            URL sptURL = null;
            try{
              sptURL = new URL(baseURL, sptPath);
            }catch(MalformedURLException mue){
              {if (true) throw(new ParseException(errorMsgPrefix(phaseNameTok)+
                "Read error " + mue.toString()));}
            }

            // sptURL can never be null at this point because the only way that could
            // happen would be if an exception occurred above, but that would trigger
            // the ParserException above
            if(sptURL == null){
              {if (true) throw(new ParseException(errorMsgPrefix(phaseNameTok)+
                "Resource not found: base = " + baseURL.toString() +
                " path = " + sptPath
              ));}
            }

            // construct a parser and parse it
            fireStatusChangedEvent("Reading " + phaseNameTok.image + "...");
            try {
              parser = spawn(sptURL);
            } catch (IOException e) {
              {if (true) throw(
                new ParseException(errorMsgPrefix(phaseNameTok)+
                  "Cannot open URL " + sptURL.toExternalForm()
                )
              );}
            }

          // adding the resultant spt to m
          if(parser != null) {
           List phases = parser.MultiPhaseTransducer().getPhases();

            //s = parser.SinglePhaseTransducer();
            //if(s != null)
            //  m.addPhase(s.getName(), s);

            if(phases != null) {
              for(int i=0; i < phases.size(); i++) {
                m.addPhase(
                  phases.get(i).getName(),
                  phases.get(i)
                  );
              }
            }
          }
        switch (jj_nt.kind) {
        case path:{
          ;
          break;
          }
        default:
          jj_la1[4] = jj_gen;
          break label_3;
        }
      }
      break;
      }
    default:
      jj_la1[5] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    jj_consume_token(0);
//move this out of here so the input file gets closed properly
//    m.finish(); // swap the various JGL types for Java arrays
    {if ("" != null) return m;}
    throw new Error("Missing return statement in function");
  }

// _MultiPhaseTransducer
  final public 

SinglePhaseTransducer SinglePhaseTransducer(String javaimportblock) throws ParseException {ruleNumber = 0;
  Token phaseNameTok = null;
  String phaseName = null;
  Token inputTok = null;
  SinglePhaseTransducer t = null;
  Rule newRule = null;
  bindingNameSet = new HashSet();
  Token optionNameTok = null;
  Token optionValueTok = null;
    jj_consume_token(phase);
    phaseNameTok = jj_consume_token(ident);
phaseName = toJavaIdentifier(phaseNameTok.image);
    t = createSinglePhaseTransducer(phaseName); curSPT = t;
    label_4:
    while (true) {
      switch (jj_nt.kind) {
      case input:
      case option:{
        ;
        break;
        }
      default:
        jj_la1[6] = jj_gen;
        break label_4;
      }
      switch (jj_nt.kind) {
      case input:{
        jj_consume_token(input);
        label_5:
        while (true) {
          switch (jj_nt.kind) {
          case string:
          case ident:{
            ;
            break;
            }
          default:
            jj_la1[7] = jj_gen;
            break label_5;
          }
          switch (jj_nt.kind) {
          case ident:{
            inputTok = jj_consume_token(ident);
            break;
            }
          case string:{
            inputTok = jj_consume_token(string);
            break;
            }
          default:
            jj_la1[8] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
          }
t.addInput(stringValueOf(inputTok));
        }
        break;
        }
      case option:{
        jj_consume_token(option);
        label_6:
        while (true) {
          switch (jj_nt.kind) {
          case ident:{
            ;
            break;
            }
          default:
            jj_la1[9] = jj_gen;
            break label_6;
          }
          optionNameTok = jj_consume_token(ident);
          jj_consume_token(assign);
          switch (jj_nt.kind) {
          case ident:{
            optionValueTok = jj_consume_token(ident);
            break;
            }
          case bool:{
            optionValueTok = jj_consume_token(bool);
            break;
            }
          default:
            jj_la1[10] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
          }
t.setOption(optionNameTok.image, optionValueTok.image);

          // control
          if(optionNameTok.image.equalsIgnoreCase("control")) {
            if(optionValueTok.image.equalsIgnoreCase("appelt"))
              t.setRuleApplicationStyle(APPELT_STYLE);
            else if(optionValueTok.image.equalsIgnoreCase("first"))
              t.setRuleApplicationStyle(FIRST_STYLE);
            else if(optionValueTok.image.equalsIgnoreCase("brill"))
              t.setRuleApplicationStyle(BRILL_STYLE);
            else if(optionValueTok.image.equalsIgnoreCase("once"))
              t.setRuleApplicationStyle(ONCE_STYLE);
            else if(optionValueTok.image.equalsIgnoreCase("all"))
              t.setRuleApplicationStyle(ALL_STYLE);
            else
              System.err.println(errorMsgPrefix(optionValueTok)+
                "ignoring unknown control strategy " + option +
                " (should be brill, appelt, first, once or all)"
              );
          } // control
          else if(optionNameTok.image.equalsIgnoreCase("debug")) {
            if(optionValueTok.image.equalsIgnoreCase("true") ||
               optionValueTok.image.equalsIgnoreCase("yes") ||
               optionValueTok.image.equalsIgnoreCase("y"))
              t.setDebugMode(true);
            else t.setDebugMode(false);
          }
          else if(optionNameTok.image.equalsIgnoreCase("matchGroup")) {
            if(optionValueTok.image.equalsIgnoreCase("true") ||
               optionValueTok.image.equalsIgnoreCase("yes") ||
               optionValueTok.image.equalsIgnoreCase("y"))
              t.setMatchGroupMode(true);
            else t.setMatchGroupMode(false);
          }
          else if(optionNameTok.image.equalsIgnoreCase("negationGrouping")) {
            if(optionValueTok.image.equalsIgnoreCase("false") ||
               optionValueTok.image.equalsIgnoreCase("no") ||
               optionValueTok.image.equalsIgnoreCase("n"))
              t.setNegationCompatMode(true);
            else t.setNegationCompatMode(false);
          }
        }
        break;
        }
      default:
        jj_la1[11] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
    }
    label_7:
    while (true) {
      switch (jj_nt.kind) {
      case rule:
      case macro:
      case template:{
        ;
        break;
        }
      default:
        jj_la1[12] = jj_gen;
        break label_7;
      }
      switch (jj_nt.kind) {
      case rule:{
        newRule = Rule(phaseName,javaimportblock);
t.addRule(newRule);
        break;
        }
      case macro:{
        MacroDef();
        break;
        }
      case template:{
        TemplateDef();
        break;
        }
      default:
        jj_la1[13] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
    }
finishSPT(t);
    {if ("" != null) return t;}
    throw new Error("Missing return statement in function");
  }

// SinglePhaseTransducer

// if there is a block, set the javaimports to the java block specified,
// otherwise set it to the default block
  final public String JavaImportBlock() throws ParseException {// default java imports
  String defaultimportblock =
      "import gate.*;\n" +
      "import java.io.*;\n" +
      "import java.util.*;\n" +
      "import gate.util.*;\n" +
      "import gate.jape.*;\n" +
      "import gate.creole.ontology.*;\n";
  String importblock = null;
    switch (jj_nt.kind) {
    case javaimport:{
      jj_consume_token(javaimport);
      jj_consume_token(leftBrace);
      importblock = ConsumeBlock();
      break;
      }
    default:
      jj_la1[14] = jj_gen;
      ;
    }
if(importblock != null) {
      {if ("" != null) return defaultimportblock+importblock;}
    } else  {
      {if ("" != null) return defaultimportblock;}
    }
    throw new Error("Missing return statement in function");
  }

  final public String ControllerStartedBlock() throws ParseException {String block = null;
    jj_consume_token(controllerstarted);
    jj_consume_token(leftBrace);
    block = ConsumeBlock();
{if ("" != null) return block;}
    throw new Error("Missing return statement in function");
  }

  final public String ControllerFinishedBlock() throws ParseException {String block = null;
    jj_consume_token(controllerfinished);
    jj_consume_token(leftBrace);
    block = ConsumeBlock();
{if ("" != null) return block;}
    throw new Error("Missing return statement in function");
  }

  final public String ControllerAbortedBlock() throws ParseException {String block = null;
    jj_consume_token(controlleraborted);
    jj_consume_token(leftBrace);
    block = ConsumeBlock();
{if ("" != null) return block;}
    throw new Error("Missing return statement in function");
  }

  final public Rule Rule(String phaseName, String currentImports) throws ParseException {Token ruleNameTok = null;
  String ruleName = null;
  Token priorityTok = null;
  int rulePriority = 0;
  LeftHandSide lhs = null;
  RightHandSide rhs = null;
  Rule newRule = null;
  // forget the labels we saw in the previous rule
  bindingNameSet.clear();
    jj_consume_token(rule);
    ruleNameTok = jj_consume_token(ident);
ruleName=toJavaIdentifier(ruleNameTok.image);
    switch (jj_nt.kind) {
    case priority:{
      jj_consume_token(priority);
      priorityTok = jj_consume_token(integer);
try { rulePriority=Integer.parseInt(priorityTok.image); }
      catch(NumberFormatException e) {
        System.err.println(errorMsgPrefix(priorityTok)+
          "bad priority spec(" + priorityTok.image +
          "), rule(" + ruleName + ") - treating as 0");
        rulePriority=0;
      }
      break;
      }
    default:
      jj_la1[15] = jj_gen;
      ;
    }
    lhs = LeftHandSide();
    jj_consume_token(72);
    rhs = RightHandSide(phaseName, ruleName, lhs, currentImports);
try {
      rhs.createActionClass();
    } catch(JapeException e) {
      /*Debug.pr(
        this, "ParseCpsl.Rule, FAILED rhs: " + rhs.getActionClassString()
      );*/
      {if (true) throw new ParseException(errorMsgPrefix(null)+
        "couldn't create rule RHS: " + e.toString());}
    }
    /*Debug.pr(this, "ParseCpsl.Rule, done rhs: " + rhs.getActionClassString());*/
    newRule = new Rule(ruleName, ruleNumber, rulePriority, lhs, rhs);
 // if there were "Input:" annotation types specified ...
   if(curSPT.isInputRestricted()) {
      // find all the different annotation types used in the
      // LHS of the rule
      HashSet set = new HashSet();
     lhs.getConstraintGroup().getContainedAnnotationTypes(set);
     // and check if each of them is mentioned in the list
     for (String type : set) {
      if(!curSPT.hasInput(type)) {
        System.err.println(errorMsgPrefix(null)+
          "Rule "+ruleNameTok.image+" contains unlisted annotation type " + type);
      }
     }
   }
    ruleNumber++;
    {if ("" != null) return newRule;}
    throw new Error("Missing return statement in function");
  }

// Rule
  final public 

void MacroDef() throws ParseException {Token macroNameTok = null;
  Object body = null;
    jj_consume_token(macro);
    macroNameTok = jj_consume_token(ident);
    if (jj_2_1(2)) {
      // both blocks and PEs may start with "{"
          body = PatternElement();
    } else {
      switch (jj_nt.kind) {
      case ident:
      case colon:
      case leftBrace:
      case colonplus:{
        body = Action(false);
        break;
        }
      default:
        jj_la1[16] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
    }
macrosMap.put(macroNameTok.image, body);
  }

// MacroDef
  final public 
void TemplateDef() throws ParseException {Token templateNameTok = null;
  Pair value = null;
    jj_consume_token(template);
    templateNameTok = jj_consume_token(ident);
    jj_consume_token(assign);
    value = AttrVal();
templatesMap.put(templateNameTok.image, value);
  }

// TemplateDef
  final public 

LeftHandSide LeftHandSide() throws ParseException {ConstraintGroup cg = new ConstraintGroup();
    ConstraintGroup(cg);
LeftHandSide lhs = new LeftHandSide(cg);
    // pull out all bindings (including nested ones) and add them to the LHS
    Iterator boundCPEs = cg.getCPEs();
    while(boundCPEs.hasNext()) {
      ComplexPatternElement cpe = boundCPEs.next();
      String bindingName = cpe.getBindingName();
      if(bindingName != null) {
        try {
          lhs.addBinding(bindingName, cpe, bindingNameSet);
        } catch(JapeException e) {
          System.err.println(errorMsgPrefix(null)+
            "duplicate binding name " + bindingName +
            " - ignoring this binding! exception was: " + e.toString()
          );
        }

      }
    }
    {if ("" != null) return lhs;}
    throw new Error("Missing return statement in function");
  }

// LeftHandSide


// we pass the lhs down so we can add bindings in CPEs, and the cg
// so we can add PEs and create disjunctions here
  final public void ConstraintGroup(ConstraintGroup cg) throws ParseException {PatternElement pat = null;
    label_8:
    while (true) {
      pat = PatternElement();
cg.addPatternElement(pat);
      switch (jj_nt.kind) {
      case string:
      case ident:
      case leftBrace:
      case leftBracket:{
        ;
        break;
        }
      default:
        jj_la1[17] = jj_gen;
        break label_8;
      }
    }
    label_9:
    while (true) {
      switch (jj_nt.kind) {
      case bar:{
        ;
        break;
        }
      default:
        jj_la1[18] = jj_gen;
        break label_9;
      }
      jj_consume_token(bar);
cg.createDisjunction();
      label_10:
      while (true) {
        pat = PatternElement();
cg.addPatternElement(pat);
        switch (jj_nt.kind) {
        case string:
        case ident:
        case leftBrace:
        case leftBracket:{
          ;
          break;
          }
        default:
          jj_la1[19] = jj_gen;
          break label_10;
        }
      }
    }
  }

// ConstraintGroup
  final public 

PatternElement PatternElement() throws ParseException {PatternElement pat = null;
  Token macroRefTok = null;
    switch (jj_nt.kind) {
    case ident:{
      macroRefTok = jj_consume_token(ident);
Object macro = macrosMap.get(macroRefTok.image);
      if(macro == null)
        {if (true) throw(new ParseException(errorMsgPrefix(macroRefTok)+
          "unknown macro name " + macroRefTok.image));}
      else if(macro instanceof String[])
        {if (true) throw(
          new ParseException(errorMsgPrefix(macroRefTok)+
            "macro " + macroRefTok.image +
            " references an Action, not a PatternElement"
          )
        );}
      else if(! (macro instanceof PatternElement)) // this should never happen
        {if (true) throw(
          new ParseException(errorMsgPrefix(macroRefTok)+
            "macro " + macroRefTok.image +
            " doesn't reference a PatternElement!"
          )
        );}
      else { // macro is a pattern element
        pat = (PatternElement) ((PatternElement) macro).clone();
      }
      break;
      }
    case string:
    case leftBrace:{
      pat = BasicPatternElement();
      break;
      }
    case leftBracket:{
      pat = ComplexPatternElement();
      break;
      }
    default:
      jj_la1[20] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
{if ("" != null) return pat;}
    throw new Error("Missing return statement in function");
  }

// PatternElement
  final public 

BasicPatternElement BasicPatternElement() throws ParseException {Token shortTok = null; // string shorthand token
  Constraint c = null;
  BasicPatternElement bpe = new BasicPatternElement(curSPT);
    switch (jj_nt.kind) {
    case leftBrace:{
      jj_consume_token(leftBrace);
      c = Constraint();
bpe.addConstraint(c);
      label_11:
      while (true) {
        switch (jj_nt.kind) {
        case comma:{
          ;
          break;
          }
        default:
          jj_la1[21] = jj_gen;
          break label_11;
        }
        jj_consume_token(comma);
        c = Constraint();
bpe.addConstraint(c);
      }
      jj_consume_token(rightBrace);
      break;
      }
    case string:{
      // string shorthand
            shortTok = jj_consume_token(string);
System.err.println(errorMsgPrefix(shortTok)+
        "string shorthand not supported yet, ignoring: " + shortTok.image
      );
      break;
      }
    default:
      jj_la1[22] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
finishBPE(bpe);
    {if ("" != null) return bpe;}
    throw new Error("Missing return statement in function");
  }

// BasicPatternElement
  final public 

ComplexPatternElement ComplexPatternElement() throws ParseException {KleeneOperator kleeneOperator = null;
  Token bindingNameTok = null;
  ConstraintGroup cg = new ConstraintGroup();
    jj_consume_token(leftBracket);
    ConstraintGroup(cg);
    jj_consume_token(rightBracket);
    switch (jj_nt.kind) {
    case kleeneOp:
    case leftSquare:{
      kleeneOperator = KleeneOperator();
      break;
      }
    default:
      jj_la1[23] = jj_gen;
      ;
    }
    switch (jj_nt.kind) {
    case colon:{
      jj_consume_token(colon);
      switch (jj_nt.kind) {
      case ident:{
        bindingNameTok = jj_consume_token(ident);
        break;
        }
      case integer:{
        bindingNameTok = jj_consume_token(integer);
        break;
        }
      default:
        jj_la1[24] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      break;
      }
    default:
      jj_la1[25] = jj_gen;
      ;
    }
String bindingName = null;
    if(bindingNameTok != null)
      bindingName = bindingNameTok.image;
    {if ("" != null) return new ComplexPatternElement(cg, kleeneOperator, bindingName);}
    throw new Error("Missing return statement in function");
  }

// ComplexPatternElement
  final public 
KleeneOperator KleeneOperator() throws ParseException {Token kleeneOpTok = null;
  Token minTok = null;
  Token maxTok = null;
  Integer min = null;
  Integer max = null;
    switch (jj_nt.kind) {
    case kleeneOp:{
      kleeneOpTok = jj_consume_token(kleeneOp);
if (kleeneOpTok == null) {
          {if ("" != null) return new KleeneOperator(KleeneOperator.Type.SINGLE);}
        }

        KleeneOperator.Type type = KleeneOperator.Type.getFromSymbol(kleeneOpTok.image);
        if (type != null)
            {if ("" != null) return new KleeneOperator(type);}
        else {
          System.err.println(errorMsgPrefix(kleeneOpTok)+
              "ignoring uninterpretable Kleene op " + kleeneOpTok.image);
          {if ("" != null) return new KleeneOperator(KleeneOperator.Type.SINGLE);}
        }
      break;
      }
    case leftSquare:{
      jj_consume_token(leftSquare);
      minTok = jj_consume_token(integer);
      switch (jj_nt.kind) {
      case comma:{
        jj_consume_token(comma);
        maxTok = jj_consume_token(integer);
        break;
        }
      default:
        jj_la1[26] = jj_gen;
        ;
      }
      jj_consume_token(rightSquare);
if (minTok != null)
              min = new Integer(minTok.image);
          if (maxTok != null)
              max = new Integer(maxTok.image);
          else
              max = min;
          {if ("" != null) return new KleeneOperator(min, max);}
      break;
      }
    default:
      jj_la1[27] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
  }

// KleeneOperator
  final public 
Constraint Constraint() throws ParseException {Token annotTypeTok = null;
  Token metaPropertyTok = null;
  AnnotationAccessor accessor = null;
  Token opTok = null;
  Pair attrValPair = null;
  boolean negate = false;
  Constraint c = null;
  Constraint embeddedConstraint = null;
  String opString = null;
    switch (jj_nt.kind) {
    case pling:{
      jj_consume_token(pling);
negate = true;
      break;
      }
    default:
      jj_la1[28] = jj_gen;
      ;
    }
    switch (jj_nt.kind) {
    case ident:{
      annotTypeTok = jj_consume_token(ident);
      break;
      }
    case string:{
      annotTypeTok = jj_consume_token(string);
      break;
      }
    default:
      jj_la1[29] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
c = JapeFactory.getConstraintFactory().createConstraint(stringValueOf(annotTypeTok));
    if(negate) c.negate();
    switch (jj_nt.kind) {
    case metaPropOp:
    case ident:
    case period:{
      switch (jj_nt.kind) {
      case period:{
        accessor = FeatureAccessor();
        opTok = jj_consume_token(attrOp);
        attrValPair = AttrVal();
opString = opTok.image;
        c.addAttribute(JapeFactory.getConstraintFactory().createPredicate(opString, accessor, attrValPair.second));
        break;
        }
      case metaPropOp:{
        jj_consume_token(metaPropOp);
        metaPropertyTok = jj_consume_token(ident);
        opTok = jj_consume_token(attrOp);
        attrValPair = AttrVal();
accessor = JapeFactory.getConstraintFactory().createMetaPropertyAccessor(metaPropertyTok.image);
        opString = opTok.image;
        c.addAttribute(JapeFactory.getConstraintFactory().createPredicate(opString, accessor, attrValPair.second));
        break;
        }
      case ident:{
        // custom string operator name with value
              opTok = jj_consume_token(ident);
        switch (jj_nt.kind) {
        case leftBrace:{
          jj_consume_token(leftBrace);
          embeddedConstraint = Constraint();
          jj_consume_token(rightBrace);
          break;
          }
        case pling:
        case string:
        case ident:{
          embeddedConstraint = Constraint();
          break;
          }
        default:
          jj_la1[30] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
opString = opTok.image;
        accessor = new SimpleAnnotationAccessor();
        c.addAttribute(JapeFactory.getConstraintFactory().createPredicate(opString, accessor, embeddedConstraint));
        break;
        }
      default:
        jj_la1[31] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      break;
      }
    default:
      jj_la1[32] = jj_gen;
      ;
    }
{if ("" != null) return c;}
    throw new Error("Missing return statement in function");
  }

// Constraint

//attribute values: strings, identifers (=strings), integers, floats,
//booleans
  final public AnnotationAccessor FeatureAccessor() throws ParseException {Token attrNameTok = null;
AnnotationAccessor accessor = null;
    jj_consume_token(period);
    switch (jj_nt.kind) {
    case ident:{
      attrNameTok = jj_consume_token(ident);
      break;
      }
    case string:{
      attrNameTok = jj_consume_token(string);
      break;
      }
    default:
      jj_la1[33] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
accessor = JapeFactory.getConstraintFactory().createDefaultAccessor(stringValueOf(attrNameTok));
    {if ("" != null) return accessor;}
    throw new Error("Missing return statement in function");
  }

// attribute values: strings, identifers (=strings), integers, floats,
//                   booleans
  final public Pair AttrVal() throws ParseException {Token attrValTok = null;
  Pair val = new Pair();
    switch (jj_nt.kind) {
    case integer:
    case string:
    case bool:
    case ident:
    case floatingPoint:{
      switch (jj_nt.kind) {
      case string:{
        attrValTok = jj_consume_token(string);
        break;
        }
      case ident:{
        attrValTok = jj_consume_token(ident);
        break;
        }
      case integer:{
        attrValTok = jj_consume_token(integer);
        break;
        }
      case floatingPoint:{
        attrValTok = jj_consume_token(floatingPoint);
        break;
        }
      case bool:{
        attrValTok = jj_consume_token(bool);
        break;
        }
      default:
        jj_la1[34] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
val.first = new Integer(attrValTok.kind);

      switch(attrValTok.kind) {
        case string:
          // strip the quotes
          val.second
            = attrValTok.image.substring(1, attrValTok.image.length() - 1);
          break;
        case integer:
          try {
            val.second = Long.valueOf(attrValTok.image);
          } catch(NumberFormatException e) {
            System.err.println(errorMsgPrefix(attrValTok)+
              "couldn't parse integer " +
              attrValTok.image + " - treating as 0");
            val.second = new Long(0);
          }
          break;
        case ident:
          val.second = new String(attrValTok.image);
          break;
        case bool:
          val.second = Boolean.valueOf(attrValTok.image);
          break;
        case floatingPoint:
          try {
            val.second = Double.valueOf(attrValTok.image);
          } catch(NumberFormatException e) {
            System.err.println(errorMsgPrefix(attrValTok)+
              "couldn't parse float " +
              attrValTok.image + " - treating as 0.0");
            val.second = new Double(0.0);
          }
          break;
        default:
          System.err.println(errorMsgPrefix(attrValTok)+
            "didn't understand type of " + attrValTok.image + ": ignoring"
          );
          val.second = new String("");
          break;
      } // switch

      {if ("" != null) return val;}
      break;
      }
    case leftSquare:{
      val = TemplateCall();
{if ("" != null) return val;}
      break;
      }
    default:
      jj_la1[35] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
  }

  final public Pair TemplateCall() throws ParseException {Token templateNameTok = null;
  Token attrNameTok = null;
  Pair attrVal = null;
  Map placeholders = new HashMap();
    jj_consume_token(leftSquare);
    templateNameTok = jj_consume_token(ident);
    label_12:
    while (true) {
      switch (jj_nt.kind) {
      case ident:{
        ;
        break;
        }
      default:
        jj_la1[36] = jj_gen;
        break label_12;
      }
      attrNameTok = jj_consume_token(ident);
      jj_consume_token(assign);
      attrVal = AttrVal();
placeholders.put(attrNameTok.image, attrVal.second);
      switch (jj_nt.kind) {
      case comma:{
        jj_consume_token(comma);
        break;
        }
      default:
        jj_la1[37] = jj_gen;
        ;
      }
    }
    jj_consume_token(rightSquare);
{if ("" != null) return substituteTemplate(templateNameTok, placeholders);}
    throw new Error("Missing return statement in function");
  }

  final public RightHandSide RightHandSide(String phaseName, String ruleName, LeftHandSide lhs, String imports) throws ParseException {String[] block = new String[2];
  RightHandSide rhs = new RightHandSide(phaseName, ruleName, lhs, imports);
    block = Action(true);
rhs.addBlock(block[0], block[1]);
    label_13:
    while (true) {
      switch (jj_nt.kind) {
      case comma:{
        ;
        break;
        }
      default:
        jj_la1[38] = jj_gen;
        break label_13;
      }
      jj_consume_token(comma);
      block = Action(true);
rhs.addBlock(block[0], block[1]);
    }
{if ("" != null) return rhs;} /* action class not created yet */

    throw new Error("Missing return statement in function");
  }

// RightHandSide


// actions return 2 strings, one for the name of the block, and
// one for the block itself. if the name is null, it is an anonymous block.
// The checkLabel parameter indicates whether named blocks should check
// at parse time that the label they refer to is bound.  Actions in
// a MacroDef can't make this check at parse time, but instead the
// check is done when the macro is referenced.
  final public String[] Action(boolean checkLabel) throws ParseException {String[] block = new String[2];
  Token macroRefTok = null;
    if (jj_2_2(3)) {
      block = NamedJavaBlock(checkLabel);
    } else {
      switch (jj_nt.kind) {
      case leftBrace:{
        block = AnonymousJavaBlock();
        break;
        }
      case colon:
      case colonplus:{
        block = AssignmentExpression(checkLabel);
        break;
        }
      case ident:{
        macroRefTok = jj_consume_token(ident);
Object macro = macrosMap.get(macroRefTok.image);
      if(macro == null)
        {if (true) throw(new ParseException(errorMsgPrefix(macroRefTok)+
          "unknown macro name " + macroRefTok.image));}
      else if(macro instanceof PatternElement)
        {if (true) throw(
          new ParseException(errorMsgPrefix(macroRefTok)+
            "macro " + macroRefTok.image +
            " references a PatternElement, not an Action"
          )
        );}
      else if(! (macro instanceof String[])) // this should never happen
        {if (true) throw(
          new ParseException(errorMsgPrefix(macroRefTok)+
            "macro " + macroRefTok.image + " doesn't reference an Action!"
          )
        );}
      else { // macro is an action
        block = (String[]) macro;
        // if the macro is a named block or assignment, check that
        // the label is valid
        if(block[0] != null && !bindingNameSet.contains(block[0])) {
          {if (true) throw(new ParseException(errorMsgPrefix(macroRefTok)+
            "RHS macro reference " + macroRefTok.image +
            " refers to unknown label: " + block[0]));}
        }
      }
        break;
        }
      default:
        jj_la1[39] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
    }
{if ("" != null) return block;}
    throw new Error("Missing return statement in function");
  }

// Action


// A :bind { ... } code block.  The checkLabel parameter
// indicates whether or not we should check *at parse time* that the
// :bind label is valid.  Assignments that are the body of a MacroDef
// can't check this at parse time but will be checked at reference time
  final public String[] NamedJavaBlock(boolean checkLabel) throws ParseException {String[] block = new String[2];
  Token nameTok = null;
    jj_consume_token(colon);
    nameTok = jj_consume_token(ident);
block[0] = nameTok.image;
    // did we get a non-existent block name?
    if(checkLabel && block[0] != null)
      if(! bindingNameSet.contains(block[0])) {
        {if (true) throw(new ParseException(errorMsgPrefix(nameTok)+
          "unknown label in RHS action: " + block[0]));}
      }
    jj_consume_token(leftBrace);
    block[1] = ConsumeBlock();
{if ("" != null) return block;}
    throw new Error("Missing return statement in function");
  }

// NamedJavaBlock
  final public 

String[] AnonymousJavaBlock() throws ParseException {String[] block = new String[2];
  block[0] = null; // no name

    jj_consume_token(leftBrace);
    block[1] = ConsumeBlock();
{if ("" != null) return block;}
    throw new Error("Missing return statement in function");
  }

// AnonymousJavaBlock


// A :bind.Type = {features} assignment.  The checkLabel parameter
// indicates whether or not we should check *at parse time* that the
// :bind label is valid.  Assignments that are the body of a MacroDef
// can't check this at parse time but will be checked at reference time
  final public String[] AssignmentExpression(boolean checkLabel) throws ParseException {String[] block = new String[2];
  StringBuffer blockBuffer = new StringBuffer();
  Token nameTok = null;
  Token opTok = null;
  String newAnnotType = null;
  String newAttrName = null;
  String nl = Strings.getNl();
  String annotSetName = null;
  Pair attrVal = null;
  String existingAnnotSetName = null;
  String existingAnnotType = null;
  String existingAttrName = null;
  String opName = null;

  blockBuffer.append("// RHS assignment block" + nl);
  blockBuffer.append(
    "      gate.FeatureMap features = gate.Factory.newFeatureMap();" + nl
  );
    switch (jj_nt.kind) {
    case colon:{
      jj_consume_token(colon);
      break;
      }
    case colonplus:{
      jj_consume_token(colonplus);
{if (true) throw new
        ParseException(":+ not a legal operator (no multi-span annots)");}
      break;
      }
    default:
      jj_la1[40] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    // the name of the bound annotation set we're referencing
      nameTok = jj_consume_token(ident);
block[0] = nameTok.image;
    // did we get a non-existent block name?
    if(checkLabel && block[0] != null)
      if(! bindingNameSet.contains(block[0])) {
        {if (true) throw(new ParseException(errorMsgPrefix(nameTok)+
          "unknown label in RHS action: " + block[0]));}
      }

    annotSetName = block[0] + "Annots";
    jj_consume_token(period);
    switch (jj_nt.kind) {
    case ident:{
      nameTok = jj_consume_token(ident);
      break;
      }
    case string:{
      nameTok = jj_consume_token(string);
      break;
      }
    default:
      jj_la1[41] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
newAnnotType = stringValueOf(nameTok);

    // start of the attribute stuff
    blockBuffer.append("      java.lang.Object val = null;" + nl);
    jj_consume_token(assign);
    jj_consume_token(leftBrace);
    label_14:
    while (true) {
      switch (jj_nt.kind) {
      case string:
      case ident:
      case colon:{
        ;
        break;
        }
      default:
        jj_la1[42] = jj_gen;
        break label_14;
      }
      switch (jj_nt.kind) {
      case string:
      case ident:{
        switch (jj_nt.kind) {
        case ident:{
          nameTok = jj_consume_token(ident);
          break;
          }
        case string:{
          nameTok = jj_consume_token(string);
          break;
          }
        default:
          jj_la1[43] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
        jj_consume_token(assign);
newAttrName = stringValueOf(nameTok);
        switch (jj_nt.kind) {
        case integer:
        case string:
        case bool:
        case ident:
        case floatingPoint:
        case leftSquare:{
          // a static attribute value
                    attrVal = AttrVal();
switch(((Integer) attrVal.first).intValue()) {
              case string:
                blockBuffer.append(
                  "      val = ");
                appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
                blockBuffer.append(";" + nl);
                break;
              case integer:
                blockBuffer.append("      try { " +
                  "val = java.lang.Long.valueOf(");
                appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
                blockBuffer.append("); }" +
                  nl + "      catch(java.lang.NumberFormatException e) { }" + nl
                );
                break;
              case ident:
                blockBuffer.append(
                  "      val = ");
                appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
                blockBuffer.append(";" + nl);
                break;
              case bool:
                blockBuffer.append(
                  "      val = java.lang.Boolean.valueOf(");
                appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
                blockBuffer.append(");" + nl);
                break;
              case floatingPoint:
                blockBuffer.append("      try { " +
                  "val = java.lang.Double.valueOf(");
                appendJavaStringLiteral(blockBuffer, attrVal.second.toString());
                blockBuffer.append("); }" +
                  nl + "      catch(java.lang.NumberFormatException e) { }" + nl
                );
                break;
              default:
                blockBuffer.append(
                  "      val = \"\";" + nl
                );
                break;
            } // switch

            blockBuffer.append("      features.put(");
            appendJavaStringLiteral(blockBuffer, newAttrName);
            blockBuffer.append(", val);");
            blockBuffer.append(nl);
          break;
          }
        case colon:{
          jj_consume_token(colon);
          nameTok = jj_consume_token(ident);
existingAnnotSetName = nameTok.image + "ExistingAnnots";
              if(checkLabel && ! bindingNameSet.contains(nameTok.image))
                {if (true) throw(
                  new ParseException(errorMsgPrefix(nameTok)+
                    "unknown label in RHS action(2): " + nameTok.image
                  )
                );}

              blockBuffer.append(
                "      { // need a block for the existing annot set" + nl +
                "        gate.AnnotationSet " + existingAnnotSetName +
                " = (gate.AnnotationSet)bindings.get(");
              appendJavaStringLiteral(blockBuffer, nameTok.image);
              blockBuffer.append("); " + nl +
                "        java.lang.Object existingFeatureValue;" + nl);
          switch (jj_nt.kind) {
          case period:{
            jj_consume_token(period);
            switch (jj_nt.kind) {
            case ident:{
              nameTok = jj_consume_token(ident);
              break;
              }
            case string:{
              nameTok = jj_consume_token(string);
              break;
              }
            default:
              jj_la1[44] = jj_gen;
              jj_consume_token(-1);
              throw new ParseException();
            }
existingAnnotType = stringValueOf(nameTok);
            switch (jj_nt.kind) {
            case period:{
              opTok = jj_consume_token(period);
              break;
              }
            case metaPropOp:{
              opTok = jj_consume_token(metaPropOp);
              break;
              }
            default:
              jj_la1[45] = jj_gen;
              jj_consume_token(-1);
              throw new ParseException();
            }
            switch (jj_nt.kind) {
            case ident:{
              nameTok = jj_consume_token(ident);
              break;
              }
            case string:{
              nameTok = jj_consume_token(string);
              break;
              }
            default:
              jj_la1[46] = jj_gen;
              jj_consume_token(-1);
              throw new ParseException();
            }
opName = opTok.image; existingAttrName = stringValueOf(nameTok);
blockBuffer.append(
        "        if (" + existingAnnotSetName + " != null) {" + nl +
        "          gate.AnnotationSet existingAnnots = " + nl +
        "          " + existingAnnotSetName + ".get(");
                  appendJavaStringLiteral(blockBuffer, existingAnnotType);
                  blockBuffer.append(");" + nl +
        "          if (existingAnnots != null) {" + nl +
        "            java.util.Iterator iter = existingAnnots.iterator();" + nl +
        "            while(iter.hasNext()) {" + nl +
        "              gate.Annotation existingA = (gate.Annotation) iter.next();" + nl);

                  // handle :bind.Type@string, :bind.Type@cleanString and :bind.Type@length
                  if(opName.equals("@") && ( existingAttrName.equals("string") || existingAttrName.equals("cleanString") || existingAttrName.equals("length") ) ) {
                    blockBuffer.append(
        "              int from = existingA.getStartNode().getOffset().intValue();" + nl +
        "              int to   = existingA.getEndNode().getOffset().intValue();" + nl +
        "              existingFeatureValue = doc.getContent().toString().substring(from,to);" + nl
                    );
                    if ( existingAttrName.equals("cleanString") ) {
                      blockBuffer.append(
        "                 existingFeatureValue = gate.Utils.cleanString((String)existingFeatureValue);" + nl
                      );
                    }
                    if ( existingAttrName.equals("length") ) {
                      blockBuffer.append(
        "                 existingFeatureValue = (long)to - (long)from;" + nl
                      );
                    }
                  } else {
                    blockBuffer.append("existingFeatureValue = existingA.getFeatures().get(");
                    appendJavaStringLiteral(blockBuffer, existingAttrName);
                    blockBuffer.append(");" + nl);
                  }

                  blockBuffer.append(
        "              if(existingFeatureValue != null) {" + nl +
        "                features.put(");
                  appendJavaStringLiteral(blockBuffer, newAttrName);
                  blockBuffer.append(", existingFeatureValue);" + nl +
        "                break;" + nl +
        "              }" + nl +
        "            } // while" + nl +
        "          } // if not null" + nl +
        "        } // if not null" + nl);
            break;
            }
          case metaPropOp:{
            opTok = jj_consume_token(metaPropOp);
            nameTok = jj_consume_token(ident);
opName = opTok.image; existingAttrName = nameTok.image;
if(opName.equals("@") && ( existingAttrName.equals("string") || existingAttrName.equals("cleanString") || existingAttrName.equals("length") ) ) {
                    blockBuffer.append(
        "        if (" + existingAnnotSetName + " != null) {" + nl +
        "          int from = " + existingAnnotSetName +".firstNode().getOffset().intValue();" + nl +
        "          int to   = " + existingAnnotSetName +".lastNode().getOffset().intValue();" + nl +
        "          existingFeatureValue = doc.getContent().toString().substring(from,to);" + nl
                    );
                    if ( existingAttrName.equals("cleanString") ) {
                      blockBuffer.append(
        "                 existingFeatureValue = ((String)existingFeatureValue).replaceAll(\"\\\\s+\", \" \").trim();" + nl
                      );
                    }
                    if ( existingAttrName.equals("length") ) {
                      blockBuffer.append(
        "                 existingFeatureValue = (long)to - (long)from;" + nl
                      );
                    }
                    blockBuffer.append(
        "          if(existingFeatureValue != null) {" + nl +
        "            features.put(");
                    appendJavaStringLiteral(blockBuffer, newAttrName);
                    blockBuffer.append(", existingFeatureValue);" + nl +
        "          }" + nl +
        "        } // if not null" + nl);
                  }
                  else {
                    {if (true) throw new ParseException(errorMsgPrefix(nameTok) +
                            "Unsupported RHS meta-property " + nameTok.image);}
                  }
            break;
            }
          default:
            jj_la1[47] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
          }
blockBuffer.append(
      "      } // block for existing annots" + nl
              );
          break;
          }
        default:
          jj_la1[48] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
        break;
        }
      case colon:{
        jj_consume_token(colon);
        nameTok = jj_consume_token(ident);
existingAnnotSetName = nameTok.image + "ExistingAnnots";
          if(checkLabel && ! bindingNameSet.contains(nameTok.image))
            {if (true) throw(
              new ParseException(errorMsgPrefix(nameTok)+
                "unknown label in RHS action(3): " + nameTok.image
              )
            );}

          blockBuffer.append(
            "      { // copy all features from this annotation" + nl +
            "        gate.AnnotationSet " + existingAnnotSetName +
            " = bindings.get(");
          appendJavaStringLiteral(blockBuffer, nameTok.image);
          blockBuffer.append(");" + nl);
        switch (jj_nt.kind) {
        case period:{
          jj_consume_token(period);
          switch (jj_nt.kind) {
          case ident:{
            nameTok = jj_consume_token(ident);
            break;
            }
          case string:{
            nameTok = jj_consume_token(string);
            break;
            }
          default:
            jj_la1[49] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
          }
existingAnnotType = stringValueOf(nameTok);
            blockBuffer.append(
              "        " + existingAnnotSetName + " = " + existingAnnotSetName + ".get("
            );
            appendJavaStringLiteral(blockBuffer, existingAnnotType);
            blockBuffer.append(");" + nl);
          break;
          }
        default:
          jj_la1[50] = jj_gen;
          ;
        }
blockBuffer.append(
            "        for(gate.Annotation a : " + existingAnnotSetName + ") {" + nl +
            "          if(a.getFeatures() != null && !a.getFeatures().isEmpty()) {" + nl +
            "            features.putAll(a.getFeatures());" + nl +
            "            break;" + nl +
            "          }" + nl +
            "        }" + nl +
            "      } // copy all features from this annotation" + nl
          );
        break;
        }
      default:
        jj_la1[51] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      switch (jj_nt.kind) {
      case comma:{
        jj_consume_token(comma);
        break;
        }
      default:
        jj_la1[52] = jj_gen;
        ;
      }
    }
    jj_consume_token(rightBrace);
appendAnnotationAdd(blockBuffer, newAnnotType, annotSetName);
    block[1] = blockBuffer.toString();
    {if ("" != null) return block;}
    throw new Error("Missing return statement in function");
  }

  void appendSpecials(Token tok, StringBuffer block) throws ParseException {if(tok != null) {
    // each specialToken points to its *preceding* one, so we must recursively
    // append the previous special (which will recursively append its
    // predecessor, etc.) before appending the current one.
    appendSpecials(tok.specialToken, block);
    block.append(tok.image);
  }
  }

  String ConsumeBlock() throws ParseException, ParseException {StringBuffer block = new StringBuffer(); // to collect the block in
  int nesting = 1; // the first "{" was consumed before we were called

  // this is the first 'proper' token in the block
  Token nextTok = getNextToken();
  if(nextTok.kind == EOF) {
    throw new ParseException(errorMsgPrefix(nextTok)
            + "Unexpected EOF in Java block");
  }

  // for line numbers in the original Jape we want the first
  // token, normal or special (i.e. comments) so look back from
  // the first 'proper' token until we get back to the token
  // after the opening brace 
  Token blockStart = nextTok;
  while (blockStart.specialToken != null) {
    blockStart = blockStart.specialToken;
  }

  // append the info about the source Jape to the beginning
  // of the loaded source Java block
  block.append("  // JAPE Source: " + baseURL+":" + blockStart.beginLine + "\n");

  // step through the code until the final brace
  while(nesting != 0) {

    // add in any preceding spaces and comments
    appendSpecials(nextTok.specialToken, block);

    // adjust nesting
    if(nextTok.image.equals("{")) {
      nesting++;
      /*Debug.pr(this, "ParseCpsl.ConsumeBlock: nesting = " + nesting);*/
    } else if(nextTok.image.equals("}")) {
      nesting--;
      /*Debug.pr(this, "ParseCpsl.ConsumeBlock: nesting = " + nesting);*/
    }

    // add the image to the block string (but not the final "}")
    if(nesting > 0) {
      if(nextTok.kind == string) {
        // deal with escapes in string literals
        appendJavaStringLiteral(block,
            nextTok.image.substring(1, nextTok.image.length() - 1));
      }
      else {
        block.append(nextTok.image);
      }
    }
    /*Debug.pr(this, "ParseCpsl.ConsumeBlock: nextTok.image = ^" +
             nextTok.image + "^");*/

 // if we haven't worked all the way out of the nesting
 // then get the next token
 if (nesting != 0) {
   nextTok = getNextToken();
   if(nextTok.kind == EOF) {
     throw new ParseException(errorMsgPrefix(nextTok)
             + "Unexpected EOF in Java block");
   }
 }

  } // while

  /*Debug.pr(this, "ParseCpsl.ConsumeBlock: block = " + block.toString());*/

  return block.toString();
  }

  private boolean jj_2_1(int xla)
 {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_1(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(0, xla); }
  }

  private boolean jj_2_2(int xla)
 {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return !jj_3_2(); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(1, xla); }
  }

  private boolean jj_3R_27()
 {
    if (jj_scan_token(pling)) return true;
    return false;
  }

  private boolean jj_3R_26()
 {
    if (jj_3R_15()) return true;
    return false;
  }

  private boolean jj_3R_25()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_27()) jj_scanpos = xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(49)) {
    jj_scanpos = xsp;
    if (jj_scan_token(47)) return true;
    }
    return false;
  }

  private boolean jj_3R_23()
 {
    if (jj_scan_token(string)) return true;
    return false;
  }

  private boolean jj_3R_21()
 {
    if (jj_scan_token(leftBracket)) return true;
    if (jj_3R_24()) return true;
    return false;
  }

  private boolean jj_3R_24()
 {
    Token xsp;
    if (jj_3R_26()) return true;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_26()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  private boolean jj_3R_19()
 {
    if (jj_3R_21()) return true;
    return false;
  }

  private boolean jj_3R_18()
 {
    if (jj_3R_20()) return true;
    return false;
  }

  private boolean jj_3R_16()
 {
    if (jj_scan_token(colon)) return true;
    if (jj_scan_token(ident)) return true;
    if (jj_scan_token(leftBrace)) return true;
    return false;
  }

  private boolean jj_3R_17()
 {
    if (jj_scan_token(ident)) return true;
    return false;
  }

  private boolean jj_3R_22()
 {
    if (jj_scan_token(leftBrace)) return true;
    if (jj_3R_25()) return true;
    return false;
  }

  private boolean jj_3R_15()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_17()) {
    jj_scanpos = xsp;
    if (jj_3R_18()) {
    jj_scanpos = xsp;
    if (jj_3R_19()) return true;
    }
    }
    return false;
  }

  private boolean jj_3_2()
 {
    if (jj_3R_16()) return true;
    return false;
  }

  private boolean jj_3R_20()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_22()) {
    jj_scanpos = xsp;
    if (jj_3R_23()) return true;
    }
    return false;
  }

  private boolean jj_3_1()
 {
    if (jj_3R_15()) return true;
    return false;
  }

  /** Generated Token Manager. */
  public ParseCpslTokenManager token_source;
  SimpleCharStream jj_input_stream;
  /** Current token. */
  public Token token;
  /** Next token. */
  public Token jj_nt;
  private Token jj_scanpos, jj_lastpos;
  private int jj_la;
  private int jj_gen;
  final private int[] jj_la1 = new int[53];
  static private int[] jj_la1_0;
  static private int[] jj_la1_1;
  static private int[] jj_la1_2;
  static {
      jj_la1_init_0();
      jj_la1_init_1();
      jj_la1_init_2();
   }
   private static void jj_la1_init_0() {
      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,0x0,0x0,0x0,};
   }
   private static void jj_la1_init_1() {
      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,0x128000,0x28000,0x28000,0x400004,0x28000,0x400004,0x20178008,0x28000,0x400000,0x128000,0x1000000,};
   }
   private static void jj_la1_init_2() {
      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,0x0,0x0,0x0,};
   }
  final private JJCalls[] jj_2_rtns = new JJCalls[2];
  private boolean jj_rescan = false;
  private int jj_gc = 0;

  /** Constructor with InputStream. */
  public ParseCpsl(java.io.InputStream stream) {
     this(stream, null);
  }
  /** Constructor with InputStream and supplied encoding */
  public ParseCpsl(java.io.InputStream stream, String encoding) {
    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
    token_source = new ParseCpslTokenManager(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 53; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Reinitialise. */
  public void ReInit(java.io.InputStream stream) {
     ReInit(stream, null);
  }
  /** Reinitialise. */
  public void ReInit(java.io.InputStream stream, String encoding) {
    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
    token_source.ReInit(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 53; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Constructor. */
  public ParseCpsl(java.io.Reader stream) {
    jj_input_stream = new SimpleCharStream(stream, 1, 1);
    token_source = new ParseCpslTokenManager(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 53; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Reinitialise. */
  public void ReInit(java.io.Reader stream) {
	if (jj_input_stream == null) {
      jj_input_stream = new SimpleCharStream(stream, 1, 1);
   } else {
      jj_input_stream.ReInit(stream, 1, 1);
   }
   if (token_source == null) {
      token_source = new ParseCpslTokenManager(jj_input_stream);
   }

    token_source.ReInit(jj_input_stream);
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 53; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Constructor with generated Token Manager. */
  public ParseCpsl(ParseCpslTokenManager tm) {
    token_source = tm;
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 53; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Reinitialise. */
  public void ReInit(ParseCpslTokenManager tm) {
    token_source = tm;
    token = new Token();
    token.next = jj_nt = token_source.getNextToken();
    jj_gen = 0;
    for (int i = 0; i < 53; i++) jj_la1[i] = -1;
    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  private Token jj_consume_token(int kind) throws ParseException {
    Token oldToken = token;
    if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
    else jj_nt = jj_nt.next = token_source.getNextToken();
    if (token.kind == kind) {
      jj_gen++;
      if (++jj_gc > 100) {
        jj_gc = 0;
        for (int i = 0; i < jj_2_rtns.length; i++) {
          JJCalls c = jj_2_rtns[i];
          while (c != null) {
            if (c.gen < jj_gen) c.first = null;
            c = c.next;
          }
        }
      }
      return token;
    }
    jj_nt = token;
    token = oldToken;
    jj_kind = kind;
    throw generateParseException();
  }

  @SuppressWarnings("serial")
  static private final class LookaheadSuccess extends java.lang.Error { }
  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
  private boolean jj_scan_token(int kind) {
    if (jj_scanpos == jj_lastpos) {
      jj_la--;
      if (jj_scanpos.next == null) {
        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
      } else {
        jj_lastpos = jj_scanpos = jj_scanpos.next;
      }
    } else {
      jj_scanpos = jj_scanpos.next;
    }
    if (jj_rescan) {
      int i = 0; Token tok = token;
      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
      if (tok != null) jj_add_error_token(kind, i);
    }
    if (jj_scanpos.kind != kind) return true;
    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
    return false;
  }


/** Get the next Token. */
  final public Token getNextToken() {
    if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
    else jj_nt = jj_nt.next = token_source.getNextToken();
    jj_gen++;
    return token;
  }

/** Get the specific Token. */
  final public Token getToken(int index) {
    Token t = token;
    for (int i = 0; i < index; i++) {
      if (t.next != null) t = t.next;
      else t = t.next = token_source.getNextToken();
    }
    return t;
  }

  private java.util.List jj_expentries = new java.util.ArrayList();
  private int[] jj_expentry;
  private int jj_kind = -1;
  private int[] jj_lasttokens = new int[100];
  private int jj_endpos;

  private void jj_add_error_token(int kind, int pos) {
    if (pos >= 100) {
       return;
    }

    if (pos == jj_endpos + 1) {
      jj_lasttokens[jj_endpos++] = kind;
    } else if (jj_endpos != 0) {
      jj_expentry = new int[jj_endpos];

      for (int i = 0; i < jj_endpos; i++) {
        jj_expentry[i] = jj_lasttokens[i];
      }

      for (int[] oldentry : jj_expentries) {
        if (oldentry.length == jj_expentry.length) {
          boolean isMatched = true;

          for (int i = 0; i < jj_expentry.length; i++) {
            if (oldentry[i] != jj_expentry[i]) {
              isMatched = false;
              break;
            }

          }
          if (isMatched) {
            jj_expentries.add(jj_expentry);
            break;
          }
        }
      }

      if (pos != 0) {
        jj_lasttokens[(jj_endpos = pos) - 1] = kind;
      }
    }
  }

  /** Generate ParseException. */
  public ParseException generateParseException() {
    jj_expentries.clear();
    boolean[] la1tokens = new boolean[73];
    if (jj_kind >= 0) {
      la1tokens[jj_kind] = true;
      jj_kind = -1;
    }
    for (int i = 0; i < 53; i++) {
      if (jj_la1[i] == jj_gen) {
        for (int j = 0; j < 32; j++) {
          if ((jj_la1_0[i] & (1< jj_gen) {
            jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
            switch (i) {
              case 0: jj_3_1(); break;
              case 1: jj_3_2(); break;
            }
          }
          p = p.next;
        } while (p != null);

        } catch(LookaheadSuccess ls) { }
    }
    jj_rescan = false;
  }

  private void jj_save(int index, int xla) {
    JJCalls p = jj_2_rtns[index];
    while (p.gen > jj_gen) {
      if (p.next == null) { p = p.next = new JJCalls(); break; }
      p = p.next;
    }

    p.gen = jj_gen + xla - jj_la; 
    p.first = token;
    p.arg = xla;
  }

  static final class JJCalls {
    int gen;
    Token first;
    int arg;
    JJCalls next;
  }

} // class ParseCpsl





© 2015 - 2024 Weber Informatics LLC | Privacy Policy