mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 11:15:43 -05:00
74 lines
1.6 KiB
OCaml
74 lines
1.6 KiB
OCaml
(*
|
|
MSAT is free software, using the Apache license, see file LICENSE
|
|
Copyright 2014 Guillaume Bury
|
|
Copyright 2014 Simon Cruanes
|
|
*)
|
|
|
|
exception Syntax_error of int
|
|
|
|
type line =
|
|
| Empty
|
|
| Comment
|
|
| Pcnf of int * int
|
|
| Clause of int list
|
|
|
|
let rec _read_word s acc i len =
|
|
assert (len>0);
|
|
if i+len=String.length s
|
|
then String.sub s i len :: acc
|
|
else match s.[i+len] with
|
|
| ' ' | '\t' ->
|
|
let acc = String.sub s i len :: acc in
|
|
_skip_space s acc (i+len+1)
|
|
| _ -> _read_word s acc i (len+1)
|
|
and _skip_space s acc i =
|
|
if i=String.length s
|
|
then acc
|
|
else match s.[i] with
|
|
| ' ' | '\t' -> _skip_space s acc (i+1)
|
|
| _ -> _read_word s acc i 1
|
|
|
|
let ssplit s = List.rev (_skip_space s [] 0)
|
|
|
|
let of_input f =
|
|
match ssplit (input_line f) with
|
|
| [] -> Empty
|
|
| "c" :: _ -> Comment
|
|
| "p" :: "cnf" :: i :: j :: [] ->
|
|
begin try
|
|
Pcnf (int_of_string i, int_of_string j)
|
|
with Failure _ ->
|
|
raise (Syntax_error (-1))
|
|
end
|
|
| l ->
|
|
begin try
|
|
begin match List.rev_map int_of_string l with
|
|
| 0 :: r -> Clause r
|
|
| _ -> raise (Syntax_error (-1))
|
|
end
|
|
with Failure _ -> raise (Syntax_error (-1))
|
|
end
|
|
|
|
let parse_with todo file =
|
|
let f = open_in file in
|
|
let line = ref 0 in
|
|
try
|
|
while true do
|
|
incr line;
|
|
todo (of_input f)
|
|
done
|
|
with
|
|
| Syntax_error _ ->
|
|
raise (Syntax_error !line)
|
|
| End_of_file ->
|
|
close_in f
|
|
|
|
let cnf = ref []
|
|
let parse_line = function
|
|
| Empty | Comment | Pcnf _ -> ()
|
|
| Clause l -> cnf := l :: !cnf
|
|
|
|
let parse f =
|
|
cnf := [];
|
|
parse_with parse_line f;
|
|
!cnf
|