# jay skeleton for C#
#
# character in column 1 determines outcome...
# # is a comment
# . is copied
# t is copied as //t unless -t is set
# other lines are interpreted to call jay procedures
#
version c# 1.1.0 (c) 2002-2006 ats@cs.rit.edu
.
prolog ## %{ ... %} prior to the first %%
.
. // %token constants
tokens
local ## %{ ... %} after the first %%
.
. ///
. /// final state of parser.
. ///
yyFinal protected const int yyFinal =
.
. ///
. /// parser tables.
. /// Order is mandated by jay.
. ///
. protected static readonly short[] yyLhs = new short[] {
yyLhs
. }, yyLen = new short[] {
yyLen
. }, yyDefRed = new short[] {
yyDefRed
. }, yyDgoto = new short[] {
yyDgoto
. }, yySindex = new short[] {
yySindex
. }, yyRindex = new short[] {
yyRindex
. }, yyGindex = new short[] {
yyGindex
. }, yyTable = new short[] {
yyTable
. }, yyCheck = new short[] {
yyCheck
. };
.
. ///
. /// maps symbol value to printable name.
. /// see yyExpecting
. ///
. protected static readonly string[] yyNames = {
yyNames-strings
. };
.
t ///
t /// printable rules for debugging.
t ///
t protected static readonly string[] yyRule = {
yyRule-strings
t };
t
t ///
t /// debugging support, requires yyDebug.
t /// Set to null to suppress debugging messages.
t ///
t protected yyDebugOut yyDebug;
t
t ///
t /// index-checked interface to yyNames[].
t ///
t /// single character or %token value
t /// token name or [illegal] or [unknown]
t public static string yyName(int token)
t {
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
. public static int yyToken(string name)
. {
. int token = 0;
. foreach (var n in yyNames) {
. if (n == name)
. return token;
. token++;
. }
. return yyErrorCode;
. }
.
. ///
. /// thrown for irrecoverable syntax errors and stack overflow.
. ///
. ///
. /// Nested for convenience, does not depend on parser class.
. ///
. public class yyException : System.Exception
. {
. public yyException(string message) : base(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.
. ///
. /// false if positioned beyond tokens
. /// IOException on input error
. bool Advance();
.
. ///
. /// classifies current token by %token value or single character.
. ///
. ///
. /// Should not be called if Advance() returned false.
. ///
. int Token { get; }
.
. ///
. /// value associated with current token.
. ///
. ///
. /// Should not be called if Advance() returned false.
. ///
. object Value { get; }
. }
.
. public interface yyDebugOut
. {
. void push(int state, object value);
. void lex(int state, int token, string name, object value);
. void shift(int from, int to, int errorFlag);
. void pop(int state);
. void discard(int state, int token, string name, object value);
. void reduce(int from, int to, int rule, string text, int len);
. void shift(int from, int to);
. void accept(object value);
. void error(string message);
. void reject();
. }
.
. public interface yyConsoleOut
. {
. void yyWarning(string message, object[] expected);
. void yyError(string message, object[] expected);
. }
.
. public yyConsoleOut yyConsole;
.
. ///
. /// (syntax) warning message.
. /// Can be overwritten to control message format.
. ///
. /// text to be displayed
. /// list of acceptable tokens, if available
. public void yyWarning(string message, params object[] expected)
. {
. if (yyConsole == null)
. return;
. yyConsole.yyWarning(message, expected);
. }
.
. ///
. /// (syntax) error message.
. /// Can be overwritten to control message format.
. ///
. /// text to be displayed
. /// list of acceptable tokens, if available
. public void yyError(string message, params object[] expected)
. {
. if (yyConsole == null)
. return;
. yyConsole.yyError(message, expected);
. }
.
. ///
. /// computes list of expected tokens on error by tracing the tables.
. ///
. /// for which to compute the list
. /// list of token names
. protected string[] yyExpecting(int state)
. {
. int token, n, len = 0;
. bool[] ok = new bool[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.
. ///
. /// scanner
. /// debug message writer implementing yyDebug,
. /// or null
. /// result of the last reduction, if any
. /// yyException on irrecoverable parse error
. public object yyParse(yyInput yyLex, yyDebugOut yyDebug)
. {
t this.yyDebug = yyDebug;
. 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 yyParse().
. ///
. protected int yyMax;
.
. protected int yyNest;
.
. ///
. /// executed at the beginning of a reduce action.
. /// Used as $$ = yyDefault($1), prior to the user-specified action, if any.
. /// Can be overwritten to provide deep copy, etc.
. ///
. ///
. /// the generated parser, with debugging messages.
. /// Maintains a dynamic state and value stack.
. ///
. /// scanner
. /// result of the last reduction, if any
. /// yyException on irrecoverable parse error
. public object yyParse(yyInput yyLex)
. {
. yyNest++;
. if (yyMax <= 0) yyMax = 256; // initial size
. int yyState = 0; // state stack ptr
. int[] yyStates = new int[0]; // state stack
. object yyVal = null;
. object[] yyVals = new object[0]; // value stack
. int yyToken = -1; // current input
. int yyErrorFlag = 0; // #tokens to shift
.
. for (int yyTop = 0; ; ++yyTop) {
. while (yyTop >= yyStates.Length) { // dynamically increase
. yyStates.Push(0);
. yyVals.Push(null);
. }
. yyStates[yyTop] = yyState;
. yyVals[yyTop] = yyVal;
t if (yyDebug != null) yyDebug.push(yyState, yyVal);
.
. for (bool yyLoop = true; yyLoop;) { // 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 > 0 ? yyErrorFlag - 1 : 0);
. yyState = yyTable[yyN]; // shift to yyN
. yyVal = yyLex.Value;
. yyToken = -1;
. if (yyErrorFlag > 0) --yyErrorFlag;
. break;
. }
. if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0
. && yyN < yyTable.Length && yyCheck[yyN] == yyToken)
. yyN = yyTable[yyN]; // reduce (yyN)
. else
. switch (yyErrorFlag) {
. case 0:
. case 1:
. case 2:
. if (yyErrorFlag == 0) {
. yyError("syntax error, expecting {0}", String.Join(",", yyExpecting(yyState)));
t if (yyDebug != null) yyDebug.error("syntax error");
. }
. 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;
. yyLoop = false;
. break;
. }
t if (yyDebug != null) yyDebug.pop(yyStates[yyTop]);
. } while (--yyTop >= 0);
. if (!yyLoop)
. continue;
t if (yyDebug != null) yyDebug.reject();
. throw new yyException("irrecoverable syntax error");
. case 3:
. if (yyToken == 0) {
. yyNest--;
. if (yyNest <= 0)
. return yyVal;
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; // 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);
. yyNest--;
. return yyVal;
. }
. break;
. }
. 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);
. break;
. }
. }
. }
epilog ## text following second %%