berghofe@41809
|
1 |
(* Title: HOL/SPARK/Tools/fdl_parser.ML
|
berghofe@41809
|
2 |
Author: Stefan Berghofer
|
berghofe@41809
|
3 |
Copyright: secunet Security Networks AG
|
berghofe@41809
|
4 |
|
berghofe@41809
|
5 |
Parser for fdl files.
|
berghofe@41809
|
6 |
*)
|
berghofe@41809
|
7 |
|
berghofe@41809
|
8 |
signature FDL_PARSER =
|
berghofe@41809
|
9 |
sig
|
berghofe@41809
|
10 |
datatype expr =
|
berghofe@41809
|
11 |
Ident of string
|
berghofe@41809
|
12 |
| Number of int
|
berghofe@41809
|
13 |
| Quantifier of string * string list * string * expr
|
berghofe@41809
|
14 |
| Funct of string * expr list
|
berghofe@41809
|
15 |
| Element of expr * expr list
|
berghofe@41809
|
16 |
| Update of expr * expr list * expr
|
berghofe@41809
|
17 |
| Record of string * (string * expr) list
|
berghofe@41809
|
18 |
| Array of string * expr option *
|
berghofe@41809
|
19 |
((expr * expr option) list list * expr) list;
|
berghofe@41809
|
20 |
|
berghofe@41809
|
21 |
datatype fdl_type =
|
berghofe@41809
|
22 |
Basic_Type of string
|
berghofe@41809
|
23 |
| Enum_Type of string list
|
berghofe@41809
|
24 |
| Array_Type of string list * string
|
berghofe@41809
|
25 |
| Record_Type of (string list * string) list
|
berghofe@41809
|
26 |
| Pending_Type;
|
berghofe@41809
|
27 |
|
berghofe@41809
|
28 |
datatype fdl_rule =
|
berghofe@41809
|
29 |
Inference_Rule of expr list * expr
|
berghofe@41809
|
30 |
| Substitution_Rule of expr list * expr * expr;
|
berghofe@41809
|
31 |
|
berghofe@41809
|
32 |
type rules =
|
berghofe@41809
|
33 |
((string * int) * fdl_rule) list *
|
berghofe@41809
|
34 |
(string * (expr * (string * string) list) list) list;
|
walther@60171
|
35 |
val empty_rules: rules
|
berghofe@41809
|
36 |
|
berghofe@41809
|
37 |
type vcs = (string * (string *
|
berghofe@41809
|
38 |
((string * expr) list * (string * expr) list)) list) list;
|
walther@60171
|
39 |
val empty_vcs: (string * string) * vcs
|
berghofe@41809
|
40 |
|
berghofe@41809
|
41 |
type 'a tab = 'a Symtab.table * (string * 'a) list;
|
berghofe@41809
|
42 |
|
berghofe@41809
|
43 |
val lookup: 'a tab -> string -> 'a option;
|
berghofe@41809
|
44 |
val update: string * 'a -> 'a tab -> 'a tab;
|
berghofe@41809
|
45 |
val items: 'a tab -> (string * 'a) list;
|
berghofe@41809
|
46 |
|
berghofe@41809
|
47 |
type decls =
|
berghofe@41809
|
48 |
{types: fdl_type tab,
|
berghofe@41809
|
49 |
vars: string tab,
|
berghofe@41809
|
50 |
consts: string tab,
|
berghofe@41809
|
51 |
funs: (string list * string) tab};
|
walther@60171
|
52 |
val empty_decls: decls
|
berghofe@41809
|
53 |
|
berghofe@41809
|
54 |
val parse_vcs: (Fdl_Lexer.chars -> 'a * Fdl_Lexer.chars) -> Position.T ->
|
berghofe@41809
|
55 |
string -> 'a * ((string * string) * vcs);
|
berghofe@41809
|
56 |
|
berghofe@41809
|
57 |
val parse_declarations: Position.T -> string -> (string * string) * decls;
|
berghofe@41809
|
58 |
|
berghofe@41809
|
59 |
val parse_rules: Position.T -> string -> rules;
|
walther@60171
|
60 |
val vcs: Fdl_Lexer.T list ->
|
walther@60171
|
61 |
((string * string) * (string * (string * ((string * expr) list * (string * expr) list)) list) list) * Fdl_Lexer.T list;
|
walther@60171
|
62 |
val !!! : (Fdl_Lexer.T list -> 'a) -> Fdl_Lexer.T list -> 'a;
|
walther@60171
|
63 |
val $$$ : string -> Fdl_Lexer.T list -> string * Fdl_Lexer.T list
|
walther@60171
|
64 |
val group: string -> ('a -> 'b) -> 'a -> 'b
|
walther@60171
|
65 |
val identifier: Fdl_Lexer.T list -> string * Fdl_Lexer.T list
|
walther@60171
|
66 |
val enum1: string -> (Fdl_Lexer.T list -> 'a * Fdl_Lexer.T list) -> Fdl_Lexer.T list ->
|
walther@60171
|
67 |
'a list * Fdl_Lexer.T list
|
walther@60171
|
68 |
val list1: (Fdl_Lexer.T list -> 'a * Fdl_Lexer.T list) -> Fdl_Lexer.T list ->
|
walther@60171
|
69 |
'a list * Fdl_Lexer.T list
|
berghofe@41809
|
70 |
end;
|
berghofe@41809
|
71 |
|
walther@60171
|
72 |
structure Fdl_Parser(**): FDL_PARSER(**) =
|
berghofe@41809
|
73 |
struct
|
berghofe@41809
|
74 |
|
berghofe@41809
|
75 |
(** error handling **)
|
berghofe@41809
|
76 |
|
berghofe@41809
|
77 |
fun beginning n cs =
|
berghofe@41809
|
78 |
let val dots = if length cs > n then " ..." else "";
|
berghofe@41809
|
79 |
in
|
berghofe@41809
|
80 |
space_implode " " (take n cs) ^ dots
|
berghofe@41809
|
81 |
end;
|
berghofe@41809
|
82 |
|
berghofe@41809
|
83 |
fun !!! scan =
|
berghofe@41809
|
84 |
let
|
wenzelm@49926
|
85 |
fun get_pos [] = " (end-of-input)"
|
berghofe@41809
|
86 |
| get_pos (tok :: _) = Fdl_Lexer.pos_of tok;
|
berghofe@41809
|
87 |
|
wenzelm@44818
|
88 |
fun err (syms, msg) = fn () =>
|
berghofe@41809
|
89 |
"Syntax error" ^ get_pos syms ^ " at " ^
|
wenzelm@44818
|
90 |
beginning 10 (map Fdl_Lexer.unparse syms) ^
|
wenzelm@44818
|
91 |
(case msg of NONE => "" | SOME m => "\n" ^ m () ^ " expected");
|
berghofe@41809
|
92 |
in Scan.!! err scan end;
|
berghofe@41809
|
93 |
|
berghofe@41809
|
94 |
fun parse_all p =
|
berghofe@41809
|
95 |
Scan.repeat (Scan.unless (Scan.one Fdl_Lexer.is_eof) (!!! p));
|
berghofe@41809
|
96 |
|
berghofe@41809
|
97 |
|
berghofe@41809
|
98 |
(** parsers **)
|
berghofe@41809
|
99 |
|
wenzelm@44818
|
100 |
fun group s p = p || Scan.fail_with (K (fn () => s));
|
berghofe@41809
|
101 |
|
berghofe@41809
|
102 |
fun $$$ s = group s
|
berghofe@41809
|
103 |
(Scan.one (fn t => Fdl_Lexer.kind_of t = Fdl_Lexer.Keyword andalso
|
berghofe@41809
|
104 |
Fdl_Lexer.content_of t = s) >> K s);
|
berghofe@41809
|
105 |
|
berghofe@41809
|
106 |
val identifier = group "identifier"
|
berghofe@41809
|
107 |
(Scan.one (fn t => Fdl_Lexer.kind_of t = Fdl_Lexer.Ident) >>
|
berghofe@41809
|
108 |
Fdl_Lexer.content_of);
|
berghofe@41809
|
109 |
|
berghofe@41809
|
110 |
val long_identifier = group "long identifier"
|
berghofe@41809
|
111 |
(Scan.one (fn t => Fdl_Lexer.kind_of t = Fdl_Lexer.Long_Ident) >>
|
berghofe@41809
|
112 |
Fdl_Lexer.content_of);
|
berghofe@41809
|
113 |
|
berghofe@41809
|
114 |
fun the_identifier s = group s
|
berghofe@41809
|
115 |
(Scan.one (fn t => Fdl_Lexer.kind_of t = Fdl_Lexer.Ident andalso
|
berghofe@41809
|
116 |
Fdl_Lexer.content_of t = s) >> K s);
|
berghofe@41809
|
117 |
|
berghofe@41809
|
118 |
fun prfx_identifier g s = group g
|
berghofe@41809
|
119 |
(Scan.one (fn t => Fdl_Lexer.kind_of t = Fdl_Lexer.Ident andalso
|
berghofe@41809
|
120 |
can (unprefix s) (Fdl_Lexer.content_of t)) >>
|
berghofe@41809
|
121 |
(unprefix s o Fdl_Lexer.content_of));
|
berghofe@41809
|
122 |
|
berghofe@41809
|
123 |
val mk_identifier = prfx_identifier "identifier \"mk__...\"" "mk__";
|
berghofe@41809
|
124 |
val hyp_identifier = prfx_identifier "hypothesis identifer" "H";
|
berghofe@41809
|
125 |
val concl_identifier = prfx_identifier "conclusion identifier" "C";
|
berghofe@41809
|
126 |
|
berghofe@41809
|
127 |
val number = group "number"
|
berghofe@41809
|
128 |
(Scan.one (fn t => Fdl_Lexer.kind_of t = Fdl_Lexer.Number) >>
|
berghofe@41809
|
129 |
(the o Int.fromString o Fdl_Lexer.content_of));
|
berghofe@41809
|
130 |
|
berghofe@41809
|
131 |
val traceability = group "traceability information"
|
berghofe@41809
|
132 |
(Scan.one (fn t => Fdl_Lexer.kind_of t = Fdl_Lexer.Traceability) >>
|
berghofe@41809
|
133 |
Fdl_Lexer.content_of);
|
berghofe@41809
|
134 |
|
berghofe@41809
|
135 |
fun enum1 sep scan = scan ::: Scan.repeat ($$$ sep |-- !!! scan);
|
berghofe@41809
|
136 |
fun enum sep scan = enum1 sep scan || Scan.succeed [];
|
berghofe@41809
|
137 |
|
berghofe@41809
|
138 |
fun list1 scan = enum1 "," scan;
|
berghofe@41809
|
139 |
fun list scan = enum "," scan;
|
berghofe@41809
|
140 |
|
berghofe@41809
|
141 |
|
berghofe@41809
|
142 |
(* expressions, see section 4.4 of SPARK Proof Manual *)
|
berghofe@41809
|
143 |
|
berghofe@41809
|
144 |
datatype expr =
|
berghofe@41809
|
145 |
Ident of string
|
berghofe@41809
|
146 |
| Number of int
|
berghofe@41809
|
147 |
| Quantifier of string * string list * string * expr
|
berghofe@41809
|
148 |
| Funct of string * expr list
|
berghofe@41809
|
149 |
| Element of expr * expr list
|
berghofe@41809
|
150 |
| Update of expr * expr list * expr
|
berghofe@41809
|
151 |
| Record of string * (string * expr) list
|
berghofe@41809
|
152 |
| Array of string * expr option *
|
berghofe@41809
|
153 |
((expr * expr option) list list * expr) list;
|
berghofe@41809
|
154 |
|
berghofe@41809
|
155 |
fun unop (f, x) = Funct (f, [x]);
|
berghofe@41809
|
156 |
|
berghofe@41809
|
157 |
fun binop p q = p :|-- (fn x => Scan.optional
|
berghofe@41809
|
158 |
(q -- !!! p >> (fn (f, y) => Funct (f, [x, y]))) x);
|
berghofe@41809
|
159 |
|
berghofe@41809
|
160 |
(* left-associative *)
|
berghofe@41809
|
161 |
fun binops opp argp =
|
berghofe@41809
|
162 |
argp -- Scan.repeat (opp -- !!! argp) >> (fn (x, fys) =>
|
berghofe@41809
|
163 |
fold (fn (f, y) => fn x => Funct (f, [x, y])) fys x);
|
berghofe@41809
|
164 |
|
berghofe@41809
|
165 |
(* right-associative *)
|
berghofe@41809
|
166 |
fun binops' f p = enum1 f p >> foldr1 (fn (x, y) => Funct (f, [x, y]));
|
berghofe@41809
|
167 |
|
berghofe@41809
|
168 |
val multiplying_operator = $$$ "*" || $$$ "/" || $$$ "div" || $$$ "mod";
|
berghofe@41809
|
169 |
|
berghofe@41809
|
170 |
val adding_operator = $$$ "+" || $$$ "-";
|
berghofe@41809
|
171 |
|
berghofe@41809
|
172 |
val relational_operator =
|
berghofe@41809
|
173 |
$$$ "=" || $$$ "<>"
|
berghofe@41809
|
174 |
|| $$$ "<" || $$$ ">"
|
berghofe@41809
|
175 |
|| $$$ "<="|| $$$ ">=";
|
berghofe@41809
|
176 |
|
berghofe@41809
|
177 |
val quantification_kind = $$$ "for_all" || $$$ "for_some";
|
berghofe@41809
|
178 |
|
berghofe@41809
|
179 |
val quantification_generator =
|
berghofe@41809
|
180 |
list1 identifier --| $$$ ":" -- identifier;
|
berghofe@41809
|
181 |
|
berghofe@51013
|
182 |
fun opt_parens p = $$$ "(" |-- p --| $$$ ")" || p;
|
berghofe@51013
|
183 |
|
berghofe@41809
|
184 |
fun expression xs = group "expression"
|
berghofe@41809
|
185 |
(binop disjunction ($$$ "->" || $$$ "<->")) xs
|
berghofe@41809
|
186 |
|
berghofe@41809
|
187 |
and disjunction xs = binops' "or" conjunction xs
|
berghofe@41809
|
188 |
|
berghofe@41809
|
189 |
and conjunction xs = binops' "and" negation xs
|
berghofe@41809
|
190 |
|
berghofe@41809
|
191 |
and negation xs =
|
berghofe@41809
|
192 |
( $$$ "not" -- !!! relation >> unop
|
berghofe@41809
|
193 |
|| relation) xs
|
berghofe@41809
|
194 |
|
berghofe@41809
|
195 |
and relation xs = binop sum relational_operator xs
|
berghofe@41809
|
196 |
|
berghofe@41809
|
197 |
and sum xs = binops adding_operator term xs
|
berghofe@41809
|
198 |
|
berghofe@41809
|
199 |
and term xs = binops multiplying_operator factor xs
|
berghofe@41809
|
200 |
|
berghofe@41809
|
201 |
and factor xs =
|
berghofe@41809
|
202 |
( $$$ "+" |-- !!! primary
|
berghofe@41809
|
203 |
|| $$$ "-" -- !!! primary >> unop
|
berghofe@41809
|
204 |
|| binop primary ($$$ "**")) xs
|
berghofe@41809
|
205 |
|
berghofe@41809
|
206 |
and primary xs = group "primary"
|
berghofe@41809
|
207 |
( number >> Number
|
berghofe@41809
|
208 |
|| $$$ "(" |-- !!! (expression --| $$$ ")")
|
berghofe@41809
|
209 |
|| quantified_expression
|
berghofe@41809
|
210 |
|| function_designator
|
berghofe@41809
|
211 |
|| identifier >> Ident) xs
|
berghofe@41809
|
212 |
|
berghofe@41809
|
213 |
and quantified_expression xs = (quantification_kind --
|
berghofe@41809
|
214 |
!!! ($$$ "(" |-- quantification_generator --| $$$ "," --
|
berghofe@41809
|
215 |
expression --| $$$ ")") >> (fn (q, ((xs, T), e)) =>
|
berghofe@41809
|
216 |
Quantifier (q, xs, T, e))) xs
|
berghofe@41809
|
217 |
|
berghofe@41809
|
218 |
and function_designator xs =
|
berghofe@41809
|
219 |
( mk_identifier --| $$$ "(" :|--
|
berghofe@41809
|
220 |
(fn s => record_args s || array_args s) --| $$$ ")"
|
berghofe@41809
|
221 |
|| $$$ "element" |-- !!! ($$$ "(" |-- expression --| $$$ "," --| $$$ "[" --
|
berghofe@41809
|
222 |
list1 expression --| $$$ "]" --| $$$ ")") >> Element
|
berghofe@41809
|
223 |
|| $$$ "update" |-- !!! ($$$ "(" |-- expression --| $$$ "," --| $$$ "[" --
|
berghofe@41809
|
224 |
list1 expression --| $$$ "]" --| $$$ "," -- expression --| $$$ ")") >>
|
berghofe@41809
|
225 |
(fn ((A, xs), x) => Update (A, xs, x))
|
berghofe@41809
|
226 |
|| identifier --| $$$ "(" -- !!! (list1 expression --| $$$ ")") >> Funct) xs
|
berghofe@41809
|
227 |
|
berghofe@41809
|
228 |
and record_args s xs =
|
berghofe@41809
|
229 |
(list1 (identifier --| $$$ ":=" -- !!! expression) >> (pair s #> Record)) xs
|
berghofe@41809
|
230 |
|
berghofe@41809
|
231 |
and array_args s xs =
|
berghofe@51013
|
232 |
( array_associations >> (fn assocs => Array (s, NONE, assocs))
|
berghofe@51013
|
233 |
|| expression -- Scan.optional ($$$ "," |-- !!! array_associations) [] >>
|
berghofe@51013
|
234 |
(fn (default, assocs) => Array (s, SOME default, assocs))) xs
|
berghofe@41809
|
235 |
|
berghofe@41809
|
236 |
and array_associations xs =
|
berghofe@51013
|
237 |
(list1 (opt_parens (enum1 "&" ($$$ "[" |--
|
berghofe@41809
|
238 |
!!! (list1 (expression -- Scan.option ($$$ ".." |-- !!! expression)) --|
|
berghofe@51013
|
239 |
$$$ "]"))) --| $$$ ":=" -- expression)) xs;
|
berghofe@41809
|
240 |
|
berghofe@41809
|
241 |
|
berghofe@41809
|
242 |
(* verification conditions *)
|
berghofe@41809
|
243 |
|
berghofe@41809
|
244 |
type vcs = (string * (string *
|
berghofe@41809
|
245 |
((string * expr) list * (string * expr) list)) list) list;
|
berghofe@41809
|
246 |
|
berghofe@41809
|
247 |
val vc =
|
berghofe@41809
|
248 |
identifier --| $$$ "." -- !!!
|
berghofe@41809
|
249 |
( $$$ "***" |-- !!! (the_identifier "true" --| $$$ ".") >>
|
berghofe@41809
|
250 |
(Ident #> pair "1" #> single #> pair [])
|
berghofe@41809
|
251 |
|| $$$ "!!!" |-- !!! (the_identifier "false" --| $$$ ".") >>
|
berghofe@41809
|
252 |
(Ident #> pair "1" #> single #> pair [])
|
berghofe@41809
|
253 |
|| Scan.repeat1 (hyp_identifier --
|
berghofe@41809
|
254 |
!!! ($$$ ":" |-- expression --| $$$ ".")) --| $$$ "->" --
|
berghofe@41809
|
255 |
Scan.repeat1 (concl_identifier --
|
berghofe@41809
|
256 |
!!! ($$$ ":" |-- expression --| $$$ ".")));
|
berghofe@41809
|
257 |
|
berghofe@41809
|
258 |
val subprogram_kind = $$$ "function" || $$$ "procedure";
|
berghofe@41809
|
259 |
|
berghofe@41809
|
260 |
val vcs =
|
berghofe@41809
|
261 |
subprogram_kind -- (long_identifier || identifier) --
|
berghofe@41809
|
262 |
parse_all (traceability -- !!! (Scan.repeat1 vc));
|
walther@60171
|
263 |
val empty_vcs = (("e_procedure", "e_G_C_D"), []: vcs)
|
berghofe@41809
|
264 |
|
berghofe@41809
|
265 |
fun parse_vcs header pos s =
|
walther@60171
|
266 |
(*line_1*)s |>
|
walther@60171
|
267 |
(*line_2*)Fdl_Lexer.tokenize header Fdl_Lexer.c_comment pos ||>
|
walther@60171
|
268 |
(*line_3*)filter Fdl_Lexer.is_proper ||>
|
walther@60171
|
269 |
(*line_4*)Scan.finite Fdl_Lexer.stopper (Scan.error (!!! vcs)) ||>
|
walther@60171
|
270 |
(*line_5*)fst;
|
walther@60171
|
271 |
(* vvvvvv-------- = Fdl_Lexer.siv_header*)
|
walther@60171
|
272 |
fun parse_vcs header pos s =
|
walther@60171
|
273 |
((** )@{print} {a = "//--- ###I Fdl_Parser.parse_vcs", header = header, pos = pos, s = s};( **)
|
walther@60171
|
274 |
let
|
walther@60171
|
275 |
val line_2 = Fdl_Lexer.tokenize header Fdl_Lexer.c_comment pos s
|
walther@60171
|
276 |
(** )val _ = @{print} {a = "###I Fdl_Parser.parse_vcs: ", line_2 = line_2};( **)
|
walther@60171
|
277 |
val line_3 = apsnd (filter Fdl_Lexer.is_proper) line_2
|
walther@60171
|
278 |
val line_4 = apsnd (Scan.finite Fdl_Lexer.stopper (Scan.error (!!! vcs))) line_3
|
walther@60171
|
279 |
val line_5 = apsnd fst line_4
|
walther@60171
|
280 |
(** )val _ = @{print} {z = "\\--- ###I Fdl_Parser.parse_vcs \<rightarrow>", res = line_5};( **)
|
walther@60171
|
281 |
in line_5 end
|
walther@60171
|
282 |
);
|
berghofe@41809
|
283 |
|
berghofe@41809
|
284 |
|
berghofe@41809
|
285 |
(* fdl declarations, see section 4.3 of SPARK Proof Manual *)
|
berghofe@41809
|
286 |
|
berghofe@41809
|
287 |
datatype fdl_type =
|
berghofe@41809
|
288 |
Basic_Type of string
|
berghofe@41809
|
289 |
| Enum_Type of string list
|
berghofe@41809
|
290 |
| Array_Type of string list * string
|
berghofe@41809
|
291 |
| Record_Type of (string list * string) list
|
berghofe@41809
|
292 |
| Pending_Type;
|
berghofe@41809
|
293 |
|
berghofe@41809
|
294 |
(* also store items in a list to preserve order *)
|
berghofe@41809
|
295 |
type 'a tab = 'a Symtab.table * (string * 'a) list;
|
berghofe@41809
|
296 |
|
berghofe@41809
|
297 |
fun lookup ((tab, _) : 'a tab) = Symtab.lookup tab;
|
berghofe@41809
|
298 |
fun update decl (tab, items) = (Symtab.update_new decl tab, decl :: items);
|
berghofe@41809
|
299 |
fun items ((_, items) : 'a tab) = rev items;
|
berghofe@41809
|
300 |
|
berghofe@41809
|
301 |
type decls =
|
berghofe@41809
|
302 |
{types: fdl_type tab,
|
berghofe@41809
|
303 |
vars: string tab,
|
berghofe@41809
|
304 |
consts: string tab,
|
berghofe@41809
|
305 |
funs: (string list * string) tab};
|
berghofe@41809
|
306 |
|
berghofe@41809
|
307 |
val empty_decls : decls =
|
berghofe@41809
|
308 |
{types = (Symtab.empty, []), vars = (Symtab.empty, []),
|
berghofe@41809
|
309 |
consts = (Symtab.empty, []), funs = (Symtab.empty, [])};
|
berghofe@41809
|
310 |
|
berghofe@41809
|
311 |
fun add_type_decl decl {types, vars, consts, funs} =
|
berghofe@41809
|
312 |
{types = update decl types,
|
berghofe@41809
|
313 |
vars = vars, consts = consts, funs = funs}
|
berghofe@41809
|
314 |
handle Symtab.DUP s => error ("Duplicate type " ^ s);
|
berghofe@41809
|
315 |
|
berghofe@41809
|
316 |
fun add_var_decl (vs, ty) {types, vars, consts, funs} =
|
berghofe@41809
|
317 |
{types = types,
|
berghofe@41809
|
318 |
vars = fold (update o rpair ty) vs vars,
|
berghofe@41809
|
319 |
consts = consts, funs = funs}
|
berghofe@41809
|
320 |
handle Symtab.DUP s => error ("Duplicate variable " ^ s);
|
berghofe@41809
|
321 |
|
berghofe@41809
|
322 |
fun add_const_decl decl {types, vars, consts, funs} =
|
berghofe@41809
|
323 |
{types = types, vars = vars,
|
berghofe@41809
|
324 |
consts = update decl consts,
|
berghofe@41809
|
325 |
funs = funs}
|
berghofe@41809
|
326 |
handle Symtab.DUP s => error ("Duplicate constant " ^ s);
|
berghofe@41809
|
327 |
|
berghofe@41809
|
328 |
fun add_fun_decl decl {types, vars, consts, funs} =
|
berghofe@41809
|
329 |
{types = types, vars = vars, consts = consts,
|
berghofe@41809
|
330 |
funs = update decl funs}
|
berghofe@41809
|
331 |
handle Symtab.DUP s => error ("Duplicate function " ^ s);
|
berghofe@41809
|
332 |
|
wenzelm@41868
|
333 |
fun type_decl x = ($$$ "type" |-- !!! (identifier --| $$$ "=" --
|
berghofe@41809
|
334 |
( identifier >> Basic_Type
|
berghofe@41809
|
335 |
|| $$$ "(" |-- !!! (list1 identifier --| $$$ ")") >> Enum_Type
|
berghofe@41809
|
336 |
|| $$$ "array" |-- !!! ($$$ "[" |-- list1 identifier --| $$$ "]" --|
|
berghofe@41809
|
337 |
$$$ "of" -- identifier) >> Array_Type
|
berghofe@41809
|
338 |
|| $$$ "record" |-- !!! (enum1 ";"
|
berghofe@41809
|
339 |
(list1 identifier -- !!! ($$$ ":" |-- identifier)) --|
|
berghofe@41809
|
340 |
$$$ "end") >> Record_Type
|
wenzelm@41868
|
341 |
|| $$$ "pending" >> K Pending_Type)) >> add_type_decl) x;
|
berghofe@41809
|
342 |
|
wenzelm@41868
|
343 |
fun const_decl x = ($$$ "const" |-- !!! (identifier --| $$$ ":" -- identifier --|
|
wenzelm@41868
|
344 |
$$$ "=" --| $$$ "pending") >> add_const_decl) x;
|
berghofe@41809
|
345 |
|
wenzelm@41868
|
346 |
fun var_decl x = ($$$ "var" |-- !!! (list1 identifier --| $$$ ":" -- identifier) >>
|
wenzelm@41868
|
347 |
add_var_decl) x;
|
berghofe@41809
|
348 |
|
wenzelm@41868
|
349 |
fun fun_decl x = ($$$ "function" |-- !!! (identifier --
|
berghofe@41809
|
350 |
(Scan.optional ($$$ "(" |-- !!! (list1 identifier --| $$$ ")")) [] --|
|
wenzelm@41868
|
351 |
$$$ ":" -- identifier)) >> add_fun_decl) x;
|
berghofe@41809
|
352 |
|
wenzelm@41868
|
353 |
fun declarations x =
|
berghofe@47949
|
354 |
(the_identifier "title" |-- subprogram_kind -- identifier --| $$$ ";" --
|
berghofe@41809
|
355 |
(Scan.repeat ((type_decl || const_decl || var_decl || fun_decl) --|
|
wenzelm@47662
|
356 |
!!! ($$$ ";")) >> (fn ds => fold I ds empty_decls)) --|
|
wenzelm@41868
|
357 |
$$$ "end" --| $$$ ";") x;
|
berghofe@41809
|
358 |
|
berghofe@41809
|
359 |
fun parse_declarations pos s =
|
berghofe@41809
|
360 |
s |>
|
berghofe@41809
|
361 |
Fdl_Lexer.tokenize (Scan.succeed ()) Fdl_Lexer.curly_comment pos |>
|
berghofe@41809
|
362 |
snd |> filter Fdl_Lexer.is_proper |>
|
berghofe@41809
|
363 |
Scan.finite Fdl_Lexer.stopper (Scan.error (!!! declarations)) |>
|
berghofe@41809
|
364 |
fst;
|
berghofe@41809
|
365 |
|
berghofe@41809
|
366 |
|
berghofe@41809
|
367 |
(* rules, see section 5 of SPADE Proof Checker Rules Manual *)
|
berghofe@41809
|
368 |
|
berghofe@41809
|
369 |
datatype fdl_rule =
|
berghofe@41809
|
370 |
Inference_Rule of expr list * expr
|
berghofe@41809
|
371 |
| Substitution_Rule of expr list * expr * expr;
|
berghofe@41809
|
372 |
|
berghofe@41809
|
373 |
type rules =
|
berghofe@41809
|
374 |
((string * int) * fdl_rule) list *
|
berghofe@41809
|
375 |
(string * (expr * (string * string) list) list) list;
|
walther@60171
|
376 |
val empty_rules =
|
walther@60171
|
377 |
([]: ((string * int) * fdl_rule) list,
|
walther@60171
|
378 |
[]: (string * (expr * (string * string) list) list) list);
|
berghofe@41809
|
379 |
|
berghofe@41809
|
380 |
val condition_list = $$$ "[" |-- list expression --| $$$ "]";
|
berghofe@41809
|
381 |
val if_condition_list = $$$ "if" |-- !!! condition_list;
|
berghofe@41809
|
382 |
|
berghofe@41809
|
383 |
val rule =
|
berghofe@41809
|
384 |
identifier -- !!! ($$$ "(" |-- number --| $$$ ")" --| $$$ ":" --
|
berghofe@41809
|
385 |
(expression :|-- (fn e =>
|
berghofe@41809
|
386 |
$$$ "may_be_deduced" >> K (Inference_Rule ([], e))
|
berghofe@41809
|
387 |
|| $$$ "may_be_deduced_from" |--
|
berghofe@41809
|
388 |
!!! condition_list >> (Inference_Rule o rpair e)
|
berghofe@41809
|
389 |
|| $$$ "may_be_replaced_by" |-- !!! (expression --
|
berghofe@41809
|
390 |
Scan.optional if_condition_list []) >> (fn (e', cs) =>
|
berghofe@41809
|
391 |
Substitution_Rule (cs, e, e'))
|
berghofe@41809
|
392 |
|| $$$ "&" |-- !!! (expression --| $$$ "are_interchangeable" --
|
berghofe@41809
|
393 |
Scan.optional if_condition_list []) >> (fn (e', cs) =>
|
berghofe@41809
|
394 |
Substitution_Rule (cs, e, e')))) --| $$$ ".") >>
|
berghofe@41809
|
395 |
(fn (id, (n, rl)) => ((id, n), rl));
|
berghofe@41809
|
396 |
|
berghofe@41809
|
397 |
val rule_family =
|
berghofe@41809
|
398 |
$$$ "rule_family" |-- identifier --| $$$ ":" --
|
berghofe@41809
|
399 |
enum1 "&" (expression -- !!! ($$$ "requires" |-- $$$ "[" |--
|
berghofe@41809
|
400 |
list (identifier -- !!! ($$$ ":" |-- identifier)) --| $$$ "]")) --|
|
berghofe@41809
|
401 |
$$$ ".";
|
berghofe@41809
|
402 |
|
berghofe@41809
|
403 |
val rules =
|
berghofe@41809
|
404 |
parse_all (rule >> (apfst o cons) || rule_family >> (apsnd o cons)) >>
|
wenzelm@47662
|
405 |
(fn rls => fold_rev I rls ([], []));
|
berghofe@41809
|
406 |
|
berghofe@41809
|
407 |
fun parse_rules pos s =
|
berghofe@41809
|
408 |
s |>
|
berghofe@41809
|
409 |
Fdl_Lexer.tokenize (Scan.succeed ())
|
berghofe@41809
|
410 |
(Fdl_Lexer.c_comment || Fdl_Lexer.percent_comment) pos |>
|
berghofe@41809
|
411 |
snd |> filter Fdl_Lexer.is_proper |>
|
berghofe@41809
|
412 |
Scan.finite Fdl_Lexer.stopper (Scan.error (!!! rules)) |>
|
berghofe@41809
|
413 |
fst;
|
berghofe@41809
|
414 |
|
berghofe@41809
|
415 |
end;
|