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 %%
|
---|