[270] | 1 | # jay skeleton for C#
|
---|
| 2 | #
|
---|
| 3 | # character in column 1 determines outcome...
|
---|
| 4 | # # is a comment
|
---|
| 5 | # . is copied
|
---|
| 6 | # t is copied as //t unless -t is set
|
---|
| 7 | # other lines are interpreted to call jay procedures
|
---|
| 8 | #
|
---|
| 9 | version c# 1.1.0 (c) 2002-2006 ats@cs.rit.edu
|
---|
| 10 | .
|
---|
| 11 | prolog ## %{ ... %} prior to the first %%
|
---|
| 12 | .
|
---|
| 13 | . // %token constants
|
---|
| 14 | tokens
|
---|
| 15 | local ## %{ ... %} after the first %%
|
---|
| 16 | .
|
---|
| 17 | . /// <summary>
|
---|
| 18 | . /// final state of parser.
|
---|
| 19 | . /// </summary>
|
---|
| 20 | yyFinal protected const int yyFinal =
|
---|
| 21 | .
|
---|
| 22 | . /// <summary>
|
---|
| 23 | . /// parser tables.
|
---|
| 24 | . /// Order is mandated by jay.
|
---|
| 25 | . /// </summary>
|
---|
| 26 | . protected static readonly short[] yyLhs = new short[] {
|
---|
| 27 | yyLhs
|
---|
| 28 | . }, yyLen = new short[] {
|
---|
| 29 | yyLen
|
---|
| 30 | . }, yyDefRed = new short[] {
|
---|
| 31 | yyDefRed
|
---|
| 32 | . }, yyDgoto = new short[] {
|
---|
| 33 | yyDgoto
|
---|
| 34 | . }, yySindex = new short[] {
|
---|
| 35 | yySindex
|
---|
| 36 | . }, yyRindex = new short[] {
|
---|
| 37 | yyRindex
|
---|
| 38 | . }, yyGindex = new short[] {
|
---|
| 39 | yyGindex
|
---|
| 40 | . }, yyTable = new short[] {
|
---|
| 41 | yyTable
|
---|
| 42 | . }, yyCheck = new short[] {
|
---|
| 43 | yyCheck
|
---|
| 44 | . };
|
---|
| 45 | .
|
---|
| 46 | . /// <summary>
|
---|
| 47 | . /// maps symbol value to printable name.
|
---|
| 48 | . /// see <c>yyExpecting</c>
|
---|
| 49 | . /// </summary>
|
---|
| 50 | . protected static readonly string[] yyNames = {
|
---|
| 51 | yyNames-strings
|
---|
| 52 | . };
|
---|
| 53 | .
|
---|
| 54 | t /// <summary>
|
---|
| 55 | t /// printable rules for debugging.
|
---|
| 56 | t /// </summary>
|
---|
| 57 | t protected static readonly string[] yyRule = {
|
---|
| 58 | yyRule-strings
|
---|
| 59 | t };
|
---|
| 60 | t
|
---|
| 61 | t /// <summary>
|
---|
| 62 | t /// debugging support, requires <c>yyDebug</c>.
|
---|
| 63 | t /// Set to <c>null</c> to suppress debugging messages.
|
---|
| 64 | t /// </summary>
|
---|
| 65 | t protected yyDebugOut yyDebug;
|
---|
| 66 | t
|
---|
| 67 | t /// <summary>
|
---|
| 68 | t /// index-checked interface to <c>yyNames[]</c>.
|
---|
| 69 | t /// </summary>
|
---|
| 70 | t /// <param name='token'>single character or <c>%token</c> value</param>
|
---|
| 71 | t /// <returns>token name or <c>[illegal]</c> or <c>[unknown]</c></returns>
|
---|
| 72 | t public static string yyName(int token)
|
---|
| 73 | t {
|
---|
| 74 | t if ((token < 0) || (token > yyNames.Length)) return "[illegal]";
|
---|
| 75 | t string name;
|
---|
| 76 | t if ((name = yyNames[token]) != null) return name;
|
---|
| 77 | t return "[unknown]";
|
---|
| 78 | t }
|
---|
| 79 | t
|
---|
| 80 | . public static int yyToken(string name)
|
---|
| 81 | . {
|
---|
| 82 | . int token = 0;
|
---|
| 83 | . foreach (var n in yyNames) {
|
---|
| 84 | . if (n == name)
|
---|
| 85 | . return token;
|
---|
| 86 | . token++;
|
---|
| 87 | . }
|
---|
| 88 | . return yyErrorCode;
|
---|
| 89 | . }
|
---|
| 90 | .
|
---|
| 91 | . /// <summary>
|
---|
| 92 | . /// thrown for irrecoverable syntax errors and stack overflow.
|
---|
| 93 | . /// </summary>
|
---|
| 94 | . /// <remarks>
|
---|
| 95 | . /// Nested for convenience, does not depend on parser class.
|
---|
| 96 | . /// </remarks>
|
---|
| 97 | . public class yyException : System.Exception
|
---|
| 98 | . {
|
---|
| 99 | . public yyException(string message) : base(message)
|
---|
| 100 | . {
|
---|
| 101 | . }
|
---|
| 102 | . }
|
---|
| 103 | .
|
---|
| 104 | . /// <summary>
|
---|
| 105 | . /// must be implemented by a scanner object to supply input to the parser.
|
---|
| 106 | . /// </summary>
|
---|
| 107 | . /// <remarks>
|
---|
| 108 | . /// Nested for convenience, does not depend on parser class.
|
---|
| 109 | . /// </remarks>
|
---|
| 110 | . public interface yyInput
|
---|
| 111 | . {
|
---|
| 112 | . /// <summary>
|
---|
| 113 | . /// move on to next token.
|
---|
| 114 | . /// </summary>
|
---|
| 115 | . /// <returns><c>false</c> if positioned beyond tokens</returns>
|
---|
| 116 | . /// <exception><c>IOException</c> on input error</exception>
|
---|
| 117 | . bool Advance();
|
---|
| 118 | .
|
---|
| 119 | . /// <summary>
|
---|
| 120 | . /// classifies current token by <c>%token</c> value or single character.
|
---|
| 121 | . /// </summary>
|
---|
| 122 | . /// <remarks>
|
---|
| 123 | . /// Should not be called if <c>Advance()</c> returned false.
|
---|
| 124 | . /// </remarks>
|
---|
| 125 | . int Token { get; }
|
---|
| 126 | .
|
---|
| 127 | . /// <summary>
|
---|
| 128 | . /// value associated with current token.
|
---|
| 129 | . /// </summary>
|
---|
| 130 | . /// <remarks>
|
---|
| 131 | . /// Should not be called if <c>Advance()</c> returned false.
|
---|
| 132 | . /// </remarks>
|
---|
| 133 | . object Value { get; }
|
---|
| 134 | . }
|
---|
| 135 | .
|
---|
| 136 | . public interface yyDebugOut
|
---|
| 137 | . {
|
---|
| 138 | . void push(int state, object value);
|
---|
| 139 | . void lex(int state, int token, string name, object value);
|
---|
| 140 | . void shift(int from, int to, int errorFlag);
|
---|
| 141 | . void pop(int state);
|
---|
| 142 | . void discard(int state, int token, string name, object value);
|
---|
| 143 | . void reduce(int from, int to, int rule, string text, int len);
|
---|
| 144 | . void shift(int from, int to);
|
---|
| 145 | . void accept(object value);
|
---|
| 146 | . void error(string message);
|
---|
| 147 | . void reject();
|
---|
| 148 | . }
|
---|
| 149 | .
|
---|
| 150 | . public interface yyConsoleOut
|
---|
| 151 | . {
|
---|
| 152 | . void yyWarning(string message, object[] expected);
|
---|
| 153 | . void yyError(string message, object[] expected);
|
---|
| 154 | . }
|
---|
| 155 | .
|
---|
| 156 | . public yyConsoleOut yyConsole;
|
---|
| 157 | .
|
---|
| 158 | . /// <summary>
|
---|
| 159 | . /// (syntax) warning message.
|
---|
| 160 | . /// Can be overwritten to control message format.
|
---|
| 161 | . /// </summary>
|
---|
| 162 | . /// <param name='message'>text to be displayed</param>
|
---|
| 163 | . /// <param name='expected'>list of acceptable tokens, if available</param>
|
---|
| 164 | . public void yyWarning(string message, params object[] expected)
|
---|
| 165 | . {
|
---|
| 166 | . if (yyConsole == null)
|
---|
| 167 | . return;
|
---|
| 168 | . yyConsole.yyWarning(message, expected);
|
---|
| 169 | . }
|
---|
| 170 | .
|
---|
| 171 | . /// <summary>
|
---|
| 172 | . /// (syntax) error message.
|
---|
| 173 | . /// Can be overwritten to control message format.
|
---|
| 174 | . /// </summary>
|
---|
| 175 | . /// <param name='message'>text to be displayed</param>
|
---|
| 176 | . /// <param name='expected'>list of acceptable tokens, if available</param>
|
---|
| 177 | . public void yyError(string message, params object[] expected)
|
---|
| 178 | . {
|
---|
| 179 | . if (yyConsole == null)
|
---|
| 180 | . return;
|
---|
| 181 | . yyConsole.yyError(message, expected);
|
---|
| 182 | . }
|
---|
| 183 | .
|
---|
| 184 | . /// <summary>
|
---|
| 185 | . /// computes list of expected tokens on error by tracing the tables.
|
---|
| 186 | . /// </summary>
|
---|
| 187 | . /// <param name='state'>for which to compute the list</param>
|
---|
| 188 | . /// <returns>list of token names</returns>
|
---|
| 189 | . protected string[] yyExpecting(int state)
|
---|
| 190 | . {
|
---|
| 191 | . int token, n, len = 0;
|
---|
| 192 | . bool[] ok = new bool[yyNames.Length];
|
---|
| 193 | .
|
---|
| 194 | . if ((n = yySindex[state]) != 0)
|
---|
| 195 | . for (token = n < 0 ? -n : 0;
|
---|
| 196 | . (token < yyNames.Length) && (n + token < yyTable.Length); ++token)
|
---|
| 197 | . if (yyCheck[n + token] == token && !ok[token] && yyNames[token] != null) {
|
---|
| 198 | . ++len;
|
---|
| 199 | . ok[token] = true;
|
---|
| 200 | . }
|
---|
| 201 | . if ((n = yyRindex[state]) != 0)
|
---|
| 202 | . for (token = n < 0 ? -n : 0;
|
---|
| 203 | . (token < yyNames.Length) && (n + token < yyTable.Length); ++token)
|
---|
| 204 | . if (yyCheck[n + token] == token && !ok[token] && yyNames[token] != null) {
|
---|
| 205 | . ++len;
|
---|
| 206 | . ok[token] = true;
|
---|
| 207 | . }
|
---|
| 208 | .
|
---|
| 209 | . string[] result = new string[len];
|
---|
| 210 | . for (n = token = 0; n < len; ++token)
|
---|
| 211 | . if (ok[token]) result[n++] = yyNames[token];
|
---|
| 212 | . return result;
|
---|
| 213 | . }
|
---|
| 214 | .
|
---|
| 215 | . /// <summary>
|
---|
| 216 | . /// the generated parser, with debugging messages.
|
---|
| 217 | . /// Maintains a dynamic state and value stack.
|
---|
| 218 | . /// </summary>
|
---|
| 219 | . /// <param name='yyLex'>scanner</param>
|
---|
| 220 | . /// <param name='yyDebug'>debug message writer implementing <c>yyDebug</c>,
|
---|
| 221 | . /// or <c>null</c></param>
|
---|
| 222 | . /// <returns>result of the last reduction, if any</returns>
|
---|
| 223 | . /// <exceptions><c>yyException</c> on irrecoverable parse error</exceptions>
|
---|
| 224 | . public object yyParse(yyInput yyLex, yyDebugOut yyDebug)
|
---|
| 225 | . {
|
---|
| 226 | t this.yyDebug = yyDebug;
|
---|
| 227 | . return yyParse(yyLex);
|
---|
| 228 | . }
|
---|
| 229 | .
|
---|
| 230 | . /// <summary>
|
---|
| 231 | . /// initial size and increment of the state/value stack [default 256].
|
---|
| 232 | . /// This is not final so that it can be overwritten outside of invocations
|
---|
| 233 | . /// of <c>yyParse()</c>.
|
---|
| 234 | . /// </summary>
|
---|
| 235 | . protected int yyMax;
|
---|
| 236 | .
|
---|
| 237 | . protected int yyNest;
|
---|
| 238 | .
|
---|
| 239 | . /// <summary>
|
---|
| 240 | . /// executed at the beginning of a reduce action.
|
---|
| 241 | . /// Used as <c>$$ = yyDefault($1)</c>, prior to the user-specified action, if any.
|
---|
| 242 | . /// Can be overwritten to provide deep copy, etc.
|
---|
| 243 | . /// </summary>
|
---|
| 244 | . /// <param first value for $1, or null.
|
---|
| 245 | . /// <return first.
|
---|
| 246 | . protected object yyDefault(object first)
|
---|
| 247 | . {
|
---|
| 248 | . return first;
|
---|
| 249 | . }
|
---|
| 250 | .
|
---|
| 251 | . /// <summary>
|
---|
| 252 | . /// the generated parser, with debugging messages.
|
---|
| 253 | . /// Maintains a dynamic state and value stack.
|
---|
| 254 | . /// </summary>
|
---|
| 255 | . /// <param name='yyLex'>scanner</param>
|
---|
| 256 | . /// <returns>result of the last reduction, if any</returns>
|
---|
| 257 | . /// <exceptions><c>yyException</c> on irrecoverable parse error</exceptions>
|
---|
| 258 | . public object yyParse(yyInput yyLex)
|
---|
| 259 | . {
|
---|
| 260 | . yyNest++;
|
---|
| 261 | . if (yyMax <= 0) yyMax = 256; // initial size
|
---|
| 262 | . int yyState = 0; // state stack ptr
|
---|
| 263 | . int[] yyStates = new int[0]; // state stack
|
---|
| 264 | . object yyVal = null;
|
---|
| 265 | . object[] yyVals = new object[0]; // value stack
|
---|
| 266 | . int yyToken = -1; // current input
|
---|
| 267 | . int yyErrorFlag = 0; // #tokens to shift
|
---|
| 268 | .
|
---|
| 269 | . for (int yyTop = 0; ; ++yyTop) {
|
---|
| 270 | . while (yyTop >= yyStates.Length) { // dynamically increase
|
---|
| 271 | . yyStates.Push(0);
|
---|
| 272 | . yyVals.Push(null);
|
---|
| 273 | . }
|
---|
| 274 | . yyStates[yyTop] = yyState;
|
---|
| 275 | . yyVals[yyTop] = yyVal;
|
---|
| 276 | t if (yyDebug != null) yyDebug.push(yyState, yyVal);
|
---|
| 277 | .
|
---|
| 278 | . for (bool yyLoop = true; yyLoop;) { // discarding a token does not change stack
|
---|
| 279 | . int yyN;
|
---|
| 280 | . if ((yyN = yyDefRed[yyState]) == 0) { // else [default] reduce (yyN)
|
---|
| 281 | . if (yyToken < 0) {
|
---|
| 282 | . yyToken = yyLex.Advance() ? yyLex.Token : 0;
|
---|
| 283 | t if (yyDebug != null)
|
---|
| 284 | t yyDebug.lex(yyState, yyToken, yyName(yyToken), yyLex.Value);
|
---|
| 285 | . }
|
---|
| 286 | . if ((yyN = yySindex[yyState]) != 0 && ((yyN += yyToken) >= 0)
|
---|
| 287 | . && (yyN < yyTable.Length) && (yyCheck[yyN] == yyToken)) {
|
---|
| 288 | t if (yyDebug != null)
|
---|
| 289 | t yyDebug.shift(yyState, yyTable[yyN], yyErrorFlag > 0 ? yyErrorFlag - 1 : 0);
|
---|
| 290 | . yyState = yyTable[yyN]; // shift to yyN
|
---|
| 291 | . yyVal = yyLex.Value;
|
---|
| 292 | . yyToken = -1;
|
---|
| 293 | . if (yyErrorFlag > 0) --yyErrorFlag;
|
---|
| 294 | . break;
|
---|
| 295 | . }
|
---|
| 296 | . if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0
|
---|
| 297 | . && yyN < yyTable.Length && yyCheck[yyN] == yyToken)
|
---|
| 298 | . yyN = yyTable[yyN]; // reduce (yyN)
|
---|
| 299 | . else
|
---|
| 300 | . switch (yyErrorFlag) {
|
---|
| 301 | . case 0:
|
---|
| 302 | . case 1:
|
---|
| 303 | . case 2:
|
---|
| 304 | . if (yyErrorFlag == 0) {
|
---|
| 305 | . yyError("syntax error, expecting {0}", String.Join(",", yyExpecting(yyState)));
|
---|
| 306 | t if (yyDebug != null) yyDebug.error("syntax error");
|
---|
| 307 | . }
|
---|
| 308 | . yyErrorFlag = 3;
|
---|
| 309 | . do {
|
---|
| 310 | . if ((yyN = yySindex[yyStates[yyTop]]) != 0
|
---|
| 311 | . && (yyN += yyErrorCode) >= 0 && yyN < yyTable.Length
|
---|
| 312 | . && yyCheck[yyN] == yyErrorCode) {
|
---|
| 313 | t if (yyDebug != null)
|
---|
| 314 | t yyDebug.shift(yyStates[yyTop], yyTable[yyN], 3);
|
---|
| 315 | . yyState = yyTable[yyN];
|
---|
| 316 | . yyVal = yyLex.Value;
|
---|
| 317 | . yyLoop = false;
|
---|
| 318 | . break;
|
---|
| 319 | . }
|
---|
| 320 | t if (yyDebug != null) yyDebug.pop(yyStates[yyTop]);
|
---|
| 321 | . } while (--yyTop >= 0);
|
---|
| 322 | . if (!yyLoop)
|
---|
| 323 | . continue;
|
---|
| 324 | t if (yyDebug != null) yyDebug.reject();
|
---|
| 325 | . throw new yyException("irrecoverable syntax error");
|
---|
| 326 | . case 3:
|
---|
| 327 | . if (yyToken == 0) {
|
---|
| 328 | . yyNest--;
|
---|
| 329 | . if (yyNest <= 0)
|
---|
| 330 | . return yyVal;
|
---|
| 331 | t if (yyDebug != null) yyDebug.reject();
|
---|
| 332 | . throw new yyException("irrecoverable syntax error at end-of-file");
|
---|
| 333 | . }
|
---|
| 334 | t if (yyDebug != null)
|
---|
| 335 | t yyDebug.discard(yyState, yyToken, yyName(yyToken),
|
---|
| 336 | t yyLex.Value);
|
---|
| 337 | . yyToken = -1;
|
---|
| 338 | . continue; // leave stack alone
|
---|
| 339 | . }
|
---|
| 340 | . }
|
---|
| 341 | . int yyV = yyTop + 1 - yyLen[yyN];
|
---|
| 342 | t if (yyDebug != null)
|
---|
| 343 | t yyDebug.reduce(yyState, yyStates[yyV - 1], yyN, yyRule[yyN], yyLen[yyN]);
|
---|
| 344 | . yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]);
|
---|
| 345 | . switch (yyN) {
|
---|
| 346 |
|
---|
| 347 | actions ## code from the actions within the grammar
|
---|
| 348 |
|
---|
| 349 | . }
|
---|
| 350 | . yyTop -= yyLen[yyN];
|
---|
| 351 | . yyState = yyStates[yyTop];
|
---|
| 352 | . int yyM = yyLhs[yyN];
|
---|
| 353 | . if (yyState == 0 && yyM == 0) {
|
---|
| 354 | t if (yyDebug != null) yyDebug.shift(0, yyFinal);
|
---|
| 355 | . yyState = yyFinal;
|
---|
| 356 | . if (yyToken < 0) {
|
---|
| 357 | . yyToken = yyLex.Advance() ? yyLex.Token : 0;
|
---|
| 358 | t if (yyDebug != null)
|
---|
| 359 | t yyDebug.lex(yyState, yyToken, yyName(yyToken), yyLex.Value);
|
---|
| 360 | . }
|
---|
| 361 | . if (yyToken == 0) {
|
---|
| 362 | t if (yyDebug != null) yyDebug.accept(yyVal);
|
---|
| 363 | . yyNest--;
|
---|
| 364 | . return yyVal;
|
---|
| 365 | . }
|
---|
| 366 | . break;
|
---|
| 367 | . }
|
---|
| 368 | . if (((yyN = yyGindex[yyM]) != 0) && ((yyN += yyState) >= 0)
|
---|
| 369 | . && (yyN < yyTable.Length) && (yyCheck[yyN] == yyState))
|
---|
| 370 | . yyState = yyTable[yyN];
|
---|
| 371 | . else
|
---|
| 372 | . yyState = yyDgoto[yyM];
|
---|
| 373 | t if (yyDebug != null) yyDebug.shift(yyStates[yyTop], yyState);
|
---|
| 374 | . break;
|
---|
| 375 | . }
|
---|
| 376 | . }
|
---|
| 377 | . }
|
---|
| 378 | epilog ## text following second %%
|
---|