author | wenzelm |
Sat, 23 Jul 2011 16:37:17 +0200 | |
changeset 44818 | 9b00f09f7721 |
parent 30697 | dcb233670c98 |
child 44819 | 8f5add916a99 |
permissions | -rw-r--r-- |
wenzelm@24594 | 1 |
(* Title: Pure/ML/ml_parse.ML |
wenzelm@24594 | 2 |
Author: Makarius |
wenzelm@24594 | 3 |
|
wenzelm@24594 | 4 |
Minimal parsing for SML -- fixing integer numerals. |
wenzelm@24594 | 5 |
*) |
wenzelm@24594 | 6 |
|
wenzelm@24594 | 7 |
signature ML_PARSE = |
wenzelm@24594 | 8 |
sig |
wenzelm@24594 | 9 |
val fix_ints: string -> string |
wenzelm@30687 | 10 |
val global_context: use_context |
wenzelm@24594 | 11 |
end; |
wenzelm@24594 | 12 |
|
wenzelm@24594 | 13 |
structure ML_Parse: ML_PARSE = |
wenzelm@24594 | 14 |
struct |
wenzelm@24594 | 15 |
|
wenzelm@24594 | 16 |
(** error handling **) |
wenzelm@24594 | 17 |
|
wenzelm@24594 | 18 |
fun !!! scan = |
wenzelm@24594 | 19 |
let |
wenzelm@24594 | 20 |
fun get_pos [] = " (past end-of-file!)" |
wenzelm@30697 | 21 |
| get_pos (tok :: _) = Position.str_of (ML_Lex.pos_of tok); |
wenzelm@24594 | 22 |
|
wenzelm@44818 | 23 |
fun err (toks, NONE) = (fn () => "SML syntax error" ^ get_pos toks) |
wenzelm@44818 | 24 |
| err (toks, SOME msg) = (fn () => "SML syntax error" ^ get_pos toks ^ ": " ^ msg ()); |
wenzelm@24594 | 25 |
in Scan.!! err scan end; |
wenzelm@24594 | 26 |
|
wenzelm@24594 | 27 |
fun bad_input x = |
wenzelm@30697 | 28 |
(Scan.some (fn tok => (case ML_Lex.kind_of tok of ML_Lex.Error msg => SOME msg | _ => NONE)) :|-- |
wenzelm@44818 | 29 |
(fn msg => Scan.fail_with (K (fn () => msg)))) x; |
wenzelm@24594 | 30 |
|
wenzelm@24594 | 31 |
|
wenzelm@24594 | 32 |
(** basic parsers **) |
wenzelm@24594 | 33 |
|
wenzelm@27817 | 34 |
fun $$$ x = |
wenzelm@30697 | 35 |
Scan.one (fn tok => ML_Lex.kind_of tok = ML_Lex.Keyword andalso ML_Lex.content_of tok = x) |
wenzelm@30697 | 36 |
>> ML_Lex.content_of; |
wenzelm@24594 | 37 |
|
wenzelm@30697 | 38 |
val int = Scan.one (fn tok => ML_Lex.kind_of tok = ML_Lex.Int) >> ML_Lex.content_of; |
wenzelm@30697 | 39 |
|
wenzelm@30697 | 40 |
val regular = Scan.one ML_Lex.is_regular >> ML_Lex.content_of; |
wenzelm@30697 | 41 |
val improper = Scan.one ML_Lex.is_improper >> ML_Lex.content_of; |
wenzelm@24594 | 42 |
|
wenzelm@24594 | 43 |
val blanks = Scan.repeat improper >> implode; |
wenzelm@24594 | 44 |
|
wenzelm@24594 | 45 |
|
wenzelm@24594 | 46 |
(* fix_ints *) |
wenzelm@24594 | 47 |
|
wenzelm@24594 | 48 |
(*approximation only -- corrupts numeric record field patterns *) |
wenzelm@24594 | 49 |
val fix_int = |
wenzelm@24594 | 50 |
$$$ "#" ^^ blanks ^^ int || |
wenzelm@24594 | 51 |
($$$ "infix" || $$$ "infixr") ^^ blanks ^^ int || |
wenzelm@24594 | 52 |
int >> (fn x => "(" ^ x ^ ":int)") || |
wenzelm@24594 | 53 |
regular || |
wenzelm@24594 | 54 |
bad_input; |
wenzelm@24594 | 55 |
|
wenzelm@24594 | 56 |
fun do_fix_ints s = |
wenzelm@24594 | 57 |
Source.of_string s |
wenzelm@30697 | 58 |
|> ML_Lex.source |
wenzelm@30697 | 59 |
|> Source.source ML_Lex.stopper (Scan.bulk (!!! fix_int)) NONE |
wenzelm@24594 | 60 |
|> Source.exhaust |
wenzelm@24594 | 61 |
|> implode; |
wenzelm@24594 | 62 |
|
wenzelm@24594 | 63 |
val fix_ints = if ml_system_fix_ints then do_fix_ints else I; |
wenzelm@24594 | 64 |
|
wenzelm@30687 | 65 |
|
wenzelm@30687 | 66 |
(* global use_context *) |
wenzelm@30687 | 67 |
|
wenzelm@30687 | 68 |
val global_context: use_context = |
wenzelm@30687 | 69 |
{tune_source = fix_ints, |
wenzelm@30687 | 70 |
name_space = ML_Name_Space.global, |
wenzelm@30687 | 71 |
str_of_pos = Position.str_of oo Position.line_file, |
wenzelm@30687 | 72 |
print = writeln, |
wenzelm@30687 | 73 |
error = error}; |
wenzelm@30687 | 74 |
|
wenzelm@24594 | 75 |
end; |