1 options {
   2   STATIC = false;
   3   UNICODE_INPUT = true;
   4   JAVA_UNICODE_ESCAPE = true;
   5 }
   6 
   7 PARSER_BEGIN(CompactSyntax)
   8 
   9 package com.sun.xml.internal.rngom.parse.compact;
  10 
  11 import java.io.Reader;
  12 import java.net.MalformedURLException;
  13 import java.net.URL;
  14 import java.util.Arrays;
  15 import java.util.ArrayList;
  16 import java.util.Collections;
  17 import java.util.Enumeration;
  18 import java.util.Hashtable;
  19 import java.util.List;
  20 
  21 import com.sun.xml.internal.rngom.ast.builder.Annotations;
  22 import com.sun.xml.internal.rngom.ast.builder.BuildException;
  23 import com.sun.xml.internal.rngom.ast.builder.CommentList;
  24 import com.sun.xml.internal.rngom.ast.builder.DataPatternBuilder;
  25 import com.sun.xml.internal.rngom.ast.builder.Div;
  26 import com.sun.xml.internal.rngom.ast.builder.ElementAnnotationBuilder;
  27 import com.sun.xml.internal.rngom.ast.builder.Grammar;
  28 import com.sun.xml.internal.rngom.ast.builder.GrammarSection;
  29 import com.sun.xml.internal.rngom.ast.builder.Include;
  30 import com.sun.xml.internal.rngom.ast.builder.IncludedGrammar;
  31 import com.sun.xml.internal.rngom.ast.builder.NameClassBuilder;
  32 import com.sun.xml.internal.rngom.ast.builder.SchemaBuilder;
  33 import com.sun.xml.internal.rngom.ast.builder.Scope;
  34 import com.sun.xml.internal.rngom.ast.om.Location;
  35 import com.sun.xml.internal.rngom.ast.om.ParsedElementAnnotation;
  36 import com.sun.xml.internal.rngom.ast.om.ParsedNameClass;
  37 import com.sun.xml.internal.rngom.ast.om.ParsedPattern;
  38 import com.sun.xml.internal.rngom.parse.Context;
  39 import com.sun.xml.internal.rngom.parse.IllegalSchemaException;
  40 import com.sun.xml.internal.rngom.parse.Parseable;
  41 import org.xml.sax.ErrorHandler;
  42 import org.xml.sax.SAXException;
  43 import org.xml.sax.SAXParseException;
  44 import org.xml.sax.helpers.LocatorImpl;
  45 
  46 import com.sun.xml.internal.rngom.util.Localizer;
  47 import com.sun.xml.internal.rngom.xml.util.WellKnownNamespaces;
  48 
  49 
  50 public class CompactSyntax implements Context {
  51   private static final int IN_ELEMENT = 0;
  52   private static final int IN_ATTRIBUTE = 1;
  53   private static final int IN_ANY_NAME = 2;
  54   private static final int IN_NS_NAME = 4;
  55 
  56   private String defaultNamespace;
  57   private String compatibilityPrefix = null;
  58   private SchemaBuilder sb;
  59   private NameClassBuilder ncb;
  60   private String sourceUri;
  61   /**
  62    * This is what we are parsing right now.
  63    */
  64   private CompactParseable parseable;
  65   private ErrorHandler eh;
  66   private final Hashtable namespaceTable = new Hashtable();
  67   private final Hashtable datatypesTable = new Hashtable();
  68   private boolean hadError = false;
  69   private static final Localizer localizer = new Localizer(new Localizer(Parseable.class),CompactSyntax.class);
  70   private final Hashtable attributeNameTable = new Hashtable();
  71   private boolean annotationsIncludeElements = false;
  72   
  73   /**
  74    * String that represents the inherited namespace.
  75    * 
  76    * <p>
  77    * HACK: we always allocate a new String instance so that
  78    * we can distinguish inherited value from the explicitly
  79    * given value.
  80    */
  81   private /*final*/ String inheritedNs; // essentially final but JavaCC don't let us declare it as so.
  82   
  83   final class LocatedString {
  84     private final String str;
  85     private final Token tok;
  86 
  87     LocatedString(String str, Token tok) {
  88       this.str = str;
  89       this.tok = tok;
  90     }
  91 
  92     String getString() {
  93       return str;
  94     }
  95 
  96     Location getLocation() {
  97       return makeLocation(tok);
  98     }
  99 
 100     Token getToken() {
 101       return tok;
 102     }
 103 
 104   }
 105 
 106   public CompactSyntax(CompactParseable parseable, Reader r, String sourceUri, SchemaBuilder sb, ErrorHandler eh, String inheritedNs) {
 107     this(r);
 108     this.sourceUri = sourceUri;
 109     this.parseable = parseable;
 110     this.sb = sb;
 111     this.ncb = sb.getNameClassBuilder();
 112     this.eh = eh;
 113     // this causes the root pattern to have non-null annotations
 114     // which is useful because it gives a context to trang
 115     this.topLevelComments = sb.makeCommentList();
 116     this.inheritedNs = defaultNamespace = new String(inheritedNs);
 117   }
 118 
 119   ParsedPattern parse(Scope scope) throws IllegalSchemaException {
 120     try {
 121       ParsedPattern p = Input(scope);
 122       if (!hadError)
 123         return p;
 124     }
 125     catch (ParseException e) {
 126       error("syntax_error", e.getMessage(), e.currentToken.next);
 127     }
 128     catch (EscapeSyntaxException e) {
 129       reportEscapeSyntaxException(e);
 130     }
 131     throw new IllegalSchemaException();
 132   }
 133 
 134   ParsedPattern parseInclude(IncludedGrammar g) throws IllegalSchemaException {
 135     try {
 136       ParsedPattern p = IncludedGrammar(g);
 137       if (!hadError)
 138         return p;
 139     }
 140     catch (ParseException e) {
 141       error("syntax_error", e.getMessage(), e.currentToken.next);
 142     }
 143     catch (EscapeSyntaxException e) {
 144       reportEscapeSyntaxException(e);
 145     }
 146     throw new IllegalSchemaException();
 147   }
 148 
 149   private void checkNsName(int context, LocatedString ns) {
 150     if ((context & IN_NS_NAME) != 0)
 151       error("ns_name_except_contains_ns_name", ns.getToken());
 152   }
 153 
 154   private void checkAnyName(int context, Token t) {
 155     if ((context & IN_NS_NAME) != 0)
 156       error("ns_name_except_contains_any_name", t);
 157     if ((context & IN_ANY_NAME) != 0)
 158       error("any_name_except_contains_any_name", t);
 159   }
 160 
 161   private void error(String key, Token tok) {
 162     doError(localizer.message(key), tok);
 163   }
 164 
 165   private void error(String key, String arg, Token tok) {
 166     doError(localizer.message(key, arg), tok);
 167   }
 168 
 169   private void error(String key, String arg1, String arg2, Token tok) {
 170     doError(localizer.message(key, arg1, arg2), tok);
 171   }
 172 
 173   private void doError(String message, Token tok) {
 174     hadError = true;
 175     if (eh != null) {
 176       LocatorImpl loc = new LocatorImpl();
 177       loc.setLineNumber(tok.beginLine);
 178       loc.setColumnNumber(tok.beginColumn);
 179       loc.setSystemId(sourceUri);
 180       try {
 181         eh.error(new SAXParseException(message, loc));
 182       }
 183       catch (SAXException se) {
 184         throw new BuildException(se);
 185       }
 186     }
 187   }
 188 
 189   private void reportEscapeSyntaxException(EscapeSyntaxException e) {
 190     if (eh != null) {
 191       LocatorImpl loc = new LocatorImpl();
 192       loc.setLineNumber(e.getLineNumber());
 193       loc.setColumnNumber(e.getColumnNumber());
 194       loc.setSystemId(sourceUri);
 195       try {
 196         eh.error(new SAXParseException(localizer.message(e.getKey()), loc));
 197       }
 198       catch (SAXException se) {
 199         throw new BuildException(se);
 200       }
 201     }
 202   }
 203 
 204   private static String unquote(String s) {
 205     if (s.length() >= 6 && s.charAt(0) == s.charAt(1)) {
 206       s = s.replace('\u0000', '\n');
 207       return s.substring(3, s.length() - 3);
 208     }
 209     else
 210       return s.substring(1, s.length() - 1);
 211   }
 212 
 213   Location makeLocation(Token t) {
 214     return sb.makeLocation(sourceUri, t.beginLine, t.beginColumn);
 215   }
 216 
 217   private static ParsedPattern[] addPattern(ParsedPattern[] patterns, int i, ParsedPattern p) {
 218     if (i >= patterns.length) {
 219       ParsedPattern[] oldPatterns = patterns;
 220       patterns = new ParsedPattern[oldPatterns.length*2];
 221       System.arraycopy(oldPatterns, 0, patterns, 0, oldPatterns.length);
 222     }
 223     patterns[i] = p;
 224     return patterns;
 225   }
 226 
 227   String getCompatibilityPrefix() {
 228     if (compatibilityPrefix == null) {
 229       compatibilityPrefix = "a";
 230       while (namespaceTable.get(compatibilityPrefix) != null)
 231         compatibilityPrefix = compatibilityPrefix + "a";
 232     }
 233     return compatibilityPrefix;
 234   }
 235 
 236   public String resolveNamespacePrefix(String prefix) {
 237     String result = (String)namespaceTable.get(prefix);
 238     if (result.length() == 0)
 239       return null;
 240     return result;
 241   }
 242 
 243   public Enumeration prefixes() {
 244     return namespaceTable.keys();
 245   }
 246 
 247   public String getBaseUri() {
 248     return sourceUri;
 249   }
 250 
 251   public boolean isUnparsedEntity(String entityName) {
 252     return false;
 253   }
 254 
 255   public boolean isNotation(String notationName) {
 256     return false;
 257   }
 258 
 259   public Context copy() {
 260     return this;
 261   }
 262 
 263   private Context getContext() {
 264     return this;
 265   }
 266 
 267   private CommentList getComments() {
 268     return getComments(getTopLevelComments());
 269   }
 270 
 271   private CommentList topLevelComments;
 272 
 273   private CommentList getTopLevelComments() {
 274     CommentList tem = topLevelComments;
 275     topLevelComments = null;
 276     return tem;
 277   }
 278 
 279   private void noteTopLevelComments() {
 280     topLevelComments = getComments(topLevelComments);
 281   }
 282 
 283   private void topLevelComments(GrammarSection section) {
 284     section.topLevelComment(getComments(null));
 285   }
 286 
 287   private Token lastCommentSourceToken = null;
 288 
 289   private CommentList getComments(CommentList comments) {
 290     Token nextToken = getToken(1);
 291     if (lastCommentSourceToken != nextToken) {
 292       if (lastCommentSourceToken == null)
 293         lastCommentSourceToken = token;
 294       do {
 295         lastCommentSourceToken = lastCommentSourceToken.next;
 296         Token t = lastCommentSourceToken.specialToken;
 297         if (t != null) {
 298           while (t.specialToken != null)
 299             t = t.specialToken;
 300           if (comments == null)
 301             comments = sb.makeCommentList();
 302           for (; t != null; t = t.next) {
 303             String s = mungeComment(t.image);
 304             Location loc = makeLocation(t);
 305             if (t.next != null
 306                 && t.next.kind == CompactSyntaxConstants.SINGLE_LINE_COMMENT_CONTINUE) {
 307               StringBuffer buf = new StringBuffer(s);
 308               do {
 309                 t = t.next;
 310                 buf.append('\n');
 311                 buf.append(mungeComment(t.image));
 312               } while (t.next != null
 313                        && t.next.kind == CompactSyntaxConstants.SINGLE_LINE_COMMENT_CONTINUE);
 314               s = buf.toString();
 315             }
 316             comments.addComment(s, loc);
 317           }
 318         }
 319       } while (lastCommentSourceToken != nextToken);
 320     }
 321     return comments;
 322   }
 323 
 324   private ParsedPattern afterComments(ParsedPattern p) {
 325     CommentList comments = getComments(null);
 326     if (comments == null)
 327       return p;
 328     return sb.commentAfter(p, comments);
 329   }
 330 
 331   private ParsedNameClass afterComments(ParsedNameClass nc) {
 332     CommentList comments = getComments(null);
 333     if (comments == null)
 334       return nc;
 335     return ncb.commentAfter(nc, comments);
 336   }
 337 
 338   private static String mungeComment(String image) {
 339     int i = image.indexOf('#') + 1;
 340     while (i < image.length() && image.charAt(i) == '#')
 341       i++;
 342     if (i < image.length() && image.charAt(i) == ' ')
 343       i++;
 344     return image.substring(i);
 345   }
 346 
 347   private Annotations getCommentsAsAnnotations() {
 348     CommentList comments = getComments();
 349     if (comments == null)
 350       return null;
 351     return sb.makeAnnotations(comments, getContext());
 352   }
 353 
 354   private Annotations addCommentsToChildAnnotations(Annotations a) {
 355     CommentList comments = getComments();
 356     if (comments == null)
 357       return a;
 358     if (a == null)
 359       a = sb.makeAnnotations(null, getContext());
 360     a.addComment(comments);
 361     return a;
 362   }
 363 
 364   private Annotations addCommentsToLeadingAnnotations(Annotations a) {
 365     CommentList comments = getComments();
 366     if (comments == null)
 367       return a;
 368     if (a == null)
 369       return sb.makeAnnotations(comments, getContext());
 370     a.addLeadingComment(comments);
 371     return a;
 372   }
 373 
 374   private Annotations getTopLevelCommentsAsAnnotations() {
 375     CommentList comments = getTopLevelComments();
 376     if (comments == null)
 377       return null;
 378     return sb.makeAnnotations(comments, getContext());
 379   }
 380 
 381   private void clearAttributeList() {
 382     attributeNameTable.clear();
 383   }
 384 
 385   private void addAttribute(Annotations a, String ns, String localName, String prefix, String value, Token tok) {
 386     String key = ns + "#" + localName;
 387     if (attributeNameTable.get(key) != null)
 388       error("duplicate_attribute", ns, localName, tok);
 389     else {
 390       attributeNameTable.put(key, key);
 391       a.addAttribute(ns, localName, prefix, value, makeLocation(tok));
 392     }
 393   }
 394 
 395   private void checkExcept(Token[] except) {
 396     if (except[0] != null)
 397       error("except_missing_parentheses", except[0]);
 398   }
 399 
 400   private String lookupPrefix(String prefix, Token t) {
 401     String ns = (String)namespaceTable.get(prefix);
 402     if (ns == null) {
 403       error("undeclared_prefix", prefix, t);
 404       return "#error";
 405     }
 406     return ns;
 407   }
 408   private String lookupDatatype(String prefix, Token t) {
 409     String ns = (String)datatypesTable.get(prefix);
 410     if (ns == null) {
 411       error("undeclared_prefix", prefix, t);
 412       return ""; // XXX
 413     }
 414     return ns;
 415   }
 416   private String resolve(String str) {
 417     try {
 418      return new URL(new URL(sourceUri), str).toString();
 419     }
 420     catch (MalformedURLException e) { }
 421     return str;
 422   }
 423 }
 424 
 425 PARSER_END(CompactSyntax)
 426 
 427 ParsedPattern Input(Scope scope) :
 428 {
 429   ParsedPattern p;
 430 }
 431 {
 432   Preamble()
 433   (LOOKAHEAD(TopLevelLookahead()) p = TopLevelGrammar(scope)
 434    | p = Expr(true, scope, null, null) { p = afterComments(p); } <EOF>)
 435   { return p; }
 436 }
 437 
 438 void TopLevelLookahead() :
 439 {}
 440 {
 441   <PREFIXED_NAME> "["
 442   | Identifier() ("[" | "=" | "&=" | "|=")
 443   | LookaheadGrammarKeyword()
 444   | LookaheadBody() LookaheadAfterAnnotations()
 445   | LookaheadDocumentation() (LookaheadBody())? LookaheadAfterAnnotations()
 446 }
 447 
 448 void LookaheadAfterAnnotations() :
 449 {}
 450 {
 451   Identifier() ("=" | "&=" | "|=")
 452   | LookaheadGrammarKeyword()
 453 }
 454 
 455 void LookaheadGrammarKeyword() :
 456 {}
 457 {
 458   "start" | "div" | "include"
 459 }
 460 
 461 void LookaheadDocumentation() :
 462 {}
 463 {
 464   ((<DOCUMENTATION> | <DOCUMENTATION_AFTER_SINGLE_LINE_COMMENT>) (<DOCUMENTATION_CONTINUE>)*)+
 465 }
 466 
 467 void LookaheadBody() :
 468 {}
 469 {
 470   "["
 471    (<PREFIXED_NAME> | UnprefixedName() | "=" | <LITERAL> | "~" | LookaheadBody() )*
 472   "]"
 473 }
 474 
 475 ParsedPattern IncludedGrammar(IncludedGrammar g) :
 476 {
 477   Annotations a;
 478   ParsedPattern p;
 479 }
 480 {
 481   Preamble()
 482   (LOOKAHEAD(TopLevelLookahead()) a = GrammarBody(g, g, getTopLevelCommentsAsAnnotations())
 483    | a = Annotations() "grammar" "{" a = GrammarBody(g, g, a) { topLevelComments(g); } "}")
 484   { p = afterComments(g.endIncludedGrammar(sb.makeLocation(sourceUri, 1, 1), a)); }
 485   <EOF>
 486   { return p; }
 487 }
 488 
 489 ParsedPattern TopLevelGrammar(Scope scope) :
 490 {
 491   Annotations a = getTopLevelCommentsAsAnnotations();
 492   Grammar g;
 493   ParsedPattern p;
 494 }
 495 {
 496   { g = sb.makeGrammar(scope); }
 497   a = GrammarBody(g, g, a)
 498   { p = afterComments(g.endGrammar(sb.makeLocation(sourceUri, 1, 1), a)); }
 499   <EOF>
 500   { return p; }
 501 }
 502 
 503 void Preamble() :
 504 {}
 505 {
 506   (NamespaceDecl() | DatatypesDecl())*
 507   {
 508     namespaceTable.put("xml", WellKnownNamespaces.XML);
 509     if (datatypesTable.get("xsd") == null)
 510       datatypesTable.put("xsd", WellKnownNamespaces.XML_SCHEMA_DATATYPES);
 511   }
 512 }
 513 
 514 void NamespaceDecl() :
 515 {
 516   LocatedString prefix = null;
 517   boolean isDefault = false;
 518   String namespaceName;
 519 }
 520 {
 521   { noteTopLevelComments(); }
 522   (("namespace" prefix = UnprefixedName())
 523     | ("default" { isDefault = true; }
 524       "namespace" (prefix = UnprefixedName())?))
 525   "="
 526   namespaceName = NamespaceName()
 527   {
 528     if (isDefault)
 529       defaultNamespace = namespaceName;
 530     if (prefix != null) {
 531       if (prefix.getString().equals("xmlns"))
 532         error("xmlns_prefix", prefix.getToken());
 533       else if (prefix.getString().equals("xml")) {
 534         if (!namespaceName.equals(WellKnownNamespaces.XML))
 535           error("xml_prefix_bad_uri", prefix.getToken());
 536       }
 537       else if (namespaceName.equals(WellKnownNamespaces.XML))
 538         error("xml_uri_bad_prefix", prefix.getToken());
 539       else {
 540         if (namespaceName.equals(WellKnownNamespaces.RELAX_NG_COMPATIBILITY_ANNOTATIONS))
 541           compatibilityPrefix = prefix.getString();
 542         namespaceTable.put(prefix.getString(), namespaceName);
 543       }
 544     }
 545   }
 546 }
 547 
 548 String NamespaceName() :
 549 {
 550   String r;
 551 }
 552 {
 553   (r = Literal() | "inherit" { r = this.inheritedNs; })
 554   { return r; }
 555 }
 556 
 557 void DatatypesDecl() :
 558 {
 559   LocatedString prefix;
 560   String uri;
 561 }
 562 {
 563   { noteTopLevelComments(); }
 564   "datatypes" prefix = UnprefixedName() "=" uri = Literal()
 565   {
 566     datatypesTable.put(prefix.getString(), uri);
 567   }
 568 }
 569 
 570 ParsedPattern AnnotatedPrimaryExpr(boolean topLevel, Scope scope, Token[] except) :
 571 {
 572   Annotations a;
 573   ParsedPattern p;
 574   ParsedElementAnnotation e;
 575   Token t;
 576 }
 577 {
 578   a = Annotations()
 579   p = PrimaryExpr(topLevel, scope, a, except)
 580   ( t = <FANNOTATE> e = AnnotationElement(false) {
 581        if (topLevel)
 582          error("top_level_follow_annotation", t);
 583        else
 584          p = sb.annotateAfter(p, e);
 585      })*
 586   { return p; }
 587 }
 588 
 589 
 590 ParsedPattern PrimaryExpr(boolean topLevel, Scope scope, Annotations a, Token[] except) :
 591 {
 592   ParsedPattern p;
 593 }
 594 {
 595   (p = ElementExpr(scope, a)
 596    | p = AttributeExpr(scope, a)
 597    | p = GrammarExpr(scope, a)
 598    | p = ExternalRefExpr(scope, a)
 599    | p = ListExpr(scope, a)
 600    | p = MixedExpr(scope, a)
 601    | p = ParenExpr(topLevel, scope, a)
 602    | p = IdentifierExpr(scope, a)
 603    | p = ParentExpr(scope, a)
 604    | p = DataExpr(topLevel, scope, a, except)
 605    | p = ValueExpr(topLevel, a)
 606    | p = TextExpr(a)
 607    | p = EmptyExpr(a)
 608    | p = NotAllowedExpr(a))
 609   { return p; }
 610 }
 611 
 612 ParsedPattern EmptyExpr(Annotations a) :
 613 {
 614   Token t;
 615 }
 616 {
 617   t = "empty"
 618   { return sb.makeEmpty(makeLocation(t), a); }
 619 }
 620 
 621 ParsedPattern TextExpr(Annotations a) :
 622 {
 623   Token t;
 624 }
 625 {
 626   t = "text"
 627   { return sb.makeText(makeLocation(t), a); }
 628 }
 629 
 630 ParsedPattern NotAllowedExpr(Annotations a) :
 631 {
 632   Token t;
 633 }
 634 {
 635   t = "notAllowed"
 636   { return sb.makeNotAllowed(makeLocation(t), a); }
 637 }
 638 
 639 ParsedPattern Expr(boolean topLevel, Scope scope, Token t, Annotations a) :
 640 {
 641   List patterns = new ArrayList();
 642   ParsedPattern p;
 643   boolean[] hadOccur = new boolean[1];
 644   Token[] except = new Token[1];
 645 }
 646 {
 647   p = UnaryExpr(topLevel, scope, hadOccur, except)
 648   { patterns.add(p); }
 649   (
 650    { checkExcept(except); }
 651    (t = "|" p = UnaryExpr(topLevel, scope, null, except)
 652      { patterns.add(p); checkExcept(except); } )+
 653     { p = sb.makeChoice(patterns, makeLocation(t), a); }
 654     | (t = "&" p = UnaryExpr(topLevel, scope, null, except)
 655      { patterns.add(p); checkExcept(except); } )+
 656     { p = sb.makeInterleave(patterns, makeLocation(t), a); }
 657     | (t = "," p = UnaryExpr(topLevel, scope, null, except)
 658      { patterns.add(p); checkExcept(except); } )+
 659     { p = sb.makeGroup(patterns, makeLocation(t), a); }
 660   )?
 661   {
 662     if (patterns.size() == 1 && a != null) {
 663       if (hadOccur[0])
 664         p = sb.annotate(p, a);
 665       else
 666         p = sb.makeGroup(patterns, makeLocation(t), a);
 667     }
 668     return p;
 669   }
 670 }
 671 
 672 ParsedPattern UnaryExpr(boolean topLevel, Scope scope, boolean[] hadOccur, Token[] except) :
 673 {
 674   ParsedPattern p;
 675   Token t;
 676   ParsedElementAnnotation e;
 677 }
 678 {
 679   p = AnnotatedPrimaryExpr(topLevel, scope, except)
 680   (
 681    {
 682      if (hadOccur != null) hadOccur[0] = true;
 683      p = afterComments(p);
 684    }
 685    (t = "+" { checkExcept(except); p = sb.makeOneOrMore(p, makeLocation(t), null); }
 686     | t = "?" { checkExcept(except); p = sb.makeOptional(p, makeLocation(t), null); }
 687     | t = "*" { checkExcept(except); p = sb.makeZeroOrMore(p, makeLocation(t), null); })
 688    ( t = <FANNOTATE> e = AnnotationElement(false) {
 689         if (topLevel)
 690           error("top_level_follow_annotation", t);
 691         else
 692           p = sb.annotateAfter(p, e);
 693      } )*
 694   )?
 695   { return p; }
 696 }
 697 
 698 ParsedPattern ElementExpr(Scope scope, Annotations a) :
 699 {
 700   Token t;
 701   ParsedNameClass nc;
 702   ParsedPattern p;
 703 }
 704 {
 705   t = "element"
 706   nc = NameClass(IN_ELEMENT, null)
 707   "{"
 708   p = Expr(false, scope, null, null)
 709   { p = afterComments(p); }
 710   "}"
 711   { return sb.makeElement(nc, p, makeLocation(t), a); }
 712 }
 713 
 714 ParsedPattern AttributeExpr(Scope scope, Annotations a) :
 715 {
 716   Token t;
 717   ParsedNameClass nc;
 718   ParsedPattern p;
 719 }
 720 {
 721   t = "attribute"
 722   nc = NameClass(IN_ATTRIBUTE, null)
 723   "{"
 724   p = Expr(false, scope, null, null)
 725   { p = afterComments(p); }
 726   "}"
 727   { return sb.makeAttribute(nc, p, makeLocation(t), a); }
 728 }
 729 
 730 ParsedNameClass NameClass(int context, Annotations[] pa) :
 731 {
 732   Annotations a;
 733   ParsedNameClass nc;
 734 }
 735 {
 736   a = Annotations()
 737   (nc = PrimaryNameClass(context, a) nc = AnnotateAfter(nc) nc = NameClassAlternatives(context, nc, pa)
 738    | nc = AnyNameExceptClass(context, a, pa)
 739    | nc = NsNameExceptClass(context, a, pa))
 740   { return nc; }
 741 }
 742 
 743 ParsedNameClass AnnotateAfter(ParsedNameClass nc) :
 744 {
 745   ParsedElementAnnotation e;
 746 }
 747 {
 748   ( <FANNOTATE> e = AnnotationElement(false) { nc = ncb.annotateAfter(nc, e); })*
 749   { return nc; }
 750 }
 751 
 752 ParsedNameClass NameClassAlternatives(int context, ParsedNameClass nc, Annotations[] pa) :
 753 {
 754   Token t;
 755   ParsedNameClass[] nameClasses;
 756   int nNameClasses;
 757 }
 758 {
 759   (
 760     {
 761       nameClasses = new ParsedNameClass[2];
 762       nameClasses[0] = nc;
 763       nNameClasses = 1;
 764     }
 765     (t = "|" nc = BasicNameClass(context) nc = AnnotateAfter(nc)
 766     {
 767       if (nNameClasses >= nameClasses.length) {
 768         ParsedNameClass[] oldNameClasses = nameClasses;
 769         nameClasses = new ParsedNameClass[oldNameClasses.length*2];
 770         System.arraycopy(oldNameClasses, 0, nameClasses, 0, oldNameClasses.length);
 771       }
 772       nameClasses[nNameClasses++] = nc;
 773     })+
 774     {
 775       Annotations a;
 776       if (pa == null)
 777         a = null;
 778       else {
 779         a = pa[0];
 780         pa[0] = null;
 781       }
 782       nc = ncb.makeChoice(Arrays.asList(nameClasses).subList(0,nNameClasses), makeLocation(t), a);
 783     }
 784   )?
 785   { return nc; }
 786 }
 787 
 788 ParsedNameClass BasicNameClass(int context) :
 789 {
 790   Annotations a;
 791   ParsedNameClass nc;
 792 }
 793 {
 794   a = Annotations()
 795   (nc = PrimaryNameClass(context, a)
 796    | nc = OpenNameClass(context, a))
 797   { return nc; }
 798 }
 799 
 800 ParsedNameClass PrimaryNameClass(int context, Annotations a) :
 801 {
 802   ParsedNameClass nc;
 803 }
 804 {
 805   (nc = UnprefixedNameClass(context, a)
 806    | nc = PrefixedNameClass(a)
 807    | nc = ParenNameClass(context, a))
 808   { return nc; }
 809 }
 810 
 811 ParsedNameClass OpenNameClass(int context, Annotations a) :
 812 {
 813   Token t;
 814   LocatedString ns;
 815 }
 816 {
 817   ns = NsName() { checkNsName(context, ns); return ncb.makeNsName(ns.getString(), ns.getLocation(), a); }
 818   | t = "*" { checkAnyName(context, t); return ncb.makeAnyName(makeLocation(t), a); }
 819 }
 820 
 821 
 822 ParsedNameClass UnprefixedNameClass(int context, Annotations a) :
 823 {
 824   LocatedString name;
 825 }
 826 {
 827   name = UnprefixedName()
 828   {
 829     String ns;
 830     if ((context & (IN_ATTRIBUTE|IN_ELEMENT)) == IN_ATTRIBUTE)
 831       ns = "";
 832     else
 833       ns = defaultNamespace;
 834     return ncb.makeName(ns, name.getString(), null, name.getLocation(), a);
 835   }
 836 }
 837 
 838 ParsedNameClass PrefixedNameClass(Annotations a) :
 839 {
 840   Token t;
 841 }
 842 {
 843   t = <PREFIXED_NAME>
 844   {
 845     String qn = t.image;
 846     int colon = qn.indexOf(':');
 847     String prefix = qn.substring(0, colon);
 848     return ncb.makeName(lookupPrefix(prefix, t), qn.substring(colon + 1), prefix, makeLocation(t), a);
 849   }
 850 }
 851 
 852 ParsedNameClass NsNameExceptClass(int context, Annotations a, Annotations[] pa) :
 853 {
 854   LocatedString ns;
 855   ParsedNameClass nc;
 856 }
 857 {
 858   ns = NsName()
 859   { checkNsName(context, ns); }
 860   (nc = ExceptNameClass(context | IN_NS_NAME)
 861    { nc = ncb.makeNsName(ns.getString(), nc, ns.getLocation(), a); }
 862    nc = AnnotateAfter(nc)
 863   | { nc = ncb.makeNsName(ns.getString(), ns.getLocation(), a); }
 864     nc = AnnotateAfter(nc)
 865     nc = NameClassAlternatives(context, nc, pa))
 866   { return nc; }
 867 }
 868 
 869 LocatedString NsName() :
 870 {
 871   Token t;
 872 }
 873 {
 874   t = <PREFIX_STAR>
 875   {
 876     String qn = t.image;
 877     String prefix = qn.substring(0, qn.length() - 2);
 878     return new LocatedString(lookupPrefix(prefix, t), t);
 879   }
 880 }
 881 
 882 ParsedNameClass AnyNameExceptClass(int context, Annotations a, Annotations[] pa) :
 883 {
 884   Token t;
 885   ParsedNameClass nc;
 886 }
 887 {
 888   t = "*"
 889   { checkAnyName(context, t); }
 890   (nc = ExceptNameClass(context | IN_ANY_NAME)
 891    { nc = ncb.makeAnyName(nc, makeLocation(t), a); }
 892    nc = AnnotateAfter(nc)
 893   | { nc = ncb.makeAnyName(makeLocation(t), a); }
 894     nc = AnnotateAfter(nc)
 895     nc = NameClassAlternatives(context, nc, pa))
 896   { return nc; }
 897 }
 898 
 899 ParsedNameClass ParenNameClass(int context, Annotations a) :
 900 {
 901   Token t;
 902   ParsedNameClass nc;
 903   Annotations[] pa = new Annotations[]{ a };
 904 }
 905 {
 906   t = "(" nc = NameClass(context, pa) { nc = afterComments(nc); } ")"
 907   {
 908     if (pa[0] != null)
 909       nc = ncb.makeChoice(Collections.singletonList(nc), makeLocation(t), pa[0]);
 910     return nc;
 911   }
 912 }
 913 
 914 ParsedNameClass ExceptNameClass(int context) :
 915 {
 916   ParsedNameClass nc;
 917 }
 918 {
 919   "-" nc = BasicNameClass(context)
 920   { return nc; }
 921 }
 922 
 923 ParsedPattern ListExpr(Scope scope, Annotations a) :
 924 {
 925   Token t;
 926   ParsedPattern p;
 927 }
 928 {
 929   t = "list"
 930   "{"
 931   p = Expr(false, scope, null, null)
 932   { p = afterComments(p); }
 933   "}"
 934   { return sb.makeList(p, makeLocation(t), a); }
 935 }
 936 
 937 ParsedPattern MixedExpr(Scope scope, Annotations a) :
 938 {
 939   Token t;
 940   ParsedPattern p;
 941 }
 942 {
 943   t = "mixed"
 944   "{"
 945   p = Expr(false, scope, null, null)
 946   { p = afterComments(p); }
 947   "}"
 948   { return sb.makeMixed(p, makeLocation(t), a); }
 949 }
 950 
 951 ParsedPattern GrammarExpr(Scope scope, Annotations a) :
 952 {
 953   Token t;
 954   Grammar g;
 955 }
 956 {
 957   t = "grammar" { g = sb.makeGrammar(scope); }
 958   "{" a = GrammarBody(g, g, a) { topLevelComments(g); } "}"
 959   { return g.endGrammar(makeLocation(t), a); }
 960 }
 961 
 962 ParsedPattern ParenExpr(boolean topLevel, Scope scope, Annotations a) :
 963 {
 964   Token t;
 965   ParsedPattern p;
 966 }
 967 {
 968   t = "(" p = Expr(topLevel, scope, t, a) { p = afterComments(p); } ")"
 969   { return p; }
 970 }
 971 
 972 Annotations GrammarBody(GrammarSection section, Scope scope, Annotations a) :
 973 {
 974   ParsedElementAnnotation e;
 975 }
 976 {
 977   (LOOKAHEAD(2) e = AnnotationElementNotKeyword()
 978    { if (a == null) a = sb.makeAnnotations(null, getContext()); a.addElement(e); })*
 979   (GrammarComponent(section, scope))*
 980   { return a; }
 981 }
 982 
 983 void GrammarComponent(GrammarSection section, Scope scope) :
 984 {
 985   ParsedElementAnnotation e;
 986   Annotations a;
 987 }
 988 {
 989   (a = Annotations()
 990    (Definition(section, scope, a)
 991     | Include(section, scope, a)
 992     | Div(section, scope, a)))
 993   (LOOKAHEAD(2) e = AnnotationElementNotKeyword() { section.topLevelAnnotation(e); })*
 994 }
 995 
 996 void Definition(GrammarSection section, Scope scope, Annotations a) :
 997 {}
 998 {
 999   (Define(section, scope, a) | Start(section, scope, a))
1000 }
1001 
1002 void Start(GrammarSection section, Scope scope, Annotations a) :
1003 {
1004   Token t;
1005   GrammarSection.Combine combine;
1006   ParsedPattern p;
1007 }
1008 {
1009   t = "start" combine = AssignOp() p = Expr(false, scope, null, null)
1010   { section.define(GrammarSection.START, combine, p, makeLocation(t), a); }
1011 }
1012 
1013 void Define(GrammarSection section, Scope scope, Annotations a) :
1014 {
1015   LocatedString name;
1016   GrammarSection.Combine combine;
1017   ParsedPattern p;
1018 }
1019 {
1020   name = Identifier() combine = AssignOp() p = Expr(false, scope, null, null)
1021   { section.define(name.getString(), combine, p, name.getLocation(), a); }
1022 }
1023 
1024 GrammarSection.Combine AssignOp() :
1025 {}
1026 {
1027   "=" { return null; }
1028   | "|=" { return GrammarSection.COMBINE_CHOICE; }
1029   | "&=" { return GrammarSection.COMBINE_INTERLEAVE; }
1030 }
1031 
1032 void Include(GrammarSection section, Scope scope, Annotations a) :
1033 {
1034   Token t;
1035   String href;
1036   String ns;
1037   Include include = section.makeInclude();
1038 }
1039 {
1040   t = "include" href = Literal()
1041   ns = Inherit()
1042   ("{" a = IncludeBody(include, scope, a) { topLevelComments(include); } "}")?
1043   {
1044     try {
1045       include.endInclude(parseable, resolve(href), ns, makeLocation(t), a);
1046     }
1047     catch (IllegalSchemaException e) { }
1048   }
1049 }
1050 
1051 Annotations IncludeBody(GrammarSection section, Scope scope, Annotations a) :
1052 {
1053   ParsedElementAnnotation e;
1054 }
1055 {
1056   (LOOKAHEAD(2) e = AnnotationElementNotKeyword()
1057    { if (a == null) a = sb.makeAnnotations(null, getContext()); a.addElement(e); })*
1058   (IncludeComponent(section, scope))*
1059   { return a; }
1060 }
1061 
1062 
1063 void IncludeComponent(GrammarSection section, Scope scope) :
1064 {
1065   ParsedElementAnnotation e;
1066   Annotations a;
1067 }
1068 {
1069   (a = Annotations() (Definition(section, scope, a)
1070                       | IncludeDiv(section, scope, a)))
1071   (LOOKAHEAD(2) e = AnnotationElementNotKeyword() { section.topLevelAnnotation(e); })*
1072 }
1073 
1074 void Div(GrammarSection section, Scope scope, Annotations a) :
1075 {
1076   Token t;
1077   Div div = section.makeDiv();
1078 }
1079 {
1080   t = "div" "{" a = GrammarBody(div, scope, a) { topLevelComments(div); } "}"
1081   { div.endDiv(makeLocation(t), a); }
1082 }
1083 
1084 void IncludeDiv(GrammarSection section, Scope scope, Annotations a) :
1085 {
1086   Token t;
1087   Div div = section.makeDiv();
1088 }
1089 {
1090   t = "div" "{" a = IncludeBody(div, scope, a) { topLevelComments(div); } "}"
1091   { div.endDiv(makeLocation(t), a); }
1092 }
1093 
1094 ParsedPattern ExternalRefExpr(Scope scope, Annotations a) :
1095 {
1096   Token t;
1097   String href;
1098   String ns;
1099 }
1100 {
1101   t = "external" href = Literal()
1102   ns = Inherit()
1103   {
1104     try {
1105       return sb.makeExternalRef(parseable, resolve(href), ns, scope, makeLocation(t), a);
1106     }
1107     catch (IllegalSchemaException e) {
1108       return sb.makeErrorPattern();
1109     }
1110   }
1111 }
1112 
1113 String Inherit() :
1114 {
1115   String ns = null;
1116 }
1117 {
1118   ("inherit" "=" ns = Prefix())?
1119   {
1120     if (ns == null)
1121       ns = defaultNamespace;
1122     return ns;
1123   }
1124 }
1125 
1126 ParsedPattern ParentExpr(Scope scope, Annotations a) :
1127 {
1128   LocatedString name;
1129 }
1130 {
1131   "parent" { a = addCommentsToChildAnnotations(a); } name = Identifier()
1132   {
1133     if(scope==null) {
1134       error("parent_ref_outside_grammar",name.getToken());
1135       return sb.makeErrorPattern();
1136     } else {
1137       return scope.makeParentRef(name.getString(), name.getLocation(), a);
1138     }
1139   }
1140 }
1141 
1142 ParsedPattern IdentifierExpr(Scope scope, Annotations a) :
1143 {
1144   LocatedString name;
1145 }
1146 {
1147   name = Identifier()
1148   {
1149     if(scope==null) {
1150       error("ref_outside_grammar",name.getToken());
1151       return sb.makeErrorPattern();
1152     } else {
1153       return scope.makeRef(name.getString(), name.getLocation(), a);
1154     }
1155   }
1156 }
1157 
1158 ParsedPattern ValueExpr(boolean topLevel, Annotations a) :
1159 {
1160   LocatedString s;
1161 }
1162 {
1163   s = LocatedLiteral()
1164   {
1165     if (topLevel && annotationsIncludeElements) {
1166       error("top_level_follow_annotation", s.getToken());
1167       a = null;
1168     }
1169     return sb.makeValue("", "token", s.getString(), getContext(), defaultNamespace, s.getLocation(), a);
1170   }
1171 }
1172 
1173 ParsedPattern DataExpr(boolean topLevel, Scope scope, Annotations a, Token[] except) :
1174 {
1175   Token datatypeToken;
1176   Location loc;
1177   String datatype;
1178   String datatypeUri = null;
1179   String s = null;
1180   ParsedPattern e = null;
1181   DataPatternBuilder dpb;
1182 }
1183 {
1184   datatypeToken = DatatypeName()
1185   {
1186     datatype = datatypeToken.image;
1187     loc = makeLocation(datatypeToken);
1188     int colon = datatype.indexOf(':');
1189     if (colon < 0)
1190       datatypeUri = "";
1191     else {
1192       String prefix = datatype.substring(0, colon);
1193       datatypeUri = lookupDatatype(prefix, datatypeToken);
1194       datatype = datatype.substring(colon + 1);
1195     }
1196   }
1197   ((s = Literal()
1198     {
1199       if (topLevel && annotationsIncludeElements) {
1200         error("top_level_follow_annotation", datatypeToken);
1201         a = null;
1202       }
1203       return sb.makeValue(datatypeUri, datatype, s, getContext(), defaultNamespace, loc, a);
1204     }
1205   )
1206   | ( { dpb = sb.makeDataPatternBuilder(datatypeUri, datatype, loc); }
1207       ( (Params(dpb) (e = Except(scope, except))?)
1208         | (e = Except(scope, except))?)
1209       { return e == null ? dpb.makePattern(loc, a) : dpb.makePattern(e, loc, a); }))
1210 }
1211 
1212 Token DatatypeName() :
1213 {
1214   Token t;
1215 }
1216 {
1217   (t = "string" | t = "token" | t = <PREFIXED_NAME>)
1218   { return t; }
1219 }
1220 
1221 LocatedString Identifier() :
1222 {
1223   LocatedString s;
1224   Token t;
1225 }
1226 {
1227   (t = <IDENTIFIER> { s = new LocatedString(t.image, t); }
1228   | t = <ESCAPED_IDENTIFIER> { s = new LocatedString(t.image.substring(1), t); })
1229   { return s; }
1230 }
1231 
1232 String Prefix() :
1233 {
1234   Token t;
1235   String prefix;
1236 }
1237 {
1238   (t = <IDENTIFIER> { prefix = t.image; }
1239   | t = <ESCAPED_IDENTIFIER> { prefix = t.image.substring(1); }
1240   | t = Keyword() { prefix = t.image; })
1241   { return lookupPrefix(prefix, t); }
1242 }
1243 
1244 LocatedString UnprefixedName() :
1245 {
1246   LocatedString s;
1247   Token t;
1248 }
1249 {
1250   (s = Identifier()
1251    | t = Keyword() { s = new LocatedString(t.image, t); })
1252   { return s; }
1253 }
1254 
1255 void Params(DataPatternBuilder dpb) :
1256 {}
1257 {
1258   "{" (Param(dpb))* "}"
1259 }
1260 
1261 void Param(DataPatternBuilder dpb) :
1262 {
1263   LocatedString name;
1264   Annotations a;
1265   String value;
1266 }
1267 {
1268   a = Annotations() name = UnprefixedName() "=" { a = addCommentsToLeadingAnnotations(a); } value = Literal()
1269   { dpb.addParam(name.getString(), value, getContext(), defaultNamespace, name.getLocation(), a); }
1270 }
1271 
1272 ParsedPattern Except(Scope scope, Token[] except) :
1273 {
1274   Annotations a;
1275   ParsedPattern p;
1276   Token t;
1277   Token[] innerExcept = new Token[1];
1278 }
1279 {
1280   t = "-" a = Annotations() p = PrimaryExpr(false, scope, a, innerExcept)
1281   {
1282     checkExcept(innerExcept);
1283     except[0] = t;
1284     return p;
1285   }
1286 }
1287 
1288 ParsedElementAnnotation Documentation() :
1289 {
1290   CommentList comments = getComments();
1291   ElementAnnotationBuilder eab;
1292   Token t;
1293 }
1294 {
1295   (t = <DOCUMENTATION> | t = <DOCUMENTATION_AFTER_SINGLE_LINE_COMMENT>)
1296   {
1297     eab = sb.makeElementAnnotationBuilder(WellKnownNamespaces.RELAX_NG_COMPATIBILITY_ANNOTATIONS,
1298                                           "documentation",
1299                                           getCompatibilityPrefix(),
1300                                           makeLocation(t),
1301                                           comments,
1302                                           getContext());
1303     eab.addText(mungeComment(t.image), makeLocation(t), null);
1304   }
1305   (t = <DOCUMENTATION_CONTINUE> { eab.addText("\n" + mungeComment(t.image), makeLocation(t), null); })*
1306   { return eab.makeElementAnnotation(); }
1307 }
1308 
1309 Annotations Annotations() :
1310 {
1311   CommentList comments = getComments();
1312   Annotations a = null;
1313   ParsedElementAnnotation e;
1314 }
1315 {
1316   ( { a = sb.makeAnnotations(comments, getContext()); }
1317     (e = Documentation() { a.addElement(e); })+
1318     {
1319       comments = getComments();
1320       if (comments != null)
1321         a.addLeadingComment(comments);
1322     }
1323   )?
1324   ("[" { if (a == null) a = sb.makeAnnotations(comments, getContext()); clearAttributeList(); annotationsIncludeElements = false; }
1325        (LOOKAHEAD(2) PrefixedAnnotationAttribute(a, false) )*
1326        ( e = AnnotationElement(false) { a.addElement(e); annotationsIncludeElements = true; } )*
1327        { a.addComment(getComments()); }
1328   "]")?
1329   {
1330     if (a == null && comments != null)
1331       a = sb.makeAnnotations(comments, getContext());
1332     return a;
1333   }
1334 }
1335 
1336 void AnnotationAttribute(Annotations a) :
1337 {}
1338 {
1339   PrefixedAnnotationAttribute(a, true) | UnprefixedAnnotationAttribute(a)
1340 }
1341 
1342 void PrefixedAnnotationAttribute(Annotations a, boolean nested) :
1343 {
1344   Token t;
1345   String value;
1346 }
1347 {
1348   t = <PREFIXED_NAME> "=" value = Literal()
1349   {
1350     String qn = t.image;
1351     int colon = qn.indexOf(':');
1352     String prefix = qn.substring(0, colon);
1353     String ns = lookupPrefix(prefix, t);
1354     if (ns == this.inheritedNs)
1355       error("inherited_annotation_namespace", t);
1356     else if (ns.length() == 0 && !nested)
1357       error("unqualified_annotation_attribute", t);
1358     else if (ns.equals(WellKnownNamespaces.RELAX_NG) && !nested)
1359       error("relax_ng_namespace", t);
1360     /*else if (ns.length() == 0
1361              && qn.length() - colon - 1 == 5
1362              && qn.regionMatches(colon + 1, "xmlns", 0, 5))
1363       error("xmlns_annotation_attribute", t);*/
1364     else if (ns.equals(WellKnownNamespaces.XMLNS))
1365       error("xmlns_annotation_attribute_uri", t);
1366     else {
1367       if (ns.length() == 0)
1368         prefix = null;
1369       addAttribute(a, ns, qn.substring(colon + 1), prefix, value, t);
1370     }
1371   }
1372 }
1373 
1374 void UnprefixedAnnotationAttribute(Annotations a) :
1375 {
1376   LocatedString name;
1377   String value;
1378 }
1379 {
1380   name = UnprefixedName() "=" value = Literal()
1381   {
1382     if (name.getString().equals("xmlns"))
1383       error("xmlns_annotation_attribute", name.getToken());
1384     else
1385       addAttribute(a, "", name.getString(), null, value, name.getToken());
1386   }
1387 }
1388 
1389 ParsedElementAnnotation AnnotationElement(boolean nested) :
1390 {
1391   ParsedElementAnnotation a;
1392 }
1393 {
1394   (a = PrefixedAnnotationElement(nested)
1395    | a = UnprefixedAnnotationElement())
1396   { return a; }
1397 }
1398 
1399 ParsedElementAnnotation AnnotationElementNotKeyword() :
1400 {
1401   ParsedElementAnnotation a;
1402 }
1403 {
1404   (a = PrefixedAnnotationElement(false)
1405    | a = IdentifierAnnotationElement())
1406   { return a; }
1407 }
1408 
1409 ParsedElementAnnotation PrefixedAnnotationElement(boolean nested) :
1410 {
1411   CommentList comments = getComments();
1412   Token t;
1413   ElementAnnotationBuilder eab;
1414 }
1415 {
1416   t = <PREFIXED_NAME>
1417   {
1418     String qn = t.image;
1419     int colon = qn.indexOf(':');
1420     String prefix = qn.substring(0, colon);
1421     String ns = lookupPrefix(prefix, t);
1422     if (ns == this.inheritedNs) {
1423       error("inherited_annotation_namespace", t);
1424       ns = "";
1425     }
1426     else if (!nested && ns.equals(WellKnownNamespaces.RELAX_NG)) {
1427       error("relax_ng_namespace", t);
1428       ns = "";
1429     }
1430     else {
1431       if (ns.length() == 0)
1432         prefix = null;
1433     }
1434     eab = sb.makeElementAnnotationBuilder(ns, qn.substring(colon + 1), prefix,
1435                                           makeLocation(t), comments, getContext());
1436   }
1437   AnnotationElementContent(eab)
1438   { return eab.makeElementAnnotation(); }
1439 }
1440 
1441 ParsedElementAnnotation UnprefixedAnnotationElement() :
1442 {
1443   CommentList comments = getComments();
1444   LocatedString name;
1445   ElementAnnotationBuilder eab;
1446 }
1447 {
1448   name = UnprefixedName()
1449   {
1450     eab = sb.makeElementAnnotationBuilder("", name.getString(), null,
1451                                           name.getLocation(), comments, getContext());
1452   }
1453   AnnotationElementContent(eab)
1454   { return eab.makeElementAnnotation(); }
1455 }
1456 
1457 ParsedElementAnnotation IdentifierAnnotationElement() :
1458 {
1459   CommentList comments = getComments();
1460   LocatedString name;
1461   ElementAnnotationBuilder eab;
1462 }
1463 {
1464   name = Identifier()
1465   {
1466     eab = sb.makeElementAnnotationBuilder("", name.getString(), null,
1467                                           name.getLocation(), comments, getContext());
1468   }
1469   AnnotationElementContent(eab)
1470   { return eab.makeElementAnnotation(); }
1471 }
1472 
1473 void AnnotationElementContent(ElementAnnotationBuilder eab) :
1474 {
1475   ParsedElementAnnotation e;
1476 }
1477 {
1478   "[" { clearAttributeList(); }
1479   (LOOKAHEAD(2) AnnotationAttribute(eab))*
1480   ((AnnotationElementLiteral(eab)
1481     ("~" AnnotationElementLiteral(eab))*)
1482    | e = AnnotationElement(true) { eab.addElement(e); })*
1483   { eab.addComment(getComments()); }
1484   "]"
1485 }
1486 
1487 void AnnotationElementLiteral(ElementAnnotationBuilder eab) :
1488 {
1489   Token t;
1490   CommentList comments = getComments();
1491 }
1492 {
1493   t = <LITERAL> { eab.addText(unquote(t.image), makeLocation(t), comments); }
1494 }
1495 
1496 String Literal() :
1497 {
1498   Token t;
1499   String s;
1500   StringBuffer buf;
1501 }
1502 {
1503   t = <LITERAL>
1504   {
1505     s = unquote(t.image);
1506   }
1507   (
1508     { buf = new StringBuffer(s); }
1509     ("~" t = <LITERAL> { buf.append(unquote(t.image)); })+
1510     { s = buf.toString(); }
1511   )?
1512   { return s; }
1513 }
1514 
1515 LocatedString LocatedLiteral() :
1516 {
1517   Token t;
1518   Token t2;
1519   String s;
1520   StringBuffer buf;
1521 }
1522 {
1523   t = <LITERAL>
1524   {
1525     s = unquote(t.image);
1526   }
1527   (
1528     { buf = new StringBuffer(s); }
1529     ("~" t2 = <LITERAL> { buf.append(unquote(t2.image)); })+
1530     { s = buf.toString(); }
1531   )?
1532   { return new LocatedString(s, t); }
1533 }
1534 
1535 Token Keyword() :
1536 {
1537   Token t;
1538 }
1539 {
1540   (t = "element"
1541   | t = "attribute"
1542   | t = "namespace"
1543   | t = "list"
1544   | t = "mixed"
1545   | t = "grammar"
1546   | t = "empty"
1547   | t = "text"
1548   | t = "parent"
1549   | t = "external"
1550   | t = "notAllowed"
1551   | t = "start"
1552   | t = "include"
1553   | t = "default"
1554   | t = "inherit"
1555   | t = "string"
1556   | t = "token"
1557   | t = "datatypes"
1558   | t = "div")
1559   { return t; }
1560 }
1561 
1562 <*>
1563 SKIP: {
1564   < #NEWLINE : [ "\u0000", "\n" ] >
1565   | < #NOT_NEWLINE : ~[ "\u0000", "\n" ] >
1566   | < WS: ([ "\u0000", " ", "\n", "\t" ])+ > : DEFAULT
1567 }
1568 
1569 TOKEN :
1570 {
1571   < DOCUMENTATION: "##" (<NOT_NEWLINE>)* > : AFTER_DOCUMENTATION
1572 }
1573 
1574 <AFTER_DOCUMENTATION>
1575 TOKEN :
1576 {
1577   < DOCUMENTATION_CONTINUE: <NEWLINE> ([" ", "\t"])* <DOCUMENTATION> >
1578 }
1579 
1580 SPECIAL_TOKEN:
1581 {
1582   < SINGLE_LINE_COMMENT: "#" (<NOT_NEWLINE>)* > : AFTER_SINGLE_LINE_COMMENT
1583 }
1584 
1585 <AFTER_SINGLE_LINE_COMMENT>
1586 TOKEN :
1587 {
1588   < DOCUMENTATION_AFTER_SINGLE_LINE_COMMENT: <NEWLINE> ([" ", "\t"])* <DOCUMENTATION> > : AFTER_DOCUMENTATION
1589 }
1590 
1591 <AFTER_SINGLE_LINE_COMMENT>
1592 SPECIAL_TOKEN :
1593 {
1594   < SINGLE_LINE_COMMENT_CONTINUE: <NEWLINE> ([" ", "\t"])* <SINGLE_LINE_COMMENT> >
1595 }
1596 
1597 TOKEN :
1598 {
1599   < #BASE_CHAR : [
1600     "\u0041" - "\u005a",
1601     "\u0061" - "\u007a",
1602     "\u00c0" - "\u00d6",
1603     "\u00d8" - "\u00f6",
1604     "\u00f8" - "\u00ff",
1605     "\u0100" - "\u0131",
1606     "\u0134" - "\u013e",
1607     "\u0141" - "\u0148",
1608     "\u014a" - "\u017e",
1609     "\u0180" - "\u01c3",
1610     "\u01cd" - "\u01f0",
1611     "\u01f4" - "\u01f5",
1612     "\u01fa" - "\u0217",
1613     "\u0250" - "\u02a8",
1614     "\u02bb" - "\u02c1",
1615     "\u0386",
1616     "\u0388" - "\u038a",
1617     "\u038c",
1618     "\u038e" - "\u03a1",
1619     "\u03a3" - "\u03ce",
1620     "\u03d0" - "\u03d6",
1621     "\u03da",
1622     "\u03dc",
1623     "\u03de",
1624     "\u03e0",
1625     "\u03e2" - "\u03f3",
1626     "\u0401" - "\u040c",
1627     "\u040e" - "\u044f",
1628     "\u0451" - "\u045c",
1629     "\u045e" - "\u0481",
1630     "\u0490" - "\u04c4",
1631     "\u04c7" - "\u04c8",
1632     "\u04cb" - "\u04cc",
1633     "\u04d0" - "\u04eb",
1634     "\u04ee" - "\u04f5",
1635     "\u04f8" - "\u04f9",
1636     "\u0531" - "\u0556",
1637     "\u0559",
1638     "\u0561" - "\u0586",
1639     "\u05d0" - "\u05ea",
1640     "\u05f0" - "\u05f2",
1641     "\u0621" - "\u063a",
1642     "\u0641" - "\u064a",
1643     "\u0671" - "\u06b7",
1644     "\u06ba" - "\u06be",
1645     "\u06c0" - "\u06ce",
1646     "\u06d0" - "\u06d3",
1647     "\u06d5",
1648     "\u06e5" - "\u06e6",
1649     "\u0905" - "\u0939",
1650     "\u093d",
1651     "\u0958" - "\u0961",
1652     "\u0985" - "\u098c",
1653     "\u098f" - "\u0990",
1654     "\u0993" - "\u09a8",
1655     "\u09aa" - "\u09b0",
1656     "\u09b2",
1657     "\u09b6" - "\u09b9",
1658     "\u09dc" - "\u09dd",
1659     "\u09df" - "\u09e1",
1660     "\u09f0" - "\u09f1",
1661     "\u0a05" - "\u0a0a",
1662     "\u0a0f" - "\u0a10",
1663     "\u0a13" - "\u0a28",
1664     "\u0a2a" - "\u0a30",
1665     "\u0a32" - "\u0a33",
1666     "\u0a35" - "\u0a36",
1667     "\u0a38" - "\u0a39",
1668     "\u0a59" - "\u0a5c",
1669     "\u0a5e",
1670     "\u0a72" - "\u0a74",
1671     "\u0a85" - "\u0a8b",
1672     "\u0a8d",
1673     "\u0a8f" - "\u0a91",
1674     "\u0a93" - "\u0aa8",
1675     "\u0aaa" - "\u0ab0",
1676     "\u0ab2" - "\u0ab3",
1677     "\u0ab5" - "\u0ab9",
1678     "\u0abd",
1679     "\u0ae0",
1680     "\u0b05" - "\u0b0c",
1681     "\u0b0f" - "\u0b10",
1682     "\u0b13" - "\u0b28",
1683     "\u0b2a" - "\u0b30",
1684     "\u0b32" - "\u0b33",
1685     "\u0b36" - "\u0b39",
1686     "\u0b3d",
1687     "\u0b5c" - "\u0b5d",
1688     "\u0b5f" - "\u0b61",
1689     "\u0b85" - "\u0b8a",
1690     "\u0b8e" - "\u0b90",
1691     "\u0b92" - "\u0b95",
1692     "\u0b99" - "\u0b9a",
1693     "\u0b9c",
1694     "\u0b9e" - "\u0b9f",
1695     "\u0ba3" - "\u0ba4",
1696     "\u0ba8" - "\u0baa",
1697     "\u0bae" - "\u0bb5",
1698     "\u0bb7" - "\u0bb9",
1699     "\u0c05" - "\u0c0c",
1700     "\u0c0e" - "\u0c10",
1701     "\u0c12" - "\u0c28",
1702     "\u0c2a" - "\u0c33",
1703     "\u0c35" - "\u0c39",
1704     "\u0c60" - "\u0c61",
1705     "\u0c85" - "\u0c8c",
1706     "\u0c8e" - "\u0c90",
1707     "\u0c92" - "\u0ca8",
1708     "\u0caa" - "\u0cb3",
1709     "\u0cb5" - "\u0cb9",
1710     "\u0cde",
1711     "\u0ce0" - "\u0ce1",
1712     "\u0d05" - "\u0d0c",
1713     "\u0d0e" - "\u0d10",
1714     "\u0d12" - "\u0d28",
1715     "\u0d2a" - "\u0d39",
1716     "\u0d60" - "\u0d61",
1717     "\u0e01" - "\u0e2e",
1718     "\u0e30",
1719     "\u0e32" - "\u0e33",
1720     "\u0e40" - "\u0e45",
1721     "\u0e81" - "\u0e82",
1722     "\u0e84",
1723     "\u0e87" - "\u0e88",
1724     "\u0e8a",
1725     "\u0e8d",
1726     "\u0e94" - "\u0e97",
1727     "\u0e99" - "\u0e9f",
1728     "\u0ea1" - "\u0ea3",
1729     "\u0ea5",
1730     "\u0ea7",
1731     "\u0eaa" - "\u0eab",
1732     "\u0ead" - "\u0eae",
1733     "\u0eb0",
1734     "\u0eb2" - "\u0eb3",
1735     "\u0ebd",
1736     "\u0ec0" - "\u0ec4",
1737     "\u0f40" - "\u0f47",
1738     "\u0f49" - "\u0f69",
1739     "\u10a0" - "\u10c5",
1740     "\u10d0" - "\u10f6",
1741     "\u1100",
1742     "\u1102" - "\u1103",
1743     "\u1105" - "\u1107",
1744     "\u1109",
1745     "\u110b" - "\u110c",
1746     "\u110e" - "\u1112",
1747     "\u113c",
1748     "\u113e",
1749     "\u1140",
1750     "\u114c",
1751     "\u114e",
1752     "\u1150",
1753     "\u1154" - "\u1155",
1754     "\u1159",
1755     "\u115f" - "\u1161",
1756     "\u1163",
1757     "\u1165",
1758     "\u1167",
1759     "\u1169",
1760     "\u116d" - "\u116e",
1761     "\u1172" - "\u1173",
1762     "\u1175",
1763     "\u119e",
1764     "\u11a8",
1765     "\u11ab",
1766     "\u11ae" - "\u11af",
1767     "\u11b7" - "\u11b8",
1768     "\u11ba",
1769     "\u11bc" - "\u11c2",
1770     "\u11eb",
1771     "\u11f0",
1772     "\u11f9",
1773     "\u1e00" - "\u1e9b",
1774     "\u1ea0" - "\u1ef9",
1775     "\u1f00" - "\u1f15",
1776     "\u1f18" - "\u1f1d",
1777     "\u1f20" - "\u1f45",
1778     "\u1f48" - "\u1f4d",
1779     "\u1f50" - "\u1f57",
1780     "\u1f59",
1781     "\u1f5b",
1782     "\u1f5d",
1783     "\u1f5f" - "\u1f7d",
1784     "\u1f80" - "\u1fb4",
1785     "\u1fb6" - "\u1fbc",
1786     "\u1fbe",
1787     "\u1fc2" - "\u1fc4",
1788     "\u1fc6" - "\u1fcc",
1789     "\u1fd0" - "\u1fd3",
1790     "\u1fd6" - "\u1fdb",
1791     "\u1fe0" - "\u1fec",
1792     "\u1ff2" - "\u1ff4",
1793     "\u1ff6" - "\u1ffc",
1794     "\u2126",
1795     "\u212a" - "\u212b",
1796     "\u212e",
1797     "\u2180" - "\u2182",
1798     "\u3041" - "\u3094",
1799     "\u30a1" - "\u30fa",
1800     "\u3105" - "\u312c",
1801     "\uac00" - "\ud7a3"
1802     ] >
1803   | < #IDEOGRAPHIC : [
1804     "\u4e00" - "\u9fa5",
1805     "\u3007",
1806     "\u3021" - "\u3029"
1807     ] >
1808   | < #LETTER : (<BASE_CHAR> | <IDEOGRAPHIC>) >
1809   | < #COMBINING_CHAR : [
1810     "\u0300" - "\u0345",
1811     "\u0360" - "\u0361",
1812     "\u0483" - "\u0486",
1813     "\u0591" - "\u05a1",
1814     "\u05a3" - "\u05b9",
1815     "\u05bb" - "\u05bd",
1816     "\u05bf",
1817     "\u05c1" - "\u05c2",
1818     "\u05c4",
1819     "\u064b" - "\u0652",
1820     "\u0670",
1821     "\u06d6" - "\u06dc",
1822     "\u06dd" - "\u06df",
1823     "\u06e0" - "\u06e4",
1824     "\u06e7" - "\u06e8",
1825     "\u06ea" - "\u06ed",
1826     "\u0901" - "\u0903",
1827     "\u093c",
1828     "\u093e" - "\u094c",
1829     "\u094d",
1830     "\u0951" - "\u0954",
1831     "\u0962" - "\u0963",
1832     "\u0981" - "\u0983",
1833     "\u09bc",
1834     "\u09be",
1835     "\u09bf",
1836     "\u09c0" - "\u09c4",
1837     "\u09c7" - "\u09c8",
1838     "\u09cb" - "\u09cd",
1839     "\u09d7",
1840     "\u09e2" - "\u09e3",
1841     "\u0a02",
1842     "\u0a3c",
1843     "\u0a3e",
1844     "\u0a3f",
1845     "\u0a40" - "\u0a42",
1846     "\u0a47" - "\u0a48",
1847     "\u0a4b" - "\u0a4d",
1848     "\u0a70" - "\u0a71",
1849     "\u0a81" - "\u0a83",
1850     "\u0abc",
1851     "\u0abe" - "\u0ac5",
1852     "\u0ac7" - "\u0ac9",
1853     "\u0acb" - "\u0acd",
1854     "\u0b01" - "\u0b03",
1855     "\u0b3c",
1856     "\u0b3e" - "\u0b43",
1857     "\u0b47" - "\u0b48",
1858     "\u0b4b" - "\u0b4d",
1859     "\u0b56" - "\u0b57",
1860     "\u0b82" - "\u0b83",
1861     "\u0bbe" - "\u0bc2",
1862     "\u0bc6" - "\u0bc8",
1863     "\u0bca" - "\u0bcd",
1864     "\u0bd7",
1865     "\u0c01" - "\u0c03",
1866     "\u0c3e" - "\u0c44",
1867     "\u0c46" - "\u0c48",
1868     "\u0c4a" - "\u0c4d",
1869     "\u0c55" - "\u0c56",
1870     "\u0c82" - "\u0c83",
1871     "\u0cbe" - "\u0cc4",
1872     "\u0cc6" - "\u0cc8",
1873     "\u0cca" - "\u0ccd",
1874     "\u0cd5" - "\u0cd6",
1875     "\u0d02" - "\u0d03",
1876     "\u0d3e" - "\u0d43",
1877     "\u0d46" - "\u0d48",
1878     "\u0d4a" - "\u0d4d",
1879     "\u0d57",
1880     "\u0e31",
1881     "\u0e34" - "\u0e3a",
1882     "\u0e47" - "\u0e4e",
1883     "\u0eb1",
1884     "\u0eb4" - "\u0eb9",
1885     "\u0ebb" - "\u0ebc",
1886     "\u0ec8" - "\u0ecd",
1887     "\u0f18" - "\u0f19",
1888     "\u0f35",
1889     "\u0f37",
1890     "\u0f39",
1891     "\u0f3e",
1892     "\u0f3f",
1893     "\u0f71" - "\u0f84",
1894     "\u0f86" - "\u0f8b",
1895     "\u0f90" - "\u0f95",
1896     "\u0f97",
1897     "\u0f99" - "\u0fad",
1898     "\u0fb1" - "\u0fb7",
1899     "\u0fb9",
1900     "\u20d0" - "\u20dc",
1901     "\u20e1",
1902     "\u302a" - "\u302f",
1903     "\u3099",
1904     "\u309a"
1905     ] >
1906   | < #DIGIT : [
1907     "\u0030" - "\u0039",
1908     "\u0660" - "\u0669",
1909     "\u06f0" - "\u06f9",
1910     "\u0966" - "\u096f",
1911     "\u09e6" - "\u09ef",
1912     "\u0a66" - "\u0a6f",
1913     "\u0ae6" - "\u0aef",
1914     "\u0b66" - "\u0b6f",
1915     "\u0be7" - "\u0bef",
1916     "\u0c66" - "\u0c6f",
1917     "\u0ce6" - "\u0cef",
1918     "\u0d66" - "\u0d6f",
1919     "\u0e50" - "\u0e59",
1920     "\u0ed0" - "\u0ed9",
1921     "\u0f20" - "\u0f29"
1922     ] >
1923   | < #EXTENDER : [
1924     "\u00b7",
1925     "\u02d0",
1926     "\u02d1",
1927     "\u0387",
1928     "\u0640",
1929     "\u0e46",
1930     "\u0ec6",
1931     "\u3005",
1932     "\u3031" - "\u3035",
1933     "\u309d" - "\u309e",
1934     "\u30fc" - "\u30fe"
1935     ] >
1936   | < #NMSTART : (<LETTER> | "_") >
1937   | < #NMCHAR : (<LETTER> | <COMBINING_CHAR> | <EXTENDER> | <DIGIT> | "." | "-" | "_") >
1938   | < #NCNAME: <NMSTART> (<NMCHAR>)* >
1939 }
1940 
1941 TOKEN :
1942 {
1943   < IDENTIFIER: <NCNAME> >
1944   | < ESCAPED_IDENTIFIER: "\\" <NCNAME> >
1945   | < PREFIX_STAR: <NCNAME> ":*" >
1946   | < PREFIXED_NAME: <NCNAME> ":" <NCNAME> >
1947   | < LITERAL : ("\"" (~["\u0000", "\""])* "\"")
1948                 | ("'" (~["\u0000", "'"])* "'")
1949                 | ("\"\"\"" (~["\""]
1950                              | ("\"" ~["\""])
1951                              | ("\"\"" ~["\""]))* "\"\"\"")
1952                 | ("'''" (~["'"]
1953                              | ("'" ~["'"])
1954                              | ("''" ~["'"]))* "'''") >
1955   | < FANNOTATE : ">>" >
1956 }
1957 
1958 /* This avoids lexical errors from JavaCC. */
1959 <*>
1960 TOKEN :
1961 {
1962   < ILLEGAL_CHAR : [ "\u0000" - "\u0008", "\u000b" - "\uffff" ] >
1963 }