pub struct SmtParser<R> { /* private fields */ }
Expand description

SMT-LIB 2.0 parser.

Implementations

Constructor from a string, mostly for doc/test purposes.

Creates an SMT parser.

Swaps the input source.

Immutable access to the buffer.

Immutable access to the part of the buffer that’s not been parsed yet.

The current position in the buffer.

Returns the next s-expression and positions the cursor directly after it.

An s-expression is an ident, a constant with no parens (42, false, etc.), or something between (nested) parens.

let txt = "\
    token ; a comment\n\n next_token; more comments\n\
    (+ |quoted ident,; a comment\n parens don't count)| 7)42 false\
";
let mut parser = SmtParser::of_str(txt);

assert_eq!( parser.get_sexpr().unwrap(), "token" );
assert_eq!( parser.buff_rest(), " ; a comment\n" );

assert_eq!( parser.get_sexpr().unwrap(), "next_token" );
assert_eq!( parser.buff_rest(), "; more comments\n" );

assert_eq!(
    parser.get_sexpr().unwrap(),
    "(+ |quoted ident,; a comment\n parens don't count)| 7)"
);
assert_eq!( parser.buff_rest(), "42 false" );

assert_eq!( parser.get_sexpr().unwrap(), "42" );
assert_eq!( parser.buff_rest(), " false" );

assert_eq!( parser.get_sexpr().unwrap(), "false" );
assert_eq!( parser.buff_rest(), "" );

Clears the buffer up to the current position.

Prints itself, for debugging.

Parses some spaces or some comments.

Parsing a tag or loading an s-expression fetches new lines, this does not.

let txt = "  token ; a comment\n\n next token; last comment";
let mut parser = SmtParser::of_str(txt);

parser.spc_cmt();
assert_eq!( parser.buff_rest(), "" );
assert_eq!( parser.buff(), "" );

assert!( parser.try_tag("token").expect("token") );
assert_eq!( parser.buff_rest(), " ; a comment\n" );
assert_eq!( parser.buff(), "  token ; a comment\n" );

parser.spc_cmt();
assert_eq!( parser.buff_rest(), "" );
assert_eq!( parser.buff(), "  token ; a comment\n" );

assert!( parser.try_tag("next token").expect("token") );
assert_eq!( parser.buff_rest(), "; last comment" );
assert_eq!( parser.buff(), txt );

parser.spc_cmt();
assert_eq!( parser.buff_rest(), "" );
assert_eq!( parser.buff(), txt );

Tries to parse a tag, true if successful. Parse whitespaces and comments if any before the token.

If this function returns false, then the cursor is at the first non-whitespace non-commented character after the original cursor position.

See also Self::tag, Self::tag_info and Self::tags.

let txt = "\
  a tag is anything  |(>_<)| ; a comment\n\n next token; last comment\
";
let mut parser = SmtParser::of_str(txt);
assert!( parser.try_tag("a tag is anything").expect("tag") );
assert_eq!( parser.buff_rest(), "  |(>_<)| ; a comment\n" );
assert!( ! parser.try_tag("not the token").expect("tag") );
assert_eq!( parser.buff_rest(), "|(>_<)| ; a comment\n" );
assert!( parser.try_tag("|(>_<)|").expect("tag") );
assert!( ! parser.try_tag("not the next token").expect("tag") );
assert_eq!( parser.buff_rest(), "next token; last comment" );
assert!( parser.try_tag("next token").expect("tag") );

Parses a tag or fails.

Returns () exactly when Self::try_tag returns true, and an error otherwise.

Parses a tag or fails, appends err_msg at the end of the error message.

Returns () exactly when Self::try_tag returns true, and an error otherwise.

Parses a tag followed by a whitespace, a paren or a comment.

If this function returns false, then the cursor is at the first non-whitespace non-commented character after the original cursor position.

