changeset 62015 | db9c2af6ce72 |
parent 56281 | 03c3d1a7c3b8 |
62014:446fcbadc6bf | 62015:db9c2af6ce72 |
---|---|
56 *) |
56 *) |
57 |
57 |
58 signature LR_TABLE = |
58 signature LR_TABLE = |
59 sig |
59 sig |
60 datatype ('a,'b) pairlist = EMPTY | PAIR of 'a * 'b * ('a,'b) pairlist |
60 datatype ('a,'b) pairlist = EMPTY | PAIR of 'a * 'b * ('a,'b) pairlist |
61 datatype state = STATE of int |
61 datatype state = STATE of int |
62 datatype term = T of int |
62 datatype term = T of int |
63 datatype nonterm = NT of int |
63 datatype nonterm = NT of int |
64 datatype action = SHIFT of state |
64 datatype action = SHIFT of state |
65 | REDUCE of int |
65 | REDUCE of int |
66 | ACCEPT |
66 | ACCEPT |
67 | ERROR |
67 | ERROR |
68 type table |
68 type table |
69 |
69 |
70 val numStates : table -> int |
70 val numStates : table -> int |
71 val numRules : table -> int |
71 val numRules : table -> int |
72 val describeActions : table -> state -> |
72 val describeActions : table -> state -> |
73 (term,action) pairlist * action |
73 (term,action) pairlist * action |
74 val describeGoto : table -> state -> (nonterm,state) pairlist |
74 val describeGoto : table -> state -> (nonterm,state) pairlist |
75 val action : table -> state * term -> action |
75 val action : table -> state * term -> action |
76 val goto : table -> state * nonterm -> state |
76 val goto : table -> state * nonterm -> state |
77 val initialState : table -> state |
77 val initialState : table -> state |
78 exception Goto of state * nonterm |
78 exception Goto of state * nonterm |
79 |
79 |
80 val mkLrTable : {actions : ((term,action) pairlist * action) array, |
80 val mkLrTable : {actions : ((term,action) pairlist * action) array, |
81 gotos : (nonterm,state) pairlist array, |
81 gotos : (nonterm,state) pairlist array, |
82 numStates : int, numRules : int, |
82 numStates : int, numRules : int, |
83 initialState : state} -> table |
83 initialState : state} -> table |
84 end |
84 end |
85 |
85 |
86 (* TOKEN: signature revealing the internal structure of a token. This signature |
86 (* TOKEN: signature revealing the internal structure of a token. This signature |
87 TOKEN distinct from the signature {parser name}_TOKENS produced by ML-Yacc. |
87 TOKEN distinct from the signature {parser name}_TOKENS produced by ML-Yacc. |
88 The {parser name}_TOKENS structures contain some types and functions to |
88 The {parser name}_TOKENS structures contain some types and functions to |
95 This has had an impact on the TOKENS structure produced by SML-Yacc, which |
95 This has had an impact on the TOKENS structure produced by SML-Yacc, which |
96 is a structure parameter to lexer functors. We would like to have some |
96 is a structure parameter to lexer functors. We would like to have some |
97 type 'a token which functions to construct tokens would create. A |
97 type 'a token which functions to construct tokens would create. A |
98 constructor function for a integer token might be |
98 constructor function for a integer token might be |
99 |
99 |
100 INT: int * 'a * 'a -> 'a token. |
100 INT: int * 'a * 'a -> 'a token. |
101 |
101 |
102 This is not possible because we need to have tokens with the representation |
102 This is not possible because we need to have tokens with the representation |
103 given below for the polymorphic parser. |
103 given below for the polymorphic parser. |
104 |
104 |
105 Thus our constructur functions for tokens have the form: |
105 Thus our constructur functions for tokens have the form: |
106 |
106 |
107 INT: int * 'a * 'a -> (svalue,'a) token |
107 INT: int * 'a * 'a -> (svalue,'a) token |
108 |
108 |
109 This in turn has had an impact on the signature that lexers for SML-Yacc |
109 This in turn has had an impact on the signature that lexers for SML-Yacc |
110 must match and the types that a user must declare in the user declarations |
110 must match and the types that a user must declare in the user declarations |
111 section of lexers. |
111 section of lexers. |
112 *) |
112 *) |
113 |
113 |
114 signature TOKEN = |
114 signature TOKEN = |
115 sig |
115 sig |
116 structure LrTable : LR_TABLE |
116 structure LrTable : LR_TABLE |
117 datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b) |
117 datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b) |
118 val sameToken : ('a,'b) token * ('a,'b) token -> bool |
118 val sameToken : ('a,'b) token * ('a,'b) token -> bool |
119 end |
119 end |
120 |
120 |
121 (* LR_PARSER: signature for a polymorphic LR parser *) |
121 (* LR_PARSER: signature for a polymorphic LR parser *) |
122 |
122 |
123 signature LR_PARSER = |
123 signature LR_PARSER = |
124 sig |
124 sig |
125 structure Stream: STREAM |
125 structure Stream: STREAM |
126 structure LrTable : LR_TABLE |
126 structure LrTable : LR_TABLE |
127 structure Token : TOKEN |
127 structure Token : TOKEN |
128 |
128 |
129 sharing LrTable = Token.LrTable |
129 sharing LrTable = Token.LrTable |
130 |
130 |
131 exception ParseError |
131 exception ParseError |
132 |
132 |
133 val parse : {table : LrTable.table, |
133 val parse : {table : LrTable.table, |
134 lexer : ('_b,'_c) Token.token Stream.stream, |
134 lexer : ('_b,'_c) Token.token Stream.stream, |
135 arg: 'arg, |
135 arg: 'arg, |
136 saction : int * |
136 saction : int * |
137 '_c * |
137 '_c * |
138 (LrTable.state * ('_b * '_c * '_c)) list * |
138 (LrTable.state * ('_b * '_c * '_c)) list * |
139 'arg -> |
139 'arg -> |
140 LrTable.nonterm * |
140 LrTable.nonterm * |
141 ('_b * '_c * '_c) * |
141 ('_b * '_c * '_c) * |
142 ((LrTable.state *('_b * '_c * '_c)) list), |
142 ((LrTable.state *('_b * '_c * '_c)) list), |
143 void : '_b, |
143 void : '_b, |
144 ec : { is_keyword : LrTable.term -> bool, |
144 ec : { is_keyword : LrTable.term -> bool, |
145 noShift : LrTable.term -> bool, |
145 noShift : LrTable.term -> bool, |
146 preferred_change : (LrTable.term list * LrTable.term list) list, |
146 preferred_change : (LrTable.term list * LrTable.term list) list, |
147 errtermvalue : LrTable.term -> '_b, |
147 errtermvalue : LrTable.term -> '_b, |
148 showTerminal : LrTable.term -> string, |
148 showTerminal : LrTable.term -> string, |
149 terms: LrTable.term list, |
149 terms: LrTable.term list, |
150 error : string * '_c * '_c -> unit |
150 error : string * '_c * '_c -> unit |
151 }, |
151 }, |
152 lookahead : int (* max amount of lookahead used in *) |
152 lookahead : int (* max amount of lookahead used in *) |
153 (* error correction *) |
153 (* error correction *) |
154 } -> '_b * |
154 } -> '_b * |
155 (('_b,'_c) Token.token Stream.stream) |
155 (('_b,'_c) Token.token Stream.stream) |
156 end |
156 end |
157 |
157 |
158 (* LEXER: a signature that most lexers produced for use with SML-Yacc's |
158 (* LEXER: a signature that most lexers produced for use with SML-Yacc's |
159 output will match. The user is responsible for declaring type token, |
159 output will match. The user is responsible for declaring type token, |
160 type pos, and type svalue in the UserDeclarations section of a lexer. |
160 type pos, and type svalue in the UserDeclarations section of a lexer. |
167 *) |
167 *) |
168 |
168 |
169 signature LEXER = |
169 signature LEXER = |
170 sig |
170 sig |
171 structure UserDeclarations : |
171 structure UserDeclarations : |
172 sig |
172 sig |
173 type ('a,'b) token |
173 type ('a,'b) token |
174 type pos |
174 type pos |
175 type svalue |
175 type svalue |
176 end |
176 end |
177 val makeLexer : (int -> string) -> unit -> |
177 val makeLexer : (int -> string) -> unit -> |
178 (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token |
178 (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token |
179 end |
179 end |
180 |
180 |
181 (* ARG_LEXER: the %arg option of ML-Lex allows users to produce lexers which |
181 (* ARG_LEXER: the %arg option of ML-Lex allows users to produce lexers which |
182 also take an argument before yielding a function from unit to a token |
182 also take an argument before yielding a function from unit to a token |
183 *) |
183 *) |
184 |
184 |
185 signature ARG_LEXER = |
185 signature ARG_LEXER = |
186 sig |
186 sig |
187 structure UserDeclarations : |
187 structure UserDeclarations : |
188 sig |
188 sig |
189 type ('a,'b) token |
189 type ('a,'b) token |
190 type pos |
190 type pos |
191 type svalue |
191 type svalue |
192 type arg |
192 type arg |
193 end |
193 end |
194 val makeLexer : (int -> string) -> UserDeclarations.arg -> unit -> |
194 val makeLexer : (int -> string) -> UserDeclarations.arg -> unit -> |
195 (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token |
195 (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token |
196 end |
196 end |
197 |
197 |
198 (* PARSER_DATA: the signature of ParserData structures in {parser name}LrValsFun |
198 (* PARSER_DATA: the signature of ParserData structures in {parser name}LrValsFun |
199 produced by SML-Yacc. All such structures match this signature. |
199 produced by SML-Yacc. All such structures match this signature. |
206 |
206 |
207 signature PARSER_DATA = |
207 signature PARSER_DATA = |
208 sig |
208 sig |
209 (* the type of line numbers *) |
209 (* the type of line numbers *) |
210 |
210 |
211 type pos |
211 type pos |
212 |
212 |
213 (* the type of semantic values *) |
213 (* the type of semantic values *) |
214 |
214 |
215 type svalue |
215 type svalue |
216 |
216 |
217 (* the type of the user-supplied argument to the parser *) |
217 (* the type of the user-supplied argument to the parser *) |
218 type arg |
218 type arg |
219 |
219 |
220 (* the intended type of the result of the parser. This value is |
220 (* the intended type of the result of the parser. This value is |
221 produced by applying extract from the structure Actions to the |
221 produced by applying extract from the structure Actions to the |
222 final semantic value resultiing from a parse. |
222 final semantic value resultiing from a parse. |
223 *) |
223 *) |
224 |
224 |
225 type result |
225 type result |
226 |
226 |
227 structure LrTable : LR_TABLE |
227 structure LrTable : LR_TABLE |
228 structure Token : TOKEN |
228 structure Token : TOKEN |
229 sharing Token.LrTable = LrTable |
229 sharing Token.LrTable = LrTable |
230 |
230 |
231 (* structure Actions contains the functions which mantain the |
231 (* structure Actions contains the functions which mantain the |
232 semantic values stack in the parser. Void is used to provide |
232 semantic values stack in the parser. Void is used to provide |
233 a default value for the semantic stack. |
233 a default value for the semantic stack. |
234 *) |
234 *) |
235 |
235 |
236 structure Actions : |
236 structure Actions : |
237 sig |
237 sig |
238 val actions : int * pos * |
238 val actions : int * pos * |
239 (LrTable.state * (svalue * pos * pos)) list * arg-> |
239 (LrTable.state * (svalue * pos * pos)) list * arg-> |
240 LrTable.nonterm * (svalue * pos * pos) * |
240 LrTable.nonterm * (svalue * pos * pos) * |
241 ((LrTable.state *(svalue * pos * pos)) list) |
241 ((LrTable.state *(svalue * pos * pos)) list) |
242 val void : svalue |
242 val void : svalue |
243 val extract : svalue -> result |
243 val extract : svalue -> result |
244 end |
244 end |
245 |
245 |
246 (* structure EC contains information used to improve error |
246 (* structure EC contains information used to improve error |
247 recovery in an error-correcting parser *) |
247 recovery in an error-correcting parser *) |
248 |
248 |
249 structure EC : |
249 structure EC : |
250 sig |
250 sig |
251 val is_keyword : LrTable.term -> bool |
251 val is_keyword : LrTable.term -> bool |
252 val noShift : LrTable.term -> bool |
252 val noShift : LrTable.term -> bool |
253 val preferred_change : (LrTable.term list * LrTable.term list) list |
253 val preferred_change : (LrTable.term list * LrTable.term list) list |
254 val errtermvalue : LrTable.term -> svalue |
254 val errtermvalue : LrTable.term -> svalue |
255 val showTerminal : LrTable.term -> string |
255 val showTerminal : LrTable.term -> string |
256 val terms: LrTable.term list |
256 val terms: LrTable.term list |
257 end |
257 end |
258 |
258 |
259 (* table is the LR table for the parser *) |
259 (* table is the LR table for the parser *) |
260 |
260 |
261 val table : LrTable.table |
261 val table : LrTable.table |
262 end |
262 end |
263 |
263 |
264 (* signature PARSER is the signature that most user parsers created by |
264 (* signature PARSER is the signature that most user parsers created by |
265 SML-Yacc will match. |
265 SML-Yacc will match. |
266 *) |
266 *) |
267 |
267 |
268 signature PARSER = |
268 signature PARSER = |
269 sig |
269 sig |
270 structure Token : TOKEN |
270 structure Token : TOKEN |
271 structure Stream : STREAM |
271 structure Stream : STREAM |
272 exception ParseError |
272 exception ParseError |
273 |
273 |
274 (* type pos is the type of line numbers *) |
274 (* type pos is the type of line numbers *) |
275 |
275 |
276 type pos |
276 type pos |
277 |
277 |
278 (* type result is the type of the result from the parser *) |
278 (* type result is the type of the result from the parser *) |
279 |
279 |
280 type result |
280 type result |
281 |
281 |
282 (* the type of the user-supplied argument to the parser *) |
282 (* the type of the user-supplied argument to the parser *) |
283 type arg |
283 type arg |
284 |
284 |
285 (* type svalue is the type of semantic values for the semantic value |
285 (* type svalue is the type of semantic values for the semantic value |
286 stack |
286 stack |
287 *) |
287 *) |
288 |
288 |
289 type svalue |
289 type svalue |
290 |
290 |
291 (* val makeLexer is used to create a stream of tokens for the parser *) |
291 (* val makeLexer is used to create a stream of tokens for the parser *) |
292 |
292 |
293 val makeLexer : (int -> string) -> |
293 val makeLexer : (int -> string) -> |
294 (svalue,pos) Token.token Stream.stream |
294 (svalue,pos) Token.token Stream.stream |
295 |
295 |
296 (* val parse takes a stream of tokens and a function to TextIO.print |
296 (* val parse takes a stream of tokens and a function to TextIO.print |
297 errors and returns a value of type result and a stream containing |
297 errors and returns a value of type result and a stream containing |
298 the unused tokens |
298 the unused tokens |
299 *) |
299 *) |
300 |
300 |
301 val parse : int * ((svalue,pos) Token.token Stream.stream) * |
301 val parse : int * ((svalue,pos) Token.token Stream.stream) * |
302 (string * pos * pos -> unit) * arg -> |
302 (string * pos * pos -> unit) * arg -> |
303 result * (svalue,pos) Token.token Stream.stream |
303 result * (svalue,pos) Token.token Stream.stream |
304 |
304 |
305 val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> |
305 val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> |
306 bool |
306 bool |
307 end |
307 end |
308 |
308 |
309 (* signature ARG_PARSER is the signature that will be matched by parsers whose |
309 (* signature ARG_PARSER is the signature that will be matched by parsers whose |
310 lexer takes an additional argument. |
310 lexer takes an additional argument. |
311 *) |
311 *) |
312 |
312 |
313 signature ARG_PARSER = |
313 signature ARG_PARSER = |
314 sig |
314 sig |
315 structure Token : TOKEN |
315 structure Token : TOKEN |
316 structure Stream : STREAM |
316 structure Stream : STREAM |
317 exception ParseError |
317 exception ParseError |
318 |
318 |
319 type arg |
319 type arg |
320 type lexarg |
320 type lexarg |
321 type pos |
321 type pos |
322 type result |
322 type result |
323 type svalue |
323 type svalue |
324 |
324 |
325 val makeLexer : (int -> string) -> lexarg -> |
325 val makeLexer : (int -> string) -> lexarg -> |
326 (svalue,pos) Token.token Stream.stream |
326 (svalue,pos) Token.token Stream.stream |
327 val parse : int * ((svalue,pos) Token.token Stream.stream) * |
327 val parse : int * ((svalue,pos) Token.token Stream.stream) * |
328 (string * pos * pos -> unit) * arg -> |
328 (string * pos * pos -> unit) * arg -> |
329 result * (svalue,pos) Token.token Stream.stream |
329 result * (svalue,pos) Token.token Stream.stream |
330 |
330 |
331 val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> |
331 val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> |
332 bool |
332 bool |
333 end |
333 end |
334 |
334 |
335 |
335 |
336 (**** Original file: join.sml ****) |
336 (**** Original file: join.sml ****) |
337 |
337 |
343 of line numbers), the type svalues for semantic values, and the type |
343 of line numbers), the type svalues for semantic values, and the type |
344 of tokens. |
344 of tokens. |
345 *) |
345 *) |
346 |
346 |
347 functor Join(structure Lex : LEXER |
347 functor Join(structure Lex : LEXER |
348 structure ParserData: PARSER_DATA |
348 structure ParserData: PARSER_DATA |
349 structure LrParser : LR_PARSER |
349 structure LrParser : LR_PARSER |
350 sharing ParserData.LrTable = LrParser.LrTable |
350 sharing ParserData.LrTable = LrParser.LrTable |
351 sharing ParserData.Token = LrParser.Token |
351 sharing ParserData.Token = LrParser.Token |
352 sharing type Lex.UserDeclarations.svalue = ParserData.svalue |
352 sharing type Lex.UserDeclarations.svalue = ParserData.svalue |
353 sharing type Lex.UserDeclarations.pos = ParserData.pos |
353 sharing type Lex.UserDeclarations.pos = ParserData.pos |
354 sharing type Lex.UserDeclarations.token = ParserData.Token.token) |
354 sharing type Lex.UserDeclarations.token = ParserData.Token.token) |
355 : PARSER = |
355 : PARSER = |
356 struct |
356 struct |
357 structure Token = ParserData.Token |
357 structure Token = ParserData.Token |
358 structure Stream = LrParser.Stream |
358 structure Stream = LrParser.Stream |
359 |
359 |
360 exception ParseError = LrParser.ParseError |
360 exception ParseError = LrParser.ParseError |
363 type pos = ParserData.pos |
363 type pos = ParserData.pos |
364 type result = ParserData.result |
364 type result = ParserData.result |
365 type svalue = ParserData.svalue |
365 type svalue = ParserData.svalue |
366 val makeLexer = LrParser.Stream.streamify o Lex.makeLexer |
366 val makeLexer = LrParser.Stream.streamify o Lex.makeLexer |
367 val parse = fn (lookahead,lexer,error,arg) => |
367 val parse = fn (lookahead,lexer,error,arg) => |
368 (fn (a,b) => (ParserData.Actions.extract a,b)) |
368 (fn (a,b) => (ParserData.Actions.extract a,b)) |
369 (LrParser.parse {table = ParserData.table, |
369 (LrParser.parse {table = ParserData.table, |
370 lexer=lexer, |
370 lexer=lexer, |
371 lookahead=lookahead, |
371 lookahead=lookahead, |
372 saction = ParserData.Actions.actions, |
372 saction = ParserData.Actions.actions, |
373 arg=arg, |
373 arg=arg, |
374 void= ParserData.Actions.void, |
374 void= ParserData.Actions.void, |
375 ec = {is_keyword = ParserData.EC.is_keyword, |
375 ec = {is_keyword = ParserData.EC.is_keyword, |
376 noShift = ParserData.EC.noShift, |
376 noShift = ParserData.EC.noShift, |
377 preferred_change = ParserData.EC.preferred_change, |
377 preferred_change = ParserData.EC.preferred_change, |
378 errtermvalue = ParserData.EC.errtermvalue, |
378 errtermvalue = ParserData.EC.errtermvalue, |
379 error=error, |
379 error=error, |
380 showTerminal = ParserData.EC.showTerminal, |
380 showTerminal = ParserData.EC.showTerminal, |
381 terms = ParserData.EC.terms}} |
381 terms = ParserData.EC.terms}} |
382 ) |
382 ) |
383 val sameToken = Token.sameToken |
383 val sameToken = Token.sameToken |
384 end |
384 end |
385 |
385 |
386 (* functor JoinWithArg creates a variant of the parser structure produced |
386 (* functor JoinWithArg creates a variant of the parser structure produced |
387 above. In this case, the makeLexer take an additional argument before |
387 above. In this case, the makeLexer take an additional argument before |
388 yielding a value of type unit -> (svalue,pos) token |
388 yielding a value of type unit -> (svalue,pos) token |
389 *) |
389 *) |
390 |
390 |
391 functor JoinWithArg(structure Lex : ARG_LEXER |
391 functor JoinWithArg(structure Lex : ARG_LEXER |
392 structure ParserData: PARSER_DATA |
392 structure ParserData: PARSER_DATA |
393 structure LrParser : LR_PARSER |
393 structure LrParser : LR_PARSER |
394 sharing ParserData.LrTable = LrParser.LrTable |
394 sharing ParserData.LrTable = LrParser.LrTable |
395 sharing ParserData.Token = LrParser.Token |
395 sharing ParserData.Token = LrParser.Token |
396 sharing type Lex.UserDeclarations.svalue = ParserData.svalue |
396 sharing type Lex.UserDeclarations.svalue = ParserData.svalue |
397 sharing type Lex.UserDeclarations.pos = ParserData.pos |
397 sharing type Lex.UserDeclarations.pos = ParserData.pos |
398 sharing type Lex.UserDeclarations.token = ParserData.Token.token) |
398 sharing type Lex.UserDeclarations.token = ParserData.Token.token) |
399 : ARG_PARSER = |
399 : ARG_PARSER = |
400 struct |
400 struct |
401 structure Token = ParserData.Token |
401 structure Token = ParserData.Token |
402 structure Stream = LrParser.Stream |
402 structure Stream = LrParser.Stream |
403 |
403 |
404 exception ParseError = LrParser.ParseError |
404 exception ParseError = LrParser.ParseError |
408 type pos = ParserData.pos |
408 type pos = ParserData.pos |
409 type result = ParserData.result |
409 type result = ParserData.result |
410 type svalue = ParserData.svalue |
410 type svalue = ParserData.svalue |
411 |
411 |
412 val makeLexer = fn s => fn arg => |
412 val makeLexer = fn s => fn arg => |
413 LrParser.Stream.streamify (Lex.makeLexer s arg) |
413 LrParser.Stream.streamify (Lex.makeLexer s arg) |
414 val parse = fn (lookahead,lexer,error,arg) => |
414 val parse = fn (lookahead,lexer,error,arg) => |
415 (fn (a,b) => (ParserData.Actions.extract a,b)) |
415 (fn (a,b) => (ParserData.Actions.extract a,b)) |
416 (LrParser.parse {table = ParserData.table, |
416 (LrParser.parse {table = ParserData.table, |
417 lexer=lexer, |
417 lexer=lexer, |
418 lookahead=lookahead, |
418 lookahead=lookahead, |
419 saction = ParserData.Actions.actions, |
419 saction = ParserData.Actions.actions, |
420 arg=arg, |
420 arg=arg, |
421 void= ParserData.Actions.void, |
421 void= ParserData.Actions.void, |
422 ec = {is_keyword = ParserData.EC.is_keyword, |
422 ec = {is_keyword = ParserData.EC.is_keyword, |
423 noShift = ParserData.EC.noShift, |
423 noShift = ParserData.EC.noShift, |
424 preferred_change = ParserData.EC.preferred_change, |
424 preferred_change = ParserData.EC.preferred_change, |
425 errtermvalue = ParserData.EC.errtermvalue, |
425 errtermvalue = ParserData.EC.errtermvalue, |
426 error=error, |
426 error=error, |
427 showTerminal = ParserData.EC.showTerminal, |
427 showTerminal = ParserData.EC.showTerminal, |
428 terms = ParserData.EC.terms}} |
428 terms = ParserData.EC.terms}} |
429 ) |
429 ) |
430 val sameToken = Token.sameToken |
430 val sameToken = Token.sameToken |
431 end; |
431 end; |
432 |
432 |
433 (**** Original file: lrtable.sml ****) |
433 (**** Original file: lrtable.sml ****) |
434 |
434 |
435 (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) |
435 (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *) |
436 structure LrTable : LR_TABLE = |
436 structure LrTable : LR_TABLE = |
437 struct |
437 struct |
438 open Array List |
438 open Array List |
439 infix 9 sub |
439 infix 9 sub |
440 datatype ('a,'b) pairlist = EMPTY |
440 datatype ('a,'b) pairlist = EMPTY |
441 | PAIR of 'a * 'b * ('a,'b) pairlist |
441 | PAIR of 'a * 'b * ('a,'b) pairlist |
442 datatype term = T of int |
442 datatype term = T of int |
443 datatype nonterm = NT of int |
443 datatype nonterm = NT of int |
444 datatype state = STATE of int |
444 datatype state = STATE of int |
445 datatype action = SHIFT of state |
445 datatype action = SHIFT of state |
446 | REDUCE of int (* rulenum from grammar *) |
446 | REDUCE of int (* rulenum from grammar *) |
447 | ACCEPT |
447 | ACCEPT |
448 | ERROR |
448 | ERROR |
449 exception Goto of state * nonterm |
449 exception Goto of state * nonterm |
450 type table = {states: int, rules : int,initialState: state, |
450 type table = {states: int, rules : int,initialState: state, |
451 action: ((term,action) pairlist * action) array, |
451 action: ((term,action) pairlist * action) array, |
452 goto : (nonterm,state) pairlist array} |
452 goto : (nonterm,state) pairlist array} |
453 val numStates = fn ({states,...} : table) => states |
453 val numStates = fn ({states,...} : table) => states |
454 val numRules = fn ({rules,...} : table) => rules |
454 val numRules = fn ({rules,...} : table) => rules |
455 val describeActions = |
455 val describeActions = |
456 fn ({action,...} : table) => |
456 fn ({action,...} : table) => |
457 fn (STATE s) => action sub s |
457 fn (STATE s) => action sub s |
458 val describeGoto = |
458 val describeGoto = |
459 fn ({goto,...} : table) => |
459 fn ({goto,...} : table) => |
460 fn (STATE s) => goto sub s |
460 fn (STATE s) => goto sub s |
461 fun findTerm (T term,row,default) = |
461 fun findTerm (T term,row,default) = |
462 let fun find (PAIR (T key,data,r)) = |
462 let fun find (PAIR (T key,data,r)) = |
463 if key < term then find r |
463 if key < term then find r |
464 else if key=term then data |
464 else if key=term then data |
465 else default |
465 else default |
466 | find EMPTY = default |
466 | find EMPTY = default |
467 in find row |
467 in find row |
468 end |
468 end |
469 fun findNonterm (NT nt,row) = |
469 fun findNonterm (NT nt,row) = |
470 let fun find (PAIR (NT key,data,r)) = |
470 let fun find (PAIR (NT key,data,r)) = |
471 if key < nt then find r |
471 if key < nt then find r |
472 else if key=nt then SOME data |
472 else if key=nt then SOME data |
473 else NONE |
473 else NONE |
474 | find EMPTY = NONE |
474 | find EMPTY = NONE |
475 in find row |
475 in find row |
476 end |
476 end |
477 val action = fn ({action,...} : table) => |
477 val action = fn ({action,...} : table) => |
478 fn (STATE state,term) => |
478 fn (STATE state,term) => |
479 let val (row,default) = action sub state |
479 let val (row,default) = action sub state |
480 in findTerm(term,row,default) |
480 in findTerm(term,row,default) |
481 end |
481 end |
482 val goto = fn ({goto,...} : table) => |
482 val goto = fn ({goto,...} : table) => |
483 fn (a as (STATE state,nonterm)) => |
483 fn (a as (STATE state,nonterm)) => |
484 case findNonterm(nonterm,goto sub state) |
484 case findNonterm(nonterm,goto sub state) |
485 of SOME state => state |
485 of SOME state => state |
486 | NONE => raise (Goto a) |
486 | NONE => raise (Goto a) |
487 val initialState = fn ({initialState,...} : table) => initialState |
487 val initialState = fn ({initialState,...} : table) => initialState |
488 val mkLrTable = fn {actions,gotos,initialState,numStates,numRules} => |
488 val mkLrTable = fn {actions,gotos,initialState,numStates,numRules} => |
489 ({action=actions,goto=gotos, |
489 ({action=actions,goto=gotos, |
490 states=numStates, |
490 states=numStates, |
491 rules=numRules, |
491 rules=numRules, |
492 initialState=initialState} : table) |
492 initialState=initialState} : table) |
493 end; |
493 end; |
494 |
494 |
495 (**** Original file: stream.sml ****) |
495 (**** Original file: stream.sml ****) |
496 |
496 |
505 |
505 |
506 type 'a stream = 'a str Unsynchronized.ref |
506 type 'a stream = 'a str Unsynchronized.ref |
507 |
507 |
508 fun get(Unsynchronized.ref(EVAL t)) = t |
508 fun get(Unsynchronized.ref(EVAL t)) = t |
509 | get(s as Unsynchronized.ref(UNEVAL f)) = |
509 | get(s as Unsynchronized.ref(UNEVAL f)) = |
510 let val t = (f(), Unsynchronized.ref(UNEVAL f)) in s := EVAL t; t end |
510 let val t = (f(), Unsynchronized.ref(UNEVAL f)) in s := EVAL t; t end |
511 |
511 |
512 fun streamify f = Unsynchronized.ref(UNEVAL f) |
512 fun streamify f = Unsynchronized.ref(UNEVAL f) |
513 fun cons(a,s) = Unsynchronized.ref(EVAL(a,s)) |
513 fun cons(a,s) = Unsynchronized.ref(EVAL(a,s)) |
514 |
514 |
515 end; |
515 end; |
520 |
520 |
521 (* parser.sml: This is a parser driver for LR tables with an error-recovery |
521 (* parser.sml: This is a parser driver for LR tables with an error-recovery |
522 routine added to it. The routine used is described in detail in this |
522 routine added to it. The routine used is described in detail in this |
523 article: |
523 article: |
524 |
524 |
525 'A Practical Method for LR and LL Syntactic Error Diagnosis and |
525 'A Practical Method for LR and LL Syntactic Error Diagnosis and |
526 Recovery', by M. Burke and G. Fisher, ACM Transactions on |
526 Recovery', by M. Burke and G. Fisher, ACM Transactions on |
527 Programming Langauges and Systems, Vol. 9, No. 2, April 1987, |
527 Programming Langauges and Systems, Vol. 9, No. 2, April 1987, |
528 pp. 164-197. |
528 pp. 164-197. |
529 |
529 |
530 This program is an implementation is the partial, deferred method discussed |
530 This program is an implementation is the partial, deferred method discussed |
531 in the article. The algorithm and data structures used in the program |
531 in the article. The algorithm and data structures used in the program |
532 are described below. |
532 are described below. |
533 |
533 |
539 |
539 |
540 It also assumes that the lexer is a lazy stream. |
540 It also assumes that the lexer is a lazy stream. |
541 |
541 |
542 Data Structures: |
542 Data Structures: |
543 ---------------- |
543 ---------------- |
544 |
544 |
545 * The parser: |
545 * The parser: |
546 |
546 |
547 The state stack has the type |
547 The state stack has the type |
548 |
548 |
549 (state * (semantic value * line # * line #)) list |
549 (state * (semantic value * line # * line #)) list |
550 |
550 |
551 The parser keeps a queue of (state stack * lexer pair). A lexer pair |
551 The parser keeps a queue of (state stack * lexer pair). A lexer pair |
552 consists of a terminal * value pair and a lexer. This allows the |
552 consists of a terminal * value pair and a lexer. This allows the |
553 parser to reconstruct the states for terminals to the left of a |
553 parser to reconstruct the states for terminals to the left of a |
554 syntax error, and attempt to make error corrections there. |
554 syntax error, and attempt to make error corrections there. |
555 |
555 |
556 The queue consists of a pair of lists (x,y). New additions to |
556 The queue consists of a pair of lists (x,y). New additions to |
557 the queue are cons'ed onto y. The first element of x is the top |
557 the queue are cons'ed onto y. The first element of x is the top |
558 of the queue. If x is nil, then y is reversed and used |
558 of the queue. If x is nil, then y is reversed and used |
559 in place of x. |
559 in place of x. |
560 |
560 |
561 Algorithm: |
561 Algorithm: |
562 ---------- |
562 ---------- |
563 |
563 |
564 * The steady-state parser: |
564 * The steady-state parser: |
565 |
565 |
566 This parser keeps the length of the queue of state stacks at |
566 This parser keeps the length of the queue of state stacks at |
567 a steady state by always removing an element from the front when |
567 a steady state by always removing an element from the front when |
568 another element is placed on the end. |
568 another element is placed on the end. |
569 |
569 |
570 It has these arguments: |
570 It has these arguments: |
571 |
571 |
572 stack: current stack |
572 stack: current stack |
573 queue: value of the queue |
573 queue: value of the queue |
574 lexPair ((terminal,value),lex stream) |
574 lexPair ((terminal,value),lex stream) |
575 |
575 |
576 When SHIFT is encountered, the state to shift to and the value are |
576 When SHIFT is encountered, the state to shift to and the value are |
577 are pushed onto the state stack. The state stack and lexPair are |
577 are pushed onto the state stack. The state stack and lexPair are |
578 placed on the queue. The front element of the queue is removed. |
578 placed on the queue. The front element of the queue is removed. |
579 |
579 |
580 When REDUCTION is encountered, the rule is applied to the current |
580 When REDUCTION is encountered, the rule is applied to the current |
581 stack to yield a triple (nonterm,value,new stack). A new |
581 stack to yield a triple (nonterm,value,new stack). A new |
582 stack is formed by adding (goto(top state of stack,nonterm),value) |
582 stack is formed by adding (goto(top state of stack,nonterm),value) |
583 to the stack. |
583 to the stack. |
584 |
584 |
585 When ACCEPT is encountered, the top value from the stack and the |
585 When ACCEPT is encountered, the top value from the stack and the |
586 lexer are returned. |
586 lexer are returned. |
587 |
587 |
588 When an ERROR is encountered, fixError is called. FixError |
588 When an ERROR is encountered, fixError is called. FixError |
589 takes the arguments to the parser, fixes the error if possible and |
589 takes the arguments to the parser, fixes the error if possible and |
590 returns a new set of arguments. |
590 returns a new set of arguments. |
591 |
591 |
592 * The distance-parser: |
592 * The distance-parser: |
593 |
593 |
594 This parser includes an additional argument distance. It pushes |
594 This parser includes an additional argument distance. It pushes |
595 elements on the queue until it has parsed distance tokens, or an |
595 elements on the queue until it has parsed distance tokens, or an |
596 ACCEPT or ERROR occurs. It returns a stack, lexer, the number of |
596 ACCEPT or ERROR occurs. It returns a stack, lexer, the number of |
597 tokens left unparsed, a queue, and an action option. |
597 tokens left unparsed, a queue, and an action option. |
598 *) |
598 *) |
599 |
599 |
600 signature FIFO = |
600 signature FIFO = |
601 sig type 'a queue |
601 sig type 'a queue |
602 val empty : 'a queue |
602 val empty : 'a queue |
607 |
607 |
608 (* drt (12/15/89) -- the functor should be used in development work, but |
608 (* drt (12/15/89) -- the functor should be used in development work, but |
609 it wastes space in the release version. |
609 it wastes space in the release version. |
610 |
610 |
611 functor ParserGen(structure LrTable : LR_TABLE |
611 functor ParserGen(structure LrTable : LR_TABLE |
612 structure Stream : STREAM) : LR_PARSER = |
612 structure Stream : STREAM) : LR_PARSER = |
613 *) |
613 *) |
614 |
614 |
615 structure LrParser :> LR_PARSER = |
615 structure LrParser :> LR_PARSER = |
616 struct |
616 struct |
617 structure LrTable = LrTable |
617 structure LrTable = LrTable |
618 structure Stream = Stream |
618 structure Stream = Stream |
619 |
619 |
620 fun eqT (LrTable.T i, LrTable.T i') = i = i' |
620 fun eqT (LrTable.T i, LrTable.T i') = i = i' |
621 |
621 |
622 structure Token : TOKEN = |
622 structure Token : TOKEN = |
623 struct |
623 struct |
624 structure LrTable = LrTable |
624 structure LrTable = LrTable |
625 datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b) |
625 datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b) |
626 val sameToken = fn (TOKEN(t,_),TOKEN(t',_)) => eqT (t,t') |
626 val sameToken = fn (TOKEN(t,_),TOKEN(t',_)) => eqT (t,t') |
627 end |
627 end |
628 |
628 |
629 open LrTable |
629 open LrTable |
630 open Token |
630 open Token |
631 |
631 |
634 exception ParseError |
634 exception ParseError |
635 exception ParseImpossible of int |
635 exception ParseImpossible of int |
636 |
636 |
637 structure Fifo :> FIFO = |
637 structure Fifo :> FIFO = |
638 struct |
638 struct |
639 type 'a queue = ('a list * 'a list) |
639 type 'a queue = ('a list * 'a list) |
640 val empty = (nil,nil) |
640 val empty = (nil,nil) |
641 exception Empty |
641 exception Empty |
642 fun get(a::x, y) = (a, (x,y)) |
642 fun get(a::x, y) = (a, (x,y)) |
643 | get(nil, nil) = raise Empty |
643 | get(nil, nil) = raise Empty |
644 | get(nil, y) = get(rev y, nil) |
644 | get(nil, y) = get(rev y, nil) |
645 fun put(a,(x,y)) = (x,a::y) |
645 fun put(a,(x,y)) = (x,a::y) |
646 end |
646 end |
647 |
647 |
648 type ('a,'b) elem = (state * ('a * 'b * 'b)) |
648 type ('a,'b) elem = (state * ('a * 'b * 'b)) |
649 type ('a,'b) stack = ('a,'b) elem list |
649 type ('a,'b) stack = ('a,'b) elem list |
650 type ('a,'b) lexv = ('a,'b) token |
650 type ('a,'b) lexv = ('a,'b) token |
651 type ('a,'b) lexpair = ('a,'b) lexv * (('a,'b) lexv Stream.stream) |
651 type ('a,'b) lexpair = ('a,'b) lexv * (('a,'b) lexv Stream.stream) |
652 type ('a,'b) distanceParse = |
652 type ('a,'b) distanceParse = |
653 ('a,'b) lexpair * |
653 ('a,'b) lexpair * |
654 ('a,'b) stack * |
654 ('a,'b) stack * |
655 (('a,'b) stack * ('a,'b) lexpair) Fifo.queue * |
655 (('a,'b) stack * ('a,'b) lexpair) Fifo.queue * |
656 int -> |
656 int -> |
657 ('a,'b) lexpair * |
657 ('a,'b) lexpair * |
658 ('a,'b) stack * |
658 ('a,'b) stack * |
659 (('a,'b) stack * ('a,'b) lexpair) Fifo.queue * |
659 (('a,'b) stack * ('a,'b) lexpair) Fifo.queue * |
660 int * |
660 int * |
661 action option |
661 action option |
662 |
662 |
663 type ('a,'b) ecRecord = |
663 type ('a,'b) ecRecord = |
664 {is_keyword : term -> bool, |
664 {is_keyword : term -> bool, |
665 preferred_change : (term list * term list) list, |
665 preferred_change : (term list * term list) list, |
666 error : string * 'b * 'b -> unit, |
666 error : string * 'b * 'b -> unit, |
667 errtermvalue : term -> 'a, |
667 errtermvalue : term -> 'a, |
668 terms : term list, |
668 terms : term list, |
669 showTerminal : term -> string, |
669 showTerminal : term -> string, |
670 noShift : term -> bool} |
670 noShift : term -> bool} |
671 |
671 |
672 local |
672 local |
673 |
673 |
674 val println = fn s => (TextIO.print s; TextIO.print "\n") |
674 val println = fn s => (TextIO.print s; TextIO.print "\n") |
675 val showState = fn (STATE s) => "STATE " ^ (Int.toString s) |
675 val showState = fn (STATE s) => "STATE " ^ (Int.toString s) |
676 in |
676 in |
677 fun printStack(stack: ('a,'b) stack, n: int) = |
677 fun printStack(stack: ('a,'b) stack, n: int) = |
678 case stack |
678 case stack |
679 of (state,_) :: rest => |
679 of (state,_) :: rest => |
680 (TextIO.print("\t" ^ Int.toString n ^ ": "); |
680 (TextIO.print("\t" ^ Int.toString n ^ ": "); |
681 println(showState state); |
681 println(showState state); |
682 printStack(rest, n+1)) |
682 printStack(rest, n+1)) |
683 | nil => () |
683 | nil => () |
684 |
684 |
685 fun prAction showTerminal |
685 fun prAction showTerminal |
686 (stack as (state,_) :: _, next as (TOKEN (term,_),_), action) = |
686 (stack as (state,_) :: _, next as (TOKEN (term,_),_), action) = |
687 (println "Parse: state stack:"; |
687 (println "Parse: state stack:"; |
688 printStack(stack, 0); |
688 printStack(stack, 0); |
689 TextIO.print(" state=" |
689 TextIO.print(" state=" |
690 ^ showState state |
690 ^ showState state |
691 ^ " next=" |
691 ^ " next=" |
692 ^ showTerminal term |
692 ^ showTerminal term |
693 ^ " action=" |
693 ^ " action=" |
694 ); |
694 ); |
695 case action |
695 case action |
696 of SHIFT state => println ("SHIFT " ^ (showState state)) |
696 of SHIFT state => println ("SHIFT " ^ (showState state)) |
697 | REDUCE i => println ("REDUCE " ^ (Int.toString i)) |
697 | REDUCE i => println ("REDUCE " ^ (Int.toString i)) |
698 | ERROR => println "ERROR" |
698 | ERROR => println "ERROR" |
699 | ACCEPT => println "ACCEPT") |
699 | ACCEPT => println "ACCEPT") |
700 | prAction _ (_,_,action) = () |
700 | prAction _ (_,_,action) = () |
701 end |
701 end |
702 |
702 |
703 (* ssParse: parser which maintains the queue of (state * lexvalues) in a |
703 (* ssParse: parser which maintains the queue of (state * lexvalues) in a |
704 steady-state. It takes a table, showTerminal function, saction |
704 steady-state. It takes a table, showTerminal function, saction |
705 function, and fixError function. It parses until an ACCEPT is |
705 function, and fixError function. It parses until an ACCEPT is |
706 encountered, or an exception is raised. When an error is encountered, |
706 encountered, or an exception is raised. When an error is encountered, |
707 fixError is called with the arguments of parseStep (lexv,stack,and |
707 fixError is called with the arguments of parseStep (lexv,stack,and |
708 queue). It returns the lexv, and a new stack and queue adjusted so |
708 queue). It returns the lexv, and a new stack and queue adjusted so |
709 that the lexv can be parsed *) |
709 that the lexv can be parsed *) |
710 |
710 |
711 val ssParse = |
711 val ssParse = |
712 fn (table,showTerminal,saction,fixError,arg) => |
712 fn (table,showTerminal,saction,fixError,arg) => |
713 let val prAction = prAction showTerminal |
713 let val prAction = prAction showTerminal |
714 val action = LrTable.action table |
714 val action = LrTable.action table |
715 val goto = LrTable.goto table |
715 val goto = LrTable.goto table |
716 fun parseStep(args as |
716 fun parseStep(args as |
717 (lexPair as (TOKEN (terminal, value as (_,leftPos,_)), |
717 (lexPair as (TOKEN (terminal, value as (_,leftPos,_)), |
718 lexer |
718 lexer |
719 ), |
719 ), |
720 stack as (state,_) :: _, |
720 stack as (state,_) :: _, |
721 queue)) = |
721 queue)) = |
722 let val nextAction = action (state,terminal) |
722 let val nextAction = action (state,terminal) |
723 val _ = if DEBUG1 then prAction(stack,lexPair,nextAction) |
723 val _ = if DEBUG1 then prAction(stack,lexPair,nextAction) |
724 else () |
724 else () |
725 in case nextAction |
725 in case nextAction |
726 of SHIFT s => |
726 of SHIFT s => |
727 let val newStack = (s,value) :: stack |
727 let val newStack = (s,value) :: stack |
728 val newLexPair = Stream.get lexer |
728 val newLexPair = Stream.get lexer |
729 val (_,newQueue) =Fifo.get(Fifo.put((newStack,newLexPair), |
729 val (_,newQueue) =Fifo.get(Fifo.put((newStack,newLexPair), |
730 queue)) |
730 queue)) |
731 in parseStep(newLexPair,(s,value)::stack,newQueue) |
731 in parseStep(newLexPair,(s,value)::stack,newQueue) |
732 end |
732 end |
733 | REDUCE i => |
733 | REDUCE i => |
734 (case saction(i,leftPos,stack,arg) |
734 (case saction(i,leftPos,stack,arg) |
735 of (nonterm,value,stack as (state,_) :: _) => |
735 of (nonterm,value,stack as (state,_) :: _) => |
736 parseStep(lexPair,(goto(state,nonterm),value)::stack, |
736 parseStep(lexPair,(goto(state,nonterm),value)::stack, |
737 queue) |
737 queue) |
738 | _ => raise (ParseImpossible 197)) |
738 | _ => raise (ParseImpossible 197)) |
739 | ERROR => parseStep(fixError args) |
739 | ERROR => parseStep(fixError args) |
740 | ACCEPT => |
740 | ACCEPT => |
741 (case stack |
741 (case stack |
742 of (_,(topvalue,_,_)) :: _ => |
742 of (_,(topvalue,_,_)) :: _ => |
743 let val (token,restLexer) = lexPair |
743 let val (token,restLexer) = lexPair |
744 in (topvalue,Stream.cons(token,restLexer)) |
744 in (topvalue,Stream.cons(token,restLexer)) |
745 end |
745 end |
746 | _ => raise (ParseImpossible 202)) |
746 | _ => raise (ParseImpossible 202)) |
747 end |
747 end |
748 | parseStep _ = raise (ParseImpossible 204) |
748 | parseStep _ = raise (ParseImpossible 204) |
749 in parseStep |
749 in parseStep |
750 end |
750 end |
751 |
751 |
752 (* distanceParse: parse until n tokens are shifted, or accept or |
752 (* distanceParse: parse until n tokens are shifted, or accept or |
753 error are encountered. Takes a table, showTerminal function, and |
753 error are encountered. Takes a table, showTerminal function, and |
754 semantic action function. Returns a parser which takes a lexPair |
754 semantic action function. Returns a parser which takes a lexPair |
755 (lex result * lexer), a state stack, a queue, and a distance |
755 (lex result * lexer), a state stack, a queue, and a distance |
756 (must be > 0) to parse. The parser returns a new lex-value, a stack |
756 (must be > 0) to parse. The parser returns a new lex-value, a stack |
757 with the nth token shifted on top, a queue, a distance, and action |
757 with the nth token shifted on top, a queue, a distance, and action |
758 option. *) |
758 option. *) |
759 |
759 |
760 val distanceParse = |
760 val distanceParse = |
761 fn (table,showTerminal,saction,arg) => |
761 fn (table,showTerminal,saction,arg) => |
762 let val prAction = prAction showTerminal |
762 let val prAction = prAction showTerminal |
763 val action = LrTable.action table |
763 val action = LrTable.action table |
764 val goto = LrTable.goto table |
764 val goto = LrTable.goto table |
765 fun parseStep(lexPair,stack,queue,0) = (lexPair,stack,queue,0,NONE) |
765 fun parseStep(lexPair,stack,queue,0) = (lexPair,stack,queue,0,NONE) |
766 | parseStep(lexPair as (TOKEN (terminal, value as (_,leftPos,_)), |
766 | parseStep(lexPair as (TOKEN (terminal, value as (_,leftPos,_)), |
767 lexer |
767 lexer |
768 ), |
768 ), |
769 stack as (state,_) :: _, |
769 stack as (state,_) :: _, |
770 queue,distance) = |
770 queue,distance) = |
771 let val nextAction = action(state,terminal) |
771 let val nextAction = action(state,terminal) |
772 val _ = if DEBUG1 then prAction(stack,lexPair,nextAction) |
772 val _ = if DEBUG1 then prAction(stack,lexPair,nextAction) |
773 else () |
773 else () |
774 in case nextAction |
774 in case nextAction |
775 of SHIFT s => |
775 of SHIFT s => |
776 let val newStack = (s,value) :: stack |
776 let val newStack = (s,value) :: stack |
777 val newLexPair = Stream.get lexer |
777 val newLexPair = Stream.get lexer |
778 in parseStep(newLexPair,(s,value)::stack, |
778 in parseStep(newLexPair,(s,value)::stack, |
779 Fifo.put((newStack,newLexPair),queue),distance-1) |
779 Fifo.put((newStack,newLexPair),queue),distance-1) |
780 end |
780 end |
781 | REDUCE i => |
781 | REDUCE i => |
782 (case saction(i,leftPos,stack,arg) |
782 (case saction(i,leftPos,stack,arg) |
783 of (nonterm,value,stack as (state,_) :: _) => |
783 of (nonterm,value,stack as (state,_) :: _) => |
784 parseStep(lexPair,(goto(state,nonterm),value)::stack, |
784 parseStep(lexPair,(goto(state,nonterm),value)::stack, |
785 queue,distance) |
785 queue,distance) |
786 | _ => raise (ParseImpossible 240)) |
786 | _ => raise (ParseImpossible 240)) |
787 | ERROR => (lexPair,stack,queue,distance,SOME nextAction) |
787 | ERROR => (lexPair,stack,queue,distance,SOME nextAction) |
788 | ACCEPT => (lexPair,stack,queue,distance,SOME nextAction) |
788 | ACCEPT => (lexPair,stack,queue,distance,SOME nextAction) |
789 end |
789 end |
790 | parseStep _ = raise (ParseImpossible 242) |
790 | parseStep _ = raise (ParseImpossible 242) |
791 in parseStep : ('_a,'_b) distanceParse |
791 in parseStep : ('_a,'_b) distanceParse |
792 end |
792 end |
793 |
793 |
794 (* mkFixError: function to create fixError function which adjusts parser state |
794 (* mkFixError: function to create fixError function which adjusts parser state |
795 so that parse may continue in the presence of an error *) |
795 so that parse may continue in the presence of an error *) |
796 |
796 |
797 fun mkFixError({is_keyword,terms,errtermvalue, |
797 fun mkFixError({is_keyword,terms,errtermvalue, |
798 preferred_change,noShift, |
798 preferred_change,noShift, |
799 showTerminal,error,...} : ('_a,'_b) ecRecord, |
799 showTerminal,error,...} : ('_a,'_b) ecRecord, |
800 distanceParse : ('_a,'_b) distanceParse, |
800 distanceParse : ('_a,'_b) distanceParse, |
801 minAdvance,maxAdvance) |
801 minAdvance,maxAdvance) |
802 |
802 |
803 (lexv as (TOKEN (term,value as (_,leftPos,_)),_),stack,queue) = |
803 (lexv as (TOKEN (term,value as (_,leftPos,_)),_),stack,queue) = |
804 let val _ = if DEBUG2 then |
804 let val _ = if DEBUG2 then |
805 error("syntax error found at " ^ (showTerminal term), |
805 error("syntax error found at " ^ (showTerminal term), |
806 leftPos,leftPos) |
806 leftPos,leftPos) |
807 else () |
807 else () |
808 |
808 |
809 fun tokAt(t,p) = TOKEN(t,(errtermvalue t,p,p)) |
809 fun tokAt(t,p) = TOKEN(t,(errtermvalue t,p,p)) |
810 |
810 |
811 val minDelta = 3 |
811 val minDelta = 3 |
812 |
812 |
813 (* pull all the state * lexv elements from the queue *) |
813 (* pull all the state * lexv elements from the queue *) |
814 |
814 |
815 val stateList = |
815 val stateList = |
816 let fun f q = let val (elem,newQueue) = Fifo.get q |
816 let fun f q = let val (elem,newQueue) = Fifo.get q |
817 in elem :: (f newQueue) |
817 in elem :: (f newQueue) |
818 end handle Fifo.Empty => nil |
818 end handle Fifo.Empty => nil |
819 in f queue |
819 in f queue |
820 end |
820 end |
821 |
821 |
822 (* now number elements of stateList, giving distance from |
822 (* now number elements of stateList, giving distance from |
823 error token *) |
823 error token *) |
824 |
824 |
825 val (_, numStateList) = |
825 val (_, numStateList) = |
826 List.foldr (fn (a,(num,r)) => (num+1,(a,num)::r)) (0, []) stateList |
826 List.foldr (fn (a,(num,r)) => (num+1,(a,num)::r)) (0, []) stateList |
827 |
827 |
828 (* Represent the set of potential changes as a linked list. |
828 (* Represent the set of potential changes as a linked list. |
829 |
829 |
830 Values of datatype Change hold information about a potential change. |
830 Values of datatype Change hold information about a potential change. |
831 |
831 |
832 oper = oper to be applied |
832 oper = oper to be applied |
833 pos = the # of the element in stateList that would be altered. |
833 pos = the # of the element in stateList that would be altered. |
834 distance = the number of tokens beyond the error token which the |
834 distance = the number of tokens beyond the error token which the |
835 change allows us to parse. |
835 change allows us to parse. |
836 new = new terminal * value pair at that point |
836 new = new terminal * value pair at that point |
837 orig = original terminal * value pair at the point being changed. |
837 orig = original terminal * value pair at the point being changed. |
838 *) |
838 *) |
839 |
839 |
840 datatype ('a,'b) change = CHANGE of |
840 datatype ('a,'b) change = CHANGE of |
841 {pos : int, distance : int, leftPos: 'b, rightPos: 'b, |
841 {pos : int, distance : int, leftPos: 'b, rightPos: 'b, |
842 new : ('a,'b) lexv list, orig : ('a,'b) lexv list} |
842 new : ('a,'b) lexv list, orig : ('a,'b) lexv list} |
843 |
843 |
844 |
844 |
845 val showTerms = String.concat o map (fn TOKEN(t,_) => " " ^ showTerminal t) |
845 val showTerms = String.concat o map (fn TOKEN(t,_) => " " ^ showTerminal t) |
846 |
846 |
847 val printChange = fn c => |
847 val printChange = fn c => |
848 let val CHANGE {distance,new,orig,pos,...} = c |
848 let val CHANGE {distance,new,orig,pos,...} = c |
849 in (TextIO.print ("{distance= " ^ (Int.toString distance)); |
849 in (TextIO.print ("{distance= " ^ (Int.toString distance)); |
850 TextIO.print (",orig ="); TextIO.print(showTerms orig); |
850 TextIO.print (",orig ="); TextIO.print(showTerms orig); |
851 TextIO.print (",new ="); TextIO.print(showTerms new); |
851 TextIO.print (",new ="); TextIO.print(showTerms new); |
852 TextIO.print (",pos= " ^ (Int.toString pos)); |
852 TextIO.print (",pos= " ^ (Int.toString pos)); |
853 TextIO.print "}\n") |
853 TextIO.print "}\n") |
854 end |
854 end |
855 |
855 |
856 val printChangeList = app printChange |
856 val printChangeList = app printChange |
857 |
857 |
858 (* parse: given a lexPair, a stack, and the distance from the error |
858 (* parse: given a lexPair, a stack, and the distance from the error |
859 token, return the distance past the error token that we are able to parse.*) |
859 token, return the distance past the error token that we are able to parse.*) |
860 |
860 |
861 fun parse (lexPair,stack,queuePos : int) = |
861 fun parse (lexPair,stack,queuePos : int) = |
862 case distanceParse(lexPair,stack,Fifo.empty,queuePos+maxAdvance+1) |
862 case distanceParse(lexPair,stack,Fifo.empty,queuePos+maxAdvance+1) |
863 of (_,_,_,distance,SOME ACCEPT) => |
863 of (_,_,_,distance,SOME ACCEPT) => |
864 if maxAdvance-distance-1 >= 0 |
864 if maxAdvance-distance-1 >= 0 |
865 then maxAdvance |
865 then maxAdvance |
866 else maxAdvance-distance-1 |
866 else maxAdvance-distance-1 |
867 | (_,_,_,distance,_) => maxAdvance - distance - 1 |
867 | (_,_,_,distance,_) => maxAdvance - distance - 1 |
868 |
868 |
869 (* catList: concatenate results of scanning list *) |
869 (* catList: concatenate results of scanning list *) |
870 |
870 |
871 fun catList l f = List.foldr (fn(a,r)=> f a @ r) [] l |
871 fun catList l f = List.foldr (fn(a,r)=> f a @ r) [] l |
872 |
872 |
873 fun keywordsDelta new = if List.exists (fn(TOKEN(t,_))=>is_keyword t) new |
873 fun keywordsDelta new = if List.exists (fn(TOKEN(t,_))=>is_keyword t) new |
874 then minDelta else 0 |
874 then minDelta else 0 |
875 |
875 |
876 fun tryChange{lex,stack,pos,leftPos,rightPos,orig,new} = |
876 fun tryChange{lex,stack,pos,leftPos,rightPos,orig,new} = |
877 let val lex' = List.foldr (fn (t',p)=>(t',Stream.cons p)) lex new |
877 let val lex' = List.foldr (fn (t',p)=>(t',Stream.cons p)) lex new |
878 val distance = parse(lex',stack,pos+length new-length orig) |
878 val distance = parse(lex',stack,pos+length new-length orig) |
879 in if distance >= minAdvance + keywordsDelta new |
879 in if distance >= minAdvance + keywordsDelta new |
880 then [CHANGE{pos=pos,leftPos=leftPos,rightPos=rightPos, |
880 then [CHANGE{pos=pos,leftPos=leftPos,rightPos=rightPos, |
881 distance=distance,orig=orig,new=new}] |
881 distance=distance,orig=orig,new=new}] |
882 else [] |
882 else [] |
883 end |
883 end |
884 |
884 |
885 |
885 |
886 (* tryDelete: Try to delete n terminals. |
886 (* tryDelete: Try to delete n terminals. |
887 Return single-element [success] or nil. |
887 Return single-element [success] or nil. |
888 Do not delete unshiftable terminals. *) |
888 Do not delete unshiftable terminals. *) |
889 |
889 |
890 |
890 |
891 fun tryDelete n ((stack,lexPair as (TOKEN(term,(_,l,r)),_)),qPos) = |
891 fun tryDelete n ((stack,lexPair as (TOKEN(term,(_,l,r)),_)),qPos) = |
892 let fun del(0,accum,left,right,lexPair) = |
892 let fun del(0,accum,left,right,lexPair) = |
893 tryChange{lex=lexPair,stack=stack, |
893 tryChange{lex=lexPair,stack=stack, |
894 pos=qPos,leftPos=left,rightPos=right, |
894 pos=qPos,leftPos=left,rightPos=right, |
895 orig=rev accum, new=[]} |
895 orig=rev accum, new=[]} |
896 | del(n,accum,left,right,(tok as TOKEN(term,(_,_,r)),lexer)) = |
896 | del(n,accum,left,right,(tok as TOKEN(term,(_,_,r)),lexer)) = |
897 if noShift term then [] |
897 if noShift term then [] |
898 else del(n-1,tok::accum,left,r,Stream.get lexer) |
898 else del(n-1,tok::accum,left,r,Stream.get lexer) |
899 in del(n,[],l,r,lexPair) |
899 in del(n,[],l,r,lexPair) |
900 end |
900 end |
901 |
901 |
902 (* tryInsert: try to insert tokens before the current terminal; |
902 (* tryInsert: try to insert tokens before the current terminal; |
903 return a list of the successes *) |
903 return a list of the successes *) |
904 |
904 |
905 fun tryInsert((stack,lexPair as (TOKEN(_,(_,l,_)),_)),queuePos) = |
905 fun tryInsert((stack,lexPair as (TOKEN(_,(_,l,_)),_)),queuePos) = |
906 catList terms (fn t => |
906 catList terms (fn t => |
907 tryChange{lex=lexPair,stack=stack, |
907 tryChange{lex=lexPair,stack=stack, |
908 pos=queuePos,orig=[],new=[tokAt(t,l)], |
908 pos=queuePos,orig=[],new=[tokAt(t,l)], |
909 leftPos=l,rightPos=l}) |
909 leftPos=l,rightPos=l}) |
910 |
910 |
911 (* trySubst: try to substitute tokens for the current terminal; |
911 (* trySubst: try to substitute tokens for the current terminal; |
912 return a list of the successes *) |
912 return a list of the successes *) |
913 |
913 |
914 fun trySubst ((stack,lexPair as (orig as TOKEN (term,(_,l,r)),lexer)), |
914 fun trySubst ((stack,lexPair as (orig as TOKEN (term,(_,l,r)),lexer)), |
915 queuePos) = |
915 queuePos) = |
916 if noShift term then [] |
916 if noShift term then [] |
917 else |
917 else |
918 catList terms (fn t => |
918 catList terms (fn t => |
919 tryChange{lex=Stream.get lexer,stack=stack, |
919 tryChange{lex=Stream.get lexer,stack=stack, |
920 pos=queuePos, |
920 pos=queuePos, |
921 leftPos=l,rightPos=r,orig=[orig], |
921 leftPos=l,rightPos=r,orig=[orig], |
922 new=[tokAt(t,r)]}) |
922 new=[tokAt(t,r)]}) |
923 |
923 |
924 (* do_delete(toks,lexPair) tries to delete tokens "toks" from "lexPair". |
924 (* do_delete(toks,lexPair) tries to delete tokens "toks" from "lexPair". |
925 If it succeeds, returns SOME(toks',l,r,lp), where |
925 If it succeeds, returns SOME(toks',l,r,lp), where |
926 toks' is the actual tokens (with positions and values) deleted, |
926 toks' is the actual tokens (with positions and values) deleted, |
927 (l,r) are the (leftmost,rightmost) position of toks', |
927 (l,r) are the (leftmost,rightmost) position of toks', |
928 lp is what remains of the stream after deletion |
928 lp is what remains of the stream after deletion |
929 *) |
929 *) |
930 fun do_delete(nil,lp as (TOKEN(_,(_,l,_)),_)) = SOME(nil,l,l,lp) |
930 fun do_delete(nil,lp as (TOKEN(_,(_,l,_)),_)) = SOME(nil,l,l,lp) |
931 | do_delete([t],(tok as TOKEN(t',(_,l,r)),lp')) = |
931 | do_delete([t],(tok as TOKEN(t',(_,l,r)),lp')) = |
932 if eqT (t, t') |
932 if eqT (t, t') |
933 then SOME([tok],l,r,Stream.get lp') |
933 then SOME([tok],l,r,Stream.get lp') |
934 else NONE |
934 else NONE |
935 | do_delete(t::rest,(tok as TOKEN(t',(_,l,r)),lp')) = |
935 | do_delete(t::rest,(tok as TOKEN(t',(_,l,r)),lp')) = |
936 if eqT (t,t') |
936 if eqT (t,t') |
937 then case do_delete(rest,Stream.get lp') |
937 then case do_delete(rest,Stream.get lp') |
938 of SOME(deleted,l',r',lp'') => |
938 of SOME(deleted,l',r',lp'') => |
939 SOME(tok::deleted,l,r',lp'') |
939 SOME(tok::deleted,l,r',lp'') |
940 | NONE => NONE |
940 | NONE => NONE |
941 else NONE |
941 else NONE |
942 |
942 |
943 fun tryPreferred((stack,lexPair),queuePos) = |
943 fun tryPreferred((stack,lexPair),queuePos) = |
944 catList preferred_change (fn (delete,insert) => |
944 catList preferred_change (fn (delete,insert) => |
945 if List.exists noShift delete then [] (* should give warning at |
945 if List.exists noShift delete then [] (* should give warning at |
946 parser-generation time *) |
946 parser-generation time *) |
947 else case do_delete(delete,lexPair) |
947 else case do_delete(delete,lexPair) |
948 of SOME(deleted,l,r,lp) => |
948 of SOME(deleted,l,r,lp) => |
949 tryChange{lex=lp,stack=stack,pos=queuePos, |
949 tryChange{lex=lp,stack=stack,pos=queuePos, |
950 leftPos=l,rightPos=r,orig=deleted, |
950 leftPos=l,rightPos=r,orig=deleted, |
951 new=map (fn t=>(tokAt(t,r))) insert} |
951 new=map (fn t=>(tokAt(t,r))) insert} |
952 | NONE => []) |
952 | NONE => []) |
953 |
953 |
954 val changes = catList numStateList tryPreferred @ |
954 val changes = catList numStateList tryPreferred @ |
955 catList numStateList tryInsert @ |
955 catList numStateList tryInsert @ |
956 catList numStateList trySubst @ |
956 catList numStateList trySubst @ |
957 catList numStateList (tryDelete 1) @ |
957 catList numStateList (tryDelete 1) @ |
958 catList numStateList (tryDelete 2) @ |
958 catList numStateList (tryDelete 2) @ |
959 catList numStateList (tryDelete 3) |
959 catList numStateList (tryDelete 3) |
960 |
960 |
961 val findMaxDist = fn l => |
961 val findMaxDist = fn l => |
962 List.foldr (fn (CHANGE {distance,...},high) => Int.max(distance,high)) 0 l |
962 List.foldr (fn (CHANGE {distance,...},high) => Int.max(distance,high)) 0 l |
963 |
963 |
964 (* maxDist: max distance past error taken that we could parse *) |
964 (* maxDist: max distance past error taken that we could parse *) |
965 |
965 |
966 val maxDist = findMaxDist changes |
966 val maxDist = findMaxDist changes |
967 |
967 |
968 (* remove changes which did not parse maxDist tokens past the error token *) |
968 (* remove changes which did not parse maxDist tokens past the error token *) |
969 |
969 |
970 val changes = catList changes |
970 val changes = catList changes |
971 (fn(c as CHANGE{distance,...}) => |
971 (fn(c as CHANGE{distance,...}) => |
972 if distance=maxDist then [c] else []) |
972 if distance=maxDist then [c] else []) |
973 |
973 |
974 in case changes |
974 in case changes |
975 of (l as change :: _) => |
975 of (l as change :: _) => |
976 let fun print_msg (CHANGE {new,orig,leftPos,rightPos,...}) = |
976 let fun print_msg (CHANGE {new,orig,leftPos,rightPos,...}) = |
977 let val s = |
977 let val s = |
978 case (orig,new) |
978 case (orig,new) |
979 of (_::_,[]) => "deleting " ^ (showTerms orig) |
979 of (_::_,[]) => "deleting " ^ (showTerms orig) |
980 | ([],_::_) => "inserting " ^ (showTerms new) |
980 | ([],_::_) => "inserting " ^ (showTerms new) |
981 | _ => "replacing " ^ (showTerms orig) ^ |
981 | _ => "replacing " ^ (showTerms orig) ^ |
982 " with " ^ (showTerms new) |
982 " with " ^ (showTerms new) |
983 in error ("syntax error: " ^ s,leftPos,rightPos) |
983 in error ("syntax error: " ^ s,leftPos,rightPos) |
984 end |
984 end |
985 |
985 |
986 val _ = |
986 val _ = |
987 (if length l > 1 andalso DEBUG2 then |
987 (if length l > 1 andalso DEBUG2 then |
988 (TextIO.print "multiple fixes possible; could fix it by:\n"; |
988 (TextIO.print "multiple fixes possible; could fix it by:\n"; |
989 app print_msg l; |
989 app print_msg l; |
990 TextIO.print "chosen correction:\n") |
990 TextIO.print "chosen correction:\n") |
991 else (); |
991 else (); |
992 print_msg change) |
992 print_msg change) |
993 |
993 |
994 (* findNth: find nth queue entry from the error |
994 (* findNth: find nth queue entry from the error |
995 entry. Returns the Nth queue entry and the portion of |
995 entry. Returns the Nth queue entry and the portion of |
996 the queue from the beginning to the nth-1 entry. The |
996 the queue from the beginning to the nth-1 entry. The |
997 error entry is at the end of the queue. |
997 error entry is at the end of the queue. |
998 |
998 |
999 Examples: |
999 Examples: |
1000 |
1000 |
1001 queue = a b c d e |
1001 queue = a b c d e |
1002 findNth 0 = (e,a b c d) |
1002 findNth 0 = (e,a b c d) |
1003 findNth 1 = (d,a b c) |
1003 findNth 1 = (d,a b c) |
1004 *) |
1004 *) |
1005 |
1005 |
1006 val findNth = fn n => |
1006 val findNth = fn n => |
1007 let fun f (h::t,0) = (h,rev t) |
1007 let fun f (h::t,0) = (h,rev t) |
1008 | f (h::t,n) = f(t,n-1) |
1008 | f (h::t,n) = f(t,n-1) |
1009 | f (nil,_) = let exception FindNth |
1009 | f (nil,_) = let exception FindNth |
1010 in raise FindNth |
1010 in raise FindNth |
1011 end |
1011 end |
1012 in f (rev stateList,n) |
1012 in f (rev stateList,n) |
1013 end |
1013 end |
1014 |
1014 |
1015 val CHANGE {pos,orig,new,...} = change |
1015 val CHANGE {pos,orig,new,...} = change |
1016 val (last,queueFront) = findNth pos |
1016 val (last,queueFront) = findNth pos |
1017 val (stack,lexPair) = last |
1017 val (stack,lexPair) = last |
1018 |
1018 |
1019 val lp1 = List.foldl(fn (_,(_,r)) => Stream.get r) lexPair orig |
1019 val lp1 = List.foldl(fn (_,(_,r)) => Stream.get r) lexPair orig |
1020 val lp2 = List.foldr(fn(t,r)=>(t,Stream.cons r)) lp1 new |
1020 val lp2 = List.foldr(fn(t,r)=>(t,Stream.cons r)) lp1 new |
1021 |
1021 |
1022 val restQueue = |
1022 val restQueue = |
1023 Fifo.put((stack,lp2), |
1023 Fifo.put((stack,lp2), |
1024 List.foldl Fifo.put Fifo.empty queueFront) |
1024 List.foldl Fifo.put Fifo.empty queueFront) |
1025 |
1025 |
1026 val (lexPair,stack,queue,_,_) = |
1026 val (lexPair,stack,queue,_,_) = |
1027 distanceParse(lp2,stack,restQueue,pos) |
1027 distanceParse(lp2,stack,restQueue,pos) |
1028 |
1028 |
1029 in (lexPair,stack,queue) |
1029 in (lexPair,stack,queue) |
1030 end |
1030 end |
1031 | nil => (error("syntax error found at " ^ (showTerminal term), |
1031 | nil => (error("syntax error found at " ^ (showTerminal term), |
1032 leftPos,leftPos); raise ParseError) |
1032 leftPos,leftPos); raise ParseError) |
1033 end |
1033 end |
1034 |
1034 |
1035 val parse = fn {arg,table,lexer,saction,void,lookahead, |
1035 val parse = fn {arg,table,lexer,saction,void,lookahead, |
1036 ec=ec as {showTerminal,...} : ('_a,'_b) ecRecord} => |
1036 ec=ec as {showTerminal,...} : ('_a,'_b) ecRecord} => |
1037 let val distance = 15 (* defer distance tokens *) |
1037 let val distance = 15 (* defer distance tokens *) |
1038 val minAdvance = 1 (* must parse at least 1 token past error *) |
1038 val minAdvance = 1 (* must parse at least 1 token past error *) |
1039 val maxAdvance = Int.max(lookahead,0)(* max distance for parse check *) |
1039 val maxAdvance = Int.max(lookahead,0)(* max distance for parse check *) |
1040 val lexPair = Stream.get lexer |
1040 val lexPair = Stream.get lexer |
1041 val (TOKEN (_,(_,leftPos,_)),_) = lexPair |
1041 val (TOKEN (_,(_,leftPos,_)),_) = lexPair |
1042 val startStack = [(initialState table,(void,leftPos,leftPos))] |
1042 val startStack = [(initialState table,(void,leftPos,leftPos))] |
1043 val startQueue = Fifo.put((startStack,lexPair),Fifo.empty) |
1043 val startQueue = Fifo.put((startStack,lexPair),Fifo.empty) |
1044 val distanceParse = distanceParse(table,showTerminal,saction,arg) |
1044 val distanceParse = distanceParse(table,showTerminal,saction,arg) |
1045 val fixError = mkFixError(ec,distanceParse,minAdvance,maxAdvance) |
1045 val fixError = mkFixError(ec,distanceParse,minAdvance,maxAdvance) |
1046 val ssParse = ssParse(table,showTerminal,saction,fixError,arg) |
1046 val ssParse = ssParse(table,showTerminal,saction,fixError,arg) |
1047 fun loop (lexPair,stack,queue,_,SOME ACCEPT) = |
1047 fun loop (lexPair,stack,queue,_,SOME ACCEPT) = |
1048 ssParse(lexPair,stack,queue) |
1048 ssParse(lexPair,stack,queue) |
1049 | loop (lexPair,stack,queue,0,_) = ssParse(lexPair,stack,queue) |
1049 | loop (lexPair,stack,queue,0,_) = ssParse(lexPair,stack,queue) |
1050 | loop (lexPair,stack,queue,distance,SOME ERROR) = |
1050 | loop (lexPair,stack,queue,distance,SOME ERROR) = |
1051 let val (lexPair,stack,queue) = fixError(lexPair,stack,queue) |
1051 let val (lexPair,stack,queue) = fixError(lexPair,stack,queue) |
1052 in loop (distanceParse(lexPair,stack,queue,distance)) |
1052 in loop (distanceParse(lexPair,stack,queue,distance)) |
1053 end |
1053 end |
1054 | loop _ = let exception ParseInternal |
1054 | loop _ = let exception ParseInternal |
1055 in raise ParseInternal |
1055 in raise ParseInternal |
1056 end |
1056 end |
1057 in loop (distanceParse(lexPair,startStack,startQueue,distance)) |
1057 in loop (distanceParse(lexPair,startStack,startQueue,distance)) |
1058 end |
1058 end |
1059 end; |
1059 end; |
1060 |
1060 |
1061 ; |
1061 ; |