286 |
287 |
287 fun triple_int_ord ((a, b, c), (a', b', c')) = |
288 fun triple_int_ord ((a, b, c), (a', b', c')) = |
288 prod_ord int_ord (prod_ord int_ord int_ord) ((a, (b, c)), (a', (b', c'))); |
289 prod_ord int_ord (prod_ord int_ord int_ord) ((a, (b, c)), (a', (b', c'))); |
289 structure Inttriplefunc = FuncFun(type key = int * int * int val ord = triple_int_ord); |
290 structure Inttriplefunc = FuncFun(type key = int * int * int val ord = triple_int_ord); |
290 |
291 |
291 fun index_char str chr pos = |
|
292 if pos >= String.size str then ~1 |
|
293 else if String.sub(str,pos) = chr then pos |
|
294 else index_char str chr (pos + 1); |
|
295 |
|
296 fun rat_of_quotient (a,b) = |
|
297 if b = 0 then @0 else Rat.make (a, b); |
|
298 |
|
299 fun rat_of_string s = |
|
300 let val n = index_char s #"/" 0 in |
|
301 if n = ~1 then s |> Int.fromString |> the |> Rat.of_int |
|
302 else |
|
303 let |
|
304 val SOME numer = Int.fromString(String.substring(s,0,n)) |
|
305 val SOME den = Int.fromString (String.substring(s,n+1,String.size s - n - 1)) |
|
306 in rat_of_quotient(numer, den) end |
|
307 end; |
|
308 |
|
309 |
|
310 fun isnum x = member (op =) ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] x; |
|
311 |
292 |
312 (* More parser basics. *) |
293 (* More parser basics. *) |
|
294 |
|
295 local |
|
296 |
|
297 val decimal_digits = Scan.many1 Symbol.is_ascii_digit |
|
298 val decimal_nat = decimal_digits >> (#1 o Library.read_int); |
|
299 val decimal_int = decimal_nat >> Rat.of_int; |
|
300 |
|
301 val decimal_sig = |
|
302 decimal_int -- Scan.option (Scan.$$ "." |-- decimal_digits) >> |
|
303 (fn (a, NONE) => a |
|
304 | (a, SOME bs) => a + Rat.of_int (#1 (Library.read_int bs)) / rat_pow @10 (length bs)); |
|
305 |
|
306 fun signed neg parse = $$ "-" |-- parse >> neg || $$ "+" |-- parse || parse; |
|
307 val exponent = ($$ "e" || $$ "E") |-- signed ~ decimal_nat; |
|
308 |
|
309 in |
|
310 |
|
311 val decimal = |
|
312 signed ~ decimal_sig -- Scan.optional exponent 0 |
|
313 >> (fn (a, b) => a * rat_pow @10 b); |
|
314 |
|
315 end; |
|
316 |
|
317 |
|
318 (* Parse back csdp output. *) |
|
319 |
313 (* FIXME improper use of parser combinators ahead *) |
320 (* FIXME improper use of parser combinators ahead *) |
314 |
|
315 val numeral = Scan.one isnum |
|
316 val decimalint = Scan.repeat1 numeral >> (rat_of_string o implode) |
|
317 val decimalfrac = Scan.repeat1 numeral |
|
318 >> (fn s => rat_of_string(implode s) / rat_pow @10 (length s)) |
|
319 val decimalsig = |
|
320 decimalint -- Scan.option (Scan.$$ "." |-- decimalfrac) |
|
321 >> (fn (h,NONE) => h | (h,SOME x) => h + x) |
|
322 fun signed prs = |
|
323 $$ "-" |-- prs >> Rat.neg |
|
324 || $$ "+" |-- prs |
|
325 || prs; |
|
326 |
|
327 fun emptyin def xs = if null xs then (def, xs) else Scan.fail xs |
|
328 |
|
329 val exponent = ($$ "e" || $$ "E") |-- signed decimalint; |
|
330 |
|
331 val decimal = signed decimalsig -- (emptyin @0|| exponent) |
|
332 >> (fn (h, x) => h * rat_pow @10 (int_of_rat x)); |
|
333 |
321 |
334 fun mkparser p s = |
322 fun mkparser p s = |
335 let val (x,rst) = p (raw_explode s) |
323 let val (x,rst) = p (raw_explode s) |
336 in if null rst then x else error "mkparser: unparsed input" end; |
324 in if null rst then x else error "mkparser: unparsed input" end; |
337 |
|
338 (* Parse back csdp output. *) |
|
339 (* FIXME improper use of parser combinators ahead *) |
|
340 |
325 |
341 fun ignore _ = ((),[]) |
326 fun ignore _ = ((),[]) |
342 fun csdpoutput inp = |
327 fun csdpoutput inp = |
343 ((decimal -- Scan.repeat (Scan.$$ " " |-- Scan.option decimal) >> |
328 ((decimal -- Scan.repeat (Scan.$$ " " |-- Scan.option decimal) >> |
344 (fn (h,to) => map_filter I ((SOME h)::to))) --| ignore >> vector_of_list) inp |
329 (fn (h,to) => map_filter I ((SOME h)::to))) --| ignore >> vector_of_list) inp |