3 # character in column 1 determines outcome...
6 # t is copied as //t if -t is set
7 # other lines are interpreted to call jay procedures
9 .// created by jay 0.7 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de
11 prolog
## %{ ... %} prior to the first %%
14 . /** error output stream.
15 . It should be changeable.
17 . public System
.IO
.TextWriter ErrorOutput
= System
.Console
.Out
;
19 . /** simplified error message.
20 . @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a>
22 . public void yyerror (string message
) {
23 . yyerror(message
, null);
25 .#pragma warning disable 649
27 . public int eof_token
;
28 .#pragma warning restore 649
29 . /** (syntax) error message.
30 . Can be overwritten to control message format.
31 . @param message text to be displayed.
32 . @param expected vector of acceptable tokens, if available.
34 . public void yyerror (string message
, string[] expected
) {
35 . if ((yacc_verbose_flag
> 0) && (expected
!= null) && (expected
.Length
> 0)) {
36 . ErrorOutput
.Write (message
+", expecting");
37 . for (int n
= 0; n
< expected
.Length
; ++ n
)
38 . ErrorOutput
.Write (" "+expected
[n
]);
39 . ErrorOutput
.WriteLine ();
41 . ErrorOutput
.WriteLine (message
);
44 . /** debugging support, requires the package jay.yydebug.
45 . Set to null to suppress debugging messages.
47 t
internal yydebug
.yyDebug debug
;
49 debug
## tables for debugging support
51 . /** index-checked interface to yyNames[].
52 . @param token single character or %token value.
53 . @return token name or [illegal] or [unknown].
55 t
public static string yyname (int token
) {
56 t
if ((token
< 0) || (token
> yyNames
.Length
)) return "[illegal]";
58 t
if ((name
= yyNames
[token
]) != null) return name
;
62 .#pragma warning disable 414
63 . int yyExpectingState
;
64 .#pragma warning restore 414
65 . /** computes list of expected tokens on error by tracing the tables.
66 . @param state for which to compute the list.
67 . @return list of token names.
69 . protected int [] yyExpectingTokens (int state
){
70 . int token
, n
, len
= 0;
71 . bool[] ok
= new bool[yyNames
.Length
];
72 . if ((n
= yySindex
[state
]) != 0)
73 . for (token
= n
< 0 ? -n
: 0;
74 . (token
< yyNames
.Length
) && (n
+token
< yyTable
.Length
); ++ token
)
75 . if (yyCheck
[n
+token
] == token
&& !ok
[token
] && yyNames
[token
] != null) {
79 . if ((n
= yyRindex
[state
]) != 0)
80 . for (token
= n
< 0 ? -n
: 0;
81 . (token
< yyNames
.Length
) && (n
+token
< yyTable
.Length
); ++ token
)
82 . if (yyCheck
[n
+token
] == token
&& !ok
[token
] && yyNames
[token
] != null) {
86 . int [] result
= new int [len
];
87 . for (n
= token
= 0; n
< len
; ++ token
)
88 . if (ok
[token
]) result
[n
++] = token
;
91 . protected string[] yyExpecting (int state
) {
92 . int [] tokens
= yyExpectingTokens (state
);
93 . string [] result
= new string[tokens
.Length
];
94 . for (int n
= 0; n
< tokens
.Length
; n
++)
95 . result
[n
++] = yyNames
[tokens
[n
]];
99 . /** the generated parser, with debugging messages.
100 . Maintains a state and a value stack, currently with fixed maximum size.
101 . @param yyLex scanner.
102 . @param yydebug debug message writer implementing yyDebug, or null.
103 . @return result of the last reduction, if any.
104 . @throws yyException on irrecoverable parse error.
106 . internal Object
yyparse (yyParser
.yyInput yyLex
, Object yyd
)
108 t
this.debug
= (yydebug
.yyDebug
)yyd
;
109 . return yyparse(yyLex
);
112 . /** initial size and increment of the state/value stack [default 256].
113 . This is not final so that it can be overwritten outside of invocations
116 . protected int yyMax
;
118 . /** executed at the beginning of a reduce action.
119 . Used as $$ = yyDefault($1), prior to the user-specified action, if any.
120 . Can be overwritten to provide deep copy, etc.
121 . @param first value for $1, or null.
124 . protected Object
yyDefault (Object first
) {
128 . static int[] global_yyStates
;
129 . static object[] global_yyVals
;
130 .#pragma warning disable 649
131 . protected bool use_global_stacks
;
132 .#pragma warning restore 649
133 . object[] yyVals
; // value stack
134 . object yyVal
; // value stack ptr
135 . int yyToken
; // current input
138 . /** the generated parser.
139 . Maintains a state and a value stack, currently with fixed maximum size.
140 . @param yyLex scanner.
141 . @return result of the last reduction, if any.
142 . @throws yyException on irrecoverable parse error.
144 . internal Object
yyparse (yyParser
.yyInput yyLex
)
146 . if (yyMax
<= 0) yyMax
= 256; // initial size
147 . int yyState
= 0; // state stack ptr
148 . int [] yyStates
; // state stack
151 . int yyErrorFlag
= 0; // #tks to shift
152 . if (use_global_stacks
&& global_yyStates
!= null) {
153 . yyVals
= global_yyVals
;
154 . yyStates
= global_yyStates
;
156 . yyVals
= new object [yyMax
];
157 . yyStates
= new int [yyMax
];
158 . if (use_global_stacks
) {
159 . global_yyVals
= yyVals
;
160 . global_yyStates
= yyStates
;
164 local
## %{ ... %} after the first %%
166 . /*yyLoop:*/ for (yyTop
= 0;; ++ yyTop
) {
167 . if (yyTop
>= yyStates
.Length
) { // dynamically increase
168 . global::System
.Array
.Resize (ref yyStates
, yyStates
.Length
+yyMax
);
169 . global::System
.Array
.Resize (ref yyVals
, yyVals
.Length
+yyMax
);
171 . yyStates
[yyTop
] = yyState
;
172 . yyVals
[yyTop
] = yyVal
;
173 t
if (debug
!= null) debug
.push(yyState
, yyVal
);
175 . /*yyDiscarded:*/ while (true) { // discarding a token does not change stack
177 . if ((yyN
= yyDefRed
[yyState
]) == 0) { // else [default] reduce (yyN)
179 . yyToken
= yyLex
.advance() ? yyLex
.token() : 0;
182 t debug
.lex(yyState
, yyToken
, yyname(yyToken
), yyLex
.value());
184 . if ((yyN
= yySindex
[yyState
]) != 0 && ((yyN
+= yyToken
) >= 0)
185 . && (yyN
< yyTable
.Length
) && (yyCheck
[yyN
] == yyToken
)) {
187 t debug
.shift(yyState
, yyTable
[yyN
], yyErrorFlag
-1);
188 . yyState
= yyTable
[yyN
]; // shift to yyN
189 . yyVal
= yyLex
.value();
191 . if (yyErrorFlag
> 0) -- yyErrorFlag
;
192 . goto continue_yyLoop
;
194 . if ((yyN
= yyRindex
[yyState
]) != 0 && (yyN
+= yyToken
) >= 0
195 . && yyN
< yyTable
.Length
&& yyCheck
[yyN
] == yyToken
)
196 . yyN
= yyTable
[yyN
]; // reduce (yyN)
198 . switch (yyErrorFlag
) {
201 . yyExpectingState
= yyState
;
202 . // yyerror(String.Format ("syntax error, got token `{0}'", yyname (yyToken)), yyExpecting(yyState));
203 t
if (debug
!= null) debug
.error("syntax error");
204 . if (yyToken
== 0 /*eof*/ || yyToken
== eof_token
) throw new yyParser
.yyUnexpectedEof ();
209 . if ((yyN
= yySindex
[yyStates
[yyTop
]]) != 0
210 . && (yyN
+= Token
.yyErrorCode
) >= 0 && yyN
< yyTable
.Length
211 . && yyCheck
[yyN
] == Token
.yyErrorCode
) {
213 t debug
.shift(yyStates
[yyTop
], yyTable
[yyN
], 3);
214 . yyState
= yyTable
[yyN
];
215 . yyVal
= yyLex
.value();
216 . goto continue_yyLoop
;
218 t
if (debug
!= null) debug
.pop(yyStates
[yyTop
]);
219 . } while (-- yyTop
>= 0);
220 t
if (debug
!= null) debug
.reject();
221 . throw new yyParser
.yyException("irrecoverable syntax error");
224 . if (yyToken
== 0) {
225 t
if (debug
!= null) debug
.reject();
226 . throw new yyParser
.yyException("irrecoverable syntax error at end-of-file");
229 t debug
.discard(yyState
, yyToken
, yyname(yyToken
),
232 . goto continue_yyDiscarded
; // leave stack alone
235 . int yyV
= yyTop
+ 1-yyLen
[yyN
];
237 t debug
.reduce(yyState
, yyStates
[yyV
-1], yyN
, YYRules
.getRule (yyN
), yyLen
[yyN
]);
238 . yyVal
= yyV
> yyTop
? null : yyVals
[yyV
]; // yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]);
241 actions
## code from the actions within the grammar
244 . yyTop
-= yyLen
[yyN
];
245 . yyState
= yyStates
[yyTop
];
246 . int yyM
= yyLhs
[yyN
];
247 . if (yyState
== 0 && yyM
== 0) {
248 t
if (debug
!= null) debug
.shift(0, yyFinal
);
251 . yyToken
= yyLex
.advance() ? yyLex
.token() : 0;
254 t debug
.lex(yyState
, yyToken
,yyname(yyToken
), yyLex
.value());
256 . if (yyToken
== 0) {
257 t
if (debug
!= null) debug
.accept(yyVal
);
260 . goto continue_yyLoop
;
262 . if (((yyN
= yyGindex
[yyM
]) != 0) && ((yyN
+= yyState
) >= 0)
263 . && (yyN
< yyTable
.Length
) && (yyCheck
[yyN
] == yyState
))
264 . yyState
= yyTable
[yyN
];
266 . yyState
= yyDgoto
[yyM
];
267 t
if (debug
!= null) debug
.shift(yyStates
[yyTop
], yyState
);
268 . goto continue_yyLoop
;
269 . continue_yyDiscarded
: ; // implements the named-loop continue: 'continue yyDiscarded'
271 . continue_yyLoop
: ; // implements the named-loop continue: 'continue yyLoop'
275 tables
## tables for rules, default reduction, and action calls
277 epilog
## text following second %%
280 . internal interface yyDebug
{
281 . void push (int state
, Object
value);
282 . void lex (int state
, int token
, string name
, Object
value);
283 . void shift (int from, int to
, int errorFlag
);
284 . void pop (int state
);
285 . void discard (int state
, int token
, string name
, Object
value);
286 . void reduce (int from, int to
, int rule
, string text
, int len
);
287 . void shift (int from, int to
);
288 . void accept (Object
value);
289 . void error (string message
);
293 . class yyDebugSimple
: yyDebug
{
294 . void println (string s
){
295 . Console
.Error
.WriteLine (s
);
298 . public void push (int state
, Object
value) {
299 . println ("push\tstate "+state
+"\tvalue "+value);
302 . public void lex (int state
, int token
, string name
, Object
value) {
303 . println("lex\tstate "+state
+"\treading "+name
+"\tvalue "+value);
306 . public void shift (int from, int to
, int errorFlag
) {
307 . switch (errorFlag
) {
308 . default: // normally
309 . println("shift\tfrom state "+from+" to "+to
);
311 . case 0: case 1: case 2: // in error recovery
312 . println("shift\tfrom state "+from+" to "+to
313 . +"\t"+errorFlag
+" left to recover");
315 . case 3: // normally
316 . println("shift\tfrom state "+from+" to "+to
+"\ton error");
321 . public void pop (int state
) {
322 . println("pop\tstate "+state
+"\ton error");
325 . public void discard (int state
, int token
, string name
, Object
value) {
326 . println("discard\tstate "+state
+"\ttoken "+name
+"\tvalue "+value);
329 . public void reduce (int from, int to
, int rule
, string text
, int len
) {
330 . println("reduce\tstate "+from+"\tuncover "+to
331 . +"\trule ("+rule
+") "+text
);
334 . public void shift (int from, int to
) {
335 . println("goto\tfrom state "+from+" to "+to
);
338 . public void accept (Object
value) {
339 . println("accept\tvalue "+value);
342 . public void error (string message
) {
343 . println("error\t"+message
);
346 . public void reject () {
354 tokens
public const int
356 . namespace yyParser
{
358 . /** thrown for irrecoverable syntax errors and stack overflow.
360 . internal class yyException
: System
.Exception
{
361 . public yyException (string message
) : base (message
) {
364 . internal class yyUnexpectedEof
: yyException
{
365 . public yyUnexpectedEof (string message
) : base (message
) {
367 . public yyUnexpectedEof () : base ("") {
371 . /** must be implemented by a scanner object to supply input to the parser.
373 . internal interface yyInput
{
374 . /** move on to next token.
375 . @return false if positioned beyond tokens.
376 . @throws IOException on input error.
378 . bool advance (); // throws java.io.IOException;
379 . /** classifies current token.
380 . Should not be called if advance() returned false.
381 . @return current %token or single character.
384 . /** associated with current token.
385 . Should not be called if advance() returned false.
386 . @return value for token().
391 .} // close outermost namespace, that MUST HAVE BEEN opened in the prolog