| # jay skeleton for Java |
| |
| # character in column 1 determines outcome... |
| # # is a comment |
| # . is copied |
| # t is copied as //t if -t is set |
| # other lines are interpreted to call jay procedures |
| |
| version Java 1.0 (c) 2002 ats@cs.rit.edu |
| . |
| prolog ## %{ ... %} prior to the first %% |
| |
| . // %token constants |
| tokens public static final int |
| . |
| . /** number of final state. |
| . */ |
| yyFinal protected static final int yyFinal = |
| . |
| . /** parser tables. |
| . Order is mandated by <i>jay</i>. |
| . */ |
| . protected static final short[] yyLhs = { |
| yyLhs |
| . }, yyLen = { |
| yyLen |
| . }, yyDefRed = { |
| yyDefRed |
| . }, yyDgoto = { |
| yyDgoto |
| . }, yySindex = { |
| yySindex |
| . }, yyRindex = { |
| yyRindex |
| . }, yyGindex = { |
| yyGindex |
| . }; |
| . protected static final short[] yyTable = { |
| yyTable |
| . }; |
| . protected static final short[] yyCheck = { |
| yyCheck |
| . }; |
| . |
| . /** maps symbol value to printable name. |
| . @see #yyExpecting |
| . */ |
| . protected static final String[] yyNames = { |
| yyNames-strings |
| . }; |
| . |
| t /** printable rules for debugging. |
| t */ |
| t protected static final String [] yyRule = { |
| yyRule-strings |
| t }; |
| t |
| t /** debugging support, requires the package <tt>jay.yydebug</tt>. |
| t Set to <tt>null</tt> to suppress debugging messages. |
| t */ |
| t protected jay.yydebug.yyDebug yydebug; |
| t |
| t /** index-checked interface to {@link #yyNames}. |
| t @param token single character or <tt>%token</tt> value. |
| t @return token name or <tt>[illegal]</tt> or <tt>[unknown]</tt>. |
| t */ |
| t public static final String yyName (int token) { |
| t if (token < 0 || token > yyNames.length) return "[illegal]"; |
| t String name; |
| t if ((name = yyNames[token]) != null) return name; |
| t return "[unknown]"; |
| t } |
| t |
| . /** thrown for irrecoverable syntax errors and stack overflow. |
| . Nested for convenience, does not depend on parser class. |
| . */ |
| . public static class yyException extends java.lang.Exception { |
| . private static final long serialVersionUID = 1L; |
| . public yyException (String message) { |
| . super(message); |
| . } |
| . } |
| . |
| . /** must be implemented by a scanner object to supply input to the parser. |
| . Nested for convenience, does not depend on parser class. |
| . */ |
| . public interface yyInput { |
| . |
| . /** move on to next token. |
| . @return <tt>false</tt> if positioned beyond tokens. |
| . @throws IOException on input error. |
| . */ |
| . boolean advance () throws java.io.IOException; |
| . |
| . /** classifies current token. |
| . Should not be called if {@link #advance()} returned <tt>false</tt>. |
| . @return current <tt>%token</tt> or single character. |
| . */ |
| . int token (); |
| . |
| . /** associated with current token. |
| . Should not be called if {@link #advance()} returned <tt>false</tt>. |
| . @return value for {@link #token()}. |
| . */ |
| . Object value (); |
| . } |
| . |
| . /** simplified error message. |
| . @see #yyerror(java.lang.String, java.lang.String[]) |
| . */ |
| . public void yyerror (String message) { |
| . yyerror(message, null, null); |
| . } |
| . |
| . /** (syntax) error message. |
| . Can be overwritten to control message format. |
| . @param message text to be displayed. |
| . @param expected list of acceptable tokens, if available. |
| . */ |
| . public void yyerror(String message, String[] expected, String found) { |
| . if (found != null) { |
| . throw new SyntaxException(getPosition(null), message |
| . + ", unexpected " + found); |
| . } else { |
| . throw new SyntaxException(getPosition(null), message); |
| . } |
| . } |
| . |
| . /** computes list of expected tokens on error by tracing the tables. |
| . @param state for which to compute the list. |
| . @return list of token names. |
| . */ |
| . protected String[] yyExpecting (int state) { |
| . int token, n, len = 0; |
| . boolean[] ok = new boolean[yyNames.length]; |
| . |
| . if ((n = yySindex[state]) != 0) |
| . for (token = n < 0 ? -n : 0; |
| . token < yyNames.length && n+token < yyTable.length; ++ token) |
| . if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) { |
| . ++ len; |
| . ok[token] = true; |
| . } |
| . if ((n = yyRindex[state]) != 0) |
| . for (token = n < 0 ? -n : 0; |
| . token < yyNames.length && n+token < yyTable.length; ++ token) |
| . if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) { |
| . ++ len; |
| . ok[token] = true; |
| . } |
| . |
| . String result[] = new String[len]; |
| . for (n = token = 0; n < len; ++ token) |
| . if (ok[token]) result[n++] = yyNames[token]; |
| . return result; |
| . } |
| . |
| . /** the generated parser, with debugging messages. |
| . Maintains a dynamic state and value stack. |
| . @param yyLex scanner. |
| . @param yydebug debug message writer implementing <tt>yyDebug</tt>, or <tt>null</tt>. |
| . @return result of the last reduction, if any. |
| . @throws yyException on irrecoverable parse error. |
| . */ |
| . public Object yyparse (RubyYaccLexer yyLex, Object ayydebug) |
| . throws java.io.IOException, yyException { |
| t this.yydebug = (jay.yydebug.yyDebug)ayydebug; |
| . return yyparse(yyLex); |
| . } |
| . |
| . /** initial size and increment of the state/value stack [default 256]. |
| . This is not final so that it can be overwritten outside of invocations |
| . of {@link #yyparse}. |
| . */ |
| . protected int yyMax; |
| . |
| . /** executed at the beginning of a reduce action. |
| . Used as <tt>$$ = yyDefault($1)</tt>, prior to the user-specified action, if any. |
| . Can be overwritten to provide deep copy, etc. |
| . @param first value for <tt>$1</tt>, or <tt>null</tt>. |
| . @return first. |
| . */ |
| . protected Object yyDefault (Object first) { |
| . return first; |
| . } |
| . |
| . /** the generated parser. |
| . Maintains a dynamic state and value stack. |
| . @param yyLex scanner. |
| . @return result of the last reduction, if any. |
| . @throws yyException on irrecoverable parse error. |
| . */ |
| . public Object yyparse (RubyYaccLexer yyLex) throws java.io.IOException, yyException { |
| . if (yyMax <= 0) yyMax = 256; // initial size |
| . int yyState = 0, yyStates[] = new int[yyMax]; // state stack |
| . Object yyVal = null, yyVals[] = new Object[yyMax]; // value stack |
| . int yyToken = -1; // current input |
| . int yyErrorFlag = 0; // #tokens to shift |
| . |
| local ## %{ ... %} after the first %% |
| |
| . yyLoop: for (int yyTop = 0;; ++ yyTop) { |
| . if (yyTop >= yyStates.length) { // dynamically increase |
| . int[] i = new int[yyStates.length+yyMax]; |
| . System.arraycopy(yyStates, 0, i, 0, yyStates.length); |
| . yyStates = i; |
| . Object[] o = new Object[yyVals.length+yyMax]; |
| . System.arraycopy(yyVals, 0, o, 0, yyVals.length); |
| . yyVals = o; |
| . } |
| . yyStates[yyTop] = yyState; |
| . yyVals[yyTop] = yyVal; |
| t if (yydebug != null) yydebug.push(yyState, yyVal); |
| . |
| . yyDiscarded: for (;;) { // discarding a token does not change stack |
| . int yyN; |
| . if ((yyN = yyDefRed[yyState]) == 0) { // else [default] reduce (yyN) |
| . if (yyToken < 0) { |
| . yyToken = yyLex.advance() ? yyLex.token() : 0; |
| t if (yydebug != null) |
| t yydebug.lex(yyState, yyToken, yyName(yyToken), yyLex.value()); |
| . } |
| . if ((yyN = yySindex[yyState]) != 0 && (yyN += yyToken) >= 0 |
| . && yyN < yyTable.length && yyCheck[yyN] == yyToken) { |
| t if (yydebug != null) |
| t yydebug.shift(yyState, yyTable[yyN], yyErrorFlag-1); |
| . yyState = yyTable[yyN]; // shift to yyN |
| . yyVal = yyLex.value(); |
| . yyToken = -1; |
| . if (yyErrorFlag > 0) -- yyErrorFlag; |
| . continue yyLoop; |
| . } |
| . if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0 |
| . && yyN < yyTable.length && yyCheck[yyN] == yyToken) |
| . yyN = yyTable[yyN]; // reduce (yyN) |
| . else |
| . switch (yyErrorFlag) { |
| . |
| . case 0: |
| . yyerror("syntax error", yyExpecting(yyState), yyNames[yyToken]); |
| t if (yydebug != null) yydebug.error("syntax error"); |
| . |
| . case 1: case 2: |
| . yyErrorFlag = 3; |
| . do { |
| . if ((yyN = yySindex[yyStates[yyTop]]) != 0 |
| . && (yyN += yyErrorCode) >= 0 && yyN < yyTable.length |
| . && yyCheck[yyN] == yyErrorCode) { |
| t if (yydebug != null) |
| t yydebug.shift(yyStates[yyTop], yyTable[yyN], 3); |
| . yyState = yyTable[yyN]; |
| . yyVal = yyLex.value(); |
| . continue yyLoop; |
| . } |
| t if (yydebug != null) yydebug.pop(yyStates[yyTop]); |
| . } while (-- yyTop >= 0); |
| t if (yydebug != null) yydebug.reject(); |
| . throw new yyException("irrecoverable syntax error"); |
| . |
| . case 3: |
| . if (yyToken == 0) { |
| t if (yydebug != null) yydebug.reject(); |
| . throw new yyException("irrecoverable syntax error at end-of-file"); |
| . } |
| t if (yydebug != null) |
| t yydebug.discard(yyState, yyToken, yyName(yyToken), |
| t yyLex.value()); |
| . yyToken = -1; |
| . continue yyDiscarded; // leave stack alone |
| . } |
| . } |
| . int yyV = yyTop + 1-yyLen[yyN]; |
| t if (yydebug != null) |
| t yydebug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]); |
| . yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]); |
| . switch (yyN) { |
| |
| actions ## code from the actions within the grammar |
| |
| . } |
| . yyTop -= yyLen[yyN]; |
| . yyState = yyStates[yyTop]; |
| . int yyM = yyLhs[yyN]; |
| . if (yyState == 0 && yyM == 0) { |
| t if (yydebug != null) yydebug.shift(0, yyFinal); |
| . yyState = yyFinal; |
| . if (yyToken < 0) { |
| . yyToken = yyLex.advance() ? yyLex.token() : 0; |
| t if (yydebug != null) |
| t yydebug.lex(yyState, yyToken,yyName(yyToken), yyLex.value()); |
| . } |
| . if (yyToken == 0) { |
| t if (yydebug != null) yydebug.accept(yyVal); |
| . return yyVal; |
| . } |
| . continue yyLoop; |
| . } |
| . if ((yyN = yyGindex[yyM]) != 0 && (yyN += yyState) >= 0 |
| . && yyN < yyTable.length && yyCheck[yyN] == yyState) |
| . yyState = yyTable[yyN]; |
| . else |
| . yyState = yyDgoto[yyM]; |
| t if (yydebug != null) yydebug.shift(yyStates[yyTop], yyState); |
| . continue yyLoop; |
| . } |
| . } |
| . } |
| . |
| epilog ## text following second %% |