--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class BooleanLiteral extends Literal {
+ Boolean val;
+ BooleanLiteral(boolean b) { this.val = new Boolean(b); }
+
+ Symbol token() { return new Symbol(Sym.BOOLEAN_LITERAL, val); }
+
+ public String toString() { return "BooleanLiteral <"+val.toString()+">"; }
+}
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class CharacterLiteral extends Literal {
+ Character val;
+ CharacterLiteral(char c) { this.val = new Character(c); }
+
+ Symbol token() { return new Symbol(Sym.CHARACTER_LITERAL, val); }
+
+ public String toString() {
+ return "CharacterLiteral <"+Token.escape(val.toString())+">";
+ }
+}
--- /dev/null
+package Lex;
+
+abstract class Comment extends InputElement {
+ private StringBuffer comment = new StringBuffer();
+
+ String getComment() { return comment.toString(); }
+
+ void appendLine(String more) { // 'more' is '\n' terminated.
+ int i=0;
+
+ // skip leading white space.
+ for (; i<more.length(); i++)
+ if (!Character.isSpaceChar(more.charAt(i)))
+ break;
+
+ // skip any leading stars.
+ for (; i<more.length(); i++)
+ if (more.charAt(i)!='*')
+ break;
+
+ // the rest of the string belongs to the comment.
+ if (i<more.length())
+ comment.append(more.substring(i));
+ }
+
+}
--- /dev/null
+package Lex;
+
+class DocumentationComment extends Comment {
+ DocumentationComment() { }
+}
+
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class DoubleLiteral extends NumericLiteral {
+ DoubleLiteral(double d) { this.val = new Double(d); }
+
+ Symbol token() { return new Symbol(Sym.FLOATING_POINT_LITERAL, val); }
+}
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class EOF extends Token {
+ EOF() {}
+ Symbol token() { return new Symbol(Sym.EOF); }
+ public String toString() { return "EOF"; }
+}
--- /dev/null
+package Lex;
+
+class EndOfLineComment extends Comment {
+ EndOfLineComment(String comment) { appendLine(comment); }
+}
--- /dev/null
+package Lex;
+
+import java.io.Reader;
+import java.io.FilterReader;
+import java.io.IOException;
+
+public class EscapedUnicodeReader extends FilterReader {
+
+ int pushback=-1;
+ boolean isEvenSlash = true;
+
+ public EscapedUnicodeReader(Reader in) {
+ super(in);
+ }
+ public int read() throws IOException {
+ int r = (pushback==-1)?in.read():pushback; pushback=-1;
+
+ if (r!='\\') {
+ isEvenSlash=true;
+ return r;
+ } else { // found a backslash;
+ if (!isEvenSlash) { // Only even slashes are eligible unicode escapes.
+ isEvenSlash=true;
+ return r;
+ }
+
+ // Check for the trailing u.
+ pushback=in.read();
+ if (pushback!='u') {
+ isEvenSlash=false;
+ return '\\';
+ }
+
+ // OK, we've found backslash-u.
+ // Reset pushback and snarf up all trailing u's.
+ pushback=-1;
+ while((r=in.read())=='u')
+ ;
+ // Now we should find 4 hex digits.
+ // If we don't, we can raise bloody hell.
+ int val=0;
+ for (int i=0; i<4; i++, r=in.read()) {
+ int d=Character.digit((char)r, 16);
+ if (r<0 || d<0)
+ throw new Error("Invalid unicode escape character.");
+ val = (val*16) + d;
+ }
+ // yeah, we made it.
+ pushback = r;
+ isEvenSlash=true;
+ return val;
+ }
+ }
+ // synthesize array read from single-character read.
+ public int read(char cbuf[], int off, int len) throws IOException {
+ for (int i=0; i<len; i++) {
+ int c = read();
+ if (c==-1) return (i==0)?-1:i; // end of stream reached.
+ else cbuf[i+off] = (char) c;
+ }
+ return len;
+ }
+
+ public boolean markSupported() { return false; }
+
+ public boolean ready() throws IOException {
+ if (pushback!=-1) return true;
+ else return in.ready();
+ }
+}
--- /dev/null
+package Lex;
+
+/** FIFO class. This helps implement the lookahead we need for JSR-14.
+ * Copyright (C) 2002 C. Scott Ananian <cananian@alumni.princeton.edu>
+ * This program is released under the terms of the GPL; see the file
+ * COPYING for more details. There is NO WARRANTY on this code.
+ */
+
+class FIFO {
+ java_cup.runtime.Symbol[] backing = new java_cup.runtime.Symbol[10];
+ int start=0, end=0;
+ final Getter getter;
+ FIFO(Getter getter) { this.getter = getter; }
+ public boolean isEmpty() { return start==end; }
+ private boolean isFull() {
+ return start==end+1 || (start==0 && end==backing.length-1);
+ }
+ private int size() {
+ return ((end<start)?end+backing.length:end)-start;
+ }
+ public void put(java_cup.runtime.Symbol o) {
+ if (isFull()) {
+ java_cup.runtime.Symbol[] nbacking =
+ new java_cup.runtime.Symbol[backing.length*2];
+ System.arraycopy(backing, start, nbacking, 0, backing.length-start);
+ System.arraycopy(backing, 0, nbacking, backing.length-start, start);
+ start = 0;
+ end = backing.length-1;
+ backing = nbacking;
+ }
+ ASSERT(!isFull());
+ backing[end++] = o;
+ if (end == backing.length)
+ end = 0;
+ ASSERT(!isEmpty());
+ }
+ public java_cup.runtime.Symbol get() throws java.io.IOException {
+ if (isEmpty())
+ put(getter.next());
+ ASSERT(!isEmpty());
+ java_cup.runtime.Symbol o = backing[start++];
+ if (start == backing.length)
+ start = 0;
+ ASSERT(!isFull());
+ return o;
+ }
+ public java_cup.runtime.Symbol peek(int i) throws java.io.IOException {
+ while (i >= size())
+ put(getter.next());
+ int index = start+i;
+ if (index >= backing.length) index -= backing.length;
+ ASSERT(0<= index && index < backing.length);
+ return backing[index];
+ }
+ abstract static class Getter {
+ abstract java_cup.runtime.Symbol next()
+ throws java.io.IOException;
+ }
+ private static void ASSERT(boolean b) {
+ if (!b) throw new RuntimeException();
+ }
+}
+
+
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class FloatLiteral extends NumericLiteral {
+ FloatLiteral(float f) { this.val = new Float(f); }
+
+ Symbol token() { return new Symbol(Sym.FLOATING_POINT_LITERAL, val); }
+}
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+public class Identifier extends Token {
+ String identifier;
+ public Identifier(String identifier) { this.identifier=identifier; }
+
+ public String toString() { return "Identifier <"+identifier+">"; }
+
+ /* Ben Walter <bwalter@mit.edu> correctly pointed out that
+ * the first released version of this grammar/lexer did not
+ * return the string value of the identifier in the parser token.
+ * Should be fixed now. ;-) <cananian@alumni.princeton.edu>
+ */
+ Symbol token() { return new Symbol(Sym.IDENTIFIER, identifier); }
+}
--- /dev/null
+package Lex;
+
+abstract class InputElement {}
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class IntegerLiteral extends NumericLiteral {
+ IntegerLiteral(int i) { this.val = new Integer(i); }
+
+ Symbol token() { return new Symbol(Sym.INTEGER_LITERAL, val); }
+}
--- /dev/null
+package Lex;
+
+import java.util.Hashtable;
+import java_cup.runtime.Symbol;
+
+class Keyword extends Token {
+ String keyword;
+ Keyword(String s) { keyword = s; }
+
+ Symbol token() {
+ Integer i = (Integer) key_table.get(keyword);
+ return new Symbol(i.intValue());
+ }
+ public String toString() { return "Keyword <"+keyword+">"; }
+
+ static private final Hashtable key_table = new Hashtable();
+ static {
+ key_table.put("abstract", new Integer(Sym.ABSTRACT));
+ key_table.put("assert", new Integer(Sym.ASSERT));
+ key_table.put("boolean", new Integer(Sym.BOOLEAN));
+ key_table.put("break", new Integer(Sym.BREAK));
+ key_table.put("byte", new Integer(Sym.BYTE));
+ key_table.put("case", new Integer(Sym.CASE));
+ key_table.put("catch", new Integer(Sym.CATCH));
+ key_table.put("char", new Integer(Sym.CHAR));
+ key_table.put("class", new Integer(Sym.CLASS));
+ key_table.put("const", new Integer(Sym.CONST));
+ key_table.put("continue", new Integer(Sym.CONTINUE));
+ key_table.put("default", new Integer(Sym.DEFAULT));
+ key_table.put("do", new Integer(Sym.DO));
+ key_table.put("double", new Integer(Sym.DOUBLE));
+ key_table.put("else", new Integer(Sym.ELSE));
+ key_table.put("enum", new Integer(Sym.ENUM));
+ key_table.put("extends", new Integer(Sym.EXTENDS));
+ key_table.put("final", new Integer(Sym.FINAL));
+ key_table.put("finally", new Integer(Sym.FINALLY));
+ key_table.put("float", new Integer(Sym.FLOAT));
+ key_table.put("for", new Integer(Sym.FOR));
+ key_table.put("goto", new Integer(Sym.GOTO));
+ key_table.put("if", new Integer(Sym.IF));
+ key_table.put("implements", new Integer(Sym.IMPLEMENTS));
+ key_table.put("import", new Integer(Sym.IMPORT));
+ key_table.put("instanceof", new Integer(Sym.INSTANCEOF));
+ key_table.put("int", new Integer(Sym.INT));
+ key_table.put("interface", new Integer(Sym.INTERFACE));
+ key_table.put("long", new Integer(Sym.LONG));
+ key_table.put("native", new Integer(Sym.NATIVE));
+ key_table.put("new", new Integer(Sym.NEW));
+ key_table.put("package", new Integer(Sym.PACKAGE));
+ key_table.put("private", new Integer(Sym.PRIVATE));
+ key_table.put("protected", new Integer(Sym.PROTECTED));
+ key_table.put("public", new Integer(Sym.PUBLIC));
+ key_table.put("return", new Integer(Sym.RETURN));
+ key_table.put("short", new Integer(Sym.SHORT));
+ key_table.put("static", new Integer(Sym.STATIC));
+ key_table.put("strictfp", new Integer(Sym.STRICTFP));
+ key_table.put("super", new Integer(Sym.SUPER));
+ key_table.put("switch", new Integer(Sym.SWITCH));
+ key_table.put("synchronized", new Integer(Sym.SYNCHRONIZED));
+ key_table.put("this", new Integer(Sym.THIS));
+ key_table.put("throw", new Integer(Sym.THROW));
+ key_table.put("throws", new Integer(Sym.THROWS));
+ key_table.put("transient", new Integer(Sym.TRANSIENT));
+ key_table.put("try", new Integer(Sym.TRY));
+ key_table.put("void", new Integer(Sym.VOID));
+ key_table.put("volatile", new Integer(Sym.VOLATILE));
+ key_table.put("while", new Integer(Sym.WHILE));
+ }
+}
--- /dev/null
+package Lex;
+
+import java.io.Reader;
+import java.io.LineNumberReader;
+
+/* Java lexer.
+ * Copyright (C) 2002 C. Scott Ananian <cananian@alumni.princeton.edu>
+ * This program is released under the terms of the GPL; see the file
+ * COPYING for more details. There is NO WARRANTY on this code.
+ */
+
+public class Lexer implements Parse.Lexer {
+ LineNumberReader reader;
+ boolean isJava12;
+ boolean isJava14;
+ boolean isJava15;
+ String line = null;
+ int line_pos = 1;
+ int line_num = 0;
+ LineList lineL = new LineList(-line_pos, null); // sentinel for line #0
+
+ public Lexer(Reader reader) {
+ this(reader, 2); // by default, use a Java 1.2-compatible lexer.
+ }
+ public Lexer(Reader reader, int java_minor_version) {
+ this.reader = new LineNumberReader(new EscapedUnicodeReader(reader));
+ this.isJava12 = java_minor_version >= 2;
+ this.isJava14 = java_minor_version >= 4;
+ this.isJava15 = java_minor_version >= 5;
+ }
+
+ public java_cup.runtime.Symbol nextToken() throws java.io.IOException {
+ java_cup.runtime.Symbol sym =
+ lookahead==null ? _nextToken() : lookahead.get();
+ /* Old "smart lexer" hack to parse JSR-14 syntax. New, better, grammar
+ * makes this unnecessary. (Credit to Eric Blake for its discovery.)
+ *
+ if (isJava15 && sym.sym==Sym.LT && shouldBePLT())
+ sym.sym=Sym.PLT;
+ */
+ last = sym;
+ return sym;
+ }
+ private boolean shouldBePLT() throws java.io.IOException {
+ // look ahead to see if this LT should be changed to a PLT
+ if (last==null || last.sym!=Sym.IDENTIFIER)
+ return false;
+ if (lookahead==null) lookahead = new FIFO(new FIFO.Getter() {
+ java_cup.runtime.Symbol next() throws java.io.IOException
+ { return _nextToken(); }
+ });
+ int i=0;
+ // skip past IDENTIFIER (DOT IDENTIFIER)*
+ if (lookahead.peek(i++).sym != Sym.IDENTIFIER)
+ return false;
+ while (lookahead.peek(i).sym == Sym.DOT) {
+ i++;
+ if (lookahead.peek(i++).sym != Sym.IDENTIFIER)
+ return false;
+ }
+ // skip past (LBRACK RBRACK)*
+ while (lookahead.peek(i).sym == Sym.LBRACK) {
+ i++;
+ if (lookahead.peek(i++).sym != Sym.RBRACK)
+ return false;
+ }
+ // now the next sym has to be one of LT GT COMMA EXTENDS IMPLEMENTS
+ switch(lookahead.peek(i).sym) {
+ default:
+ return false;
+ case Sym.LT:
+ case Sym.GT:
+ case Sym.COMMA:
+ case Sym.EXTENDS:
+ case Sym.IMPLEMENTS:
+ return true;
+ }
+ }
+ private java_cup.runtime.Symbol last = null;
+ private FIFO lookahead = null;
+ public java_cup.runtime.Symbol _nextToken() throws java.io.IOException {
+ /* tokens are:
+ * Identifiers/Keywords/true/false/null (start with java letter)
+ * numeric literal (start with number)
+ * character literal (start with single quote)
+ * string (start with double quote)
+ * separator (parens, braces, brackets, semicolon, comma, period)
+ * operator (equals, plus, minus, etc)
+ * whitespace
+ * comment (start with slash)
+ */
+ InputElement ie;
+ int startpos, endpos;
+ do {
+ startpos = lineL.head + line_pos;
+ ie = getInputElement();
+ if (ie instanceof DocumentationComment)
+ comment = ((Comment)ie).getComment();
+ } while (!(ie instanceof Token));
+ endpos = lineL.head + line_pos - 1;
+
+ //System.out.println(ie.toString()); // uncomment to debug lexer.
+ java_cup.runtime.Symbol sym = ((Token)ie).token();
+ // fix up left/right positions.
+ sym.left = startpos; sym.right = endpos;
+ // return token.
+ return sym;
+ }
+ public boolean debug_lex() throws java.io.IOException {
+ InputElement ie = getInputElement();
+ System.out.println(ie);
+ return !(ie instanceof EOF);
+ }
+
+ String comment;
+ public String lastComment() { return comment; }
+ public void clearComment() { comment=""; }
+
+ InputElement getInputElement() throws java.io.IOException {
+ if (line_num == 0)
+ nextLine();
+ if (line==null)
+ return new EOF();
+ if (line.length()<=line_pos) { // end of line.
+ nextLine();
+ if (line==null)
+ return new EOF();
+ }
+
+ switch (line.charAt(line_pos)) {
+
+ // White space:
+ case ' ': // ASCII SP
+ case '\t': // ASCII HT
+ case '\f': // ASCII FF
+ case '\n': // LineTerminator
+ return new WhiteSpace(consume());
+
+ // EOF character:
+ case '\020': // ASCII SUB
+ consume();
+ return new EOF();
+
+ // Comment prefix:
+ case '/':
+ return getComment();
+
+ // else, a Token
+ default:
+ return getToken();
+ }
+ }
+ // May get Token instead of Comment.
+ InputElement getComment() throws java.io.IOException {
+ String comment;
+ // line.charAt(line_pos+0) is '/'
+ switch (line.charAt(line_pos+1)) {
+ case '/': // EndOfLineComment
+ comment = line.substring(line_pos+2);
+ line_pos = line.length();
+ return new EndOfLineComment(comment);
+ case '*': // TraditionalComment or DocumentationComment
+ line_pos += 2;
+ if (line.charAt(line_pos)=='*') { // DocumentationComment
+ return snarfComment(new DocumentationComment());
+ } else { // TraditionalComment
+ return snarfComment(new TraditionalComment());
+ }
+ default: // it's a token, not a comment.
+ return getToken();
+ }
+ }
+
+ Comment snarfComment(Comment c) throws java.io.IOException {
+ StringBuffer text=new StringBuffer();
+ while(true) { // Grab CommentTail
+ while (line.charAt(line_pos)!='*') { // Add NotStar to comment.
+ int star_pos = line.indexOf('*', line_pos);
+ if (star_pos<0) {
+ text.append(line.substring(line_pos));
+ c.appendLine(text.toString()); text.setLength(0);
+ line_pos = line.length();
+ nextLine();
+ if (line==null)
+ throw new Error("Unterminated comment at end of file.");
+ } else {
+ text.append(line.substring(line_pos, star_pos));
+ line_pos=star_pos;
+ }
+ }
+ // At this point, line.charAt(line_pos)=='*'
+ // Grab CommentTailStar starting at line_pos+1.
+ if (line.charAt(line_pos+1)=='/') { // safe because line ends with '\n'
+ c.appendLine(text.toString()); line_pos+=2; return c;
+ }
+ text.append(line.charAt(line_pos++)); // add the '*'
+ }
+ }
+
+ Token getToken() {
+ // Tokens are: Identifiers, Keywords, Literals, Separators, Operators.
+ switch (line.charAt(line_pos)) {
+ // Separators: (period is a special case)
+ case '(':
+ case ')':
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ case ';':
+ case ',':
+ return new Separator(consume());
+
+ // Operators:
+ case '=':
+ case '>':
+ case '<':
+ case '!':
+ case '~':
+ case '?':
+ case ':':
+ case '&':
+ case '|':
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '^':
+ case '%':
+ return getOperator();
+ case '\'':
+ return getCharLiteral();
+ case '\"':
+ return getStringLiteral();
+
+ // a period is a special case:
+ case '.':
+ if (Character.digit(line.charAt(line_pos+1),10)!=-1)
+ return getNumericLiteral();
+ else if (isJava15 &&
+ line.charAt(line_pos+1)=='.' &&
+ line.charAt(line_pos+2)=='.') {
+ consume(); consume(); consume();
+ return new Separator('\u2026'); // unicode ellipsis character.
+ } else return new Separator(consume());
+ default:
+ break;
+ }
+ if (Character.isJavaIdentifierStart(line.charAt(line_pos)))
+ return getIdentifier();
+ if (Character.isDigit(line.charAt(line_pos)))
+ return getNumericLiteral();
+ throw new Error("Illegal character on line "+line_num);
+ }
+
+ static final String[] keywords = new String[] {
+ "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char",
+ "class", "const", "continue", "default", "do", "double", "else", "enum",
+ "extends", "final", "finally", "float", "for", "goto", "if",
+ "implements", "import", "instanceof", "int", "interface", "long",
+ "native", "new", "package", "private", "protected", "public",
+ "return", "short", "static", "strictfp", "super", "switch",
+ "synchronized", "this", "throw", "throws", "transient", "try", "void",
+ "volatile", "while" };
+ Token getIdentifier() {
+ // Get id string.
+ StringBuffer sb = new StringBuffer().append(consume());
+
+ if (!Character.isJavaIdentifierStart(sb.charAt(0)))
+ throw new Error("Invalid Java Identifier on line "+line_num);
+ while (Character.isJavaIdentifierPart(line.charAt(line_pos)))
+ sb.append(consume());
+ String s = sb.toString();
+ // Now check against boolean literals and null literal.
+ if (s.equals("null")) return new NullLiteral();
+ if (s.equals("true")) return new BooleanLiteral(true);
+ if (s.equals("false")) return new BooleanLiteral(false);
+ // Check against keywords.
+ // pre-java 1.5 compatibility:
+ if (!isJava15 && s.equals("enum")) return new Identifier(s);
+ // pre-java 1.4 compatibility:
+ if (!isJava14 && s.equals("assert")) return new Identifier(s);
+ // pre-java 1.2 compatibility:
+ if (!isJava12 && s.equals("strictfp")) return new Identifier(s);
+ // use binary search.
+ for (int l=0, r=keywords.length; r > l; ) {
+ int x = (l+r)/2, cmp = s.compareTo(keywords[x]);
+ if (cmp < 0) r=x; else l=x+1;
+ if (cmp== 0) return new Keyword(s);
+ }
+ // not a keyword.
+ return new Identifier(s);
+ }
+ NumericLiteral getNumericLiteral() {
+ int i;
+ // leading decimal indicates float.
+ if (line.charAt(line_pos)=='.')
+ return getFloatingPointLiteral();
+ // 0x indicates Hex.
+ if (line.charAt(line_pos)=='0' &&
+ (line.charAt(line_pos+1)=='x' ||
+ line.charAt(line_pos+1)=='X')) {
+ line_pos+=2; return getIntegerLiteral(/*base*/16);
+ }
+ // otherwise scan to first non-numeric
+ for (i=line_pos; Character.digit(line.charAt(i),10)!=-1; )
+ i++;
+ switch(line.charAt(i)) { // discriminate based on first non-numeric
+ case '.':
+ case 'f':
+ case 'F':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ return getFloatingPointLiteral();
+ case 'L':
+ case 'l':
+ default:
+ if (line.charAt(line_pos)=='0')
+ return getIntegerLiteral(/*base*/8);
+ return getIntegerLiteral(/*base*/10);
+ }
+ }
+ NumericLiteral getIntegerLiteral(int radix) {
+ long val=0;
+ while (Character.digit(line.charAt(line_pos),radix)!=-1)
+ val = (val*radix) + Character.digit(consume(),radix);
+ if (line.charAt(line_pos) == 'l' ||
+ line.charAt(line_pos) == 'L') {
+ consume();
+ return new LongLiteral(val);
+ }
+ // we compare MAX_VALUE against val/2 to allow constants like
+ // 0xFFFF0000 to get past the test. (unsigned long->signed int)
+ if ((val/2) > Integer.MAX_VALUE ||
+ val < Integer.MIN_VALUE)
+ throw new Error("Constant does not fit in integer on line "+line_num);
+ return new IntegerLiteral((int)val);
+ }
+ NumericLiteral getFloatingPointLiteral() {
+ String rep = getDigits();
+ if (line.charAt(line_pos)=='.')
+ rep+=consume() + getDigits();
+ if (line.charAt(line_pos)=='e' ||
+ line.charAt(line_pos)=='E') {
+ rep+=consume();
+ if (line.charAt(line_pos)=='+' ||
+ line.charAt(line_pos)=='-')
+ rep+=consume();
+ rep+=getDigits();
+ }
+ try {
+ switch (line.charAt(line_pos)) {
+ case 'f':
+ case 'F':
+ consume();
+ return new FloatLiteral(Float.valueOf(rep).floatValue());
+ case 'd':
+ case 'D':
+ consume();
+ /* falls through */
+ default:
+ return new DoubleLiteral(Double.valueOf(rep).doubleValue());
+ }
+ } catch (NumberFormatException e) {
+ throw new Error("Illegal floating-point on line "+line_num+": "+e);
+ }
+ }
+ String getDigits() {
+ StringBuffer sb = new StringBuffer();
+ while (Character.digit(line.charAt(line_pos),10)!=-1)
+ sb.append(consume());
+ return sb.toString();
+ }
+
+ Operator getOperator() {
+ char first = consume();
+ char second= line.charAt(line_pos);
+
+ switch(first) {
+ // single-character operators.
+ case '~':
+ case '?':
+ case ':':
+ return new Operator(new String(new char[] {first}));
+ // doubled operators
+ case '+':
+ case '-':
+ case '&':
+ case '|':
+ if (first==second)
+ return new Operator(new String(new char[] {first, consume()}));
+ default:
+ break;
+ }
+ // Check for trailing '='
+ if (second=='=')
+ return new Operator(new String(new char[] {first, consume()}));
+
+ // Special-case '<<', '>>' and '>>>'
+ if ((first=='<' && second=='<') || // <<
+ (first=='>' && second=='>')) { // >>
+ String op = new String(new char[] {first, consume()});
+ if (first=='>' && line.charAt(line_pos)=='>') // >>>
+ op += consume();
+ if (line.charAt(line_pos)=='=') // <<=, >>=, >>>=
+ op += consume();
+ return new Operator(op);
+ }
+
+ // Otherwise return single operator.
+ return new Operator(new String(new char[] {first}));
+ }
+
+ CharacterLiteral getCharLiteral() {
+ char firstquote = consume();
+ char val;
+ switch (line.charAt(line_pos)) {
+ case '\\':
+ val = getEscapeSequence();
+ break;
+ case '\'':
+ throw new Error("Invalid character literal on line "+line_num);
+ case '\n':
+ throw new Error("Invalid character literal on line "+line_num);
+ default:
+ val = consume();
+ break;
+ }
+ char secondquote = consume();
+ if (firstquote != '\'' || secondquote != '\'')
+ throw new Error("Invalid character literal on line "+line_num);
+ return new CharacterLiteral(val);
+ }
+ StringLiteral getStringLiteral() {
+ char openquote = consume();
+ StringBuffer val = new StringBuffer();
+ while (line.charAt(line_pos)!='\"') {
+ switch(line.charAt(line_pos)) {
+ case '\\':
+ val.append(getEscapeSequence());
+ break;
+ case '\n':
+ throw new Error("Invalid string literal on line " + line_num);
+ default:
+ val.append(consume());
+ break;
+ }
+ }
+ char closequote = consume();
+ if (openquote != '\"' || closequote != '\"')
+ throw new Error("Invalid string literal on line " + line_num);
+
+ return new StringLiteral(val.toString().intern());
+ }
+
+ char getEscapeSequence() {
+ if (consume() != '\\')
+ throw new Error("Invalid escape sequence on line " + line_num);
+ switch(line.charAt(line_pos)) {
+ case 'b':
+ consume(); return '\b';
+ case 't':
+ consume(); return '\t';
+ case 'n':
+ consume(); return '\n';
+ case 'f':
+ consume(); return '\f';
+ case 'r':
+ consume(); return '\r';
+ case '\"':
+ consume(); return '\"';
+ case '\'':
+ consume(); return '\'';
+ case '\\':
+ consume(); return '\\';
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ return (char) getOctal(3);
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ return (char) getOctal(2);
+ default:
+ throw new Error("Invalid escape sequence on line " + line_num);
+ }
+ }
+ int getOctal(int maxlength) {
+ int i, val=0;
+ for (i=0; i<maxlength; i++)
+ if (Character.digit(line.charAt(line_pos), 8)!=-1) {
+ val = (8*val) + Character.digit(consume(), 8);
+ } else break;
+ if ((i==0) || (val>0xFF)) // impossible.
+ throw new Error("Invalid octal escape sequence in line " + line_num);
+ return val;
+ }
+
+ char consume() { return line.charAt(line_pos++); }
+ void nextLine() throws java.io.IOException {
+ line=reader.readLine();
+ if (line!=null) line=line+'\n';
+ lineL = new LineList(lineL.head+line_pos, lineL); // for error reporting
+ line_pos=0;
+ line_num++;
+ }
+
+ // Deal with error messages.
+ public void errorMsg(String msg, java_cup.runtime.Symbol info) {
+ int n=line_num, c=info.left-lineL.head;
+ for (LineList p = lineL; p!=null; p=p.tail, n--)
+ if (p.head<=info.left) { c=info.left-p.head; break; }
+ System.err.println(msg+" at line "+n);
+ num_errors++;
+ }
+ private int num_errors = 0;
+ public int numErrors() { return num_errors; }
+
+ class LineList {
+ int head;
+ LineList tail;
+ LineList(int head, LineList tail) { this.head = head; this.tail = tail; }
+ }
+}
--- /dev/null
+package Lex;
+
+abstract class Literal extends Token { }
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class LongLiteral extends NumericLiteral {
+ LongLiteral(long l) { this.val = new Long(l); }
+
+ Symbol token() { return new Symbol(Sym.INTEGER_LITERAL, val); }
+}
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class NullLiteral extends Literal {
+ NullLiteral() { }
+
+ Symbol token() { return new Symbol(Sym.NULL_LITERAL); }
+
+ public String toString() { return "NullLiteral <null>"; }
+}
--- /dev/null
+package Lex;
+
+abstract class NumericLiteral extends Literal {
+ Number val;
+
+ public String toString() { return "NumericLiteral <"+val.toString()+">"; }
+}
--- /dev/null
+package Lex;
+
+import java.util.Hashtable;
+import java_cup.runtime.Symbol;
+
+class Operator extends Token {
+ String which;
+ Operator(String which) { this.which = which; }
+
+ public String toString() { return "Operator <"+which+">"; }
+
+ Symbol token() {
+ Integer i = (Integer) op_table.get(which);
+ return new Symbol(i.intValue());
+ }
+
+ static private final Hashtable op_table = new Hashtable();
+ static {
+ op_table.put("=", new Integer(Sym.EQ));
+ op_table.put(">", new Integer(Sym.GT));
+ op_table.put("<", new Integer(Sym.LT));
+ op_table.put("!", new Integer(Sym.NOT));
+ op_table.put("~", new Integer(Sym.COMP));
+ op_table.put("?", new Integer(Sym.QUESTION));
+ op_table.put(":", new Integer(Sym.COLON));
+ op_table.put("==", new Integer(Sym.EQEQ));
+ op_table.put("<=", new Integer(Sym.LTEQ));
+ op_table.put(">=", new Integer(Sym.GTEQ));
+ op_table.put("!=", new Integer(Sym.NOTEQ));
+ op_table.put("&&", new Integer(Sym.ANDAND));
+ op_table.put("||", new Integer(Sym.OROR));
+ op_table.put("++", new Integer(Sym.PLUSPLUS));
+ op_table.put("--", new Integer(Sym.MINUSMINUS));
+ op_table.put("+", new Integer(Sym.PLUS));
+ op_table.put("-", new Integer(Sym.MINUS));
+ op_table.put("*", new Integer(Sym.MULT));
+ op_table.put("/", new Integer(Sym.DIV));
+ op_table.put("&", new Integer(Sym.AND));
+ op_table.put("|", new Integer(Sym.OR));
+ op_table.put("^", new Integer(Sym.XOR));
+ op_table.put("%", new Integer(Sym.MOD));
+ op_table.put("<<", new Integer(Sym.LSHIFT));
+ op_table.put(">>", new Integer(Sym.RSHIFT));
+ op_table.put(">>>", new Integer(Sym.URSHIFT));
+ op_table.put("+=", new Integer(Sym.PLUSEQ));
+ op_table.put("-=", new Integer(Sym.MINUSEQ));
+ op_table.put("*=", new Integer(Sym.MULTEQ));
+ op_table.put("/=", new Integer(Sym.DIVEQ));
+ op_table.put("&=", new Integer(Sym.ANDEQ));
+ op_table.put("|=", new Integer(Sym.OREQ));
+ op_table.put("^=", new Integer(Sym.XOREQ));
+ op_table.put("%=", new Integer(Sym.MODEQ));
+ op_table.put("<<=", new Integer(Sym.LSHIFTEQ));
+ op_table.put(">>=", new Integer(Sym.RSHIFTEQ));
+ op_table.put(">>>=", new Integer(Sym.URSHIFTEQ));
+ }
+}
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class Separator extends Token {
+ char which;
+ Separator(char which) { this.which = which; }
+
+ Symbol token() {
+ switch(which) {
+ case '(': return new Symbol(Sym.LPAREN);
+ case ')': return new Symbol(Sym.RPAREN);
+ case '{': return new Symbol(Sym.LBRACE);
+ case '}': return new Symbol(Sym.RBRACE);
+ case '[': return new Symbol(Sym.LBRACK);
+ case ']': return new Symbol(Sym.RBRACK);
+ case ';': return new Symbol(Sym.SEMICOLON);
+ case ',': return new Symbol(Sym.COMMA);
+ case '.': return new Symbol(Sym.DOT);
+ case '\u2026': return new Symbol(Sym.ELLIPSIS);
+ default:
+ throw new Error("Invalid separator.");
+ }
+ }
+
+ public String toString() {
+ return "Separator <"+which+">";
+ }
+}
--- /dev/null
+package Lex;
+
+import java_cup.runtime.Symbol;
+
+class StringLiteral extends Literal {
+ String val;
+ StringLiteral(String s) { this.val = s; }
+
+ Symbol token() { return new Symbol(Sym.STRING_LITERAL, val); }
+
+ public String toString() {
+ return "StringLiteral <"+Token.escape(val)+">";
+ }
+}
--- /dev/null
+package Lex;
+
+abstract class Token extends InputElement {
+ abstract java_cup.runtime.Symbol token();
+
+ protected static String escape(String s) {
+ StringBuffer sb = new StringBuffer();
+ for (int i=0; i<s.length(); i++)
+ switch(s.charAt(i)) {
+ case '\t': sb.append("\\t"); break;
+ case '\f': sb.append("\\f"); break;
+ case '\n': sb.append("\\n"); break;
+ default:
+ if ((int)s.charAt(i)<32)
+ sb.append("\\"+Integer.toOctalString((int)s.charAt(i)));
+ else
+ sb.append(s.charAt(i));
+ }
+ return sb.toString();
+ }
+}
--- /dev/null
+package Lex;
+
+class TraditionalComment extends Comment {
+ TraditionalComment() { }
+}
--- /dev/null
+package Lex;
+
+class WhiteSpace extends InputElement {
+ char whitespace;
+ WhiteSpace(char which) { this.whitespace=which; }
+
+ public String toString() {
+ String s;
+ switch(whitespace) {
+ case ' ': s = "SP"; break;
+ case '\t': s = "HT"; break;
+ case '\f': s = "FF"; break;
+ case '\n': s = "LT"; break;
+ default: s = "Unknown Whitespace character."; break;
+ }
+ return "Whitespace <"+s+">";
+ }
+}
--- /dev/null
+package Main;
+
+import java.io.Reader;
+import java.io.BufferedReader;
+import java.io.FileReader;
+
+/* Test skeleton for java parser/lexer.
+ * Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
+ * This is released under the terms of the GPL with NO WARRANTY.
+ * See the file COPYING for more details.
+ */
+
+public class Main {
+ public static void main(String args[]) throws Exception {
+ Reader fr = new BufferedReader(new FileReader(args[0]));
+ // the integer in the next line specifies the java minor version.
+ // for example, for a java 1.0 lexer specify '0'
+ // for a java 1.1 lexer specify '1'
+ // etc.
+ // As far as the lexer's concerned, 'strictfp' was added in Java 1.2,
+ // 'assert' in Java 1.4, and we need a "lookahead <" token PLT
+ // to correctly parse Java 1.5.
+ int java_minor_version = 5;
+ if (args.length>1) java_minor_version = Integer.parseInt(args[1]);
+ Lex.Lexer l = new Lex.Lexer(fr, java_minor_version);
+ java_cup.runtime.lr_parser g;
+ switch (java_minor_version) {
+ default:
+ case 5: g = new Parse.Grm15(l); break;
+ case 4: g = new Parse.Grm14(l); break;
+ case 3:
+ case 2: g = new Parse.Grm12(l); break;
+ case 1: g = new Parse.Grm11(l); break;
+ case 0: g = new Parse.Grm10(l); break;
+ }
+ g./*debug_*/parse();
+ System.exit(l.numErrors());
+ }
+}
--- /dev/null
+package Parse;
+
+/* Lexer.java. Copyright (C) 1998 C. Scott Ananian.
+ * This program is free software; see the file COPYING for more details.
+ */
+
+public interface Lexer {
+ public java_cup.runtime.Symbol nextToken() throws java.io.IOException;
+ /** report an error */
+ public void errorMsg(String msg, java_cup.runtime.Symbol info);
+ /** return the number of errors reported */
+ public int numErrors();
+}
--- /dev/null
+package Parse;
+
+import java_cup.runtime.*;
+
+/* Java 1.0 parser for CUP.
+ * Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
+ * This program is released under the terms of the GPL; see the file
+ * COPYING for more details. There is NO WARRANTY on this code.
+ */
+
+parser code {:
+ Lexer lexer;
+
+ public Grm10(Lexer l) {
+ this();
+ lexer=l;
+ }
+
+ public void syntax_error(java_cup.runtime.Symbol current) {
+ report_error("Syntax error (" + current.sym + ")", current);
+ }
+ public void report_error(String message, java_cup.runtime.Symbol info) {
+ lexer.errorMsg(message, info);
+ }
+:};
+
+scan with {: return lexer.nextToken(); :};
+
+terminal BOOLEAN; // primitive_type
+terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
+terminal FLOAT, DOUBLE; // floating_point_type
+terminal LBRACK, RBRACK; // array_type
+terminal java.lang.String IDENTIFIER; // name
+terminal DOT; // qualified_name
+terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
+terminal PACKAGE; // package_declaration
+terminal IMPORT; // import_declaration
+terminal PUBLIC, PROTECTED, PRIVATE; // modifier
+terminal STATIC; // modifier
+terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
+terminal CLASS; // class_declaration
+terminal EXTENDS; // super
+terminal IMPLEMENTS; // interfaces
+terminal VOID; // method_header
+terminal THROWS; // throws
+terminal THIS, SUPER; // explicit_constructor_invocation
+terminal INTERFACE; // interface_declaration
+terminal IF, ELSE; // if_then_statement, if_then_else_statement
+terminal SWITCH; // switch_statement
+terminal CASE, DEFAULT; // switch_label
+terminal DO, WHILE; // while_statement, do_statement
+terminal FOR; // for_statement
+terminal BREAK; // break_statement
+terminal CONTINUE; // continue_statement
+terminal RETURN; // return_statement
+terminal THROW; // throw_statement
+terminal TRY; // try_statement
+terminal CATCH; // catch_clause
+terminal FINALLY; // finally
+terminal NEW; // class_instance_creation_expression
+terminal PLUSPLUS; // postincrement_expression
+terminal MINUSMINUS; // postdecrement_expression
+terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
+terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
+terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
+terminal EQEQ, NOTEQ; // equality_expression
+terminal AND; // and_expression
+terminal XOR; // exclusive_or_expression
+terminal OR; // inclusive_or_expression
+terminal ANDAND; // conditional_and_expression
+terminal OROR; // conditional_or_expression
+terminal QUESTION; // conditional_expression
+terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
+terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
+terminal ANDEQ, XOREQ, OREQ; // assignment_operator
+
+terminal java.lang.Number INTEGER_LITERAL;
+terminal java.lang.Number FLOATING_POINT_LITERAL;
+terminal java.lang.Boolean BOOLEAN_LITERAL;
+terminal java.lang.Character CHARACTER_LITERAL;
+terminal java.lang.String STRING_LITERAL;
+terminal NULL_LITERAL;
+
+// Reserved but unused:
+terminal CONST, GOTO;
+// lexer compatibility with Java 1.2:
+terminal STRICTFP;
+// lexer compatibility with Java 1.4
+terminal ASSERT;
+// lexer compatibility with Java 1.5
+terminal ELLIPSIS;
+terminal ENUM;
+
+// 19.2) The Syntactic Grammar
+non terminal goal;
+// 19.3) Lexical Structure
+non terminal literal;
+// 19.4) Types, Values, and Variables
+non terminal type, primitive_type, numeric_type;
+non terminal integral_type, floating_point_type;
+non terminal reference_type;
+non terminal class_or_interface_type;
+non terminal class_type, interface_type;
+non terminal array_type;
+// 19.5) Names
+non terminal name, simple_name, qualified_name;
+// 19.6) Packages
+non terminal compilation_unit;
+non terminal package_declaration_opt, package_declaration;
+non terminal import_declarations_opt, import_declarations;
+non terminal type_declarations_opt, type_declarations;
+non terminal import_declaration;
+non terminal single_type_import_declaration;
+non terminal type_import_on_demand_declaration;
+non terminal type_declaration;
+// 19.7) Productions used only in the LALR(1) grammar
+non terminal modifiers_opt, modifiers, modifier;
+// 19.8.1) Class Declaration
+non terminal class_declaration, super, super_opt;
+non terminal interfaces, interfaces_opt, interface_type_list;
+non terminal class_body;
+non terminal class_body_declarations, class_body_declarations_opt;
+non terminal class_body_declaration, class_member_declaration;
+// 19.8.2) Field Declarations
+non terminal field_declaration, variable_declarators, variable_declarator;
+non terminal variable_declarator_id, variable_initializer;
+// 19.8.3) Method Declarations
+non terminal method_declaration, method_header, method_declarator;
+non terminal formal_parameter_list_opt, formal_parameter_list;
+non terminal formal_parameter;
+non terminal throws_opt, throws;
+non terminal class_type_list, method_body;
+// 19.8.4) Static Initializers
+non terminal static_initializer;
+// 19.8.5) Constructor Declarations
+non terminal constructor_declaration, constructor_declarator;
+non terminal constructor_body;
+non terminal explicit_constructor_invocation;
+// 19.9.1) Interface Declarations
+non terminal interface_declaration;
+non terminal extends_interfaces_opt, extends_interfaces;
+non terminal interface_body;
+non terminal interface_member_declarations_opt, interface_member_declarations;
+non terminal interface_member_declaration, constant_declaration;
+non terminal abstract_method_declaration;
+// 19.10) Arrays
+non terminal array_initializer;
+non terminal variable_initializers;
+// 19.11) Blocks and Statements
+non terminal block;
+non terminal block_statements_opt, block_statements, block_statement;
+non terminal local_variable_declaration_statement, local_variable_declaration;
+non terminal statement, statement_no_short_if;
+non terminal statement_without_trailing_substatement;
+non terminal empty_statement;
+non terminal labeled_statement, labeled_statement_no_short_if;
+non terminal expression_statement, statement_expression;
+non terminal if_then_statement;
+non terminal if_then_else_statement, if_then_else_statement_no_short_if;
+non terminal switch_statement, switch_block;
+non terminal switch_block_statement_groups;
+non terminal switch_block_statement_group;
+non terminal switch_labels, switch_label;
+non terminal while_statement, while_statement_no_short_if;
+non terminal do_statement;
+non terminal for_statement, for_statement_no_short_if;
+non terminal for_init_opt, for_init;
+non terminal for_update_opt, for_update;
+non terminal statement_expression_list;
+non terminal identifier_opt;
+non terminal break_statement, continue_statement;
+non terminal return_statement, throw_statement;
+non terminal synchronized_statement, try_statement;
+non terminal catches_opt, catches, catch_clause;
+non terminal finally;
+// 19.12) Expressions
+non terminal primary, primary_no_new_array;
+non terminal class_instance_creation_expression;
+non terminal argument_list_opt, argument_list;
+non terminal array_creation_expression;
+non terminal dim_exprs, dim_expr, dims_opt, dims;
+non terminal field_access, method_invocation, array_access;
+non terminal postfix_expression;
+non terminal postincrement_expression, postdecrement_expression;
+non terminal unary_expression, unary_expression_not_plus_minus;
+non terminal preincrement_expression, predecrement_expression;
+non terminal cast_expression;
+non terminal multiplicative_expression, additive_expression;
+non terminal shift_expression, relational_expression, equality_expression;
+non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
+non terminal conditional_and_expression, conditional_or_expression;
+non terminal conditional_expression, assignment_expression;
+non terminal assignment;
+non terminal left_hand_side;
+non terminal assignment_operator;
+non terminal expression_opt, expression;
+non terminal constant_expression;
+
+start with goal;
+
+// 19.2) The Syntactic Grammar
+goal ::= compilation_unit
+ ;
+
+// 19.3) Lexical Structure.
+literal ::= INTEGER_LITERAL
+ | FLOATING_POINT_LITERAL
+ | BOOLEAN_LITERAL
+ | CHARACTER_LITERAL
+ | STRING_LITERAL
+ | NULL_LITERAL
+ ;
+
+// 19.4) Types, Values, and Variables
+type ::= primitive_type
+ | reference_type
+ ;
+primitive_type ::=
+ numeric_type
+ | BOOLEAN
+ ;
+numeric_type::= integral_type
+ | floating_point_type
+ ;
+integral_type ::=
+ BYTE
+ | SHORT
+ | INT
+ | LONG
+ | CHAR
+ ;
+floating_point_type ::=
+ FLOAT
+ | DOUBLE
+ ;
+
+reference_type ::=
+ class_or_interface_type
+ | array_type
+ ;
+class_or_interface_type ::= name;
+
+class_type ::= class_or_interface_type;
+interface_type ::= class_or_interface_type;
+
+array_type ::= primitive_type LBRACK RBRACK
+ | name LBRACK RBRACK
+ | array_type LBRACK RBRACK
+ ;
+
+// 19.5) Names
+name ::= simple_name
+ | qualified_name
+ ;
+simple_name ::= IDENTIFIER
+ ;
+qualified_name ::=
+ name DOT IDENTIFIER
+ ;
+
+// 19.6) Packages
+compilation_unit ::=
+ package_declaration_opt
+ import_declarations_opt
+ type_declarations_opt
+ ;
+package_declaration_opt ::= package_declaration | ;
+import_declarations_opt ::= import_declarations | ;
+type_declarations_opt ::= type_declarations | ;
+
+import_declarations ::=
+ import_declaration
+ | import_declarations import_declaration
+ ;
+type_declarations ::=
+ type_declaration
+ | type_declarations type_declaration
+ ;
+package_declaration ::=
+ PACKAGE name SEMICOLON
+ ;
+import_declaration ::=
+ single_type_import_declaration
+ | type_import_on_demand_declaration
+ ;
+single_type_import_declaration ::=
+ IMPORT name SEMICOLON
+ ;
+type_import_on_demand_declaration ::=
+ IMPORT name DOT MULT SEMICOLON
+ ;
+type_declaration ::=
+ class_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+
+// 19.7) Productions used only in the LALR(1) grammar
+modifiers_opt::=
+ | modifiers
+ ;
+modifiers ::= modifier
+ | modifiers modifier
+ ;
+modifier ::= PUBLIC | PROTECTED | PRIVATE
+ | STATIC
+ | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
+ ;
+
+// 19.8) Classes
+
+// 19.8.1) Class Declaration:
+class_declaration ::=
+ modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
+ ;
+super ::= EXTENDS class_type
+ ;
+super_opt ::=
+ | super
+ ;
+interfaces ::= IMPLEMENTS interface_type_list
+ ;
+interfaces_opt::=
+ | interfaces
+ ;
+interface_type_list ::=
+ interface_type
+ | interface_type_list COMMA interface_type
+ ;
+class_body ::= LBRACE class_body_declarations_opt RBRACE
+ ;
+class_body_declarations_opt ::=
+ | class_body_declarations ;
+class_body_declarations ::=
+ class_body_declaration
+ | class_body_declarations class_body_declaration
+ ;
+class_body_declaration ::=
+ class_member_declaration
+ | static_initializer
+ | constructor_declaration
+ ;
+class_member_declaration ::=
+ field_declaration
+ | method_declaration
+ | SEMICOLON
+ ;
+
+// 19.8.2) Field Declarations
+field_declaration ::=
+ modifiers_opt type variable_declarators SEMICOLON
+ ;
+variable_declarators ::=
+ variable_declarator
+ | variable_declarators COMMA variable_declarator
+ ;
+variable_declarator ::=
+ variable_declarator_id
+ | variable_declarator_id EQ variable_initializer
+ ;
+variable_declarator_id ::=
+ IDENTIFIER
+ | variable_declarator_id LBRACK RBRACK
+ ;
+variable_initializer ::=
+ expression
+ | array_initializer
+ ;
+
+// 19.8.3) Method Declarations
+method_declaration ::=
+ method_header method_body
+ ;
+method_header ::=
+ modifiers_opt type method_declarator throws_opt
+ | modifiers_opt VOID method_declarator throws_opt
+ ;
+method_declarator ::=
+ IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
+ | method_declarator LBRACK RBRACK
+ ;
+formal_parameter_list_opt ::=
+ | formal_parameter_list
+ ;
+formal_parameter_list ::=
+ formal_parameter
+ | formal_parameter_list COMMA formal_parameter
+ ;
+formal_parameter ::=
+ type variable_declarator_id
+ ;
+throws_opt ::=
+ | throws
+ ;
+throws ::= THROWS class_type_list
+ ;
+class_type_list ::=
+ class_type
+ | class_type_list COMMA class_type
+ ;
+method_body ::= block
+ | SEMICOLON
+ ;
+
+// 19.8.4) Static Initializers
+static_initializer ::=
+ STATIC block
+ ;
+
+// 19.8.5) Constructor Declarations
+constructor_declaration ::=
+ modifiers_opt constructor_declarator throws_opt
+ constructor_body
+ ;
+constructor_declarator ::=
+ simple_name LPAREN formal_parameter_list_opt RPAREN
+ ;
+constructor_body ::=
+ LBRACE explicit_constructor_invocation
+ block_statements RBRACE
+ | LBRACE explicit_constructor_invocation RBRACE
+ | LBRACE block_statements RBRACE
+ | LBRACE RBRACE
+ ;
+explicit_constructor_invocation ::=
+ THIS LPAREN argument_list_opt RPAREN SEMICOLON
+ | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ ;
+
+// 19.9) Interfaces
+
+// 19.9.1) Interface Declarations
+interface_declaration ::=
+ modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
+ interface_body
+ ;
+extends_interfaces_opt ::=
+ | extends_interfaces
+ ;
+extends_interfaces ::=
+ EXTENDS interface_type
+ | extends_interfaces COMMA interface_type
+ ;
+interface_body ::=
+ LBRACE interface_member_declarations_opt RBRACE
+ ;
+interface_member_declarations_opt ::=
+ | interface_member_declarations
+ ;
+interface_member_declarations ::=
+ interface_member_declaration
+ | interface_member_declarations interface_member_declaration
+ ;
+interface_member_declaration ::=
+ constant_declaration
+ | abstract_method_declaration
+ | SEMICOLON
+ ;
+constant_declaration ::=
+ field_declaration
+ ;
+abstract_method_declaration ::=
+ method_header SEMICOLON
+ ;
+
+// 19.10) Arrays
+array_initializer ::=
+ LBRACE variable_initializers COMMA RBRACE
+ | LBRACE variable_initializers RBRACE
+ | LBRACE COMMA RBRACE
+ | LBRACE RBRACE
+ ;
+variable_initializers ::=
+ variable_initializer
+ | variable_initializers COMMA variable_initializer
+ ;
+
+// 19.11) Blocks and Statements
+block ::= LBRACE block_statements_opt RBRACE
+ ;
+block_statements_opt ::=
+ | block_statements
+ ;
+block_statements ::=
+ block_statement
+ | block_statements block_statement
+ ;
+block_statement ::=
+ local_variable_declaration_statement
+ | statement
+ ;
+local_variable_declaration_statement ::=
+ local_variable_declaration SEMICOLON
+ ;
+local_variable_declaration ::=
+ type variable_declarators
+ ;
+statement ::= statement_without_trailing_substatement
+ | labeled_statement
+ | if_then_statement
+ | if_then_else_statement
+ | while_statement
+ | for_statement
+ ;
+statement_no_short_if ::=
+ statement_without_trailing_substatement
+ | labeled_statement_no_short_if
+ | if_then_else_statement_no_short_if
+ | while_statement_no_short_if
+ | for_statement_no_short_if
+ ;
+statement_without_trailing_substatement ::=
+ block
+ | empty_statement
+ | expression_statement
+ | switch_statement
+ | do_statement
+ | break_statement
+ | continue_statement
+ | return_statement
+ | synchronized_statement
+ | throw_statement
+ | try_statement
+ ;
+empty_statement ::=
+ SEMICOLON
+ ;
+labeled_statement ::=
+ IDENTIFIER COLON statement
+ ;
+labeled_statement_no_short_if ::=
+ IDENTIFIER COLON statement_no_short_if
+ ;
+expression_statement ::=
+ statement_expression SEMICOLON
+ ;
+statement_expression ::=
+ assignment
+ | preincrement_expression
+ | predecrement_expression
+ | postincrement_expression
+ | postdecrement_expression
+ | method_invocation
+ | class_instance_creation_expression
+ ;
+if_then_statement ::=
+ IF LPAREN expression RPAREN statement
+ ;
+if_then_else_statement ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement
+ ;
+if_then_else_statement_no_short_if ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement_no_short_if
+ ;
+switch_statement ::=
+ SWITCH LPAREN expression RPAREN switch_block
+ ;
+switch_block ::=
+ LBRACE switch_block_statement_groups switch_labels RBRACE
+ | LBRACE switch_block_statement_groups RBRACE
+ | LBRACE switch_labels RBRACE
+ | LBRACE RBRACE
+ ;
+switch_block_statement_groups ::=
+ switch_block_statement_group
+ | switch_block_statement_groups switch_block_statement_group
+ ;
+switch_block_statement_group ::=
+ switch_labels block_statements
+ ;
+switch_labels ::=
+ switch_label
+ | switch_labels switch_label
+ ;
+switch_label ::=
+ CASE constant_expression COLON
+ | DEFAULT COLON
+ ;
+
+while_statement ::=
+ WHILE LPAREN expression RPAREN statement
+ ;
+while_statement_no_short_if ::=
+ WHILE LPAREN expression RPAREN statement_no_short_if
+ ;
+do_statement ::=
+ DO statement WHILE LPAREN expression RPAREN SEMICOLON
+ ;
+for_statement ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement
+ ;
+for_statement_no_short_if ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement_no_short_if
+ ;
+for_init_opt ::=
+ | for_init
+ ;
+for_init ::= statement_expression_list
+ | local_variable_declaration
+ ;
+for_update_opt ::=
+ | for_update
+ ;
+for_update ::= statement_expression_list
+ ;
+statement_expression_list ::=
+ statement_expression
+ | statement_expression_list COMMA statement_expression
+ ;
+
+identifier_opt ::=
+ | IDENTIFIER
+ ;
+
+break_statement ::=
+ BREAK identifier_opt SEMICOLON
+ ;
+
+continue_statement ::=
+ CONTINUE identifier_opt SEMICOLON
+ ;
+return_statement ::=
+ RETURN expression_opt SEMICOLON
+ ;
+throw_statement ::=
+ THROW expression SEMICOLON
+ ;
+synchronized_statement ::=
+ SYNCHRONIZED LPAREN expression RPAREN block
+ ;
+try_statement ::=
+ TRY block catches
+ | TRY block catches_opt finally
+ ;
+catches_opt ::=
+ | catches
+ ;
+catches ::= catch_clause
+ | catches catch_clause
+ ;
+catch_clause ::=
+ CATCH LPAREN formal_parameter RPAREN block
+ ;
+finally ::= FINALLY block
+ ;
+
+// 19.12) Expressions
+primary ::= primary_no_new_array
+ | array_creation_expression
+ ;
+primary_no_new_array ::=
+ literal
+ | THIS
+ | LPAREN expression RPAREN
+ | class_instance_creation_expression
+ | field_access
+ | method_invocation
+ | array_access
+ ;
+class_instance_creation_expression ::=
+ NEW class_type LPAREN argument_list_opt RPAREN
+ ;
+argument_list_opt ::=
+ | argument_list
+ ;
+argument_list ::=
+ expression
+ | argument_list COMMA expression
+ ;
+array_creation_expression ::=
+ NEW primitive_type dim_exprs dims_opt
+ | NEW class_or_interface_type dim_exprs dims_opt
+ ;
+dim_exprs ::= dim_expr
+ | dim_exprs dim_expr
+ ;
+dim_expr ::= LBRACK expression RBRACK
+ ;
+dims_opt ::=
+ | dims
+ ;
+dims ::= LBRACK RBRACK
+ | dims LBRACK RBRACK
+ ;
+field_access ::=
+ primary DOT IDENTIFIER
+ | SUPER DOT IDENTIFIER
+ ;
+method_invocation ::=
+ name LPAREN argument_list_opt RPAREN
+ | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ ;
+array_access ::=
+ name LBRACK expression RBRACK
+ | primary_no_new_array LBRACK expression RBRACK
+ ;
+postfix_expression ::=
+ primary
+ | name
+ | postincrement_expression
+ | postdecrement_expression
+ ;
+postincrement_expression ::=
+ postfix_expression PLUSPLUS
+ ;
+postdecrement_expression ::=
+ postfix_expression MINUSMINUS
+ ;
+unary_expression ::=
+ preincrement_expression
+ | predecrement_expression
+ | PLUS unary_expression
+ | MINUS unary_expression
+ | unary_expression_not_plus_minus
+ ;
+preincrement_expression ::=
+ PLUSPLUS unary_expression
+ ;
+predecrement_expression ::=
+ MINUSMINUS unary_expression
+ ;
+unary_expression_not_plus_minus ::=
+ postfix_expression
+ | COMP unary_expression
+ | NOT unary_expression
+ | cast_expression
+ ;
+cast_expression ::=
+ LPAREN primitive_type dims_opt RPAREN unary_expression
+ | LPAREN expression RPAREN unary_expression_not_plus_minus
+ | LPAREN name dims RPAREN unary_expression_not_plus_minus
+ ;
+multiplicative_expression ::=
+ unary_expression
+ | multiplicative_expression MULT unary_expression
+ | multiplicative_expression DIV unary_expression
+ | multiplicative_expression MOD unary_expression
+ ;
+additive_expression ::=
+ multiplicative_expression
+ | additive_expression PLUS multiplicative_expression
+ | additive_expression MINUS multiplicative_expression
+ ;
+shift_expression ::=
+ additive_expression
+ | shift_expression LSHIFT additive_expression
+ | shift_expression RSHIFT additive_expression
+ | shift_expression URSHIFT additive_expression
+ ;
+relational_expression ::=
+ shift_expression
+ | relational_expression LT shift_expression
+ | relational_expression GT shift_expression
+ | relational_expression LTEQ shift_expression
+ | relational_expression GTEQ shift_expression
+ | relational_expression INSTANCEOF reference_type
+ ;
+equality_expression ::=
+ relational_expression
+ | equality_expression EQEQ relational_expression
+ | equality_expression NOTEQ relational_expression
+ ;
+and_expression ::=
+ equality_expression
+ | and_expression AND equality_expression
+ ;
+exclusive_or_expression ::=
+ and_expression
+ | exclusive_or_expression XOR and_expression
+ ;
+inclusive_or_expression ::=
+ exclusive_or_expression
+ | inclusive_or_expression OR exclusive_or_expression
+ ;
+conditional_and_expression ::=
+ inclusive_or_expression
+ | conditional_and_expression ANDAND inclusive_or_expression
+ ;
+conditional_or_expression ::=
+ conditional_and_expression
+ | conditional_or_expression OROR conditional_and_expression
+ ;
+conditional_expression ::=
+ conditional_or_expression
+ | conditional_or_expression QUESTION expression
+ COLON conditional_expression
+ ;
+assignment_expression ::=
+ conditional_expression
+ | assignment
+ ;
+assignment ::= left_hand_side assignment_operator assignment_expression
+ ;
+left_hand_side ::=
+ name
+ | field_access
+ | array_access
+ ;
+assignment_operator ::=
+ EQ
+ | MULTEQ
+ | DIVEQ
+ | MODEQ
+ | PLUSEQ
+ | MINUSEQ
+ | LSHIFTEQ
+ | RSHIFTEQ
+ | URSHIFTEQ
+ | ANDEQ
+ | XOREQ
+ | OREQ
+ ;
+expression_opt ::=
+ | expression
+ ;
+expression ::= assignment_expression
+ ;
+constant_expression ::=
+ expression
+ ;
--- /dev/null
+package Parse;
+
+import java_cup.runtime.*;
+
+/* Java 1.1 parser for CUP.
+ * Copyright (C) 1998-2003 C. Scott Ananian <cananian@alumni.princeton.edu>
+ * This program is released under the terms of the GPL; see the file
+ * COPYING for more details. There is NO WARRANTY on this code.
+ */
+
+/*
+JDK 1.1 Features added:
+ instance initializers
+ anonymous array expressions.
+ class literals.
+ blank finals; final local variables.
+ inner classes:
+ block ::= class/interface decl
+ primary_no_new_array ::= class_name DOT THIS
+ class_instance_creation_expresion ::= ...
+ explicit_constructor_invocation ::= ...
+*/
+parser code {:
+ Lexer lexer;
+
+ public Grm11(Lexer l) {
+ this();
+ lexer=l;
+ }
+
+ public void syntax_error(java_cup.runtime.Symbol current) {
+ report_error("Syntax error (" + current.sym + ")", current);
+ }
+ public void report_error(String message, java_cup.runtime.Symbol info) {
+ lexer.errorMsg(message, info);
+ }
+:};
+
+scan with {: return lexer.nextToken(); :};
+
+terminal BOOLEAN; // primitive_type
+terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
+terminal FLOAT, DOUBLE; // floating_point_type
+terminal LBRACK, RBRACK; // array_type
+terminal java.lang.String IDENTIFIER; // name
+terminal DOT; // qualified_name
+terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
+terminal PACKAGE; // package_declaration
+terminal IMPORT; // import_declaration
+terminal PUBLIC, PROTECTED, PRIVATE; // modifier
+terminal STATIC; // modifier
+terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
+terminal CLASS; // class_declaration
+terminal EXTENDS; // super
+terminal IMPLEMENTS; // interfaces
+terminal VOID; // method_header
+terminal THROWS; // throws
+terminal THIS, SUPER; // explicit_constructor_invocation
+terminal INTERFACE; // interface_declaration
+terminal IF, ELSE; // if_then_statement, if_then_else_statement
+terminal SWITCH; // switch_statement
+terminal CASE, DEFAULT; // switch_label
+terminal DO, WHILE; // while_statement, do_statement
+terminal FOR; // for_statement
+terminal BREAK; // break_statement
+terminal CONTINUE; // continue_statement
+terminal RETURN; // return_statement
+terminal THROW; // throw_statement
+terminal TRY; // try_statement
+terminal CATCH; // catch_clause
+terminal FINALLY; // finally
+terminal NEW; // class_instance_creation_expression
+terminal PLUSPLUS; // postincrement_expression
+terminal MINUSMINUS; // postdecrement_expression
+terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
+terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
+terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
+terminal EQEQ, NOTEQ; // equality_expression
+terminal AND; // and_expression
+terminal XOR; // exclusive_or_expression
+terminal OR; // inclusive_or_expression
+terminal ANDAND; // conditional_and_expression
+terminal OROR; // conditional_or_expression
+terminal QUESTION; // conditional_expression
+terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
+terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
+terminal ANDEQ, XOREQ, OREQ; // assignment_operator
+
+terminal java.lang.Number INTEGER_LITERAL;
+terminal java.lang.Number FLOATING_POINT_LITERAL;
+terminal java.lang.Boolean BOOLEAN_LITERAL;
+terminal java.lang.Character CHARACTER_LITERAL;
+terminal java.lang.String STRING_LITERAL;
+terminal NULL_LITERAL;
+
+// Reserved but unused:
+terminal CONST, GOTO;
+// lexer compatibility with Java 1.2:
+terminal STRICTFP;
+// lexer compatibility with Java 1.4
+terminal ASSERT;
+// lexer compatibility with Java 1.5
+terminal ELLIPSIS;
+terminal ENUM;
+
+// 19.2) The Syntactic Grammar
+non terminal goal;
+// 19.3) Lexical Structure
+non terminal literal;
+// 19.4) Types, Values, and Variables
+non terminal type, primitive_type, numeric_type;
+non terminal integral_type, floating_point_type;
+non terminal reference_type;
+non terminal class_or_interface_type;
+non terminal class_type, interface_type;
+non terminal array_type;
+// 19.5) Names
+non terminal name, simple_name, qualified_name;
+// 19.6) Packages
+non terminal compilation_unit;
+non terminal package_declaration_opt, package_declaration;
+non terminal import_declarations_opt, import_declarations;
+non terminal type_declarations_opt, type_declarations;
+non terminal import_declaration;
+non terminal single_type_import_declaration;
+non terminal type_import_on_demand_declaration;
+non terminal type_declaration;
+// 19.7) Productions used only in the LALR(1) grammar
+non terminal modifiers_opt, modifiers, modifier;
+// 19.8.1) Class Declaration
+non terminal class_declaration, super, super_opt;
+non terminal interfaces, interfaces_opt, interface_type_list;
+non terminal class_body;
+non terminal class_body_declarations, class_body_declarations_opt;
+non terminal class_body_declaration, class_member_declaration;
+// 19.8.2) Field Declarations
+non terminal field_declaration, variable_declarators, variable_declarator;
+non terminal variable_declarator_id, variable_initializer;
+// 19.8.3) Method Declarations
+non terminal method_declaration, method_header, method_declarator;
+non terminal formal_parameter_list_opt, formal_parameter_list;
+non terminal formal_parameter;
+non terminal throws_opt, throws;
+non terminal class_type_list, method_body;
+// 19.8.4) Static Initializers
+non terminal static_initializer;
+// 19.8.5) Constructor Declarations
+non terminal constructor_declaration, constructor_declarator;
+non terminal constructor_body;
+non terminal explicit_constructor_invocation;
+// 19.9.1) Interface Declarations
+non terminal interface_declaration;
+non terminal extends_interfaces_opt, extends_interfaces;
+non terminal interface_body;
+non terminal interface_member_declarations_opt, interface_member_declarations;
+non terminal interface_member_declaration, constant_declaration;
+non terminal abstract_method_declaration;
+// 19.10) Arrays
+non terminal array_initializer;
+non terminal variable_initializers;
+// 19.11) Blocks and Statements
+non terminal block;
+non terminal block_statements_opt, block_statements, block_statement;
+non terminal local_variable_declaration_statement, local_variable_declaration;
+non terminal statement, statement_no_short_if;
+non terminal statement_without_trailing_substatement;
+non terminal empty_statement;
+non terminal labeled_statement, labeled_statement_no_short_if;
+non terminal expression_statement, statement_expression;
+non terminal if_then_statement;
+non terminal if_then_else_statement, if_then_else_statement_no_short_if;
+non terminal switch_statement, switch_block;
+non terminal switch_block_statement_groups;
+non terminal switch_block_statement_group;
+non terminal switch_labels, switch_label;
+non terminal while_statement, while_statement_no_short_if;
+non terminal do_statement;
+non terminal for_statement, for_statement_no_short_if;
+non terminal for_init_opt, for_init;
+non terminal for_update_opt, for_update;
+non terminal statement_expression_list;
+non terminal identifier_opt;
+non terminal break_statement, continue_statement;
+non terminal return_statement, throw_statement;
+non terminal synchronized_statement, try_statement;
+non terminal catches_opt, catches, catch_clause;
+non terminal finally;
+// 19.12) Expressions
+non terminal primary, primary_no_new_array;
+non terminal class_instance_creation_expression;
+non terminal argument_list_opt, argument_list;
+non terminal array_creation_expression;
+non terminal dim_exprs, dim_expr, dims_opt, dims;
+non terminal field_access, method_invocation, array_access;
+non terminal postfix_expression;
+non terminal postincrement_expression, postdecrement_expression;
+non terminal unary_expression, unary_expression_not_plus_minus;
+non terminal preincrement_expression, predecrement_expression;
+non terminal cast_expression;
+non terminal multiplicative_expression, additive_expression;
+non terminal shift_expression, relational_expression, equality_expression;
+non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
+non terminal conditional_and_expression, conditional_or_expression;
+non terminal conditional_expression, assignment_expression;
+non terminal assignment;
+non terminal left_hand_side;
+non terminal assignment_operator;
+non terminal expression_opt, expression;
+non terminal constant_expression;
+
+start with goal;
+
+// 19.2) The Syntactic Grammar
+goal ::= compilation_unit
+ ;
+
+// 19.3) Lexical Structure.
+literal ::= INTEGER_LITERAL
+ | FLOATING_POINT_LITERAL
+ | BOOLEAN_LITERAL
+ | CHARACTER_LITERAL
+ | STRING_LITERAL
+ | NULL_LITERAL
+ ;
+
+// 19.4) Types, Values, and Variables
+type ::= primitive_type
+ | reference_type
+ ;
+primitive_type ::=
+ numeric_type
+ | BOOLEAN
+ ;
+numeric_type::= integral_type
+ | floating_point_type
+ ;
+integral_type ::=
+ BYTE
+ | SHORT
+ | INT
+ | LONG
+ | CHAR
+ ;
+floating_point_type ::=
+ FLOAT
+ | DOUBLE
+ ;
+
+reference_type ::=
+ class_or_interface_type
+ | array_type
+ ;
+class_or_interface_type ::= name;
+
+class_type ::= class_or_interface_type;
+interface_type ::= class_or_interface_type;
+
+array_type ::= primitive_type dims
+ | name dims
+ ;
+
+// 19.5) Names
+name ::= simple_name
+ | qualified_name
+ ;
+simple_name ::= IDENTIFIER
+ ;
+qualified_name ::=
+ name DOT IDENTIFIER
+ ;
+
+// 19.6) Packages
+compilation_unit ::=
+ package_declaration_opt
+ import_declarations_opt
+ type_declarations_opt
+ ;
+package_declaration_opt ::= package_declaration | ;
+import_declarations_opt ::= import_declarations | ;
+type_declarations_opt ::= type_declarations | ;
+
+import_declarations ::=
+ import_declaration
+ | import_declarations import_declaration
+ ;
+type_declarations ::=
+ type_declaration
+ | type_declarations type_declaration
+ ;
+package_declaration ::=
+ PACKAGE name SEMICOLON
+ ;
+import_declaration ::=
+ single_type_import_declaration
+ | type_import_on_demand_declaration
+ ;
+single_type_import_declaration ::=
+ IMPORT name SEMICOLON
+ ;
+type_import_on_demand_declaration ::=
+ IMPORT name DOT MULT SEMICOLON
+ ;
+type_declaration ::=
+ class_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+
+// 19.7) Productions used only in the LALR(1) grammar
+modifiers_opt::=
+ | modifiers
+ ;
+modifiers ::= modifier
+ | modifiers modifier
+ ;
+modifier ::= PUBLIC | PROTECTED | PRIVATE
+ | STATIC
+ | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
+ ;
+
+// 19.8) Classes
+
+// 19.8.1) Class Declaration:
+class_declaration ::=
+ modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
+ ;
+super ::= EXTENDS class_type
+ ;
+super_opt ::=
+ | super
+ ;
+interfaces ::= IMPLEMENTS interface_type_list
+ ;
+interfaces_opt::=
+ | interfaces
+ ;
+interface_type_list ::=
+ interface_type
+ | interface_type_list COMMA interface_type
+ ;
+class_body ::= LBRACE class_body_declarations_opt RBRACE
+ ;
+class_body_declarations_opt ::=
+ | class_body_declarations ;
+class_body_declarations ::=
+ class_body_declaration
+ | class_body_declarations class_body_declaration
+ ;
+class_body_declaration ::=
+ class_member_declaration
+ | static_initializer
+ | constructor_declaration
+ | block
+ ;
+class_member_declaration ::=
+ field_declaration
+ | method_declaration
+ /* repeat the prod for 'class_declaration' here: */
+ | modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
+ | interface_declaration
+ | SEMICOLON
+ ;
+
+// 19.8.2) Field Declarations
+field_declaration ::=
+ modifiers_opt type variable_declarators SEMICOLON
+ ;
+variable_declarators ::=
+ variable_declarator
+ | variable_declarators COMMA variable_declarator
+ ;
+variable_declarator ::=
+ variable_declarator_id
+ | variable_declarator_id EQ variable_initializer
+ ;
+variable_declarator_id ::=
+ IDENTIFIER
+ | variable_declarator_id LBRACK RBRACK
+ ;
+variable_initializer ::=
+ expression
+ | array_initializer
+ ;
+
+// 19.8.3) Method Declarations
+method_declaration ::=
+ method_header method_body
+ ;
+method_header ::=
+ modifiers_opt type method_declarator throws_opt
+ | modifiers_opt VOID method_declarator throws_opt
+ ;
+method_declarator ::=
+ IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
+ | method_declarator LBRACK RBRACK
+ ;
+formal_parameter_list_opt ::=
+ | formal_parameter_list
+ ;
+formal_parameter_list ::=
+ formal_parameter
+ | formal_parameter_list COMMA formal_parameter
+ ;
+formal_parameter ::=
+ type variable_declarator_id
+ | FINAL type variable_declarator_id
+ ;
+throws_opt ::=
+ | throws
+ ;
+throws ::= THROWS class_type_list
+ ;
+class_type_list ::=
+ class_type
+ | class_type_list COMMA class_type
+ ;
+method_body ::= block
+ | SEMICOLON
+ ;
+
+// 19.8.4) Static Initializers
+static_initializer ::=
+ STATIC block
+ ;
+
+// 19.8.5) Constructor Declarations
+constructor_declaration ::=
+ modifiers_opt constructor_declarator throws_opt
+ constructor_body
+ ;
+constructor_declarator ::=
+ simple_name LPAREN formal_parameter_list_opt RPAREN
+ ;
+constructor_body ::=
+ LBRACE explicit_constructor_invocation
+ block_statements RBRACE
+ | LBRACE explicit_constructor_invocation RBRACE
+ | LBRACE block_statements RBRACE
+ | LBRACE RBRACE
+ ;
+explicit_constructor_invocation ::=
+ THIS LPAREN argument_list_opt RPAREN SEMICOLON
+ | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ ;
+
+// 19.9) Interfaces
+
+// 19.9.1) Interface Declarations
+interface_declaration ::=
+ modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
+ interface_body
+ ;
+extends_interfaces_opt ::=
+ | extends_interfaces
+ ;
+extends_interfaces ::=
+ EXTENDS interface_type
+ | extends_interfaces COMMA interface_type
+ ;
+interface_body ::=
+ LBRACE interface_member_declarations_opt RBRACE
+ ;
+interface_member_declarations_opt ::=
+ | interface_member_declarations
+ ;
+interface_member_declarations ::=
+ interface_member_declaration
+ | interface_member_declarations interface_member_declaration
+ ;
+interface_member_declaration ::=
+ constant_declaration
+ | abstract_method_declaration
+ | class_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+constant_declaration ::=
+ field_declaration
+ // need to semantically check that modifiers of field declaration
+ // include only PUBLIC, STATIC, or FINAL. Other modifiers are
+ // disallowed.
+ ;
+abstract_method_declaration ::=
+ method_header SEMICOLON
+ ;
+
+// 19.10) Arrays
+array_initializer ::=
+ LBRACE variable_initializers COMMA RBRACE
+ | LBRACE variable_initializers RBRACE
+ | LBRACE COMMA RBRACE
+ | LBRACE RBRACE
+ ;
+variable_initializers ::=
+ variable_initializer
+ | variable_initializers COMMA variable_initializer
+ ;
+
+// 19.11) Blocks and Statements
+block ::= LBRACE block_statements_opt RBRACE
+ ;
+block_statements_opt ::=
+ | block_statements
+ ;
+block_statements ::=
+ block_statement
+ | block_statements block_statement
+ ;
+block_statement ::=
+ local_variable_declaration_statement
+ | statement
+ | class_declaration
+ | interface_declaration
+ ;
+local_variable_declaration_statement ::=
+ local_variable_declaration SEMICOLON
+ ;
+local_variable_declaration ::=
+ type variable_declarators
+ | FINAL type variable_declarators
+ ;
+statement ::= statement_without_trailing_substatement
+ | labeled_statement
+ | if_then_statement
+ | if_then_else_statement
+ | while_statement
+ | for_statement
+ ;
+statement_no_short_if ::=
+ statement_without_trailing_substatement
+ | labeled_statement_no_short_if
+ | if_then_else_statement_no_short_if
+ | while_statement_no_short_if
+ | for_statement_no_short_if
+ ;
+statement_without_trailing_substatement ::=
+ block
+ | empty_statement
+ | expression_statement
+ | switch_statement
+ | do_statement
+ | break_statement
+ | continue_statement
+ | return_statement
+ | synchronized_statement
+ | throw_statement
+ | try_statement
+ ;
+empty_statement ::=
+ SEMICOLON
+ ;
+labeled_statement ::=
+ IDENTIFIER COLON statement
+ ;
+labeled_statement_no_short_if ::=
+ IDENTIFIER COLON statement_no_short_if
+ ;
+expression_statement ::=
+ statement_expression SEMICOLON
+ ;
+statement_expression ::=
+ assignment
+ | preincrement_expression
+ | predecrement_expression
+ | postincrement_expression
+ | postdecrement_expression
+ | method_invocation
+ | class_instance_creation_expression
+ ;
+if_then_statement ::=
+ IF LPAREN expression RPAREN statement
+ ;
+if_then_else_statement ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement
+ ;
+if_then_else_statement_no_short_if ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement_no_short_if
+ ;
+switch_statement ::=
+ SWITCH LPAREN expression RPAREN switch_block
+ ;
+switch_block ::=
+ LBRACE switch_block_statement_groups switch_labels RBRACE
+ | LBRACE switch_block_statement_groups RBRACE
+ | LBRACE switch_labels RBRACE
+ | LBRACE RBRACE
+ ;
+switch_block_statement_groups ::=
+ switch_block_statement_group
+ | switch_block_statement_groups switch_block_statement_group
+ ;
+switch_block_statement_group ::=
+ switch_labels block_statements
+ ;
+switch_labels ::=
+ switch_label
+ | switch_labels switch_label
+ ;
+switch_label ::=
+ CASE constant_expression COLON
+ | DEFAULT COLON
+ ;
+
+while_statement ::=
+ WHILE LPAREN expression RPAREN statement
+ ;
+while_statement_no_short_if ::=
+ WHILE LPAREN expression RPAREN statement_no_short_if
+ ;
+do_statement ::=
+ DO statement WHILE LPAREN expression RPAREN SEMICOLON
+ ;
+for_statement ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement
+ ;
+for_statement_no_short_if ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement_no_short_if
+ ;
+for_init_opt ::=
+ | for_init
+ ;
+for_init ::= statement_expression_list
+ | local_variable_declaration
+ ;
+for_update_opt ::=
+ | for_update
+ ;
+for_update ::= statement_expression_list
+ ;
+statement_expression_list ::=
+ statement_expression
+ | statement_expression_list COMMA statement_expression
+ ;
+
+identifier_opt ::=
+ | IDENTIFIER
+ ;
+
+break_statement ::=
+ BREAK identifier_opt SEMICOLON
+ ;
+
+continue_statement ::=
+ CONTINUE identifier_opt SEMICOLON
+ ;
+return_statement ::=
+ RETURN expression_opt SEMICOLON
+ ;
+throw_statement ::=
+ THROW expression SEMICOLON
+ ;
+synchronized_statement ::=
+ SYNCHRONIZED LPAREN expression RPAREN block
+ ;
+try_statement ::=
+ TRY block catches
+ | TRY block catches_opt finally
+ ;
+catches_opt ::=
+ | catches
+ ;
+catches ::= catch_clause
+ | catches catch_clause
+ ;
+catch_clause ::=
+ CATCH LPAREN formal_parameter RPAREN block
+ ;
+finally ::= FINALLY block
+ ;
+
+// 19.12) Expressions
+primary ::= primary_no_new_array
+ | array_creation_expression
+ ;
+primary_no_new_array ::=
+ literal
+ | THIS
+ | LPAREN expression RPAREN
+ | class_instance_creation_expression
+ | field_access
+ | method_invocation
+ | array_access
+ | primitive_type DOT CLASS
+ | VOID DOT CLASS
+ | array_type DOT CLASS
+ | name DOT CLASS
+ | name DOT THIS
+ ;
+class_instance_creation_expression ::=
+ NEW class_type LPAREN argument_list_opt RPAREN
+ | NEW class_type LPAREN argument_list_opt RPAREN class_body
+ | primary DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN
+ | primary DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN class_body
+ ;
+argument_list_opt ::=
+ | argument_list
+ ;
+argument_list ::=
+ expression
+ | argument_list COMMA expression
+ ;
+array_creation_expression ::=
+ NEW primitive_type dim_exprs dims_opt
+ | NEW class_or_interface_type dim_exprs dims_opt
+ | NEW primitive_type dims array_initializer
+ | NEW class_or_interface_type dims array_initializer
+ ;
+dim_exprs ::= dim_expr
+ | dim_exprs dim_expr
+ ;
+dim_expr ::= LBRACK expression RBRACK
+ ;
+dims_opt ::=
+ | dims
+ ;
+dims ::= LBRACK RBRACK
+ | dims LBRACK RBRACK
+ ;
+field_access ::=
+ primary DOT IDENTIFIER
+ | SUPER DOT IDENTIFIER
+ ;
+method_invocation ::=
+ name LPAREN argument_list_opt RPAREN
+ | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ ;
+array_access ::=
+ name LBRACK expression RBRACK
+ | primary_no_new_array LBRACK expression RBRACK
+ ;
+postfix_expression ::=
+ primary
+ | name
+ | postincrement_expression
+ | postdecrement_expression
+ ;
+postincrement_expression ::=
+ postfix_expression PLUSPLUS
+ ;
+postdecrement_expression ::=
+ postfix_expression MINUSMINUS
+ ;
+unary_expression ::=
+ preincrement_expression
+ | predecrement_expression
+ | PLUS unary_expression
+ | MINUS unary_expression
+ | unary_expression_not_plus_minus
+ ;
+preincrement_expression ::=
+ PLUSPLUS unary_expression
+ ;
+predecrement_expression ::=
+ MINUSMINUS unary_expression
+ ;
+unary_expression_not_plus_minus ::=
+ postfix_expression
+ | COMP unary_expression
+ | NOT unary_expression
+ | cast_expression
+ ;
+cast_expression ::=
+ LPAREN primitive_type dims_opt RPAREN unary_expression
+ | LPAREN expression RPAREN unary_expression_not_plus_minus
+ | LPAREN name dims RPAREN unary_expression_not_plus_minus
+ ;
+multiplicative_expression ::=
+ unary_expression
+ | multiplicative_expression MULT unary_expression
+ | multiplicative_expression DIV unary_expression
+ | multiplicative_expression MOD unary_expression
+ ;
+additive_expression ::=
+ multiplicative_expression
+ | additive_expression PLUS multiplicative_expression
+ | additive_expression MINUS multiplicative_expression
+ ;
+shift_expression ::=
+ additive_expression
+ | shift_expression LSHIFT additive_expression
+ | shift_expression RSHIFT additive_expression
+ | shift_expression URSHIFT additive_expression
+ ;
+relational_expression ::=
+ shift_expression
+ | relational_expression LT shift_expression
+ | relational_expression GT shift_expression
+ | relational_expression LTEQ shift_expression
+ | relational_expression GTEQ shift_expression
+ | relational_expression INSTANCEOF reference_type
+ ;
+equality_expression ::=
+ relational_expression
+ | equality_expression EQEQ relational_expression
+ | equality_expression NOTEQ relational_expression
+ ;
+and_expression ::=
+ equality_expression
+ | and_expression AND equality_expression
+ ;
+exclusive_or_expression ::=
+ and_expression
+ | exclusive_or_expression XOR and_expression
+ ;
+inclusive_or_expression ::=
+ exclusive_or_expression
+ | inclusive_or_expression OR exclusive_or_expression
+ ;
+conditional_and_expression ::=
+ inclusive_or_expression
+ | conditional_and_expression ANDAND inclusive_or_expression
+ ;
+conditional_or_expression ::=
+ conditional_and_expression
+ | conditional_or_expression OROR conditional_and_expression
+ ;
+conditional_expression ::=
+ conditional_or_expression
+ | conditional_or_expression QUESTION expression
+ COLON conditional_expression
+ ;
+assignment_expression ::=
+ conditional_expression
+ | assignment
+ ;
+assignment ::= left_hand_side assignment_operator assignment_expression
+ ;
+left_hand_side ::=
+ name
+ | field_access
+ | array_access
+ ;
+assignment_operator ::=
+ EQ
+ | MULTEQ
+ | DIVEQ
+ | MODEQ
+ | PLUSEQ
+ | MINUSEQ
+ | LSHIFTEQ
+ | RSHIFTEQ
+ | URSHIFTEQ
+ | ANDEQ
+ | XOREQ
+ | OREQ
+ ;
+expression_opt ::=
+ | expression
+ ;
+expression ::= assignment_expression
+ ;
+constant_expression ::=
+ expression
+ ;
--- /dev/null
+package Parse;
+
+import java_cup.runtime.*;
+
+/* Java 1.2 parser for CUP.
+ * Copyright (C) 1998-2003 C. Scott Ananian <cananian@alumni.princeton.edu>
+ * This program is released under the terms of the GPL; see the file
+ * COPYING for more details. There is NO WARRANTY on this code.
+ */
+
+/*
+JDK 1.2 Features added:
+ strictfp modifier.
+ explicit_constructor_invocation ::= ...
+ | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON ;
+ field_access ::= ...
+ | name DOT SUPER DOT IDENTIFIER ;
+ method_invocation ::= ...
+ | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN ;
+ parenthesized expression, plain identifiers qualifying instance
+ creation and explicit constructors, and array creation expression
+ fixes from JLS2 (thanks to Eric Blake for pointing these out)
+*/
+parser code {:
+ Lexer lexer;
+
+ public Grm12(Lexer l) {
+ this();
+ lexer=l;
+ }
+
+ public void syntax_error(java_cup.runtime.Symbol current) {
+ report_error("Syntax error (" + current.sym + ")", current);
+ }
+ public void report_error(String message, java_cup.runtime.Symbol info) {
+ lexer.errorMsg(message, info);
+ }
+:};
+
+scan with {: return lexer.nextToken(); :};
+
+terminal BOOLEAN; // primitive_type
+terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
+terminal FLOAT, DOUBLE; // floating_point_type
+terminal LBRACK, RBRACK; // array_type
+terminal java.lang.String IDENTIFIER; // name
+terminal DOT; // qualified_name
+terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
+terminal PACKAGE; // package_declaration
+terminal IMPORT; // import_declaration
+terminal PUBLIC, PROTECTED, PRIVATE; // modifier
+terminal STATIC; // modifier
+terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
+terminal CLASS; // class_declaration
+terminal EXTENDS; // super
+terminal IMPLEMENTS; // interfaces
+terminal VOID; // method_header
+terminal THROWS; // throws
+terminal THIS, SUPER; // explicit_constructor_invocation
+terminal INTERFACE; // interface_declaration
+terminal IF, ELSE; // if_then_statement, if_then_else_statement
+terminal SWITCH; // switch_statement
+terminal CASE, DEFAULT; // switch_label
+terminal DO, WHILE; // while_statement, do_statement
+terminal FOR; // for_statement
+terminal BREAK; // break_statement
+terminal CONTINUE; // continue_statement
+terminal RETURN; // return_statement
+terminal THROW; // throw_statement
+terminal TRY; // try_statement
+terminal CATCH; // catch_clause
+terminal FINALLY; // finally
+terminal NEW; // class_instance_creation_expression
+terminal PLUSPLUS; // postincrement_expression
+terminal MINUSMINUS; // postdecrement_expression
+terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
+terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
+terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
+terminal EQEQ, NOTEQ; // equality_expression
+terminal AND; // and_expression
+terminal XOR; // exclusive_or_expression
+terminal OR; // inclusive_or_expression
+terminal ANDAND; // conditional_and_expression
+terminal OROR; // conditional_or_expression
+terminal QUESTION; // conditional_expression
+terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
+terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
+terminal ANDEQ, XOREQ, OREQ; // assignment_operator
+
+terminal java.lang.Number INTEGER_LITERAL;
+terminal java.lang.Number FLOATING_POINT_LITERAL;
+terminal java.lang.Boolean BOOLEAN_LITERAL;
+terminal java.lang.Character CHARACTER_LITERAL;
+terminal java.lang.String STRING_LITERAL;
+terminal NULL_LITERAL;
+
+// Reserved but unused:
+terminal CONST, GOTO;
+// strictfp keyword, new in Java 1.2
+terminal STRICTFP;
+// lexer compatibility with Java 1.4
+terminal ASSERT;
+// lexer compatibility with Java 1.5
+terminal ELLIPSIS;
+terminal ENUM;
+
+// 19.2) The Syntactic Grammar
+non terminal goal;
+// 19.3) Lexical Structure
+non terminal literal;
+// 19.4) Types, Values, and Variables
+non terminal type, primitive_type, numeric_type;
+non terminal integral_type, floating_point_type;
+non terminal reference_type;
+non terminal class_or_interface_type;
+non terminal class_type, interface_type;
+non terminal array_type;
+// 19.5) Names
+non terminal name, simple_name, qualified_name;
+// 19.6) Packages
+non terminal compilation_unit;
+non terminal package_declaration_opt, package_declaration;
+non terminal import_declarations_opt, import_declarations;
+non terminal type_declarations_opt, type_declarations;
+non terminal import_declaration;
+non terminal single_type_import_declaration;
+non terminal type_import_on_demand_declaration;
+non terminal type_declaration;
+// 19.7) Productions used only in the LALR(1) grammar
+non terminal modifiers_opt, modifiers, modifier;
+// 19.8.1) Class Declaration
+non terminal class_declaration, super, super_opt;
+non terminal interfaces, interfaces_opt, interface_type_list;
+non terminal class_body;
+non terminal class_body_declarations, class_body_declarations_opt;
+non terminal class_body_declaration, class_member_declaration;
+// 19.8.2) Field Declarations
+non terminal field_declaration, variable_declarators, variable_declarator;
+non terminal variable_declarator_id, variable_initializer;
+// 19.8.3) Method Declarations
+non terminal method_declaration, method_header, method_declarator;
+non terminal formal_parameter_list_opt, formal_parameter_list;
+non terminal formal_parameter;
+non terminal throws_opt, throws;
+non terminal class_type_list, method_body;
+// 19.8.4) Static Initializers
+non terminal static_initializer;
+// 19.8.5) Constructor Declarations
+non terminal constructor_declaration, constructor_declarator;
+non terminal constructor_body;
+non terminal explicit_constructor_invocation;
+// 19.9.1) Interface Declarations
+non terminal interface_declaration;
+non terminal extends_interfaces_opt, extends_interfaces;
+non terminal interface_body;
+non terminal interface_member_declarations_opt, interface_member_declarations;
+non terminal interface_member_declaration, constant_declaration;
+non terminal abstract_method_declaration;
+// 19.10) Arrays
+non terminal array_initializer;
+non terminal variable_initializers;
+// 19.11) Blocks and Statements
+non terminal block;
+non terminal block_statements_opt, block_statements, block_statement;
+non terminal local_variable_declaration_statement, local_variable_declaration;
+non terminal statement, statement_no_short_if;
+non terminal statement_without_trailing_substatement;
+non terminal empty_statement;
+non terminal labeled_statement, labeled_statement_no_short_if;
+non terminal expression_statement, statement_expression;
+non terminal if_then_statement;
+non terminal if_then_else_statement, if_then_else_statement_no_short_if;
+non terminal switch_statement, switch_block;
+non terminal switch_block_statement_groups;
+non terminal switch_block_statement_group;
+non terminal switch_labels, switch_label;
+non terminal while_statement, while_statement_no_short_if;
+non terminal do_statement;
+non terminal for_statement, for_statement_no_short_if;
+non terminal for_init_opt, for_init;
+non terminal for_update_opt, for_update;
+non terminal statement_expression_list;
+non terminal identifier_opt;
+non terminal break_statement, continue_statement;
+non terminal return_statement, throw_statement;
+non terminal synchronized_statement, try_statement;
+non terminal catches_opt, catches, catch_clause;
+non terminal finally;
+// 19.12) Expressions
+non terminal primary, primary_no_new_array;
+non terminal class_instance_creation_expression;
+non terminal argument_list_opt, argument_list;
+non terminal array_creation_init, array_creation_uninit;
+non terminal dim_exprs, dim_expr, dims_opt, dims;
+non terminal field_access, method_invocation, array_access;
+non terminal postfix_expression;
+non terminal postincrement_expression, postdecrement_expression;
+non terminal unary_expression, unary_expression_not_plus_minus;
+non terminal preincrement_expression, predecrement_expression;
+non terminal cast_expression;
+non terminal multiplicative_expression, additive_expression;
+non terminal shift_expression, relational_expression, equality_expression;
+non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
+non terminal conditional_and_expression, conditional_or_expression;
+non terminal conditional_expression, assignment_expression;
+non terminal assignment;
+non terminal assignment_operator;
+non terminal expression_opt, expression;
+non terminal constant_expression;
+
+start with goal;
+
+// 19.2) The Syntactic Grammar
+goal ::= compilation_unit
+ ;
+
+// 19.3) Lexical Structure.
+literal ::= INTEGER_LITERAL
+ | FLOATING_POINT_LITERAL
+ | BOOLEAN_LITERAL
+ | CHARACTER_LITERAL
+ | STRING_LITERAL
+ | NULL_LITERAL
+ ;
+
+// 19.4) Types, Values, and Variables
+type ::= primitive_type
+ | reference_type
+ ;
+primitive_type ::=
+ numeric_type
+ | BOOLEAN
+ ;
+numeric_type::= integral_type
+ | floating_point_type
+ ;
+integral_type ::=
+ BYTE
+ | SHORT
+ | INT
+ | LONG
+ | CHAR
+ ;
+floating_point_type ::=
+ FLOAT
+ | DOUBLE
+ ;
+
+reference_type ::=
+ class_or_interface_type
+ | array_type
+ ;
+class_or_interface_type ::= name;
+
+class_type ::= class_or_interface_type;
+interface_type ::= class_or_interface_type;
+
+array_type ::= primitive_type dims
+ | name dims
+ ;
+
+// 19.5) Names
+name ::= simple_name
+ | qualified_name
+ ;
+simple_name ::= IDENTIFIER
+ ;
+qualified_name ::=
+ name DOT IDENTIFIER
+ ;
+
+// 19.6) Packages
+compilation_unit ::=
+ package_declaration_opt
+ import_declarations_opt
+ type_declarations_opt
+ ;
+package_declaration_opt ::= package_declaration | ;
+import_declarations_opt ::= import_declarations | ;
+type_declarations_opt ::= type_declarations | ;
+
+import_declarations ::=
+ import_declaration
+ | import_declarations import_declaration
+ ;
+type_declarations ::=
+ type_declaration
+ | type_declarations type_declaration
+ ;
+package_declaration ::=
+ PACKAGE name SEMICOLON
+ ;
+import_declaration ::=
+ single_type_import_declaration
+ | type_import_on_demand_declaration
+ ;
+single_type_import_declaration ::=
+ IMPORT name SEMICOLON
+ ;
+type_import_on_demand_declaration ::=
+ IMPORT name DOT MULT SEMICOLON
+ ;
+type_declaration ::=
+ class_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+
+// 19.7) Productions used only in the LALR(1) grammar
+modifiers_opt::=
+ | modifiers
+ ;
+modifiers ::= modifier
+ | modifiers modifier
+ ;
+modifier ::= PUBLIC | PROTECTED | PRIVATE
+ | STATIC
+ | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
+ | STRICTFP // note that semantic analysis must check that the
+ // context of the modifier allows strictfp.
+ ;
+
+// 19.8) Classes
+
+// 19.8.1) Class Declaration:
+class_declaration ::=
+ modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
+ ;
+super ::= EXTENDS class_type
+ ;
+super_opt ::=
+ | super
+ ;
+interfaces ::= IMPLEMENTS interface_type_list
+ ;
+interfaces_opt::=
+ | interfaces
+ ;
+interface_type_list ::=
+ interface_type
+ | interface_type_list COMMA interface_type
+ ;
+class_body ::= LBRACE class_body_declarations_opt RBRACE
+ ;
+class_body_declarations_opt ::=
+ | class_body_declarations ;
+class_body_declarations ::=
+ class_body_declaration
+ | class_body_declarations class_body_declaration
+ ;
+class_body_declaration ::=
+ class_member_declaration
+ | static_initializer
+ | constructor_declaration
+ | block
+ ;
+class_member_declaration ::=
+ field_declaration
+ | method_declaration
+ /* repeat the prod for 'class_declaration' here: */
+ | modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
+ | interface_declaration
+ | SEMICOLON
+ ;
+
+// 19.8.2) Field Declarations
+field_declaration ::=
+ modifiers_opt type variable_declarators SEMICOLON
+ ;
+variable_declarators ::=
+ variable_declarator
+ | variable_declarators COMMA variable_declarator
+ ;
+variable_declarator ::=
+ variable_declarator_id
+ | variable_declarator_id EQ variable_initializer
+ ;
+variable_declarator_id ::=
+ IDENTIFIER
+ | variable_declarator_id LBRACK RBRACK
+ ;
+variable_initializer ::=
+ expression
+ | array_initializer
+ ;
+
+// 19.8.3) Method Declarations
+method_declaration ::=
+ method_header method_body
+ ;
+method_header ::=
+ modifiers_opt type method_declarator throws_opt
+ | modifiers_opt VOID method_declarator throws_opt
+ ;
+method_declarator ::=
+ IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
+ | method_declarator LBRACK RBRACK // deprecated
+ // be careful; the above production also allows 'void foo() []'
+ ;
+formal_parameter_list_opt ::=
+ | formal_parameter_list
+ ;
+formal_parameter_list ::=
+ formal_parameter
+ | formal_parameter_list COMMA formal_parameter
+ ;
+formal_parameter ::=
+ type variable_declarator_id
+ | FINAL type variable_declarator_id
+ ;
+throws_opt ::=
+ | throws
+ ;
+throws ::= THROWS class_type_list
+ ;
+class_type_list ::=
+ class_type
+ | class_type_list COMMA class_type
+ ;
+method_body ::= block
+ | SEMICOLON
+ ;
+
+// 19.8.4) Static Initializers
+static_initializer ::=
+ STATIC block
+ ;
+
+// 19.8.5) Constructor Declarations
+constructor_declaration ::=
+ modifiers_opt constructor_declarator throws_opt
+ constructor_body
+ ;
+constructor_declarator ::=
+ simple_name LPAREN formal_parameter_list_opt RPAREN
+ ;
+constructor_body ::=
+ LBRACE explicit_constructor_invocation
+ block_statements RBRACE
+ | LBRACE explicit_constructor_invocation RBRACE
+ | LBRACE block_statements RBRACE
+ | LBRACE RBRACE
+ ;
+explicit_constructor_invocation ::=
+ THIS LPAREN argument_list_opt RPAREN SEMICOLON
+ | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ | name DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ ;
+
+// 19.9) Interfaces
+
+// 19.9.1) Interface Declarations
+interface_declaration ::=
+ modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
+ interface_body
+ ;
+extends_interfaces_opt ::=
+ | extends_interfaces
+ ;
+extends_interfaces ::=
+ EXTENDS interface_type
+ | extends_interfaces COMMA interface_type
+ ;
+interface_body ::=
+ LBRACE interface_member_declarations_opt RBRACE
+ ;
+interface_member_declarations_opt ::=
+ | interface_member_declarations
+ ;
+interface_member_declarations ::=
+ interface_member_declaration
+ | interface_member_declarations interface_member_declaration
+ ;
+interface_member_declaration ::=
+ constant_declaration
+ | abstract_method_declaration
+ | class_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+constant_declaration ::=
+ field_declaration
+ // need to semantically check that modifiers of field declaration
+ // include only PUBLIC, STATIC, or FINAL. Other modifiers are
+ // disallowed.
+ ;
+abstract_method_declaration ::=
+ method_header SEMICOLON
+ ;
+
+// 19.10) Arrays
+array_initializer ::=
+ LBRACE variable_initializers COMMA RBRACE
+ | LBRACE variable_initializers RBRACE
+ | LBRACE COMMA RBRACE
+ | LBRACE RBRACE
+ ;
+variable_initializers ::=
+ variable_initializer
+ | variable_initializers COMMA variable_initializer
+ ;
+
+// 19.11) Blocks and Statements
+block ::= LBRACE block_statements_opt RBRACE
+ ;
+block_statements_opt ::=
+ | block_statements
+ ;
+block_statements ::=
+ block_statement
+ | block_statements block_statement
+ ;
+block_statement ::=
+ local_variable_declaration_statement
+ | statement
+ | class_declaration
+ | interface_declaration
+ ;
+local_variable_declaration_statement ::=
+ local_variable_declaration SEMICOLON
+ ;
+local_variable_declaration ::=
+ type variable_declarators
+ | FINAL type variable_declarators
+ ;
+statement ::= statement_without_trailing_substatement
+ | labeled_statement
+ | if_then_statement
+ | if_then_else_statement
+ | while_statement
+ | for_statement
+ ;
+statement_no_short_if ::=
+ statement_without_trailing_substatement
+ | labeled_statement_no_short_if
+ | if_then_else_statement_no_short_if
+ | while_statement_no_short_if
+ | for_statement_no_short_if
+ ;
+statement_without_trailing_substatement ::=
+ block
+ | empty_statement
+ | expression_statement
+ | switch_statement
+ | do_statement
+ | break_statement
+ | continue_statement
+ | return_statement
+ | synchronized_statement
+ | throw_statement
+ | try_statement
+ ;
+empty_statement ::=
+ SEMICOLON
+ ;
+labeled_statement ::=
+ IDENTIFIER COLON statement
+ ;
+labeled_statement_no_short_if ::=
+ IDENTIFIER COLON statement_no_short_if
+ ;
+expression_statement ::=
+ statement_expression SEMICOLON
+ ;
+statement_expression ::=
+ assignment
+ | preincrement_expression
+ | predecrement_expression
+ | postincrement_expression
+ | postdecrement_expression
+ | method_invocation
+ | class_instance_creation_expression
+ ;
+if_then_statement ::=
+ IF LPAREN expression RPAREN statement
+ ;
+if_then_else_statement ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement
+ ;
+if_then_else_statement_no_short_if ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement_no_short_if
+ ;
+switch_statement ::=
+ SWITCH LPAREN expression RPAREN switch_block
+ ;
+switch_block ::=
+ LBRACE switch_block_statement_groups switch_labels RBRACE
+ | LBRACE switch_block_statement_groups RBRACE
+ | LBRACE switch_labels RBRACE
+ | LBRACE RBRACE
+ ;
+switch_block_statement_groups ::=
+ switch_block_statement_group
+ | switch_block_statement_groups switch_block_statement_group
+ ;
+switch_block_statement_group ::=
+ switch_labels block_statements
+ ;
+switch_labels ::=
+ switch_label
+ | switch_labels switch_label
+ ;
+switch_label ::=
+ CASE constant_expression COLON
+ | DEFAULT COLON
+ ;
+
+while_statement ::=
+ WHILE LPAREN expression RPAREN statement
+ ;
+while_statement_no_short_if ::=
+ WHILE LPAREN expression RPAREN statement_no_short_if
+ ;
+do_statement ::=
+ DO statement WHILE LPAREN expression RPAREN SEMICOLON
+ ;
+for_statement ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement
+ ;
+for_statement_no_short_if ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement_no_short_if
+ ;
+for_init_opt ::=
+ | for_init
+ ;
+for_init ::= statement_expression_list
+ | local_variable_declaration
+ ;
+for_update_opt ::=
+ | for_update
+ ;
+for_update ::= statement_expression_list
+ ;
+statement_expression_list ::=
+ statement_expression
+ | statement_expression_list COMMA statement_expression
+ ;
+
+identifier_opt ::=
+ | IDENTIFIER
+ ;
+
+break_statement ::=
+ BREAK identifier_opt SEMICOLON
+ ;
+
+continue_statement ::=
+ CONTINUE identifier_opt SEMICOLON
+ ;
+return_statement ::=
+ RETURN expression_opt SEMICOLON
+ ;
+throw_statement ::=
+ THROW expression SEMICOLON
+ ;
+synchronized_statement ::=
+ SYNCHRONIZED LPAREN expression RPAREN block
+ ;
+try_statement ::=
+ TRY block catches
+ | TRY block catches_opt finally
+ ;
+catches_opt ::=
+ | catches
+ ;
+catches ::= catch_clause
+ | catches catch_clause
+ ;
+catch_clause ::=
+ CATCH LPAREN formal_parameter RPAREN block
+ ;
+finally ::= FINALLY block
+ ;
+
+// 19.12) Expressions
+primary ::= primary_no_new_array
+ | array_creation_init
+ | array_creation_uninit
+ ;
+primary_no_new_array ::=
+ literal
+ | THIS
+ | LPAREN expression RPAREN
+ | class_instance_creation_expression
+ | field_access
+ | method_invocation
+ | array_access
+ | primitive_type DOT CLASS
+ | VOID DOT CLASS
+ | array_type DOT CLASS
+ | name DOT CLASS
+ | name DOT THIS
+ ;
+class_instance_creation_expression ::=
+ NEW class_or_interface_type LPAREN argument_list_opt RPAREN
+ | NEW class_or_interface_type LPAREN argument_list_opt RPAREN class_body
+ | primary DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN
+ | primary DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN class_body
+ | name DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN
+ | name DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN class_body
+ ;
+argument_list_opt ::=
+ | argument_list
+ ;
+argument_list ::=
+ expression
+ | argument_list COMMA expression
+ ;
+array_creation_uninit ::=
+ NEW primitive_type dim_exprs dims_opt
+ | NEW class_or_interface_type dim_exprs dims_opt
+ ;
+array_creation_init ::=
+ NEW primitive_type dims array_initializer
+ | NEW class_or_interface_type dims array_initializer
+ ;
+dim_exprs ::= dim_expr
+ | dim_exprs dim_expr
+ ;
+dim_expr ::= LBRACK expression RBRACK
+ ;
+dims_opt ::=
+ | dims
+ ;
+dims ::= LBRACK RBRACK
+ | dims LBRACK RBRACK
+ ;
+field_access ::=
+ primary DOT IDENTIFIER
+ | SUPER DOT IDENTIFIER
+ | name DOT SUPER DOT IDENTIFIER
+ ;
+method_invocation ::=
+ name LPAREN argument_list_opt RPAREN
+ | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ ;
+array_access ::=
+ name LBRACK expression RBRACK
+ | primary_no_new_array LBRACK expression RBRACK
+ | array_creation_init LBRACK expression RBRACK
+ ;
+postfix_expression ::=
+ primary
+ | name
+ | postincrement_expression
+ | postdecrement_expression
+ ;
+postincrement_expression ::=
+ postfix_expression PLUSPLUS
+ ;
+postdecrement_expression ::=
+ postfix_expression MINUSMINUS
+ ;
+unary_expression ::=
+ preincrement_expression
+ | predecrement_expression
+ | PLUS unary_expression
+ | MINUS unary_expression
+ | unary_expression_not_plus_minus
+ ;
+preincrement_expression ::=
+ PLUSPLUS unary_expression
+ ;
+predecrement_expression ::=
+ MINUSMINUS unary_expression
+ ;
+unary_expression_not_plus_minus ::=
+ postfix_expression
+ | COMP unary_expression
+ | NOT unary_expression
+ | cast_expression
+ ;
+cast_expression ::=
+ LPAREN primitive_type dims_opt RPAREN unary_expression
+ | LPAREN expression RPAREN unary_expression_not_plus_minus
+ | LPAREN name dims RPAREN unary_expression_not_plus_minus
+ ;
+multiplicative_expression ::=
+ unary_expression
+ | multiplicative_expression MULT unary_expression
+ | multiplicative_expression DIV unary_expression
+ | multiplicative_expression MOD unary_expression
+ ;
+additive_expression ::=
+ multiplicative_expression
+ | additive_expression PLUS multiplicative_expression
+ | additive_expression MINUS multiplicative_expression
+ ;
+shift_expression ::=
+ additive_expression
+ | shift_expression LSHIFT additive_expression
+ | shift_expression RSHIFT additive_expression
+ | shift_expression URSHIFT additive_expression
+ ;
+relational_expression ::=
+ shift_expression
+ | relational_expression LT shift_expression
+ | relational_expression GT shift_expression
+ | relational_expression LTEQ shift_expression
+ | relational_expression GTEQ shift_expression
+ | relational_expression INSTANCEOF reference_type
+ ;
+equality_expression ::=
+ relational_expression
+ | equality_expression EQEQ relational_expression
+ | equality_expression NOTEQ relational_expression
+ ;
+and_expression ::=
+ equality_expression
+ | and_expression AND equality_expression
+ ;
+exclusive_or_expression ::=
+ and_expression
+ | exclusive_or_expression XOR and_expression
+ ;
+inclusive_or_expression ::=
+ exclusive_or_expression
+ | inclusive_or_expression OR exclusive_or_expression
+ ;
+conditional_and_expression ::=
+ inclusive_or_expression
+ | conditional_and_expression ANDAND inclusive_or_expression
+ ;
+conditional_or_expression ::=
+ conditional_and_expression
+ | conditional_or_expression OROR conditional_and_expression
+ ;
+conditional_expression ::=
+ conditional_or_expression
+ | conditional_or_expression QUESTION expression
+ COLON conditional_expression
+ ;
+assignment_expression ::=
+ conditional_expression
+ | assignment
+ ;
+// semantic check necessary here to ensure a valid left-hand side.
+// allowing a parenthesized variable here on the lhs was introduced in
+// JLS 2; thanks to Eric Blake for pointing this out.
+assignment ::= postfix_expression assignment_operator assignment_expression
+ ;
+assignment_operator ::=
+ EQ
+ | MULTEQ
+ | DIVEQ
+ | MODEQ
+ | PLUSEQ
+ | MINUSEQ
+ | LSHIFTEQ
+ | RSHIFTEQ
+ | URSHIFTEQ
+ | ANDEQ
+ | XOREQ
+ | OREQ
+ ;
+expression_opt ::=
+ | expression
+ ;
+expression ::= assignment_expression
+ ;
+constant_expression ::=
+ expression
+ ;
--- /dev/null
+package Parse;
+
+import java_cup.runtime.*;
+
+/* Java 1.4 parser for CUP.
+ * Copyright (C) 2002-2003 C. Scott Ananian <cananian@alumni.princeton.edu>
+ * This program is released under the terms of the GPL; see the file
+ * COPYING for more details. There is NO WARRANTY on this code.
+ */
+
+/*
+JDK 1.4 Features added:
+ assertion statement.
+ statement_without_trailing_substatement ::= ...
+ | assert_statement ;
+ assert_statement ::=
+ ASSERT expression SEMICOLON
+ | ASSERT expression COLON expression SEMICOLON
+ ;
+*/
+parser code {:
+ Lexer lexer;
+
+ public Grm14(Lexer l) {
+ this();
+ lexer=l;
+ }
+
+ public void syntax_error(java_cup.runtime.Symbol current) {
+ report_error("Syntax error (" + current.sym + ")", current);
+ }
+ public void report_error(String message, java_cup.runtime.Symbol info) {
+ lexer.errorMsg(message, info);
+ }
+:};
+
+scan with {: return lexer.nextToken(); :};
+
+terminal BOOLEAN; // primitive_type
+terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
+terminal FLOAT, DOUBLE; // floating_point_type
+terminal LBRACK, RBRACK; // array_type
+terminal java.lang.String IDENTIFIER; // name
+terminal DOT; // qualified_name
+terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
+terminal PACKAGE; // package_declaration
+terminal IMPORT; // import_declaration
+terminal PUBLIC, PROTECTED, PRIVATE; // modifier
+terminal STATIC; // modifier
+terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
+terminal CLASS; // class_declaration
+terminal EXTENDS; // super
+terminal IMPLEMENTS; // interfaces
+terminal VOID; // method_header
+terminal THROWS; // throws
+terminal THIS, SUPER; // explicit_constructor_invocation
+terminal INTERFACE; // interface_declaration
+terminal IF, ELSE; // if_then_statement, if_then_else_statement
+terminal SWITCH; // switch_statement
+terminal CASE, DEFAULT; // switch_label
+terminal DO, WHILE; // while_statement, do_statement
+terminal FOR; // for_statement
+terminal BREAK; // break_statement
+terminal CONTINUE; // continue_statement
+terminal RETURN; // return_statement
+terminal THROW; // throw_statement
+terminal TRY; // try_statement
+terminal CATCH; // catch_clause
+terminal FINALLY; // finally
+terminal NEW; // class_instance_creation_expression
+terminal PLUSPLUS; // postincrement_expression
+terminal MINUSMINUS; // postdecrement_expression
+terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
+terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
+terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
+terminal EQEQ, NOTEQ; // equality_expression
+terminal AND; // and_expression
+terminal XOR; // exclusive_or_expression
+terminal OR; // inclusive_or_expression
+terminal ANDAND; // conditional_and_expression
+terminal OROR; // conditional_or_expression
+terminal QUESTION; // conditional_expression
+terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
+terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
+terminal ANDEQ, XOREQ, OREQ; // assignment_operator
+
+terminal java.lang.Number INTEGER_LITERAL;
+terminal java.lang.Number FLOATING_POINT_LITERAL;
+terminal java.lang.Boolean BOOLEAN_LITERAL;
+terminal java.lang.Character CHARACTER_LITERAL;
+terminal java.lang.String STRING_LITERAL;
+terminal NULL_LITERAL;
+
+// Reserved but unused:
+terminal CONST, GOTO;
+// strictfp keyword, new in Java 1.2
+terminal STRICTFP;
+// assert keyword, new in Java 1.4
+terminal ASSERT; // assert_statement
+// lexer compatibility with Java 1.5
+terminal ELLIPSIS;
+terminal ENUM;
+
+// 19.2) The Syntactic Grammar
+non terminal goal;
+// 19.3) Lexical Structure
+non terminal literal;
+// 19.4) Types, Values, and Variables
+non terminal type, primitive_type, numeric_type;
+non terminal integral_type, floating_point_type;
+non terminal reference_type;
+non terminal class_or_interface_type;
+non terminal class_type, interface_type;
+non terminal array_type;
+// 19.5) Names
+non terminal name, simple_name, qualified_name;
+// 19.6) Packages
+non terminal compilation_unit;
+non terminal package_declaration_opt, package_declaration;
+non terminal import_declarations_opt, import_declarations;
+non terminal type_declarations_opt, type_declarations;
+non terminal import_declaration;
+non terminal single_type_import_declaration;
+non terminal type_import_on_demand_declaration;
+non terminal type_declaration;
+// 19.7) Productions used only in the LALR(1) grammar
+non terminal modifiers_opt, modifiers, modifier;
+// 19.8.1) Class Declaration
+non terminal class_declaration, super, super_opt;
+non terminal interfaces, interfaces_opt, interface_type_list;
+non terminal class_body;
+non terminal class_body_declarations, class_body_declarations_opt;
+non terminal class_body_declaration, class_member_declaration;
+// 19.8.2) Field Declarations
+non terminal field_declaration, variable_declarators, variable_declarator;
+non terminal variable_declarator_id, variable_initializer;
+// 19.8.3) Method Declarations
+non terminal method_declaration, method_header, method_declarator;
+non terminal formal_parameter_list_opt, formal_parameter_list;
+non terminal formal_parameter;
+non terminal throws_opt, throws;
+non terminal class_type_list, method_body;
+// 19.8.4) Static Initializers
+non terminal static_initializer;
+// 19.8.5) Constructor Declarations
+non terminal constructor_declaration, constructor_declarator;
+non terminal constructor_body;
+non terminal explicit_constructor_invocation;
+// 19.9.1) Interface Declarations
+non terminal interface_declaration;
+non terminal extends_interfaces_opt, extends_interfaces;
+non terminal interface_body;
+non terminal interface_member_declarations_opt, interface_member_declarations;
+non terminal interface_member_declaration, constant_declaration;
+non terminal abstract_method_declaration;
+// 19.10) Arrays
+non terminal array_initializer;
+non terminal variable_initializers;
+// 19.11) Blocks and Statements
+non terminal block;
+non terminal block_statements_opt, block_statements, block_statement;
+non terminal local_variable_declaration_statement, local_variable_declaration;
+non terminal statement, statement_no_short_if;
+non terminal statement_without_trailing_substatement;
+non terminal empty_statement;
+non terminal labeled_statement, labeled_statement_no_short_if;
+non terminal expression_statement, statement_expression;
+non terminal if_then_statement;
+non terminal if_then_else_statement, if_then_else_statement_no_short_if;
+non terminal switch_statement, switch_block;
+non terminal switch_block_statement_groups;
+non terminal switch_block_statement_group;
+non terminal switch_labels, switch_label;
+non terminal while_statement, while_statement_no_short_if;
+non terminal do_statement;
+non terminal for_statement, for_statement_no_short_if;
+non terminal for_init_opt, for_init;
+non terminal for_update_opt, for_update;
+non terminal statement_expression_list;
+non terminal identifier_opt;
+non terminal break_statement, continue_statement;
+non terminal return_statement, throw_statement;
+non terminal synchronized_statement, try_statement;
+non terminal catches_opt, catches, catch_clause;
+non terminal finally;
+non terminal assert_statement;
+// 19.12) Expressions
+non terminal primary, primary_no_new_array;
+non terminal class_instance_creation_expression;
+non terminal argument_list_opt, argument_list;
+non terminal array_creation_init, array_creation_uninit;
+non terminal dim_exprs, dim_expr, dims_opt, dims;
+non terminal field_access, method_invocation, array_access;
+non terminal postfix_expression;
+non terminal postincrement_expression, postdecrement_expression;
+non terminal unary_expression, unary_expression_not_plus_minus;
+non terminal preincrement_expression, predecrement_expression;
+non terminal cast_expression;
+non terminal multiplicative_expression, additive_expression;
+non terminal shift_expression, relational_expression, equality_expression;
+non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
+non terminal conditional_and_expression, conditional_or_expression;
+non terminal conditional_expression, assignment_expression;
+non terminal assignment;
+non terminal assignment_operator;
+non terminal expression_opt, expression;
+non terminal constant_expression;
+
+start with goal;
+
+// 19.2) The Syntactic Grammar
+goal ::= compilation_unit
+ ;
+
+// 19.3) Lexical Structure.
+literal ::= INTEGER_LITERAL
+ | FLOATING_POINT_LITERAL
+ | BOOLEAN_LITERAL
+ | CHARACTER_LITERAL
+ | STRING_LITERAL
+ | NULL_LITERAL
+ ;
+
+// 19.4) Types, Values, and Variables
+type ::= primitive_type
+ | reference_type
+ ;
+primitive_type ::=
+ numeric_type
+ | BOOLEAN
+ ;
+numeric_type::= integral_type
+ | floating_point_type
+ ;
+integral_type ::=
+ BYTE
+ | SHORT
+ | INT
+ | LONG
+ | CHAR
+ ;
+floating_point_type ::=
+ FLOAT
+ | DOUBLE
+ ;
+
+reference_type ::=
+ class_or_interface_type
+ | array_type
+ ;
+class_or_interface_type ::= name;
+
+class_type ::= class_or_interface_type;
+interface_type ::= class_or_interface_type;
+
+array_type ::= primitive_type dims
+ | name dims
+ ;
+
+// 19.5) Names
+name ::= simple_name
+ | qualified_name
+ ;
+simple_name ::= IDENTIFIER
+ ;
+qualified_name ::=
+ name DOT IDENTIFIER
+ ;
+
+// 19.6) Packages
+compilation_unit ::=
+ package_declaration_opt
+ import_declarations_opt
+ type_declarations_opt
+ ;
+package_declaration_opt ::= package_declaration | ;
+import_declarations_opt ::= import_declarations | ;
+type_declarations_opt ::= type_declarations | ;
+
+import_declarations ::=
+ import_declaration
+ | import_declarations import_declaration
+ ;
+type_declarations ::=
+ type_declaration
+ | type_declarations type_declaration
+ ;
+package_declaration ::=
+ PACKAGE name SEMICOLON
+ ;
+import_declaration ::=
+ single_type_import_declaration
+ | type_import_on_demand_declaration
+ ;
+single_type_import_declaration ::=
+ IMPORT name SEMICOLON
+ ;
+type_import_on_demand_declaration ::=
+ IMPORT name DOT MULT SEMICOLON
+ ;
+type_declaration ::=
+ class_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+
+// 19.7) Productions used only in the LALR(1) grammar
+modifiers_opt::=
+ | modifiers
+ ;
+modifiers ::= modifier
+ | modifiers modifier
+ ;
+modifier ::= PUBLIC | PROTECTED | PRIVATE
+ | STATIC
+ | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
+ | STRICTFP // note that semantic analysis must check that the
+ // context of the modifier allows strictfp.
+ ;
+
+// 19.8) Classes
+
+// 19.8.1) Class Declaration:
+class_declaration ::=
+ modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
+ ;
+super ::= EXTENDS class_type
+ ;
+super_opt ::=
+ | super
+ ;
+interfaces ::= IMPLEMENTS interface_type_list
+ ;
+interfaces_opt::=
+ | interfaces
+ ;
+interface_type_list ::=
+ interface_type
+ | interface_type_list COMMA interface_type
+ ;
+class_body ::= LBRACE class_body_declarations_opt RBRACE
+ ;
+class_body_declarations_opt ::=
+ | class_body_declarations ;
+class_body_declarations ::=
+ class_body_declaration
+ | class_body_declarations class_body_declaration
+ ;
+class_body_declaration ::=
+ class_member_declaration
+ | static_initializer
+ | constructor_declaration
+ | block
+ ;
+class_member_declaration ::=
+ field_declaration
+ | method_declaration
+ /* repeat the prod for 'class_declaration' here: */
+ | modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body
+ | interface_declaration
+ | SEMICOLON
+ ;
+
+// 19.8.2) Field Declarations
+field_declaration ::=
+ modifiers_opt type variable_declarators SEMICOLON
+ ;
+variable_declarators ::=
+ variable_declarator
+ | variable_declarators COMMA variable_declarator
+ ;
+variable_declarator ::=
+ variable_declarator_id
+ | variable_declarator_id EQ variable_initializer
+ ;
+variable_declarator_id ::=
+ IDENTIFIER
+ | variable_declarator_id LBRACK RBRACK
+ ;
+variable_initializer ::=
+ expression
+ | array_initializer
+ ;
+
+// 19.8.3) Method Declarations
+method_declaration ::=
+ method_header method_body
+ ;
+method_header ::=
+ modifiers_opt type method_declarator throws_opt
+ | modifiers_opt VOID method_declarator throws_opt
+ ;
+method_declarator ::=
+ IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
+ | method_declarator LBRACK RBRACK // deprecated
+ // be careful; the above production also allows 'void foo() []'
+ ;
+formal_parameter_list_opt ::=
+ | formal_parameter_list
+ ;
+formal_parameter_list ::=
+ formal_parameter
+ | formal_parameter_list COMMA formal_parameter
+ ;
+formal_parameter ::=
+ type variable_declarator_id
+ | FINAL type variable_declarator_id
+ ;
+throws_opt ::=
+ | throws
+ ;
+throws ::= THROWS class_type_list
+ ;
+class_type_list ::=
+ class_type
+ | class_type_list COMMA class_type
+ ;
+method_body ::= block
+ | SEMICOLON
+ ;
+
+// 19.8.4) Static Initializers
+static_initializer ::=
+ STATIC block
+ ;
+
+// 19.8.5) Constructor Declarations
+constructor_declaration ::=
+ modifiers_opt constructor_declarator throws_opt
+ constructor_body
+ ;
+constructor_declarator ::=
+ simple_name LPAREN formal_parameter_list_opt RPAREN
+ ;
+constructor_body ::=
+ LBRACE explicit_constructor_invocation
+ block_statements RBRACE
+ | LBRACE explicit_constructor_invocation RBRACE
+ | LBRACE block_statements RBRACE
+ | LBRACE RBRACE
+ ;
+explicit_constructor_invocation ::=
+ THIS LPAREN argument_list_opt RPAREN SEMICOLON
+ | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON
+ | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ ;
+
+// 19.9) Interfaces
+
+// 19.9.1) Interface Declarations
+interface_declaration ::=
+ modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
+ interface_body
+ ;
+extends_interfaces_opt ::=
+ | extends_interfaces
+ ;
+extends_interfaces ::=
+ EXTENDS interface_type
+ | extends_interfaces COMMA interface_type
+ ;
+interface_body ::=
+ LBRACE interface_member_declarations_opt RBRACE
+ ;
+interface_member_declarations_opt ::=
+ | interface_member_declarations
+ ;
+interface_member_declarations ::=
+ interface_member_declaration
+ | interface_member_declarations interface_member_declaration
+ ;
+interface_member_declaration ::=
+ constant_declaration
+ | abstract_method_declaration
+ | class_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+constant_declaration ::=
+ field_declaration
+ // need to semantically check that modifiers of field declaration
+ // include only PUBLIC, STATIC, or FINAL. Other modifiers are
+ // disallowed.
+ ;
+abstract_method_declaration ::=
+ method_header SEMICOLON
+ ;
+
+// 19.10) Arrays
+array_initializer ::=
+ LBRACE variable_initializers COMMA RBRACE
+ | LBRACE variable_initializers RBRACE
+ | LBRACE COMMA RBRACE
+ | LBRACE RBRACE
+ ;
+variable_initializers ::=
+ variable_initializer
+ | variable_initializers COMMA variable_initializer
+ ;
+
+// 19.11) Blocks and Statements
+block ::= LBRACE block_statements_opt RBRACE
+ ;
+block_statements_opt ::=
+ | block_statements
+ ;
+block_statements ::=
+ block_statement
+ | block_statements block_statement
+ ;
+block_statement ::=
+ local_variable_declaration_statement
+ | statement
+ | class_declaration
+ | interface_declaration
+ ;
+local_variable_declaration_statement ::=
+ local_variable_declaration SEMICOLON
+ ;
+local_variable_declaration ::=
+ type variable_declarators
+ | FINAL type variable_declarators
+ ;
+statement ::= statement_without_trailing_substatement
+ | labeled_statement
+ | if_then_statement
+ | if_then_else_statement
+ | while_statement
+ | for_statement
+ ;
+statement_no_short_if ::=
+ statement_without_trailing_substatement
+ | labeled_statement_no_short_if
+ | if_then_else_statement_no_short_if
+ | while_statement_no_short_if
+ | for_statement_no_short_if
+ ;
+statement_without_trailing_substatement ::=
+ block
+ | empty_statement
+ | expression_statement
+ | switch_statement
+ | do_statement
+ | break_statement
+ | continue_statement
+ | return_statement
+ | synchronized_statement
+ | throw_statement
+ | try_statement
+ | assert_statement
+ ;
+empty_statement ::=
+ SEMICOLON
+ ;
+labeled_statement ::=
+ IDENTIFIER COLON statement
+ ;
+labeled_statement_no_short_if ::=
+ IDENTIFIER COLON statement_no_short_if
+ ;
+expression_statement ::=
+ statement_expression SEMICOLON
+ ;
+statement_expression ::=
+ assignment
+ | preincrement_expression
+ | predecrement_expression
+ | postincrement_expression
+ | postdecrement_expression
+ | method_invocation
+ | class_instance_creation_expression
+ ;
+if_then_statement ::=
+ IF LPAREN expression RPAREN statement
+ ;
+if_then_else_statement ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement
+ ;
+if_then_else_statement_no_short_if ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement_no_short_if
+ ;
+switch_statement ::=
+ SWITCH LPAREN expression RPAREN switch_block
+ ;
+switch_block ::=
+ LBRACE switch_block_statement_groups switch_labels RBRACE
+ | LBRACE switch_block_statement_groups RBRACE
+ | LBRACE switch_labels RBRACE
+ | LBRACE RBRACE
+ ;
+switch_block_statement_groups ::=
+ switch_block_statement_group
+ | switch_block_statement_groups switch_block_statement_group
+ ;
+switch_block_statement_group ::=
+ switch_labels block_statements
+ ;
+switch_labels ::=
+ switch_label
+ | switch_labels switch_label
+ ;
+switch_label ::=
+ CASE constant_expression COLON
+ | DEFAULT COLON
+ ;
+
+while_statement ::=
+ WHILE LPAREN expression RPAREN statement
+ ;
+while_statement_no_short_if ::=
+ WHILE LPAREN expression RPAREN statement_no_short_if
+ ;
+do_statement ::=
+ DO statement WHILE LPAREN expression RPAREN SEMICOLON
+ ;
+for_statement ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement
+ ;
+for_statement_no_short_if ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement_no_short_if
+ ;
+for_init_opt ::=
+ | for_init
+ ;
+for_init ::= statement_expression_list
+ | local_variable_declaration
+ ;
+for_update_opt ::=
+ | for_update
+ ;
+for_update ::= statement_expression_list
+ ;
+statement_expression_list ::=
+ statement_expression
+ | statement_expression_list COMMA statement_expression
+ ;
+
+identifier_opt ::=
+ | IDENTIFIER
+ ;
+
+break_statement ::=
+ BREAK identifier_opt SEMICOLON
+ ;
+
+continue_statement ::=
+ CONTINUE identifier_opt SEMICOLON
+ ;
+return_statement ::=
+ RETURN expression_opt SEMICOLON
+ ;
+throw_statement ::=
+ THROW expression SEMICOLON
+ ;
+synchronized_statement ::=
+ SYNCHRONIZED LPAREN expression RPAREN block
+ ;
+try_statement ::=
+ TRY block catches
+ | TRY block catches_opt finally
+ ;
+catches_opt ::=
+ | catches
+ ;
+catches ::= catch_clause
+ | catches catch_clause
+ ;
+catch_clause ::=
+ CATCH LPAREN formal_parameter RPAREN block
+ ;
+finally ::= FINALLY block
+ ;
+assert_statement ::=
+ ASSERT expression SEMICOLON
+ | ASSERT expression COLON expression SEMICOLON
+ ;
+
+// 19.12) Expressions
+primary ::= primary_no_new_array
+ | array_creation_init
+ | array_creation_uninit
+ ;
+primary_no_new_array ::=
+ literal
+ | THIS
+ | LPAREN expression RPAREN
+ | class_instance_creation_expression
+ | field_access
+ | method_invocation
+ | array_access
+ | primitive_type DOT CLASS
+ | VOID DOT CLASS
+ | array_type DOT CLASS
+ | name DOT CLASS
+ | name DOT THIS
+ ;
+class_instance_creation_expression ::=
+ NEW class_or_interface_type LPAREN argument_list_opt RPAREN
+ | NEW class_or_interface_type LPAREN argument_list_opt RPAREN class_body
+ | primary DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN
+ | primary DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN class_body
+ | name DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN
+ | name DOT NEW IDENTIFIER
+ LPAREN argument_list_opt RPAREN class_body
+ ;
+argument_list_opt ::=
+ | argument_list
+ ;
+argument_list ::=
+ expression
+ | argument_list COMMA expression
+ ;
+array_creation_uninit ::=
+ NEW primitive_type dim_exprs dims_opt
+ | NEW class_or_interface_type dim_exprs dims_opt
+ ;
+array_creation_init ::=
+ NEW primitive_type dims array_initializer
+ | NEW class_or_interface_type dims array_initializer
+ ;
+dim_exprs ::= dim_expr
+ | dim_exprs dim_expr
+ ;
+dim_expr ::= LBRACK expression RBRACK
+ ;
+dims_opt ::=
+ | dims
+ ;
+dims ::= LBRACK RBRACK
+ | dims LBRACK RBRACK
+ ;
+field_access ::=
+ primary DOT IDENTIFIER
+ | SUPER DOT IDENTIFIER
+ | name DOT SUPER DOT IDENTIFIER
+ ;
+method_invocation ::=
+ name LPAREN argument_list_opt RPAREN
+ | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ ;
+array_access ::=
+ name LBRACK expression RBRACK
+ | primary_no_new_array LBRACK expression RBRACK
+ | array_creation_init LBRACK expression RBRACK
+ ;
+postfix_expression ::=
+ primary
+ | name
+ | postincrement_expression
+ | postdecrement_expression
+ ;
+postincrement_expression ::=
+ postfix_expression PLUSPLUS
+ ;
+postdecrement_expression ::=
+ postfix_expression MINUSMINUS
+ ;
+unary_expression ::=
+ preincrement_expression
+ | predecrement_expression
+ | PLUS unary_expression
+ | MINUS unary_expression
+ | unary_expression_not_plus_minus
+ ;
+preincrement_expression ::=
+ PLUSPLUS unary_expression
+ ;
+predecrement_expression ::=
+ MINUSMINUS unary_expression
+ ;
+unary_expression_not_plus_minus ::=
+ postfix_expression
+ | COMP unary_expression
+ | NOT unary_expression
+ | cast_expression
+ ;
+cast_expression ::=
+ LPAREN primitive_type dims_opt RPAREN unary_expression
+ | LPAREN expression RPAREN unary_expression_not_plus_minus
+ | LPAREN name dims RPAREN unary_expression_not_plus_minus
+ ;
+multiplicative_expression ::=
+ unary_expression
+ | multiplicative_expression MULT unary_expression
+ | multiplicative_expression DIV unary_expression
+ | multiplicative_expression MOD unary_expression
+ ;
+additive_expression ::=
+ multiplicative_expression
+ | additive_expression PLUS multiplicative_expression
+ | additive_expression MINUS multiplicative_expression
+ ;
+shift_expression ::=
+ additive_expression
+ | shift_expression LSHIFT additive_expression
+ | shift_expression RSHIFT additive_expression
+ | shift_expression URSHIFT additive_expression
+ ;
+relational_expression ::=
+ shift_expression
+ | relational_expression LT shift_expression
+ | relational_expression GT shift_expression
+ | relational_expression LTEQ shift_expression
+ | relational_expression GTEQ shift_expression
+ | relational_expression INSTANCEOF reference_type
+ ;
+equality_expression ::=
+ relational_expression
+ | equality_expression EQEQ relational_expression
+ | equality_expression NOTEQ relational_expression
+ ;
+and_expression ::=
+ equality_expression
+ | and_expression AND equality_expression
+ ;
+exclusive_or_expression ::=
+ and_expression
+ | exclusive_or_expression XOR and_expression
+ ;
+inclusive_or_expression ::=
+ exclusive_or_expression
+ | inclusive_or_expression OR exclusive_or_expression
+ ;
+conditional_and_expression ::=
+ inclusive_or_expression
+ | conditional_and_expression ANDAND inclusive_or_expression
+ ;
+conditional_or_expression ::=
+ conditional_and_expression
+ | conditional_or_expression OROR conditional_and_expression
+ ;
+conditional_expression ::=
+ conditional_or_expression
+ | conditional_or_expression QUESTION expression
+ COLON conditional_expression
+ ;
+assignment_expression ::=
+ conditional_expression
+ | assignment
+ ;
+// semantic check necessary here to ensure a valid left-hand side.
+// allowing a parenthesized variable here on the lhs was introduced in
+// JLS 2; thanks to Eric Blake for pointing this out.
+assignment ::= postfix_expression assignment_operator assignment_expression
+ ;
+assignment_operator ::=
+ EQ
+ | MULTEQ
+ | DIVEQ
+ | MODEQ
+ | PLUSEQ
+ | MINUSEQ
+ | LSHIFTEQ
+ | RSHIFTEQ
+ | URSHIFTEQ
+ | ANDEQ
+ | XOREQ
+ | OREQ
+ ;
+expression_opt ::=
+ | expression
+ ;
+expression ::= assignment_expression
+ ;
+constant_expression ::=
+ expression
+ ;
--- /dev/null
+package Parse;
+
+import java_cup.runtime.*;
+
+/* Java 1.5 (JSR-14 + JSR-201) parser for CUP.
+ * (Well, Java 1.5 as of 28 Jul 2003; it may change before official release)
+ * Copyright (C) 2003 C. Scott Ananian <cananian@alumni.princeton.edu>
+ * This program is released under the terms of the GPL; see the file
+ * COPYING for more details. There is NO WARRANTY on this code.
+ */
+
+/*
+JSR-14 Features added:
+* parameterized types, including corrections from the spec released
+ with the 2.2 prototype of the JSR-14 compiler. Arrays of parameterized
+ types bounded by wildcards are slated to be added to Java 1.5 (although
+ they are not supported by the 2.2 prototype); this grammar supports them.
+ "Wildcard" types are supported as of the 28 jul 2003 release.
+
+JSR-201 Features added:
+* no changes for autoboxing
+* new-style for:
+ foreach_statement ::=
+ FOR LPAREN type variable_declarator_id COLON expression RPAREN
+ statement
+ // must check that first IDENTIFIER is 'each' and second IDENTIFIER
+ // is 'in' -- CSA extension; not (yet?) officially adopted
+ | FOR IDENTIFIER LPAREN type variable_declarator_id IDENTIFIER
+ expression RPAREN statement
+ ;
+ foreach_statement_no_short_if ::=
+ FOR LPAREN type variable_declarator_id COLON expression RPAREN
+ statement_no_short_if
+ // must check that first IDENTIFIER is 'each' and second IDENTIFIER
+ // is 'in' -- CSA extension; not (yet?) officially adopted
+ | FOR IDENTIFIER LPAREN type variable_declarator_id IDENTIFIER
+ expression RPAREN statement_no_short_if
+ ;
+ statement ::= ...
+ | foreach_statement ;
+ statement_no_short_if ::= ...
+ | foreach_statement_no_short_if ;
+
+* static import:
+ static_single_type_import_declaration ::=
+ IMPORT STATIC name SEMICOLON
+ ;
+ static_type_import_on_demand_declaration ::=
+ IMPORT STATIC name DOT MULT SEMICOLON
+ ;
+ import_declaration ::= ...
+ | static_single_type_import_declaration
+ | static_type_import_on_demand_declaration
+ ;
+* varargs:
+ formal_parameter ::= ...
+ | type ELLIPSIS IDENTIFIER
+ | FINAL type ELLIPSIS IDENTIFIER
+ ;
+* enum:
+ enum_declaration ::=
+ modifiers_opt ENUM IDENTIFIER interfaces_opt enum_body
+ ;
+ enum_body ::=
+ LBRACE enum_constants_opt enum_body_declarations_opt RBRACE
+ ;
+ enum_constants_opt ::=
+ | enum_constants
+ ;
+ enum_constants ::=
+ enum_constant
+ | enum_constants COMMA enum_constant
+ ;
+ enum_constant ::=
+ IDENTIFIER enum_arguments_opt
+ | IDENTIFIER enum_arguments_opt class_body
+ ;
+ enum_arguments_opt ::=
+ | LPAREN argument_list_opt RPAREN
+ ;
+ enum_body_declarations_opt ::=
+ | SEMICOLON class_body_declarations_opt
+ ;
+*/
+parser code {:
+ Lexer lexer;
+
+ public Grm15(Lexer l) {
+ this();
+ lexer=l;
+ }
+
+ public void syntax_error(java_cup.runtime.Symbol current) {
+ report_error("Syntax error (" + current.sym + ")", current);
+ }
+ public void report_error(String message, java_cup.runtime.Symbol info) {
+ lexer.errorMsg(message, info);
+ }
+:};
+
+scan with {: return lexer.nextToken(); :};
+
+terminal BOOLEAN; // primitive_type
+terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type
+terminal FLOAT, DOUBLE; // floating_point_type
+terminal LBRACK, RBRACK; // array_type
+terminal java.lang.String IDENTIFIER; // name
+terminal DOT; // qualified_name
+terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON;
+terminal PACKAGE; // package_declaration
+terminal IMPORT; // import_declaration
+terminal PUBLIC, PROTECTED, PRIVATE; // modifier
+terminal STATIC; // modifier
+terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
+terminal CLASS; // class_declaration
+terminal EXTENDS; // super
+terminal IMPLEMENTS; // interfaces
+terminal VOID; // method_header
+terminal THROWS; // throws
+terminal THIS, SUPER; // explicit_constructor_invocation
+terminal INTERFACE; // interface_declaration
+terminal IF, ELSE; // if_then_statement, if_then_else_statement
+terminal SWITCH; // switch_statement
+terminal CASE, DEFAULT; // switch_label
+terminal DO, WHILE; // while_statement, do_statement
+terminal FOR; // for_statement
+terminal BREAK; // break_statement
+terminal CONTINUE; // continue_statement
+terminal RETURN; // return_statement
+terminal THROW; // throw_statement
+terminal TRY; // try_statement
+terminal CATCH; // catch_clause
+terminal FINALLY; // finally
+terminal NEW; // class_instance_creation_expression
+terminal PLUSPLUS; // postincrement_expression
+terminal MINUSMINUS; // postdecrement_expression
+terminal PLUS, MINUS, COMP, NOT, DIV, MOD;
+terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression
+terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression
+terminal EQEQ, NOTEQ; // equality_expression
+terminal AND; // and_expression
+terminal XOR; // exclusive_or_expression
+terminal OR; // inclusive_or_expression
+terminal ANDAND; // conditional_and_expression
+terminal OROR; // conditional_or_expression
+terminal QUESTION; // conditional_expression
+terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
+terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
+terminal ANDEQ, XOREQ, OREQ; // assignment_operator
+
+terminal java.lang.Number INTEGER_LITERAL;
+terminal java.lang.Number FLOATING_POINT_LITERAL;
+terminal java.lang.Boolean BOOLEAN_LITERAL;
+terminal java.lang.Character CHARACTER_LITERAL;
+terminal java.lang.String STRING_LITERAL;
+terminal NULL_LITERAL;
+
+// Reserved but unused:
+terminal CONST, GOTO;
+// strictfp keyword, new in Java 1.2
+terminal STRICTFP;
+// assert keyword, new in Java 1.4
+terminal ASSERT; // assert_statement
+// ellipsis token for varargs, new in Java 1.5 (JSR-201)
+terminal ELLIPSIS;
+// enum keyword, new in Java 1.5 (JSR-201)
+terminal ENUM;
+
+// 19.2) The Syntactic Grammar
+non terminal goal;
+// 19.3) Lexical Structure
+non terminal literal;
+// 19.4) Types, Values, and Variables
+non terminal type, primitive_type, numeric_type;
+non terminal integral_type, floating_point_type;
+non terminal reference_type;
+non terminal class_or_interface_type;
+non terminal class_type, interface_type;
+non terminal array_type;
+// 19.5) Names
+non terminal name, simple_name, qualified_name;
+// 19.6) Packages
+non terminal compilation_unit;
+non terminal package_declaration_opt, package_declaration;
+non terminal import_declarations_opt, import_declarations;
+non terminal type_declarations_opt, type_declarations;
+non terminal import_declaration;
+non terminal single_type_import_declaration;
+non terminal type_import_on_demand_declaration;
+non terminal static_single_type_import_declaration;
+non terminal static_type_import_on_demand_declaration;
+non terminal type_declaration;
+// 19.7) Productions used only in the LALR(1) grammar
+non terminal modifiers_opt, modifiers, modifier;
+// 19.8.1) Class Declaration
+non terminal class_declaration, super, super_opt;
+non terminal interfaces, interfaces_opt, interface_type_list;
+non terminal class_body, class_body_opt;
+non terminal class_body_declarations, class_body_declarations_opt;
+non terminal class_body_declaration, class_member_declaration;
+// JSR-201) Enum Declaration
+non terminal enum_declaration;
+non terminal enum_body, enum_constants_opt, enum_constants, enum_constant;
+non terminal enum_arguments_opt, enum_body_declarations_opt;
+// 19.8.2) Field Declarations
+non terminal field_declaration, variable_declarators, variable_declarator;
+non terminal variable_declarator_id, variable_initializer;
+// 19.8.3) Method Declarations
+non terminal method_declaration, method_header, method_declarator;
+non terminal formal_parameter_list_opt, formal_parameter_list;
+non terminal formal_parameter;
+non terminal throws_opt, throws;
+non terminal class_type_list, method_body;
+// 19.8.4) Static Initializers
+non terminal static_initializer;
+// 19.8.5) Constructor Declarations
+non terminal constructor_declaration, constructor_declarator;
+non terminal constructor_body;
+non terminal explicit_constructor_invocation;
+// 19.9.1) Interface Declarations
+non terminal interface_declaration;
+non terminal extends_interfaces_opt, extends_interfaces;
+non terminal interface_body;
+non terminal interface_member_declarations_opt, interface_member_declarations;
+non terminal interface_member_declaration, constant_declaration;
+non terminal abstract_method_declaration;
+// 19.10) Arrays
+non terminal array_initializer;
+non terminal variable_initializers;
+// 19.11) Blocks and Statements
+non terminal block;
+non terminal block_statements_opt, block_statements, block_statement;
+non terminal local_variable_declaration_statement, local_variable_declaration;
+non terminal statement, statement_no_short_if;
+non terminal statement_without_trailing_substatement;
+non terminal empty_statement;
+non terminal labeled_statement, labeled_statement_no_short_if;
+non terminal expression_statement, statement_expression;
+non terminal if_then_statement;
+non terminal if_then_else_statement, if_then_else_statement_no_short_if;
+non terminal switch_statement, switch_block;
+non terminal switch_block_statement_groups;
+non terminal switch_block_statement_group;
+non terminal switch_labels, switch_label;
+non terminal while_statement, while_statement_no_short_if;
+non terminal do_statement;
+non terminal foreach_statement, foreach_statement_no_short_if;
+non terminal for_statement, for_statement_no_short_if;
+non terminal for_init_opt, for_init;
+non terminal for_update_opt, for_update;
+non terminal statement_expression_list;
+non terminal identifier_opt;
+non terminal break_statement, continue_statement;
+non terminal return_statement, throw_statement;
+non terminal synchronized_statement, try_statement;
+non terminal catches_opt, catches, catch_clause;
+non terminal finally;
+non terminal assert_statement;
+// 19.12) Expressions
+non terminal primary, primary_no_new_array;
+non terminal class_instance_creation_expression;
+non terminal argument_list_opt, argument_list;
+non terminal array_creation_init, array_creation_uninit;
+non terminal dim_exprs, dim_expr, dims_opt, dims;
+non terminal field_access, method_invocation, array_access;
+non terminal postfix_expression;
+non terminal postincrement_expression, postdecrement_expression;
+non terminal unary_expression, unary_expression_not_plus_minus;
+non terminal preincrement_expression, predecrement_expression;
+non terminal cast_expression;
+non terminal multiplicative_expression, additive_expression;
+non terminal shift_expression, relational_expression, equality_expression;
+non terminal and_expression, exclusive_or_expression, inclusive_or_expression;
+non terminal conditional_and_expression, conditional_or_expression;
+non terminal conditional_expression, assignment_expression;
+non terminal assignment;
+non terminal assignment_operator;
+non terminal expression_opt, expression;
+non terminal constant_expression;
+// JSR-14 2.1) Type Syntax 2.3) Handling Consecutive Type Brackets
+non terminal class_or_interface;
+non terminal type_variable;
+non terminal type_arguments, type_arguments_opt;
+non terminal type_argument_list;
+non terminal type_argument_list_1, reference_type_1;
+non terminal type_argument_list_2, reference_type_2;
+non terminal type_argument_list_3, reference_type_3;
+// JSR-14 2.2) Parameterized Type Declarations 2.3) Handling Consecutive...
+non terminal type_parameters, type_parameters_opt;
+non terminal type_parameter, type_parameter_list;
+non terminal type_parameter_1, type_parameter_list_1;
+non terminal type_bound, type_bound_opt;
+non terminal type_bound_1;
+non terminal additional_bound_list, additional_bound_list_opt;
+non terminal additional_bound_list_1;
+non terminal additional_bound;
+non terminal additional_bound_1;
+non terminal wildcard, wildcard_1, wildcard_2, wildcard_3;
+non terminal type_argument, type_argument_1, type_argument_2, type_argument_3;
+// not mentioned in JSR-14: need to reduce the precedence of instanceof
+// Alternatively, you can tweak the relational_expression production a little.
+non terminal instanceof_expression;
+//// expressions which are Not a Name
+non terminal postfix_expression_nn;
+non terminal unary_expression_nn;
+non terminal unary_expression_not_plus_minus_nn;
+non terminal multiplicative_expression_nn;
+non terminal additive_expression_nn;
+non terminal shift_expression_nn;
+non terminal relational_expression_nn;
+non terminal instanceof_expression_nn;
+non terminal equality_expression_nn;
+non terminal and_expression_nn;
+non terminal exclusive_or_expression_nn;
+non terminal inclusive_or_expression_nn;
+non terminal conditional_and_expression_nn;
+non terminal conditional_or_expression_nn;
+non terminal conditional_expression_nn;
+non terminal assignment_expression_nn;
+non terminal expression_nn;
+
+start with goal;
+
+// 19.2) The Syntactic Grammar
+goal ::= compilation_unit
+ ;
+
+// 19.3) Lexical Structure.
+literal ::= INTEGER_LITERAL
+ | FLOATING_POINT_LITERAL
+ | BOOLEAN_LITERAL
+ | CHARACTER_LITERAL
+ | STRING_LITERAL
+ | NULL_LITERAL
+ ;
+
+// 19.4) Types, Values, and Variables
+type ::= primitive_type
+ | reference_type
+ ;
+primitive_type ::=
+ numeric_type
+ | BOOLEAN
+ ;
+numeric_type::= integral_type
+ | floating_point_type
+ ;
+integral_type ::=
+ BYTE
+ | SHORT
+ | INT
+ | LONG
+ | CHAR
+ ;
+floating_point_type ::=
+ FLOAT
+ | DOUBLE
+ ;
+
+reference_type ::=
+ class_or_interface_type
+/* note that the 'type_variable' production will come out of the grammar
+ * as a 'class_or_interface_type' with a 'simple_name'. The semantic
+ * checker will have to resolve whether this is a class name or a type
+ * variable */
+ | array_type
+ ;
+type_variable ::=
+ IDENTIFIER
+ ;
+class_or_interface ::=
+ name
+ | class_or_interface LT type_argument_list_1 DOT name
+ ;
+class_or_interface_type ::=
+ class_or_interface
+ | class_or_interface LT type_argument_list_1
+ ;
+
+class_type ::= class_or_interface_type;
+interface_type ::= class_or_interface_type;
+
+array_type ::= primitive_type dims
+ // we have class_or_interface_type here even though only unbounded
+ // wildcards are really allowed in the parameterization.
+ // we have to expand this to avoid lookahead problems.
+ | name dims
+ | class_or_interface LT type_argument_list_1 DOT name dims
+ | class_or_interface LT type_argument_list_1 dims
+ ;
+
+type_arguments_opt ::= type_arguments | ;
+
+type_arguments ::=
+ LT type_argument_list_1
+ ;
+wildcard ::= QUESTION
+ | QUESTION EXTENDS reference_type
+ | QUESTION SUPER reference_type
+ ;
+wildcard_1 ::= QUESTION GT
+ | QUESTION EXTENDS reference_type_1
+ | QUESTION SUPER reference_type_1
+ ;
+wildcard_2 ::= QUESTION RSHIFT
+ | QUESTION EXTENDS reference_type_2
+ | QUESTION SUPER reference_type_2
+ ;
+wildcard_3 ::= QUESTION URSHIFT
+ | QUESTION EXTENDS reference_type_3
+ | QUESTION SUPER reference_type_3
+ ;
+reference_type_1 ::=
+ reference_type GT
+ | class_or_interface LT type_argument_list_2
+ ;
+reference_type_2 ::=
+ reference_type RSHIFT
+ | class_or_interface LT type_argument_list_3
+ ;
+reference_type_3 ::=
+ reference_type URSHIFT
+ ;
+type_argument_list ::=
+ type_argument
+ | type_argument_list COMMA type_argument
+ ;
+type_argument_list_1 ::=
+ type_argument_1
+ | type_argument_list COMMA type_argument_1
+ ;
+type_argument_list_2 ::=
+ type_argument_2
+ | type_argument_list COMMA type_argument_2
+ ;
+type_argument_list_3 ::=
+ type_argument_3
+ | type_argument_list COMMA type_argument_3
+ ;
+type_argument ::=
+ reference_type
+ | wildcard
+ ;
+type_argument_1 ::=
+ reference_type_1
+ | wildcard_1
+ ;
+type_argument_2 ::=
+ reference_type_2
+ | wildcard_2
+ ;
+type_argument_3 ::=
+ reference_type_3
+ | wildcard_3
+ ;
+
+// 19.5) Names
+name ::= simple_name
+ | qualified_name
+ ;
+simple_name ::= IDENTIFIER
+ ;
+qualified_name ::=
+ name DOT IDENTIFIER
+ ;
+
+// 19.6) Packages
+compilation_unit ::=
+ package_declaration_opt
+ import_declarations_opt
+ type_declarations_opt
+ ;
+package_declaration_opt ::= package_declaration | ;
+import_declarations_opt ::= import_declarations | ;
+type_declarations_opt ::= type_declarations | ;
+
+import_declarations ::=
+ import_declaration
+ | import_declarations import_declaration
+ ;
+type_declarations ::=
+ type_declaration
+ | type_declarations type_declaration
+ ;
+package_declaration ::=
+ PACKAGE name SEMICOLON
+ ;
+import_declaration ::=
+ single_type_import_declaration
+ | type_import_on_demand_declaration
+ | static_single_type_import_declaration
+ | static_type_import_on_demand_declaration
+ ;
+single_type_import_declaration ::=
+ IMPORT name SEMICOLON
+ ;
+static_single_type_import_declaration ::=
+ IMPORT STATIC name SEMICOLON
+ ;
+type_import_on_demand_declaration ::=
+ IMPORT name DOT MULT SEMICOLON
+ ;
+static_type_import_on_demand_declaration ::=
+ IMPORT STATIC name DOT MULT SEMICOLON
+ ;
+type_declaration ::=
+ class_declaration
+ | enum_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+
+// 19.7) Productions used only in the LALR(1) grammar
+modifiers_opt::=
+ | modifiers
+ ;
+modifiers ::= modifier
+ | modifiers modifier
+ ;
+modifier ::= PUBLIC | PROTECTED | PRIVATE
+ | STATIC
+ | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
+ | STRICTFP // note that semantic analysis must check that the
+ // context of the modifier allows strictfp.
+ ;
+
+// 19.8) Classes
+
+// 19.8.1) Class Declaration:
+class_declaration ::=
+ modifiers_opt CLASS IDENTIFIER type_parameters_opt
+ super_opt interfaces_opt class_body
+ ;
+super ::= EXTENDS class_type
+ ;
+super_opt ::=
+ | super
+ ;
+interfaces ::= IMPLEMENTS interface_type_list
+ ;
+interfaces_opt::=
+ | interfaces
+ ;
+interface_type_list ::=
+ interface_type
+ | interface_type_list COMMA interface_type
+ ;
+class_body ::= LBRACE class_body_declarations_opt RBRACE
+ ;
+class_body_opt ::=
+ | class_body ;
+class_body_declarations_opt ::=
+ | class_body_declarations ;
+class_body_declarations ::=
+ class_body_declaration
+ | class_body_declarations class_body_declaration
+ ;
+class_body_declaration ::=
+ class_member_declaration
+ | static_initializer
+ | constructor_declaration
+ | block
+ ;
+class_member_declaration ::=
+ field_declaration
+ | method_declaration
+ /* repeat the prod for 'class_declaration' here: */
+ | modifiers_opt CLASS IDENTIFIER type_parameters_opt super_opt interfaces_opt class_body
+ | enum_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+
+// JSR-201) Enum Declaration
+enum_declaration ::=
+ modifiers_opt ENUM IDENTIFIER interfaces_opt enum_body
+ ;
+enum_body ::=
+ LBRACE enum_constants_opt enum_body_declarations_opt RBRACE
+ ;
+enum_constants_opt ::=
+ | enum_constants
+ ;
+enum_constants ::=
+ enum_constant
+ | enum_constants COMMA enum_constant
+ ;
+enum_constant ::=
+ IDENTIFIER enum_arguments_opt
+ | IDENTIFIER enum_arguments_opt class_body
+ ;
+enum_arguments_opt ::=
+ | LPAREN argument_list_opt RPAREN
+ ;
+enum_body_declarations_opt ::=
+ | SEMICOLON class_body_declarations_opt
+ ;
+
+// 19.8.2) Field Declarations
+field_declaration ::=
+ modifiers_opt type variable_declarators SEMICOLON
+ ;
+variable_declarators ::=
+ variable_declarator
+ | variable_declarators COMMA variable_declarator
+ ;
+variable_declarator ::=
+ variable_declarator_id
+ | variable_declarator_id EQ variable_initializer
+ ;
+variable_declarator_id ::=
+ IDENTIFIER
+ | variable_declarator_id LBRACK RBRACK
+ ;
+variable_initializer ::=
+ expression
+ | array_initializer
+ ;
+
+// 19.8.3) Method Declarations
+method_declaration ::=
+ method_header method_body
+ ;
+method_header ::=
+ // have to expand type_parameters_opt here so that we don't
+ // force an early decision of whether this is a field_declaration
+ // or a method_declaration (the type_parameters_opt would have to
+ // be reduced when we see the 'type' if this was a method declaration,
+ // but it might still turn out to be a field declaration).
+ modifiers_opt type method_declarator throws_opt
+ | modifiers_opt LT type_parameter_list_1 type method_declarator throws_opt
+ | modifiers_opt VOID method_declarator throws_opt
+ | modifiers_opt LT type_parameter_list_1 VOID method_declarator throws_opt
+ ;
+method_declarator ::=
+ IDENTIFIER LPAREN formal_parameter_list_opt RPAREN
+ | method_declarator LBRACK RBRACK // deprecated
+ // be careful; the above production also allows 'void foo() []'
+ ;
+formal_parameter_list_opt ::=
+ | formal_parameter_list
+ ;
+formal_parameter_list ::=
+ formal_parameter
+ | formal_parameter_list COMMA formal_parameter
+ ;
+formal_parameter ::=
+ type variable_declarator_id
+ | FINAL type variable_declarator_id
+ // careful, productions below allow varargs in non-final positions.
+ | type ELLIPSIS IDENTIFIER
+ | FINAL type ELLIPSIS IDENTIFIER
+ ;
+throws_opt ::=
+ | throws
+ ;
+throws ::= THROWS class_type_list
+ ;
+class_type_list ::=
+ class_type
+ | class_type_list COMMA class_type
+ ;
+method_body ::= block
+ | SEMICOLON
+ ;
+
+// 19.8.4) Static Initializers
+static_initializer ::=
+ STATIC block
+ ;
+
+// 19.8.5) Constructor Declarations
+constructor_declaration ::=
+ modifiers_opt constructor_declarator
+ throws_opt constructor_body
+ | modifiers_opt LT type_parameter_list_1 constructor_declarator
+ throws_opt constructor_body
+ ;
+constructor_declarator ::=
+ simple_name LPAREN formal_parameter_list_opt RPAREN
+ ;
+constructor_body ::=
+ LBRACE explicit_constructor_invocation
+ block_statements RBRACE
+ | LBRACE explicit_constructor_invocation RBRACE
+ | LBRACE block_statements RBRACE
+ | LBRACE RBRACE
+ ;
+explicit_constructor_invocation ::=
+ THIS LPAREN argument_list_opt RPAREN SEMICOLON
+ | type_arguments THIS LPAREN argument_list_opt RPAREN SEMICOLON
+ | SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ | type_arguments SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ | primary DOT type_arguments SUPER
+ LPAREN argument_list_opt RPAREN SEMICOLON
+ | name DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ | name DOT type_arguments SUPER LPAREN argument_list_opt RPAREN SEMICOLON
+ ;
+
+// 19.9) Interfaces
+
+// 19.9.1) Interface Declarations
+interface_declaration ::=
+ modifiers_opt INTERFACE IDENTIFIER type_parameters_opt
+ extends_interfaces_opt interface_body
+ ;
+extends_interfaces_opt ::=
+ | extends_interfaces
+ ;
+extends_interfaces ::=
+ EXTENDS interface_type
+ | extends_interfaces COMMA interface_type
+ ;
+interface_body ::=
+ LBRACE interface_member_declarations_opt RBRACE
+ ;
+interface_member_declarations_opt ::=
+ | interface_member_declarations
+ ;
+interface_member_declarations ::=
+ interface_member_declaration
+ | interface_member_declarations interface_member_declaration
+ ;
+interface_member_declaration ::=
+ constant_declaration
+ | abstract_method_declaration
+ | class_declaration
+ | enum_declaration
+ | interface_declaration
+ | SEMICOLON
+ ;
+constant_declaration ::=
+ field_declaration
+ // need to semantically check that modifiers of field declaration
+ // include only PUBLIC, STATIC, or FINAL. Other modifiers are
+ // disallowed.
+ ;
+abstract_method_declaration ::=
+ method_header SEMICOLON
+ ;
+
+// 19.10) Arrays
+array_initializer ::=
+ LBRACE variable_initializers COMMA RBRACE
+ | LBRACE variable_initializers RBRACE
+ | LBRACE COMMA RBRACE
+ | LBRACE RBRACE
+ ;
+variable_initializers ::=
+ variable_initializer
+ | variable_initializers COMMA variable_initializer
+ ;
+
+// 19.11) Blocks and Statements
+block ::= LBRACE block_statements_opt RBRACE
+ ;
+block_statements_opt ::=
+ | block_statements
+ ;
+block_statements ::=
+ block_statement
+ | block_statements block_statement
+ ;
+block_statement ::=
+ local_variable_declaration_statement
+ | statement
+ | class_declaration
+ | enum_declaration
+ | interface_declaration
+ ;
+local_variable_declaration_statement ::=
+ local_variable_declaration SEMICOLON
+ ;
+/* jikes expands 'type' in production for local_variable_declaration to
+ * avoid reduce-reduce conflict: given 'name [' the grammar can't decide
+ * whether this is going to be a type (starting the local_variable_declaration)
+ * or an array access expression. */
+local_variable_declaration ::=
+ type variable_declarators
+ // you may want to accept 'modifiers' here instead of just FINAL
+ // to produce better error messages.
+ | FINAL type variable_declarators
+ ;
+statement ::= statement_without_trailing_substatement
+ | labeled_statement
+ | if_then_statement
+ | if_then_else_statement
+ | while_statement
+ | for_statement
+ | foreach_statement
+ ;
+statement_no_short_if ::=
+ statement_without_trailing_substatement
+ | labeled_statement_no_short_if
+ | if_then_else_statement_no_short_if
+ | while_statement_no_short_if
+ | for_statement_no_short_if
+ | foreach_statement_no_short_if
+ ;
+statement_without_trailing_substatement ::=
+ block
+ | empty_statement
+ | expression_statement
+ | switch_statement
+ | do_statement
+ | break_statement
+ | continue_statement
+ | return_statement
+ | synchronized_statement
+ | throw_statement
+ | try_statement
+ | assert_statement
+ ;
+empty_statement ::=
+ SEMICOLON
+ ;
+labeled_statement ::=
+ IDENTIFIER COLON statement
+ ;
+labeled_statement_no_short_if ::=
+ IDENTIFIER COLON statement_no_short_if
+ ;
+expression_statement ::=
+ statement_expression SEMICOLON
+ ;
+statement_expression ::=
+ assignment
+ | preincrement_expression
+ | predecrement_expression
+ | postincrement_expression
+ | postdecrement_expression
+ | method_invocation
+ | class_instance_creation_expression
+ ;
+if_then_statement ::=
+ IF LPAREN expression RPAREN statement
+ ;
+if_then_else_statement ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement
+ ;
+if_then_else_statement_no_short_if ::=
+ IF LPAREN expression RPAREN statement_no_short_if
+ ELSE statement_no_short_if
+ ;
+switch_statement ::=
+ SWITCH LPAREN expression RPAREN switch_block
+ ;
+switch_block ::=
+ LBRACE switch_block_statement_groups switch_labels RBRACE
+ | LBRACE switch_block_statement_groups RBRACE
+ | LBRACE switch_labels RBRACE
+ | LBRACE RBRACE
+ ;
+switch_block_statement_groups ::=
+ switch_block_statement_group
+ | switch_block_statement_groups switch_block_statement_group
+ ;
+switch_block_statement_group ::=
+ switch_labels block_statements
+ ;
+switch_labels ::=
+ switch_label
+ | switch_labels switch_label
+ ;
+switch_label ::=
+ CASE constant_expression COLON
+ | DEFAULT COLON
+ ;
+
+while_statement ::=
+ WHILE LPAREN expression RPAREN statement
+ ;
+while_statement_no_short_if ::=
+ WHILE LPAREN expression RPAREN statement_no_short_if
+ ;
+do_statement ::=
+ DO statement WHILE LPAREN expression RPAREN SEMICOLON
+ ;
+foreach_statement ::=
+ FOR LPAREN type variable_declarator_id COLON expression RPAREN
+ statement
+ // must check that first IDENTIFIER is 'each' and second IDENTIFIER
+ // is 'in'
+ | FOR IDENTIFIER LPAREN type variable_declarator_id IDENTIFIER
+ expression RPAREN statement
+ ;
+foreach_statement_no_short_if ::=
+ FOR LPAREN type variable_declarator_id COLON expression RPAREN
+ statement_no_short_if
+ // must check that first IDENTIFIER is 'each' and second IDENTIFIER
+ // is 'in'
+ | FOR IDENTIFIER LPAREN type variable_declarator_id IDENTIFIER
+ expression RPAREN statement_no_short_if
+ ;
+for_statement ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement
+ ;
+for_statement_no_short_if ::=
+ FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON
+ for_update_opt RPAREN statement_no_short_if
+ ;
+for_init_opt ::=
+ | for_init
+ ;
+for_init ::= statement_expression_list
+ | local_variable_declaration
+ ;
+for_update_opt ::=
+ | for_update
+ ;
+for_update ::= statement_expression_list
+ ;
+statement_expression_list ::=
+ statement_expression
+ | statement_expression_list COMMA statement_expression
+ ;
+
+identifier_opt ::=
+ | IDENTIFIER
+ ;
+
+break_statement ::=
+ BREAK identifier_opt SEMICOLON
+ ;
+
+continue_statement ::=
+ CONTINUE identifier_opt SEMICOLON
+ ;
+return_statement ::=
+ RETURN expression_opt SEMICOLON
+ ;
+throw_statement ::=
+ THROW expression SEMICOLON
+ ;
+synchronized_statement ::=
+ SYNCHRONIZED LPAREN expression RPAREN block
+ ;
+try_statement ::=
+ TRY block catches
+ | TRY block catches_opt finally
+ ;
+catches_opt ::=
+ | catches
+ ;
+catches ::= catch_clause
+ | catches catch_clause
+ ;
+catch_clause ::=
+ CATCH LPAREN formal_parameter RPAREN block
+ ;
+finally ::= FINALLY block
+ ;
+assert_statement ::=
+ ASSERT expression SEMICOLON
+ | ASSERT expression COLON expression SEMICOLON
+ ;
+
+// 19.12) Expressions
+primary ::= primary_no_new_array
+ | array_creation_init
+ | array_creation_uninit
+ ;
+primary_no_new_array ::=
+ literal
+ | THIS
+ | LPAREN name RPAREN
+ | LPAREN expression_nn RPAREN
+ | class_instance_creation_expression
+ | field_access
+ | method_invocation
+ | array_access
+ | name DOT THIS
+ | VOID DOT CLASS
+ // "Type DOT CLASS", but expanded
+ | primitive_type DOT CLASS
+ | primitive_type dims DOT CLASS
+ | name DOT CLASS
+ | name dims DOT CLASS
+// the following two productions are part of the expansion of
+// 'type DOT CLASS' but are not actually allowed, as they involve params.
+// [see msg from Neal Gafter <3F219367.3070903@sun.com> 25-jul-2003]
+// | class_or_interface type_arguments DOT name dims DOT CLASS
+// | class_or_interface LT type_argument_list_1 dims DOT CLASS
+ ;
+// grammar distributed with prototype 2.2 is in error; the following is correct
+// [ Neal Gafter, <3F2577E0.3090008@sun.com> ]
+class_instance_creation_expression ::=
+ NEW class_or_interface_type LPAREN argument_list_opt RPAREN class_body_opt
+ | NEW type_arguments class_or_interface_type LPAREN argument_list_opt RPAREN class_body_opt
+ | primary DOT NEW type_arguments_opt IDENTIFIER type_arguments_opt
+ LPAREN argument_list_opt RPAREN class_body_opt
+ | name DOT NEW type_arguments_opt IDENTIFIER type_arguments_opt
+ LPAREN argument_list_opt RPAREN class_body_opt
+ ;
+argument_list_opt ::=
+ | argument_list
+ ;
+argument_list ::=
+ expression
+ | argument_list COMMA expression
+ ;
+array_creation_uninit ::=
+ NEW primitive_type dim_exprs dims_opt
+ | NEW class_or_interface_type dim_exprs dims_opt
+ ;
+array_creation_init ::=
+ NEW primitive_type dims array_initializer
+ | NEW class_or_interface_type dims array_initializer
+ ;
+dim_exprs ::= dim_expr
+ | dim_exprs dim_expr
+ ;
+dim_expr ::= LBRACK expression RBRACK
+ ;
+dims_opt ::=
+ | dims
+ ;
+dims ::= LBRACK RBRACK
+ | dims LBRACK RBRACK
+ ;
+field_access ::=
+ primary DOT IDENTIFIER
+ | SUPER DOT IDENTIFIER
+ | name DOT SUPER DOT IDENTIFIER
+ ;
+method_invocation ::=
+ name LPAREN argument_list_opt RPAREN
+// the following production appeared in the prototype 2.2 spec, but it
+// introduces ambiguities in the grammar (consider the expression
+// A((B)<C,D>E());
+// which could be either an invocation on E or two boolean comparisons).
+// Neal Gafter has assured me that this production should be removed
+// from the grammar. <3F256C06.7000600@sun.com>
+// | type_arguments name LPAREN argument_list_opt RPAREN
+ | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ | primary DOT type_arguments IDENTIFIER LPAREN argument_list_opt RPAREN
+ | name DOT type_arguments IDENTIFIER LPAREN argument_list_opt RPAREN
+ | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ | SUPER DOT type_arguments IDENTIFIER LPAREN argument_list_opt RPAREN
+ | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
+ | name DOT SUPER DOT type_arguments IDENTIFIER LPAREN argument_list_opt RPAREN
+ ;
+array_access ::=
+ name LBRACK expression RBRACK
+ | primary_no_new_array LBRACK expression RBRACK
+ | array_creation_init LBRACK expression RBRACK
+ ;
+postfix_expression ::=
+ primary
+ | name
+ | postincrement_expression
+ | postdecrement_expression
+ ;
+postincrement_expression ::=
+ postfix_expression PLUSPLUS
+ ;
+postdecrement_expression ::=
+ postfix_expression MINUSMINUS
+ ;
+unary_expression ::=
+ preincrement_expression
+ | predecrement_expression
+ | PLUS unary_expression
+ | MINUS unary_expression
+ | unary_expression_not_plus_minus
+ ;
+preincrement_expression ::=
+ PLUSPLUS unary_expression
+ ;
+predecrement_expression ::=
+ MINUSMINUS unary_expression
+ ;
+unary_expression_not_plus_minus ::=
+ postfix_expression
+ | COMP unary_expression
+ | NOT unary_expression
+ | cast_expression
+ ;
+// This parsing technique was discovered by Eric Blake <ebb9@email.byu.edu>
+// We solving grammar ambiguities with between parenthesized less-than
+// relational operations and type casts with a slightly-more-complicated
+// cast_expression production.
+// Illustrative example: LPAREN name LT name ...
+// is this going to be a cast_expression or a relational_expression?
+// canonically, this production is:
+// cast_expression ::= LPAREN type RPAREN unary_expression_not_plus_minus
+cast_expression ::=
+ LPAREN primitive_type dims_opt RPAREN unary_expression
+ | LPAREN name RPAREN unary_expression_not_plus_minus
+ | LPAREN name dims RPAREN unary_expression_not_plus_minus
+ | LPAREN name LT type_argument_list_1 dims_opt RPAREN
+ unary_expression_not_plus_minus
+ | LPAREN name LT type_argument_list_1 DOT
+ class_or_interface_type dims_opt RPAREN
+ unary_expression_not_plus_minus
+ ;
+multiplicative_expression ::=
+ unary_expression
+ | multiplicative_expression MULT unary_expression
+ | multiplicative_expression DIV unary_expression
+ | multiplicative_expression MOD unary_expression
+ ;
+additive_expression ::=
+ multiplicative_expression
+ | additive_expression PLUS multiplicative_expression
+ | additive_expression MINUS multiplicative_expression
+ ;
+shift_expression ::=
+ additive_expression
+ | shift_expression LSHIFT additive_expression
+ | shift_expression RSHIFT additive_expression
+ | shift_expression URSHIFT additive_expression
+ ;
+relational_expression ::=
+ shift_expression
+ | relational_expression LT shift_expression
+ | relational_expression GT shift_expression
+ | relational_expression LTEQ shift_expression
+ | relational_expression GTEQ shift_expression
+ ;
+// we lower the precendence of instanceof to resolve a grammar ambiguity.
+// semantics are unchanged, since relational expressions do not operate
+// on boolean. Eric Blake had a different solution here, where he
+// used the production 'shift_expression LT shift_expression' to solve
+// the same problem.
+instanceof_expression ::=
+ relational_expression
+ | instanceof_expression INSTANCEOF reference_type
+ ;
+equality_expression ::=
+ instanceof_expression
+ | equality_expression EQEQ instanceof_expression
+ | equality_expression NOTEQ instanceof_expression
+ ;
+and_expression ::=
+ equality_expression
+ | and_expression AND equality_expression
+ ;
+exclusive_or_expression ::=
+ and_expression
+ | exclusive_or_expression XOR and_expression
+ ;
+inclusive_or_expression ::=
+ exclusive_or_expression
+ | inclusive_or_expression OR exclusive_or_expression
+ ;
+conditional_and_expression ::=
+ inclusive_or_expression
+ | conditional_and_expression ANDAND inclusive_or_expression
+ ;
+conditional_or_expression ::=
+ conditional_and_expression
+ | conditional_or_expression OROR conditional_and_expression
+ ;
+conditional_expression ::=
+ conditional_or_expression
+ | conditional_or_expression QUESTION expression
+ COLON conditional_expression
+ ;
+assignment_expression ::=
+ conditional_expression
+ | assignment
+ ;
+// semantic check necessary here to ensure a valid left-hand side.
+// allowing a parenthesized variable here on the lhs was introduced in
+// JLS 2; thanks to Eric Blake for pointing this out.
+assignment ::= postfix_expression assignment_operator assignment_expression
+ ;
+assignment_operator ::=
+ EQ
+ | MULTEQ
+ | DIVEQ
+ | MODEQ
+ | PLUSEQ
+ | MINUSEQ
+ | LSHIFTEQ
+ | RSHIFTEQ
+ | URSHIFTEQ
+ | ANDEQ
+ | XOREQ
+ | OREQ
+ ;
+expression_opt ::=
+ | expression
+ ;
+expression ::= assignment_expression
+ ;
+// note that this constraint must be enforced during semantic checking
+// 'constant_expression' should include enumerated constants.
+constant_expression ::=
+ expression
+ ;
+
+// JLS-14 productions.
+type_parameters_opt ::= type_parameters | ;
+type_parameters ::=
+ LT type_parameter_list_1
+ ;
+type_parameter_list ::=
+ type_parameter_list COMMA type_parameter
+ | type_parameter
+ ;
+type_parameter_list_1 ::=
+ type_parameter_1
+ | type_parameter_list COMMA type_parameter_1
+ ;
+type_parameter ::=
+ type_variable type_bound_opt
+ ;
+type_parameter_1 ::=
+ type_variable GT
+ | type_variable type_bound_1
+ ;
+type_bound_opt ::= type_bound | ;
+type_bound ::=
+ EXTENDS reference_type additional_bound_list_opt
+ ;
+type_bound_1 ::=
+ EXTENDS reference_type_1
+ | EXTENDS reference_type additional_bound_list_1
+ ;
+additional_bound_list_opt ::= additional_bound_list | ;
+additional_bound_list ::=
+ additional_bound additional_bound_list
+ | additional_bound
+ ;
+additional_bound_list_1 ::=
+ additional_bound additional_bound_list_1
+ | additional_bound_1
+ ;
+additional_bound ::=
+ AND interface_type
+ ;
+additional_bound_1 ::=
+ AND reference_type_1
+ ;
+//////////////////////////////////////////////
+// the following productions are copied from the standard ones, but
+// 'name' all alone is not allowed. The '_nn' stands for 'not name'.
+// we also expand the productions so that they recursively depend on the
+// '_nn' forms of their left hand side, then adding a new production
+// with 'name' explicit on the left-hand side.
+// this allows us to postpone the decision whether '(x)' is an expression
+// or a type-cast until we can see enough right context to make the proper
+// choice.
+postfix_expression_nn ::=
+ primary
+ // the 'name' production was removed here.
+ | postincrement_expression
+ | postdecrement_expression
+ ;
+unary_expression_nn ::=
+ preincrement_expression
+ | predecrement_expression
+ | PLUS unary_expression
+ | MINUS unary_expression
+ | unary_expression_not_plus_minus_nn
+ ;
+unary_expression_not_plus_minus_nn ::=
+ postfix_expression_nn
+ | COMP unary_expression
+ | NOT unary_expression
+ | cast_expression
+ ;
+multiplicative_expression_nn ::=
+ unary_expression_nn
+ | name MULT unary_expression
+ | multiplicative_expression_nn MULT unary_expression
+ | name DIV unary_expression
+ | multiplicative_expression_nn DIV unary_expression
+ | name MOD unary_expression
+ | multiplicative_expression_nn MOD unary_expression
+ ;
+additive_expression_nn ::=
+ multiplicative_expression_nn
+ | name PLUS multiplicative_expression
+ | additive_expression_nn PLUS multiplicative_expression
+ | name MINUS multiplicative_expression
+ | additive_expression_nn MINUS multiplicative_expression
+ ;
+shift_expression_nn ::=
+ additive_expression_nn
+ | name LSHIFT additive_expression
+ | shift_expression_nn LSHIFT additive_expression
+ | name RSHIFT additive_expression
+ | shift_expression_nn RSHIFT additive_expression
+ | name URSHIFT additive_expression
+ | shift_expression_nn URSHIFT additive_expression
+ ;
+relational_expression_nn ::=
+ shift_expression_nn
+ // note that we've tweaked the productions for LT/GT to disallow
+ // a<b<c as a valid expression. This avoids ambiguity with
+ // parameterized types in casts.
+ | name LT shift_expression
+ | shift_expression_nn LT shift_expression
+ | name GT shift_expression
+ | shift_expression_nn GT shift_expression
+ | name LTEQ shift_expression
+ | relational_expression_nn LTEQ shift_expression
+ | name GTEQ shift_expression
+ | relational_expression_nn GTEQ shift_expression
+ ;
+instanceof_expression_nn ::=
+ relational_expression_nn
+ | name INSTANCEOF reference_type
+ | instanceof_expression_nn INSTANCEOF reference_type
+ ;
+equality_expression_nn ::=
+ instanceof_expression_nn
+ | name EQEQ instanceof_expression
+ | equality_expression_nn EQEQ instanceof_expression
+ | name NOTEQ instanceof_expression
+ | equality_expression_nn NOTEQ instanceof_expression
+ ;
+and_expression_nn ::=
+ equality_expression_nn
+ | name AND equality_expression
+ | and_expression_nn AND equality_expression
+ ;
+exclusive_or_expression_nn ::=
+ and_expression_nn
+ | name XOR and_expression
+ | exclusive_or_expression_nn XOR and_expression
+ ;
+inclusive_or_expression_nn ::=
+ exclusive_or_expression_nn
+ | name OR exclusive_or_expression
+ | inclusive_or_expression_nn OR exclusive_or_expression
+ ;
+conditional_and_expression_nn ::=
+ inclusive_or_expression_nn
+ | name ANDAND inclusive_or_expression
+ | conditional_and_expression_nn ANDAND inclusive_or_expression
+ ;
+conditional_or_expression_nn ::=
+ conditional_and_expression_nn
+ | name OROR conditional_and_expression
+ | conditional_or_expression_nn OROR conditional_and_expression
+ ;
+conditional_expression_nn ::=
+ conditional_or_expression_nn
+ | name QUESTION expression COLON conditional_expression
+ | conditional_or_expression_nn QUESTION expression
+ COLON conditional_expression
+ ;
+assignment_expression_nn ::=
+ conditional_expression_nn
+ | assignment
+ ;
+expression_nn ::= assignment_expression_nn
+ ;
--- /dev/null
+/** Some valid java code from Eric Blake. Some of these constructions
+ * broke previous versions of the grammars. These should all compile
+ * with any JLS2 javac, as well as parse correctly (no syntax errors)
+ * using the java12.cup/java14.cup/java15.cup grammars in this package. */
+class Eric {
+ // parenthesized variables on the left-hand-size of assignments
+ // are legal according to JLS 2. See comments on jikes bug 105
+ // http://www-124.ibm.com/developerworks/bugs/?func=detailbug&bug_id=105&group_id=10
+ // for more details. According to Eric Blake:
+ // The 2nd edition JLS is weak on this point - the grammar
+ // in 15.26 prohibits assignments to parenthesized
+ // variables, but earlier in 15.8.5 it states that a
+ // parenthesized variable is still a variable (in JLS1, a
+ // parenthesized variable was a value), and the intent of
+ // assignment is that a variable appear on the left hand
+ // side. Also, the grammar in chapter 18 (if you can call
+ // it such, because of its numerous typos and ambiguities)
+ // permits assignment to parenthesized variables.
+ void m(int i) {
+ (i) = 1;
+ }
+ // array access of an initialized array creation is legal; see Sun
+ // bugs 4091602, 4321177:
+ // http://developer.java.sun.com/developer/bugParade/bugs/4091602.html
+ // http://developer.java.sun.com/developer/bugParade/bugs/4321177.html
+ // Eric Blake says:
+ // Again, the body of the JLS prohibits this, but chapter 18 permits it.
+ int i = new int[]{0}[0];
+ int j = new char[] { 'O', 'K' }.length;
+
+ // plain identifiers can qualify instance creation and explicit
+ // constructors; see Sun bug 4750181:
+ // http://developer.java.sun.com/developer/bugParade/bugs/4750181.html
+ // Eric Blake says:
+ // Sun admits the grammars between the earlier chapters and
+ // chapter 18 are incompatible, so they are not sure whether
+ // things like "identifier.new name()" should be legal or
+ // not. Chapter 18 treats identifiers as primaries, and javac
+ // compiles them.
+ class B { };
+ B b;
+ void foo(Eric e) {
+ e.b = e.new B();
+ }
+}
--- /dev/null
+/** Some valid java code from Eric Blake. This should compile
+ * with any JSR-14 javac, as well as parse correctly (no syntax errors)
+ * using the java15.cup grammar in this package. */
+class Eric15<T> {
+ class B<S> { }
+ Eric15<Integer>.B<Integer> c;
+}
--- /dev/null
+class Escape {
+ String s = "\477"; // this literal is valid, but..
+// char c = '\477'; // this literal is invalid.
+}
--- /dev/null
+/** A valid JSR-14 Java program, which illustrates some corner-cases in
+ * the 'smart lexer' lookahead implementation of the grammar. It should
+ * compile correctly using a JSR-14 javac, as well as parse correctly
+ * (no syntax errors) using the java15.cup grammar in this package. */
+public class Test15<X> {
+ <T> Test15(T t) { }
+ int a = 1, b = 2;
+ C c1 = new C<Integer>(), c2 = new C<B>(), c3 = new C<B[]>();
+ C<B> cc2 = c2;
+ C<B[]> cc3 = c3;
+ boolean d = a < b, e = a < b;
+ int f[] = new int[5];
+ boolean g = a < f[1];
+ boolean h = ( a < f[1] );
+ Object i0 = (A) cc3;
+ Object i = ( A < B[] > ) cc3;
+ Object j = ( A < B > ) cc2;
+ Object k = ( A < A < B[] > >) null;
+ Object kk= ( A < A < B[] >>) null;
+ Test15<X>.H hh = null;
+ {
+ Test15<X>.H hhh = null;
+ for (boolean l=a<b, m=a<b; a<b ; l=a<b, f[0]++)
+ a=a;
+ for (;d;)
+ b=b;
+ A<Integer> m = c1;
+ if (m instanceof C<Integer>)
+ a=a;
+ for (boolean n = m instanceof C<Integer>,
+ o = a<b,
+ p = cc3 instanceof C<B[]>;
+ cc3 instanceof C<B[]>;
+ n = m instanceof C<Integer>,
+ o = a<b,
+ p = cc3 instanceof C<B[]>)
+ b=b;
+ for (;m instanceof C<Integer>;)
+ a=a;
+ if (a < b >> 1)
+ ;
+ Object o1 = new A<A<B>>(),
+ o2 = new A<A<A<B>>>(),
+ o3 = new A<A<D<B,A<B>>>>();
+
+ // new, "explicit parameter" version of method invocation.
+ A<Integer> aa = Test15.<A<Integer>>foo();
+ /* although the spec says this should work:
+ A<Integer> aa_ = <A<Integer>>foo();
+ * Neal Gafter has assured me that this is a bug in the spec.
+ * Type arguments are only valid after a dot. */
+
+ // "explicit parameters" with constructor invocations.
+ new <String> K<Integer>("xh"); // prototype 2.2 chokes on this.
+ this.new <String> K<Integer>("xh");
+ }
+
+ static class A<T> { T t; }
+ static class B { }
+ static class C<T> extends A<T> { }
+ static class D<A,B> { }
+ static class E<X,Y extends A<X>> { }
+ static interface F { }
+ // wildcard bounds.
+ static class G { A<? extends F> a; A<? super C<Integer>> b; }
+ class H { }
+ static class I extends A<Object[]> { }
+ static class J extends A<byte[]> { }
+ class K<Y> { <T>K(T t) { Test15.<T>foo(); } }
+
+ static <T> T foo() { return null; }
+}
--- /dev/null
+import static java.lang.Math.*; // gratuitous test of static import
+import static java.lang.System.out; // ditto
+import java.util.*;
+class TestJSR201 {
+ enum Color { red, green, blue ; };
+ public static void main(String... args/* varargs */) {
+ /* for each on multi-dimensional array */
+ int[][] iaa = new int[10][10];
+ for (int ia[] : iaa) {
+ for (int i : ia)
+ out.print(i); // use static import.
+ out.println();
+ }
+ /** alternate syntax: */
+ for each (int ia[] in iaa)
+ for each (int i in ia) {
+ out.println(i);
+ }
+ /* */
+ for (Color c : Color.VALUES) {
+ switch(c) {
+ case Color.red: out.print("R"); break;
+ case Color.green: out.print("G"); break;
+ case Color.blue: out.print("B"); break;
+ default: assert false;
+ }
+ }
+ out.println();
+ }
+ // complex enum declaration, from JSR-201
+ public static enum Coin {
+ penny(1), nickel(5), dime(10), quarter(25);
+ Coin(int value) { this.value = value; }
+ private final int value;
+ public int value() { return value; }
+ }
+ public static class Card implements Comparable, java.io.Serializable {
+ public enum Rank { deuce, three, four, five, six, seven, eight, nine,
+ ten, jack, queen, king, ace }
+ public enum Suit { clubs, diamonds, hearts, spades }
+
+ private final Rank rank;
+ private final Suit suit;
+
+ private Card(Rank rank, Suit suit) {
+ if (rank == null || suit == null)
+ throw new NullPointerException(rank + ", " + suit);
+ this.rank = rank;
+ this.suit = suit;
+ }
+
+ public Rank rank() { return rank; }
+ public Suit suit() { return suit; }
+
+ public String toString() { return rank + " of " + suit; }
+
+ public int compareTo(Object o) {
+ Card c = (Card)o;
+ int rankCompare = rank.compareTo(c.rank);
+ return rankCompare != 0 ? rankCompare : suit.compareTo(c.suit);
+ }
+
+ private static List sortedDeck = new ArrayList(52);
+ /* BROKEN IN PROTOTYPE 2.0 */
+ static {
+ for (Rank rank : Rank.VALUES)
+ for (Suit suit : Suit.VALUES)
+ sortedDeck.add(new Card(rank, suit));
+ }
+ /* */
+ // Returns a shuffled deck
+ public static List newDeck() {
+ List result = new ArrayList(sortedDeck);
+ Collections.shuffle(result);
+ return result;
+ }
+ }
+ // sophisticated example:
+ public static abstract enum Operation {
+ plus {
+ double eval(double x, double y) { return x + y; }
+ },
+ minus {
+ double eval(double x, double y) { return x - y; }
+ },
+ times {
+ double eval(double x, double y) { return x * y; }
+ },
+ divided_by {
+ double eval(double x, double y) { return x / y; }
+ };
+
+ // Perform arithmetic operation represented by this constant
+ abstract double eval(double x, double y);
+
+ public static void main(String args[]) {
+ double x = Double.parseDouble(args[0]);
+ double y = Double.parseDouble(args[1]);
+
+ for (Operation op : VALUES)
+ out.println(x + " " + op + " " + y + " = " + op.eval(x, y));
+ }
+ }
+}