let txt = "\
  a word is anything  |(>_<)|  last; comment\
";
let mut parser = SmtParser::of_str(txt);
assert!( parser.try_word("a word is").expect("word") );
assert_eq!( parser.buff_rest(), " anything  |(>_<)|  last; comment" );
assert!( ! parser.try_word("a").expect("word") );
assert_eq!( parser.buff_rest(), "anything  |(>_<)|  last; comment" );
assert!( ! parser.try_word("any").expect("word") );
assert_eq!( parser.buff_rest(), "anything  |(>_<)|  last; comment" );
assert!( ! parser.try_word("anythin").expect("word") );
assert_eq!( parser.buff_rest(), "anything  |(>_<)|  last; comment" );
assert!( parser.try_word("anything").expect("word") );
assert_eq!( parser.buff_rest(), "  |(>_<)|  last; comment" );
assert!( parser.try_word("|").expect("word") );
assert_eq!( parser.buff_rest(), "(>_<)|  last; comment" );
assert!( parser.try_tag("(").expect("tag") );
assert_eq!( parser.buff_rest(), ">_<)|  last; comment" );
assert!( parser.try_word(">_<").expect("word") );
assert_eq!( parser.buff_rest(), ")|  last; comment" );
assert!( parser.try_tag(")").expect("tag") );
assert_eq!( parser.buff_rest(), "|  last; comment" );
assert!( parser.try_word("|").expect("word") );
assert_eq!( parser.buff_rest(), "  last; comment" );
assert!( parser.try_word("last").expect("word") );
assert_eq!( parser.buff_rest(), "; comment" );

Tries to parse a sequence of things potentially separated by whitespaces and/or comments.

If this function returns false, then the cursor is at the first non-whitespace non-commented character after the original cursor position.

let txt = "\
    a tag is anything  |(>_<)| ; a comment\n\n next token; last comment\
";
let mut parser = SmtParser::of_str(txt);
assert!(
    parser.try_tags(
        &[ "a", "tag", "is anything", "|", "(", ">_<", ")", "|" ]
    ).expect("tags")
);
assert_eq!( parser.buff_rest(), " ; a comment\n" );
assert!(
    ! parser.try_tags(
        & [ "next", "token", "something else?" ]
    ).expect("tags")
);
assert_eq!( parser.buff_rest(), "next token; last comment" )

Parses a sequence of things potentially separated by whitespaces and/or comments.

Returns () exactly when Self::try_tags returns true, and an error otherwise.

Generates a failure at the current position.

Tries to parse a boolean.

let txt = "\
    true fls  true_ly_bad_ident false; comment\
";
let mut parser = SmtParser::of_str(txt);
assert_eq!( parser.try_bool().expect("bool"), Some(true) );
assert_eq!(
    parser.buff_rest(), " fls  true_ly_bad_ident false; comment"
);
assert_eq!( parser.try_bool().expect("bool"), None );
assert_eq!(
    parser.buff_rest(), "fls  true_ly_bad_ident false; comment"
);
parser.tag("fls").expect("tag");
assert_eq!( parser.try_bool().expect("bool"), None );
assert_eq!(
    parser.buff_rest(), "true_ly_bad_ident false; comment"
);
parser.tag("true_ly_bad_ident").expect("tag");
assert_eq!( parser.try_bool().expect("bool"), Some(false) );
assert_eq!(
    parser.buff_rest(), "; comment"
);

Parses a boolean or fails.

Tries to parses an integer.

Parameters of the input function:

  • the absolute value of the integer parsed,
  • positiveness flag: true iff the integer is positive.

NB: input function f cannot return the input string in any way. Doing so will not borrow-check and is completely unsafe as the parser can and in general will discard what’s in its buffer once it’s parsed.

Only recognizes integers of the form

int   ::= usize             # Not followed by a '.'
        | '(' '-' usize ')'
