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 encoding) throws 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 existingMacros) throws IOException {
0035 this(url, encoding, existingMacros, new HashMap());
0036 }
0037
0038 public ParseCpsl(URL url, String encoding, HashMap existingMacros, HashMap existingTemplates) throws 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 sptURL) throws IOException{
0073 return new ParseCpsl(sptURL, encoding, macrosMap, templatesMap);
0074 }
0075
0076 protected void finishSPT(SinglePhaseTransducer t) throws 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 == null) formatter = 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> values) throws 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 (true) throw 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 (true) throw 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 (true) throw 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 (true) throw(
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 (true) throw(new ParseException(errorMsgPrefix(phaseNameTok)+
0415 "Read error " + mue.toString()));}
0416 }
0417
0418 if(sptURL == null){
0419 {if (true) throw(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 (true) throw(
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 (true) return m;}
0473 throw new Error("Missing return statement in function");
0474 }
0475
0476 // _MultiPhaseTransducer
0477 final public SinglePhaseTransducer SinglePhaseTransducer(String javaimportblock) throws 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 (true) return 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 (true) return defaultimportblock+importblock;}
0646 } else {
0647 {if (true) return 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 (true) return 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 (true) return 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 (true) return block;}
0676 throw new Error("Missing return statement in function");
0677 }
0678
0679 final public Rule Rule(String phaseName, String currentImports) throws 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 (true) throw 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 (true) return 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 (true) return 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 cg) throws 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 lhs) throws 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 (true) throw(new ParseException(errorMsgPrefix(macroRefTok)+
0853 "unknown macro name " + macroRefTok.image));}
0854 else if(macro instanceof String[])
0855 {if (true) throw(
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 (true) throw(
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) ((PatternElement) macro).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 = ((ComplexPatternElement) pat).getBindingName();
0888
0889 if(bindingName != null && lhs != null) {
0890
0891 try {
0892 lhs.addBinding(
0893 bindingName, (ComplexPatternElement) pat, 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 (true) return 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 (true) return bpe;}
0949 throw new Error("Missing return statement in function");
0950 }
0951
0952 // BasicPatternElement
0953 final public ComplexPatternElement ComplexPatternElement(LeftHandSide lhs) throws 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 (true) return 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 (true) return new KleeneOperator(KleeneOperator.Type.SINGLE);}
1008 }
1009
1010 KleeneOperator.Type type = KleeneOperator.Type.getFromSymbol(kleeneOpTok.image);
1011 if (type != null)
1012 {if (true) return new KleeneOperator(type);}
1013 else {
1014 System.err.println(errorMsgPrefix(kleeneOpTok)+
1015 "ignoring uninterpretable Kleene op " + kleeneOpTok.image);
1016 {if (true) return 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 (true) return 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(negate) c.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 (true) return 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 (true) return 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 (true) return val;}
1218 break;
1219 case leftSquare:
1220 val = TemplateCall();
1221 {if (true) return 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 (true) return 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 imports) throws 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 (true) return 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 checkLabel) throws 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 (true) throw(new ParseException(errorMsgPrefix(macroRefTok)+
1318 "unknown macro name " + macroRefTok.image));}
1319 else if(macro instanceof PatternElement)
1320 {if (true) throw(
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 (true) throw(
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 (true) throw(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 (true) return 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 checkLabel) throws 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 (true) throw(new ParseException(errorMsgPrefix(nameTok)+
1370 "unknown label in RHS action: " + block[0]));}
1371 }
1372 jj_consume_token(leftBrace);
1373 block[1] = ConsumeBlock();
1374 {if (true) return 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[0] = null;
1382 jj_consume_token(leftBrace);
1383 block[1] = ConsumeBlock();
1384 {if (true) return 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 checkLabel) throws 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 (true) throw 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 (true) throw(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(((Integer) attrVal.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 (true) throw(
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 (true) throw 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 (true) return block;}
1637 throw new Error("Missing return statement in function");
1638 }
1639
1640 void appendSpecials(Token tok, StringBuffer block) throws 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 != 0) nextTok = 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, 1, 1); } 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[i] = new 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, 1, 1); } 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[i] = new JJCalls();
1878 }
1879
1880 public ParseCpsl(java.io.Reader stream) {
1881 jj_input_stream = new SimpleCharStream(stream, 1, 1);
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[i] = new JJCalls();
1888 }
1889
1890 public void ReInit(java.io.Reader stream) {
1891 jj_input_stream.ReInit(stream, 1, 1);
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[i] = new 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[i] = new 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[i] = new JJCalls();
1916 }
1917
1918 final private Token jj_consume_token(int kind) throws ParseException {
1919 Token oldToken = token;
1920 if ((token = jj_nt).next != null) jj_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_gen) c.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 != null) jj_add_error_token(kind, i);
1959 }
1960 if (jj_scanpos.kind != kind) return true;
1961 if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
1962 return false;
1963 }
1964
1965 final public Token getNextToken() {
1966 if ((token = jj_nt).next != null) jj_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 != null) t = 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 >= 100) return;
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 (exists) break;
2008 }
2009 }
2010 if (!exists) jj_expentries.addElement(jj_expentry);
2011 if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = 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[i] = false;
2020 }
2021 if (jj_kind >= 0) {
2022 la1tokens[jj_kind] = true;
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[j] = true;
2030 }
2031 if ((jj_la1_1[i] & (1<<j)) != 0) {
2032 la1tokens[32+j] = true;
2033 }
2034 if ((jj_la1_2[i] & (1<<j)) != 0) {
2035 la1tokens[64+j] = true;
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(0, 0);
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 }
|