veripb_parser/
substitution_parser.rs1use std::io::{Error, ErrorKind};
17
18use logos::Lexer;
19use veripb_formula::prelude::*;
20
21use crate::substitution_token::SubstitutionToken;
22
23pub fn parse_substitution(
27 lex: &mut Lexer<SubstitutionToken>,
28 var_names: &mut VarNameManager,
29) -> Result<Substitution, Error> {
30 let mut sub = Substitution::default();
31 while let Some(token) = lex.next() {
32 let var = match token {
34 Ok(SubstitutionToken::PositiveLit) => var_names.add_by_name(lex.slice()),
35 Ok(SubstitutionToken::Semicolon) => break,
36 Ok(_) => return Err(Error::new(ErrorKind::InvalidData, "Expected variable.")),
37 Err(_) => return Err(Error::new(ErrorKind::InvalidData, "Unrecognized token.")),
38 };
39
40 if let Some(token) = lex.next() {
42 let already_set = match token {
43 Ok(SubstitutionToken::Zero) => sub.set(var, SubstitutionValue::FALSE),
44 Ok(SubstitutionToken::One) => sub.set(var, SubstitutionValue::TRUE),
45 Ok(SubstitutionToken::PositiveLit) => sub.set(
46 var,
47 SubstitutionValue::lit(Lit::from_var(
48 var_names.add_by_name(lex.slice()),
49 false,
50 )),
51 ),
52 Ok(SubstitutionToken::NegativeLit) => sub.set(
53 var,
54 SubstitutionValue::lit(Lit::from_var(
55 var_names.add_by_name(&lex.slice()[1..]),
56 true,
57 )),
58 ),
59 Ok(_) => {
60 return Err(Error::new(
61 ErrorKind::InvalidData,
62 "Expected '0', '1', or literal.",
63 ))
64 }
65 Err(_) => return Err(Error::new(ErrorKind::InvalidData, "Unrecognized token.")),
66 };
67 if already_set {
68 return Err(Error::new(
69 ErrorKind::InvalidData,
70 "A variable is assigned twice in the substitution.",
71 ));
72 }
73 } else {
74 return Err(Error::new(
75 ErrorKind::InvalidData,
76 "Substitution ended unexpectedly after variable.",
77 ));
78 }
79 }
80
81 Ok(sub)
82}