author | wenzelm |
Sat, 23 Jul 2011 17:22:28 +0200 | |
changeset 43948 | 8f5add916a99 |
parent 43947 | 9b00f09f7721 |
child 48911 | 5debc3e4fa81 |
permissions | -rw-r--r-- |
24594 | 1 |
(* Title: Pure/ML/ml_parse.ML |
2 |
Author: Makarius |
|
3 |
||
4 |
Minimal parsing for SML -- fixing integer numerals. |
|
5 |
*) |
|
6 |
||
7 |
signature ML_PARSE = |
|
8 |
sig |
|
9 |
val fix_ints: string -> string |
|
30672
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
10 |
val global_context: use_context |
24594 | 11 |
end; |
12 |
||
13 |
structure ML_Parse: ML_PARSE = |
|
14 |
struct |
|
15 |
||
16 |
(** error handling **) |
|
17 |
||
18 |
fun !!! scan = |
|
19 |
let |
|
20 |
fun get_pos [] = " (past end-of-file!)" |
|
30682
dcb233670c98
eliminated non-canonical alias structure T = ML_Lex;
wenzelm
parents:
30672
diff
changeset
|
21 |
| get_pos (tok :: _) = Position.str_of (ML_Lex.pos_of tok); |
24594 | 22 |
|
43947
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
wenzelm
parents:
30682
diff
changeset
|
23 |
fun err (toks, NONE) = (fn () => "SML syntax error" ^ get_pos toks) |
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
wenzelm
parents:
30682
diff
changeset
|
24 |
| err (toks, SOME msg) = (fn () => "SML syntax error" ^ get_pos toks ^ ": " ^ msg ()); |
24594 | 25 |
in Scan.!! err scan end; |
26 |
||
27 |
fun bad_input x = |
|
30682
dcb233670c98
eliminated non-canonical alias structure T = ML_Lex;
wenzelm
parents:
30672
diff
changeset
|
28 |
(Scan.some (fn tok => (case ML_Lex.kind_of tok of ML_Lex.Error msg => SOME msg | _ => NONE)) :|-- |
43947
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
wenzelm
parents:
30682
diff
changeset
|
29 |
(fn msg => Scan.fail_with (K (fn () => msg)))) x; |
24594 | 30 |
|
31 |
||
32 |
(** basic parsers **) |
|
33 |
||
27817 | 34 |
fun $$$ x = |
30682
dcb233670c98
eliminated non-canonical alias structure T = ML_Lex;
wenzelm
parents:
30672
diff
changeset
|
35 |
Scan.one (fn tok => ML_Lex.kind_of tok = ML_Lex.Keyword andalso ML_Lex.content_of tok = x) |
dcb233670c98
eliminated non-canonical alias structure T = ML_Lex;
wenzelm
parents:
30672
diff
changeset
|
36 |
>> ML_Lex.content_of; |
24594 | 37 |
|
30682
dcb233670c98
eliminated non-canonical alias structure T = ML_Lex;
wenzelm
parents:
30672
diff
changeset
|
38 |
val int = Scan.one (fn tok => ML_Lex.kind_of tok = ML_Lex.Int) >> ML_Lex.content_of; |
dcb233670c98
eliminated non-canonical alias structure T = ML_Lex;
wenzelm
parents:
30672
diff
changeset
|
39 |
|
dcb233670c98
eliminated non-canonical alias structure T = ML_Lex;
wenzelm
parents:
30672
diff
changeset
|
40 |
val regular = Scan.one ML_Lex.is_regular >> ML_Lex.content_of; |
dcb233670c98
eliminated non-canonical alias structure T = ML_Lex;
wenzelm
parents:
30672
diff
changeset
|
41 |
val improper = Scan.one ML_Lex.is_improper >> ML_Lex.content_of; |
24594 | 42 |
|
43 |
val blanks = Scan.repeat improper >> implode; |
|
44 |
||
45 |
||
46 |
(* fix_ints *) |
|
47 |
||
48 |
(*approximation only -- corrupts numeric record field patterns *) |
|
49 |
val fix_int = |
|
50 |
$$$ "#" ^^ blanks ^^ int || |
|
51 |
($$$ "infix" || $$$ "infixr") ^^ blanks ^^ int || |
|
52 |
int >> (fn x => "(" ^ x ^ ":int)") || |
|
53 |
regular || |
|
54 |
bad_input; |
|
55 |
||
43948 | 56 |
val fix_ints = |
57 |
ML_System.is_smlnj ? |
|
58 |
(Source.of_string #> |
|
59 |
ML_Lex.source #> |
|
60 |
Source.source ML_Lex.stopper (Scan.bulk (!!! fix_int)) NONE #> |
|
61 |
Source.exhaust #> |
|
62 |
implode); |
|
24594 | 63 |
|
30672
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
64 |
|
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
65 |
(* global use_context *) |
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
66 |
|
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
67 |
val global_context: use_context = |
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
68 |
{tune_source = fix_ints, |
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
69 |
name_space = ML_Name_Space.global, |
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
70 |
str_of_pos = Position.str_of oo Position.line_file, |
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
71 |
print = writeln, |
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
72 |
error = error}; |
beaadd5af500
more systematic type use_context, with particular values ML_Parse.global_context and ML_Context.local_context;
wenzelm
parents:
30636
diff
changeset
|
73 |
|
24594 | 74 |
end; |