Skip to content

Commit

Permalink
HolSmt: handle end-of-stream when parsing SMT-LIB files
Browse files Browse the repository at this point in the history
The SMT-LIB file parser was ending up raising an end-of-stream
exception unless the `(exit)` command was present in the SMT-LIB file,
even though the `(exit)` command does not seem to be mandatory
according to the SMT-LIB v2.6 standard.
  • Loading branch information
someplaceguy committed Mar 18, 2024
1 parent 044e6ad commit ca44d43
Showing 1 changed file with 36 additions and 22 deletions.
58 changes: 36 additions & 22 deletions src/HolSmt/SmtLib_Parser.sml
Original file line number Diff line number Diff line change
Expand Up @@ -513,17 +513,20 @@ local
(tmdict, definition)
end

(* returns the logic's name, its 'tydict', its 'tmdict' extended with
declared function symbols, and a list of asserted formulas *)
fun parse_commands get_token state =
fun dest_state cmd (SOME x) = x
| dest_state cmd NONE =
raise ERR "dest_state" ("received " ^ cmd ^ " before set-logic")

and finalize_state cmd state =
let
fun dest_state cmd =
case state of
SOME x => x
| NONE => raise ERR "parse_commands" (cmd ^ " issued before set-logic")
val _ = Library.expect_token "(" (get_token ())
val command = get_token ()
val (logic, tydict, tmdict, asserted) = dest_state cmd state
in
(logic, tydict, tmdict, List.rev asserted)
end

(* returns the logic's name, its 'tydict', its 'tmdict' extended with
declared function symbols, and a list of asserted formulas *)
and parse_command command get_token state =
case command of "set-info" =>
let
val _ = parse_set_info get_token
Expand All @@ -540,64 +543,75 @@ local
end
| "declare-sort" =>
let
val (logic, tydict, tmdict, asserted) = dest_state "declare-sort"
val (logic, tydict, tmdict, asserted) = dest_state "declare-sort" state
val tydict = parse_declare_sort get_token tydict
in
parse_commands get_token (SOME (logic, tydict, tmdict, asserted))
end
| "declare-const" =>
let
val (logic, tydict, tmdict, asserted) = dest_state "declare-const"
val (logic, tydict, tmdict, asserted) = dest_state "declare-const" state
val (_, tmdict) = parse_declare_const get_token (tydict, tmdict)
in
parse_commands get_token (SOME (logic, tydict, tmdict, asserted))
end
| "declare-fun" =>
let
val (logic, tydict, tmdict, asserted) = dest_state "declare-fun"
val (logic, tydict, tmdict, asserted) = dest_state "declare-fun" state
val (_, tmdict) = parse_declare_fun get_token (tydict, tmdict)
in
parse_commands get_token (SOME (logic, tydict, tmdict, asserted))
end
| "define-fun" =>
let
val (logic, tydict, tmdict, asserted) = dest_state "define-fun"
val (logic, tydict, tmdict, asserted) = dest_state "define-fun" state
val (tmdict, def) = parse_define_fun get_token (tydict, tmdict)
val asserted = def :: asserted
in
parse_commands get_token (SOME (logic, tydict, tmdict, asserted))
end
| "assert" =>
let
val (logic, tydict, tmdict, asserted) = dest_state "assert"
val (logic, tydict, tmdict, asserted) = dest_state "assert" state
val asserted = parse_term get_token (tydict, tmdict) :: asserted
val _ = Library.expect_token ")" (get_token ())
in
parse_commands get_token (SOME (logic, tydict, tmdict, asserted))
end
| "check-sat" =>
let
val _ = dest_state "check-sat"
val _ = dest_state "check-sat" state
val _ = Library.expect_token ")" (get_token ())
in
parse_commands get_token state
end
| "get-proof" =>
let
val _ = dest_state "get-proof"
val _ = dest_state "get-proof" state
val _ = Library.expect_token ")" (get_token ())
in
parse_commands get_token state
end
| "exit" =>
let
val (logic, tydict, tmdict, asserted) = dest_state "exit"
val _ = Library.expect_token ")" (get_token ())
in
(logic, tydict, tmdict, List.rev asserted)
end
finalize_state "exit" state
before Library.expect_token ")" (get_token ())
| _ =>
raise ERR "parse_commands" ("unknown command '" ^ command ^ "'")

(* returns the logic's name, its 'tydict', its 'tmdict' extended with
declared function symbols, and a list of asserted formulas *)
and parse_commands get_token state =
let
val tok = SOME (get_token ())
(* assume an error to be end-of-stream *)
handle _ => NONE
in
case tok of
NONE => finalize_state "(end-of-stream)" state
| SOME t => (
Library.expect_token "(" t;
parse_command (get_token ()) get_token state
)
end

(* entry point into the parser (i.e., the grammar's start symbol) *)
Expand Down

0 comments on commit ca44d43

Please sign in to comment.