467 processS [] states ([], []) |
466 processS [] states ([], []) |
468 end; |
467 end; |
469 |
468 |
470 |
469 |
471 |
470 |
472 fun syntax_error toks = |
471 fun syntax_error toks allowed = |
473 error ("Syntax error at: " ^ quote (space_implode " " (map str_of_token toks))); |
472 error |
474 |
473 ((if toks = [] then |
475 fun produce stateset i indata = |
474 "error: unexpected end of input\n" |
|
475 else |
|
476 "Syntax error at: " ^ quote (space_implode " " (map str_of_token toks)) |
|
477 ^ "\n") |
|
478 ^ "Expected tokens: " |
|
479 ^ space_implode ", " (map (quote o str_of_token) allowed)); |
|
480 |
|
481 fun produce stateset i indata prev_token = |
|
482 (*the argument prev_token is only used for error messages*) |
476 (case Array.sub (stateset, i) of |
483 (case Array.sub (stateset, i) of |
477 [] => syntax_error indata (* MMW *)(* FIXME *) |
484 [] => let (*compute a list of allowed starting tokens |
|
485 for a list of nonterminals*) |
|
486 fun get_starts [] = [] |
|
487 | get_starts (rhss_ref :: refs) = |
|
488 let fun get [] = [] |
|
489 | get ((Some tok, _) :: rhss) = |
|
490 tok :: (get rhss) |
|
491 | get ((None, _) :: rhss) = |
|
492 get rhss; |
|
493 in (get (!rhss_ref)) union (get_starts refs) end; |
|
494 |
|
495 val NTs = map (fn (_, _, _, Nonterm (a, _) :: _, _, _) => a) |
|
496 (filter (fn (_, _, _, Nonterm _ :: _, _, _) => true |
|
497 | _ => false) (Array.sub (stateset, i-1))); |
|
498 val allowed = get_starts NTs union |
|
499 (map (fn (_, _, _, Term a :: _, _, _) => a) |
|
500 (filter (fn (_, _, _, Term _ :: _, _, _) => true |
|
501 | _ => false) (Array.sub (stateset, i-1)))); |
|
502 (*terminals have to be searched for |
|
503 because of lambda productions*) |
|
504 in syntax_error (if prev_token = EndToken then indata |
|
505 else prev_token :: indata) allowed |
|
506 end |
478 | s => |
507 | s => |
479 (case indata of |
508 (case indata of |
480 [] => Array.sub (stateset, i) |
509 [] => Array.sub (stateset, i) |
481 | c :: cs => |
510 | c :: cs => |
482 let |
511 let |
483 val (si, sii) = PROCESSS stateset i c s; |
512 val (si, sii) = PROCESSS stateset i c s; |
484 in |
513 in |
485 Array.update (stateset, i, si); |
514 Array.update (stateset, i, si); |
486 Array.update (stateset, i + 1, sii); |
515 Array.update (stateset, i + 1, sii); |
487 produce stateset (i + 1) cs |
516 produce stateset (i + 1) cs c |
488 end)); |
517 end)); |
489 |
518 |
490 |
519 |
491 val get_trees = mapfilter (fn (_, _, [pt], _, _, _) => Some pt | _ => None); |
520 val get_trees = mapfilter (fn (_, _, [pt], _, _, _) => Some pt | _ => None); |
492 |
521 |