usize ::= '0' | [1-9][0-9]*
Examples
use std::str::FromStr;
fn to_int(
    input: & str, positive: bool
) -> Result<isize, <isize as FromStr>::Err> {
    isize::from_str(input).map(
        |num| if positive { num } else { - num }
    )
}
let txt = "\
    666 (- 11) false; comment\n(+ 31) (= tru)\
";
let mut parser = SmtParser::of_str(txt);
println!("666");
assert_eq!( parser.try_int(to_int).expect("int"), Some(666) );
assert_eq!(
    parser.buff_rest(), " (- 11) false; comment\n"
);

println!("- 11");
assert_eq!( parser.try_int(to_int).expect("int"), Some(- 11) );
assert_eq!(
    parser.buff_rest(), " false; comment\n"
);

assert_eq!( parser.try_int(to_int).expect("int"), None );
parser.tag("false").expect("tag");

println!("31");
assert_eq!( parser.try_int(to_int).expect("int"), Some(31) );
assert_eq!(
    parser.buff_rest(), " (= tru)"
);

assert_eq!( parser.try_int(to_int).expect("int"), None );

let txt = " 7.0 ";
println!("{}", txt);
let mut parser = SmtParser::of_str(txt);
assert_eq!( parser.try_int(to_int).expect("int"), None );
assert_eq!(
    parser.buff_rest(), " 7.0 "
);

let txt = " 00 ";
println!("{}", txt);
let mut parser = SmtParser::of_str(txt);
assert_eq!( parser.try_int(to_int).expect("int"), None );
assert_eq!(
    parser.buff_rest(), " 00 "
);

Tries to parses a rational (called Real in SMT-LIB).

Parameters of the input function:

  • numerator of the rational parsed (> 0),
  • denominator of the rational parsed (> 0),
  • positiveness flag: true iff the rational is positive.

Only recognizes integers of the form

rat   ::= '(' '/' udec udec ')'
        | '(' '-' '(' '/' udec udec ')' ')'
        | idec
idec  ::= '(' '-' udec '.' usize ')' | udec
udec  ::= usize | usize.0
usize ::= [0-9][0-9]*

NB: input function f cannot return the input strings in any way. Doing so will not borrow-check and is completely unsafe as the parser can and in general will discard what’s in its buffer once it’s parsed.

use std::str::FromStr;
fn to_rat(
    num: & str, den: & str, positive: bool
) -> Result<(isize, usize), String> {
    let num = isize::from_str(num).map(
        |num| if positive { num } else { - num }
    ).map_err(|e| format!("{}", e)) ?;
    let den = usize::from_str(den).map_err(|e| format!("{}", e)) ?;
    Ok((num, den))
}
let txt = "\
    0.0 666.0 7.42 (- 11.0) false; comment\n(/ 31 27) (- (/ 63 0)) (= tru)\
";
let mut parser = SmtParser::of_str(txt);
assert_eq!( parser.try_rat(to_rat).expect("rat"), Some((0, 1)) );
assert_eq!(
    parser.buff_rest(), " 666.0 7.42 (- 11.0) false; comment\n"
);
assert_eq!( parser.try_rat(to_rat).expect("rat"), Some((666, 1)) );
assert_eq!(
    parser.buff_rest(), " 7.42 (- 11.0) false; comment\n"
);
assert_eq!( parser.try_rat(to_rat).expect("rat"), Some((742, 100)) );
assert_eq!(
    parser.buff_rest(), " (- 11.0) false; comment\n"
);
assert_eq!( parser.try_rat(to_rat).expect("rat"), Some((- 11, 1)) );
assert_eq!(
    parser.buff_rest(), " false; comment\n"
);
assert_eq!( parser.try_rat(to_rat).expect("rat"), None );
parser.tag("false").expect("tag");
assert_eq!( parser.try_rat(to_rat).expect("rat"), Some((31, 27)) );
assert_eq!(
    parser.buff_rest(), " (- (/ 63 0)) (= tru)"
);
assert_eq!( parser.try_rat(to_rat).expect("rat"), (Some((- 63, 0))) );

