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
13 prolog
## %{ ... %} prior to the first %%
16 . /** error output stream.
17 . It should be changeable.
19 . internal System
.IO
.TextWriter ErrorOutput
= System
.Console
.Out
;
21 . /** simplified error message.
22 . @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a>
24 . internal void yyerror (string message
) {
25 . yyerror(message
, null);
28 . /** (syntax) error message.
29 . Can be overwritten to control message format.
30 . @param message text to be displayed.
31 . @param expected vector of acceptable tokens, if available.
33 . internal void yyerror (string message
, string[] expected
) {
34 . if ((expected
!= null) && (expected
.Length
> 0)) {
35 . ErrorOutput
.Write (message
+", expecting");
36 . for (int n
= 0; n
< expected
.Length
; ++ n
)
37 . ErrorOutput
.Write (" "+expected
[n
]);
38 . ErrorOutput
.WriteLine ();
40 . ErrorOutput
.WriteLine (message
);
43 . /** debugging support, requires the package jay.yydebug.
44 . Set to null to suppress debugging messages.
46 t
internal yydebug
.yyDebug debug
;
48 debug
## tables for debugging support
50 . /** index-checked interface to yyNames[].
51 . @param token single character or %token value.
52 . @return token name or [illegal] or [unknown].
54 t
internal static string yyname (int token
) {
55 t
if ((token
< 0) || (token
> yyNames
.Length
)) return "[illegal]";
57 t
if ((name
= yyNames
[token
]) != null) return name
;
61 . /** computes list of expected tokens on error by tracing the tables.
62 . @param state for which to compute the list.
63 . @return list of token names.
65 . internal string[] yyExpecting (int state
) {
66 . int token
, n
, len
= 0;
67 . bool[] ok
= new bool[yyNames
.Length
];
69 . if ((n
= yySindex
[state
]) != 0)
70 . for (token
= n
< 0 ? -n
: 0;
71 . (token
< yyNames
.Length
) && (n
+token
< yyTable
.Length
); ++ token
)
72 . if (yyCheck
[n
+token
] == token
&& !ok
[token
] && yyNames
[token
] != null) {
76 . if ((n
= yyRindex
[state
]) != 0)
77 . for (token
= n
< 0 ? -n
: 0;
78 . (token
< yyNames
.Length
) && (n
+token
< yyTable
.Length
); ++ token
)
79 . if (yyCheck
[n
+token
] == token
&& !ok
[token
] && yyNames
[token
] != null) {
84 . string [] result
= new string[len
];
85 . for (n
= token
= 0; n
< len
; ++ token
)
86 . if (ok
[token
]) result
[n
++] = yyNames
[token
];
90 . /** the generated parser, with debugging messages.
91 . Maintains a state and a value stack, currently with fixed maximum size.
92 . @param yyLex scanner.
93 . @param yydebug debug message writer implementing yyDebug, or null.
94 . @return result of the last reduction, if any.
95 . @throws yyException on irrecoverable parse error.
97 . internal Object
yyparse (yyParser
.yyInput yyLex
, Object yyd
)
99 t
this.debug
= (yydebug
.yyDebug
)yyd
;
100 . return yyparse(yyLex
);
103 . /** initial size and increment of the state/value stack [default 256].
104 . This is not final so that it can be overwritten outside of invocations
107 . internal int yyMax
;
109 . /** executed at the beginning of a reduce action.
110 . Used as $$ = yyDefault($1), prior to the user-specified action, if any.
111 . Can be overwritten to provide deep copy, etc.
112 . @param first value for $1, or null.
115 . internal Object
yyDefault (Object first
) {
119 . /** the generated parser.
120 . Maintains a state and a value stack, currently with fixed maximum size.
121 . @param yyLex scanner.
122 . @return result of the last reduction, if any.
123 . @throws yyException on irrecoverable parse error.
125 . internal Object
yyparse (yyParser
.yyInput yyLex
)
127 . if (yyMax
<= 0) yyMax
= 256; // initial size
128 . int yyState
= 0; // state stack ptr
129 . int [] yyStates
= new int[yyMax
]; // state stack
130 . Object yyVal
= null; // value stack ptr
131 . Object
[] yyVals
= new Object
[yyMax
]; // value stack
132 . int yyToken
= -1; // current input
133 . int yyErrorFlag
= 0; // #tks to shift
135 local
## %{ ... %} after the first %%
142 . for (;; ++ yyTop
) {
143 . if (yyTop
>= yyStates
.Length
) { // dynamically increase
144 . int[] i
= new int[yyStates
.Length
+yyMax
];
145 . yyStates
.CopyTo (i
, 0);
147 . Object
[] o
= new Object
[yyVals
.Length
+yyMax
];
148 . yyVals
.CopyTo (o
, 0);
151 . yyStates
[yyTop
] = yyState
;
152 . yyVals
[yyTop
] = yyVal
;
153 t
if (debug
!= null) debug
.push(yyState
, yyVal
);
155 . yyDiscarded
: for (;;) { // discarding a token does not change stack
157 . if ((yyN
= yyDefRed
[yyState
]) == 0) { // else [default] reduce (yyN)
159 . yyToken
= yyLex
.advance() ? yyLex
.token() : 0;
162 t debug
.lex(yyState
, yyToken
, yyname(yyToken
), yyLex
.value());
164 . if ((yyN
= yySindex
[yyState
]) != 0 && ((yyN
+= yyToken
) >= 0)
165 . && (yyN
< yyTable
.Length
) && (yyCheck
[yyN
] == yyToken
)) {
167 t debug
.shift(yyState
, yyTable
[yyN
], yyErrorFlag
-1);
168 . yyState
= yyTable
[yyN
]; // shift to yyN
169 . yyVal
= yyLex
.value();
171 . if (yyErrorFlag
> 0) -- yyErrorFlag
;
174 . if ((yyN
= yyRindex
[yyState
]) != 0 && (yyN
+= yyToken
) >= 0
175 . && yyN
< yyTable
.Length
&& yyCheck
[yyN
] == yyToken
)
176 . yyN
= yyTable
[yyN
]; // reduce (yyN)
178 . switch (yyErrorFlag
) {
181 . yyerror(String
.Format ("syntax error, got token `{0}'", yyname (yyToken
)), yyExpecting(yyState
));
182 t
if (debug
!= null) debug
.error("syntax error");
187 . if ((yyN
= yySindex
[yyStates
[yyTop
]]) != 0
188 . && (yyN
+= Token
.yyErrorCode
) >= 0 && yyN
< yyTable
.Length
189 . && yyCheck
[yyN
] == Token
.yyErrorCode
) {
191 t debug
.shift(yyStates
[yyTop
], yyTable
[yyN
], 3);
192 . yyState
= yyTable
[yyN
];
193 . yyVal
= yyLex
.value();
196 t
if (debug
!= null) debug
.pop(yyStates
[yyTop
]);
197 . } while (-- yyTop
>= 0);
198 t
if (debug
!= null) debug
.reject();
199 . throw new yyParser
.yyException("irrecoverable syntax error");
202 . if (yyToken
== 0) {
203 t
if (debug
!= null) debug
.reject();
204 . throw new yyParser
.yyException("irrecoverable syntax error at end-of-file");
207 t debug
.discard(yyState
, yyToken
, yyname(yyToken
),
210 . goto yyDiscarded
; // leave stack alone
213 . int yyV
= yyTop
+ 1-yyLen
[yyN
];
215 t debug
.reduce(yyState
, yyStates
[yyV
-1], yyN
, yyRule
[yyN
], yyLen
[yyN
]);
216 . yyVal
= yyDefault(yyV
> yyTop
? null : yyVals
[yyV
]);
219 actions
## code from the actions within the grammar
222 . yyTop
-= yyLen
[yyN
];
223 . yyState
= yyStates
[yyTop
];
224 . int yyM
= yyLhs
[yyN
];
225 . if (yyState
== 0 && yyM
== 0) {
226 t
if (debug
!= null) debug
.shift(0, yyFinal
);
229 . yyToken
= yyLex
.advance() ? yyLex
.token() : 0;
232 t debug
.lex(yyState
, yyToken
,yyname(yyToken
), yyLex
.value());
234 . if (yyToken
== 0) {
235 t
if (debug
!= null) debug
.accept(yyVal
);
240 . if (((yyN
= yyGindex
[yyM
]) != 0) && ((yyN
+= yyState
) >= 0)
241 . && (yyN
< yyTable
.Length
) && (yyCheck
[yyN
] == yyState
))
242 . yyState
= yyTable
[yyN
];
244 . yyState
= yyDgoto
[yyM
];
245 t
if (debug
!= null) debug
.shift(yyStates
[yyTop
], yyState
);
251 tables
## tables for rules, default reduction, and action calls
253 epilog
## text following second %%
256 . internal interface yyDebug
{
257 . void push (int state
, Object
value);
258 . void lex (int state
, int token
, string name
, Object
value);
259 . void shift (int from, int to
, int errorFlag
);
260 . void pop (int state
);
261 . void discard (int state
, int token
, string name
, Object
value);
262 . void reduce (int from, int to
, int rule
, string text
, int len
);
263 . void shift (int from, int to
);
264 . void accept (Object
value);
265 . void error (string message
);
269 . class yyDebugSimple
: yyDebug
{
270 . void println (string s
){
271 . Console
.Error
.WriteLine (s
);
274 . public void push (int state
, Object
value) {
275 . println ("push\tstate "+state
+"\tvalue "+value);
278 . public void lex (int state
, int token
, string name
, Object
value) {
279 . println("lex\tstate "+state
+"\treading "+name
+"\tvalue "+value);
282 . public void shift (int from, int to
, int errorFlag
) {
283 . switch (errorFlag
) {
284 . default: // normally
285 . println("shift\tfrom state "+from+" to "+to
);
287 . case 0: case 1: case 2: // in error recovery
288 . println("shift\tfrom state "+from+" to "+to
289 . +"\t"+errorFlag
+" left to recover");
291 . case 3: // normally
292 . println("shift\tfrom state "+from+" to "+to
+"\ton error");
297 . public void pop (int state
) {
298 . println("pop\tstate "+state
+"\ton error");
301 . public void discard (int state
, int token
, string name
, Object
value) {
302 . println("discard\tstate "+state
+"\ttoken "+name
+"\tvalue "+value);
305 . public void reduce (int from, int to
, int rule
, string text
, int len
) {
306 . println("reduce\tstate "+from+"\tuncover "+to
307 . +"\trule ("+rule
+") "+text
);
310 . public void shift (int from, int to
) {
311 . println("goto\tfrom state "+from+" to "+to
);
314 . public void accept (Object
value) {
315 . println("accept\tvalue "+value);
318 . public void error (string message
) {
319 . println("error\t"+message
);
322 . public void reject () {
330 tokens
public const int
332 . namespace yyParser
{
334 . /** thrown for irrecoverable syntax errors and stack overflow.
336 . internal class yyException
: System
.Exception
{
337 . public yyException (string message
) : base (message
) {
341 . /** must be implemented by a scanner object to supply input to the parser.
343 . internal interface yyInput
{
344 . /** move on to next token.
345 . @return false if positioned beyond tokens.
346 . @throws IOException on input error.
348 . bool advance (); // throws java.io.IOException;
349 . /** classifies current token.
350 . Should not be called if advance() returned false.
351 . @return current %token or single character.
354 . /** associated with current token.
355 . Should not be called if advance() returned false.
356 . @return value for token().
361 .} // close outermost namespace, that MUST HAVE BEEN opened in the prolog