let txt = " 7 ";
let mut parser = SmtParser::of_str(txt);
assert_eq!( parser.try_rat(to_rat).expect("rat"), None );
assert_eq!(
    parser.buff_rest(), " 7 "
);

let txt = " (- 7) ";
let mut parser = SmtParser::of_str(txt);
assert_eq!( parser.try_rat(to_rat).expect("rat"), None );
assert_eq!(
    parser.buff_rest(), " (- 7) "
);

Tries to parse a symbol.

Quoted symbols (anything but | surrounded by |) are passed with the surrounding |.

NB: input function f cannot return the input string in any way. Doing so will not borrow-check and is completely unsafe as the parser can and in general will discard what’s in its buffer once it’s parsed.

fn sym(input: & str) -> Result<String, String> {
    Ok( input.into() )
}
let txt = "\
    ident (- 11) +~stuff; comment\n |some stuff \n [{}!+)(}|\
";
let mut parser = SmtParser::of_str(txt);
assert_eq!( parser.try_sym(sym).expect("sym"), Some("ident".into()) );
assert_eq!(
    parser.buff_rest(), " (- 11) +~stuff; comment\n"
);
assert_eq!( parser.try_sym(sym).expect("sym"), None );
assert_eq!(
    parser.buff_rest(), "(- 11) +~stuff; comment\n"
);
parser.tag("(- 11)").expect("tag");
assert_eq!( parser.try_sym(sym).expect("sym"), Some("+~stuff".into()) );
assert_eq!(
    parser.buff_rest(), "; comment\n"
);
assert_eq!(
    parser.try_sym(sym).expect("sym"),
    Some("|some stuff \n [{}!+)(}|".into())
);

Parses success.

Parses an error.

Returns Ok(()) if no error was parsed, an error otherwise.

Examples
use rsmt2::parse::{ IdentParser, ValueParser };
use rsmt2::SmtRes;
let txt = "\
    ( error \"huge panic\n\n'something' () parens\" )
";
let mut parser = SmtParser::of_str(txt);
if let Err(e) = parser.try_error() {
    assert_eq! { & format!("{}", e), "solver error: \"huge panic\n\n'something' () parens\"" }
} else {
    panic!("expected error, got nothing :(")
}

Parses the result of a check-sat.

Returns None if the solver reported unknown.

Tries to parse a reserved actlit id.

Parses the result of a get-unsat-core.

Parses the result of a get-model where all symbols are nullary.

Parses the result of a get-model.

Parses the result of a get-value.

Parses the result of a get-interpolant.

Trait Implementations

Parses an expression given some info.

Parses an expression given some info.

Parses an expression given some info.

Parses an identifier.

Parses a type.

Parses an identifier.

Parses a type.

Parses a value in the context of a get-model command. Read more

Parses a value in the context of a get-model command. Read more

Parses a proof.

Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more

Like read, except that it reads into a slice of buffers. Read more

🔬This is a nightly-only experimental API. (can_vector)

Determines if this Reader has an efficient read_vectored implementation. Read more

Read all bytes until EOF in this source, placing them into buf. Read more

Read all bytes until EOF in this source, appending them to buf. Read more

Read the exact number of bytes required to fill buf. Read more

🔬This is a nightly-only experimental API. (read_buf)

Pull some bytes from this source into the specified buffer. Read more

🔬This is a nightly-only experimental API. (read_buf)

Read the exact number of bytes required to fill cursor. Read more

Creates a “by reference” adaptor for this instance of Read. Read more

Transforms this Read instance to an Iterator over its bytes. Read more

Creates an adapter which will chain this stream with another. Read more

Creates an adapter which will read at most limit bytes from it. Read more

Parses a symbol.

Parses a symbol.

Parses a symbol.

Parses a plain value.

Parses a plain value.

Parses a plain value.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Parses an identifier.

Parses a type.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Parses a value in the context of a get-model command. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.