Решение на Логически изрази от Пламен Стойнев

Обратно към всички решения

Към профила на Пламен Стойнев

Резултати

  • 3 точки от тестове
  • 0 бонус точки
  • 3 точки общо
  • 3 успешни тест(а)
  • 17 неуспешни тест(а)

Код

#[derive(Debug, PartialEq, Eq)]
pub enum ParseError {
UnexpectedExpr,
UnexpectedUnaryOp,
UnexpectedBinOp,
UnexpectedParen,
UnexpectedEnd,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
pub struct SimpleExprParser {
stack: Vec<Expr>,
}
impl SimpleExprParser {
pub fn new() -> SimpleExprParser {
SimpleExprParser { stack: vec![] }
}
pub fn push_atom(&mut self, c: char) -> Result<(), ParseError> {
if let Some(last) = self.stack.last() {
if matches!(last, Expr::And(_) | Expr::Or(_)) {
return Err(ParseError::UnexpectedExpr);
}
}
self.stack.push(Expr::Atom(c));
Ok(())
}
pub fn push_op(&mut self, op: char) -> Result<(), ParseError> {
if let Some(last) = self.stack.last() {
if matches!(last, Expr::And(_) | Expr::Or(_)) {
match op {
'&' | '|' => return Err(ParseError::UnexpectedBinOp),
'!' => return Err(ParseError::UnexpectedUnaryOp),
_ => unreachable!(),
}
}
} else if op == '!' {
return Err(ParseError::UnexpectedUnaryOp);
}
match op {
'&' => {
let ands = self.stack.drain(..).collect::<Vec<_>>();
self.stack.push(Expr::And(ands));
}
'|' => {
let ors = self.stack.drain(..).collect::<Vec<_>>();
self.stack.push(Expr::Or(ors));
}
'!' => {
let last = self.stack.pop().ok_or(ParseError::UnexpectedUnaryOp)?;
self.stack.push(Expr::Not(Box::new(last)));
}
_ => unreachable!(),
}
Ok(())
}
pub fn finish(self) -> Result<Expr, ParseError> {
if self.stack.len() != 1 {
Err(ParseError::UnexpectedEnd)
} else {
Ok(self.stack.into_iter().next().unwrap())
}
}
}
pub struct ExprParser {
stack: Vec<Expr>,
parens: i32,
}
impl ExprParser {
pub fn new() -> ExprParser {
ExprParser { stack: vec![], parens: 0 }
}
pub fn push_atom(&mut self, c: char) -> Result<(), ParseError> {
if let Some(last) = self.stack.last() {
if matches!(last, Expr::And(_) | Expr::Or(_)) {
return Err(ParseError::UnexpectedExpr);
}
}
self.stack.push(Expr::Atom(c));
Ok(())
}
pub fn push_op(&mut self, op: char) -> Result<(), ParseError> {
if let Some(last) = self.stack.last() {
if matches!(last, Expr::And(_) | Expr::Or(_)) {
match op {
'&' | '|' => return Err(ParseError::UnexpectedBinOp),
'!' => return Err(ParseError::UnexpectedUnaryOp),
_ => unreachable!(),
}
}
} else if op == '!' {
return Err(ParseError::UnexpectedUnaryOp);
}
match op {
'&' => {
let ands = self.stack.drain(..).collect::<Vec<_>>();
self.stack.push(Expr::And(ands));
}
'|' => {
let ors = self.stack.drain(..).collect::<Vec<_>>();
self.stack.push(Expr::Or(ors));
}
'!' => {
let last = self.stack.pop().ok_or(ParseError::UnexpectedUnaryOp)?;
self.stack.push(Expr::Not(Box::new(last)));
}
_ => unreachable!(),
}
Ok(())
}
pub fn open_paren(&mut self) -> Result<(), ParseError> {
self.parens += 1;
Ok(())
}
pub fn close_paren(&mut self) -> Result<(), ParseError> {
if self.parens == 0 {
return Err(ParseError::UnexpectedParen);
}
self.parens -= 1;
Ok(())
}
pub fn finish(self) -> Result<Expr, ParseError> {
if self.parens > 0 {
Err(ParseError::UnexpectedParen)
} else if self.stack.len() != 1 {
Err(ParseError::UnexpectedEnd)
} else {
Ok(self.stack.into_iter().next().unwrap())
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Value {
True,
False,
Expr(Expr),
}
pub fn eval(expr: &Expr, truthy: &[char], falsy: &[char]) -> Value {
match expr {
Expr::Atom(c) => {
if truthy.contains(c) {
Value::True
} else if falsy.contains(c) {
Value::False
} else {
Value::Expr(expr.clone())
}
}
Expr::Not(e) => {
let inner = eval(e, truthy, falsy);
match inner {
Value::True => Value::False,
Value::False => Value::True,
Value::Expr(inner_expr) => Value::Expr(Expr::Not(Box::new(inner_expr))),
}
}
Expr::And(es) => {
for e in es {
let value = eval(e, truthy, falsy);
if value == Value::False {
return Value::False;
}
}
Value::True
}
Expr::Or(es) => {
for e in es {
let value = eval(e, truthy, falsy);
if value == Value::True {
return Value::True;
}
}
Value::False
}
}
}
#[test]
fn test_basic_simple_parser() {
// A & B
let mut simple_parser = SimpleExprParser::new();
let _ = simple_parser.push_atom('A');
let _ = simple_parser.push_op('&');
let _ = simple_parser.push_atom('B');
let expr = simple_parser.finish().unwrap();
eval(&expr, &['A'], &['B']);
}
#[test]
fn test_basic_expr_parser() {
// A & (B | !C)
let mut full_parser = ExprParser::new();
let _ = full_parser.push_atom('A');
let _ = full_parser.push_op('&');
let _ = full_parser.open_paren();
let _ = full_parser.push_atom('B');
let _ = full_parser.push_op('|');
let _ = full_parser.push_op('!');
let _ = full_parser.push_atom('C');
let _ = full_parser.close_paren();
let expr = full_parser.finish().unwrap();
eval(&expr, &['A'], &['B']);
}
#[test]
fn test_basic_errors() {
let mut simple_parser = SimpleExprParser::new();
let _ = simple_parser.push_atom('A');
let _ = simple_parser.push_op('&');
assert_eq!(simple_parser.push_op('&'), Err(ParseError::UnexpectedBinOp));
let mut simple_parser = SimpleExprParser::new();
let _ = simple_parser.push_atom('A');
let _ = simple_parser.push_op('&');
let _ = simple_parser.push_atom('B');
assert_eq!(simple_parser.push_atom('B'), Err(ParseError::UnexpectedExpr));
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20241224-258381-sprno4/solution)
warning: variable does not need to be mutable
   --> tests/solution_test.rs:306:13
    |
306 |         let mut parser = SimpleExprParser::new();
    |             ----^^^^^^
    |             |
    |             help: remove this `mut`
    |
    = note: `#[warn(unused_mut)]` on by default

warning: `solution` (test "solution_test") generated 1 warning
    Finished test [unoptimized + debuginfo] target(s) in 1.79s
     Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165)

running 20 tests
test solution_test::test_eval_full ... ok
test solution_test::test_error_paren_mismatched ... FAILED
test solution_test::test_eval_not_and_or ... ok
test solution_test::test_eval_partial ... FAILED
test solution_test::test_eval_unwrap_nested ... FAILED
test solution_test::test_eval_unwrap_and_or ... FAILED
test solution_test::test_paren_around_expr ... FAILED
test solution_test::test_paren_expr_priority ... FAILED
test solution_test::test_paren_nested ... FAILED
test solution_test::test_paren_not ... FAILED
test solution_test::test_parser_alternating_ops ... FAILED
test solution_test::test_paren_surrounded ... FAILED
test solution_test::test_parser_and_or ... FAILED
test solution_test::test_parser_atom ... ok
test solution_test::test_parser_errors_basic ... FAILED
test solution_test::test_parser_error_unexpected_end ... FAILED
test solution_test::test_parser_expr_and_not ... FAILED
test solution_test::test_parser_multiple_atoms_same_op ... FAILED
test solution_test::test_parser_multiple_not ... FAILED
test solution_test::test_parser_not ... FAILED

failures:

---- solution_test::test_error_paren_mismatched stdout ----
thread '<unnamed>' panicked at 'assertion failed: matches!(parser.close_paren(), Err(_))', tests/solution_test.rs:331:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'solution_test::test_error_paren_mismatched' panicked at 'called `Option::unwrap()` on a `None` value', tests/solution_test.rs:325:5

---- solution_test::test_eval_partial stdout ----
thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
  left: `True`,
 right: `Expr(And([Atom('A'), Atom('C')]))`', tests/solution_test.rs:416:9
thread 'solution_test::test_eval_partial' panicked at 'assertion failed: `(left == right)`
  left: `True`,
 right: `Expr(And([Atom('A'), Atom('C')]))`', tests/solution_test.rs:409:5

---- solution_test::test_eval_unwrap_nested stdout ----
thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
  left: `True`,
 right: `Expr(Or([Atom('X'), Atom('B'), Not(Atom('D')), Atom('Y')]))`', tests/solution_test.rs:480:9
thread 'solution_test::test_eval_unwrap_nested' panicked at 'assertion failed: `(left == right)`
  left: `True`,
 right: `Expr(Or([Atom('X'), Atom('B'), Not(Atom('D')), Atom('Y')]))`', tests/solution_test.rs:479:5

---- solution_test::test_eval_unwrap_and_or stdout ----
thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
  left: `True`,
 right: `Expr(Atom('B'))`', tests/solution_test.rs:457:9
thread 'solution_test::test_eval_unwrap_and_or' panicked at 'assertion failed: `(left == right)`
  left: `True`,
 right: `Expr(Atom('B'))`', tests/solution_test.rs:456:5

---- solution_test::test_paren_around_expr stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:182:43
thread 'solution_test::test_paren_around_expr' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:176:5

---- solution_test::test_paren_expr_priority stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:199:47
thread 'solution_test::test_paren_expr_priority' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:197:5

---- solution_test::test_paren_nested stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:254:58
thread 'solution_test::test_paren_nested' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:252:5

---- solution_test::test_paren_not stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:218:48
thread 'solution_test::test_paren_not' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:216:5

---- solution_test::test_parser_alternating_ops stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:159:51
thread 'solution_test::test_parser_alternating_ops' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:157:5

---- solution_test::test_paren_surrounded stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:237:61
thread 'solution_test::test_paren_surrounded' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:235:5

---- solution_test::test_parser_and_or stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:87:43
thread 'solution_test::test_parser_and_or' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:84:5

---- solution_test::test_parser_errors_basic stdout ----
thread '<unnamed>' panicked at 'assertion failed: matches!(parser.push_op(\'&\'), Err(_))', tests/solution_test.rs:267:9
thread 'solution_test::test_parser_errors_basic' panicked at 'called `Option::unwrap()` on a `None` value', tests/solution_test.rs:265:5

---- solution_test::test_parser_error_unexpected_end stdout ----
thread '<unnamed>' panicked at 'assertion failed: matches!(parser.finish(), Err(_))', tests/solution_test.rs:311:9
thread 'solution_test::test_parser_error_unexpected_end' panicked at 'called `Option::unwrap()` on a `None` value', tests/solution_test.rs:305:5

---- solution_test::test_parser_expr_and_not stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:109:44
thread 'solution_test::test_parser_expr_and_not' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:107:5

---- solution_test::test_parser_multiple_atoms_same_op stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:126:47
thread 'solution_test::test_parser_multiple_atoms_same_op' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedExpr', tests/solution_test.rs:124:5

---- solution_test::test_parser_multiple_not stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:142:42
thread 'solution_test::test_parser_multiple_not' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:140:5

---- solution_test::test_parser_not stdout ----
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:100:40
thread 'solution_test::test_parser_not' panicked at 'called `Result::unwrap()` on an `Err` value: UnexpectedUnaryOp', tests/solution_test.rs:98:5


failures:
    solution_test::test_error_paren_mismatched
    solution_test::test_eval_partial
    solution_test::test_eval_unwrap_and_or
    solution_test::test_eval_unwrap_nested
    solution_test::test_paren_around_expr
    solution_test::test_paren_expr_priority
    solution_test::test_paren_nested
    solution_test::test_paren_not
    solution_test::test_paren_surrounded
    solution_test::test_parser_alternating_ops
    solution_test::test_parser_and_or
    solution_test::test_parser_error_unexpected_end
    solution_test::test_parser_errors_basic
    solution_test::test_parser_expr_and_not
    solution_test::test_parser_multiple_atoms_same_op
    solution_test::test_parser_multiple_not
    solution_test::test_parser_not

test result: FAILED. 3 passed; 17 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--test solution_test`

История (2 версии и 2 коментара)

Пламен качи първо решение на 18.12.2024 14:52 (преди 9 месеца)

Имаш някакъв фундаментален пропуск в решението и не изкарваш почти никакви точки. Препоръчвам да си напишеш тестове, защото тази задача е много трудно да се реши без тях. Погледни си решението отново и тествай стъпка по стъпка.

Пламен качи решение на 22.12.2024 15:52 (преди 9 месеца)

-#[warn(unused_variables)]
-#[derive(Clone, Debug, PartialEq, Eq)]
-
-pub enum Expr {
- Atom(char),
- Not(Box<Expr>),
- And(Vec<Expr>),
- Or(Vec<Expr>),
-}
-
#[derive(Debug, PartialEq, Eq)]
pub enum ParseError {
UnexpectedExpr,
UnexpectedUnaryOp,
UnexpectedBinOp,
UnexpectedParen,
UnexpectedEnd,
}
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum Expr {
+ Atom(char),
+ Not(Box<Expr>),
+ And(Vec<Expr>),
+ Or(Vec<Expr>),
+}
+
pub struct SimpleExprParser {
- current: Option<Expr>,
- last_op: Option<char>,
+ stack: Vec<Expr>,
}
impl SimpleExprParser {
pub fn new() -> SimpleExprParser {
- SimpleExprParser {
- current: None,
- last_op: None,
- }
+ SimpleExprParser { stack: vec![] }
}
pub fn push_atom(&mut self, c: char) -> Result<(), ParseError> {
- if self.last_op.is_some() {
- self.last_op = None;
- } else if self.current.is_some() {
- return Err(ParseError::UnexpectedExpr);
+ if let Some(last) = self.stack.last() {
+ if matches!(last, Expr::And(_) | Expr::Or(_)) {
+ return Err(ParseError::UnexpectedExpr);
+ }
}
- self.current = Some(Expr::Atom(c));
+ self.stack.push(Expr::Atom(c));
Ok(())
}
pub fn push_op(&mut self, op: char) -> Result<(), ParseError> {
- match op {
- '&' | '|' => {
- if self.last_op.is_some() || self.current.is_none() {
- return Err(ParseError::UnexpectedBinOp);
+ if let Some(last) = self.stack.last() {
+ if matches!(last, Expr::And(_) | Expr::Or(_)) {
+ match op {
+ '&' | '|' => return Err(ParseError::UnexpectedBinOp),
+ '!' => return Err(ParseError::UnexpectedUnaryOp),
+ _ => unreachable!(),
}
- self.last_op = Some(op);
}
+ } else if op == '!' {
+ return Err(ParseError::UnexpectedUnaryOp);
+ }
+
+ match op {
+ '&' => {
+ let ands = self.stack.drain(..).collect::<Vec<_>>();
+ self.stack.push(Expr::And(ands));
+ }
+ '|' => {
+ let ors = self.stack.drain(..).collect::<Vec<_>>();
+ self.stack.push(Expr::Or(ors));
+ }
'!' => {
- if self.last_op.is_some() {
- return Err(ParseError::UnexpectedUnaryOp);
- }
- self.current = Some(Expr::Not(Box::new(self.current.take().unwrap())));
+ let last = self.stack.pop().ok_or(ParseError::UnexpectedUnaryOp)?;
+ self.stack.push(Expr::Not(Box::new(last)));
}
- _ => panic!("Invalid operator provided"),
+ _ => unreachable!(),
}
Ok(())
}
pub fn finish(self) -> Result<Expr, ParseError> {
- if self.last_op.is_some() {
+ if self.stack.len() != 1 {
Err(ParseError::UnexpectedEnd)
} else {
- self.current.ok_or(ParseError::UnexpectedEnd)
+ Ok(self.stack.into_iter().next().unwrap())
}
}
}
pub struct ExprParser {
stack: Vec<Expr>,
- operators: Vec<char>,
+ parens: i32,
}
impl ExprParser {
pub fn new() -> ExprParser {
- ExprParser {
- stack: Vec::new(),
- operators: Vec::new(),
- }
+ ExprParser { stack: vec![], parens: 0 }
}
pub fn push_atom(&mut self, c: char) -> Result<(), ParseError> {
+ if let Some(last) = self.stack.last() {
+ if matches!(last, Expr::And(_) | Expr::Or(_)) {
+ return Err(ParseError::UnexpectedExpr);
+ }
+ }
self.stack.push(Expr::Atom(c));
Ok(())
}
pub fn push_op(&mut self, op: char) -> Result<(), ParseError> {
- if op == '!' {
- let expr = self.stack.pop().ok_or(ParseError::UnexpectedUnaryOp)?;
- self.stack.push(Expr::Not(Box::new(expr)));
- } else {
- self.operators.push(op);
+ if let Some(last) = self.stack.last() {
+ if matches!(last, Expr::And(_) | Expr::Or(_)) {
+ match op {
+ '&' | '|' => return Err(ParseError::UnexpectedBinOp),
+ '!' => return Err(ParseError::UnexpectedUnaryOp),
+ _ => unreachable!(),
+ }
+ }
+ } else if op == '!' {
+ return Err(ParseError::UnexpectedUnaryOp);
}
+
+ match op {
+ '&' => {
+ let ands = self.stack.drain(..).collect::<Vec<_>>();
+ self.stack.push(Expr::And(ands));
+ }
+ '|' => {
+ let ors = self.stack.drain(..).collect::<Vec<_>>();
+ self.stack.push(Expr::Or(ors));
+ }
+ '!' => {
+ let last = self.stack.pop().ok_or(ParseError::UnexpectedUnaryOp)?;
+ self.stack.push(Expr::Not(Box::new(last)));
+ }
+ _ => unreachable!(),
+ }
Ok(())
}
pub fn open_paren(&mut self) -> Result<(), ParseError> {
- self.operators.push('(');
+ self.parens += 1;
Ok(())
}
pub fn close_paren(&mut self) -> Result<(), ParseError> {
- while let Some(op) = self.operators.pop() {
- if op == '(' {
- break;
- }
+ if self.parens == 0 {
+ return Err(ParseError::UnexpectedParen);
}
+ self.parens -= 1;
Ok(())
}
- pub fn finish(mut self) -> Result<Expr, ParseError> {
- while let Some(op) = self.operators.pop() {
+ pub fn finish(self) -> Result<Expr, ParseError> {
+ if self.parens > 0 {
+ Err(ParseError::UnexpectedParen)
+ } else if self.stack.len() != 1 {
+ Err(ParseError::UnexpectedEnd)
+ } else {
+ Ok(self.stack.into_iter().next().unwrap())
}
- self.stack.pop().ok_or(ParseError::UnexpectedEnd)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Value {
True,
False,
Expr(Expr),
}
pub fn eval(expr: &Expr, truthy: &[char], falsy: &[char]) -> Value {
match expr {
Expr::Atom(c) => {
if truthy.contains(c) {
Value::True
} else if falsy.contains(c) {
Value::False
} else {
Value::Expr(expr.clone())
}
}
- Expr::Not(inner) => match eval(inner, truthy, falsy) {
- Value::True => Value::False,
- Value::False => Value::True,
- Value::Expr(e) => Value::Expr(Expr::Not(Box::new(e))),
- },
- Expr::And(exprs) => {
- let mut new_exprs = Vec::new();
- for e in exprs {
- match eval(e, truthy, falsy) {
- Value::True => {}
- Value::False => return Value::False,
- Value::Expr(ne) => new_exprs.push(ne),
+ Expr::Not(e) => {
+ let inner = eval(e, truthy, falsy);
+ match inner {
+ Value::True => Value::False,
+ Value::False => Value::True,
+ Value::Expr(inner_expr) => Value::Expr(Expr::Not(Box::new(inner_expr))),
+ }
+ }
+ Expr::And(es) => {
+ for e in es {
+ let value = eval(e, truthy, falsy);
+ if value == Value::False {
+ return Value::False;
}
}
- if new_exprs.is_empty() {
- Value::True
- } else {
- Value::Expr(Expr::And(new_exprs))
- }
+ Value::True
}
- Expr::Or(exprs) => {
- let mut new_exprs = Vec::new();
- for e in exprs {
- match eval(e, truthy, falsy) {
- Value::True => return Value::True,
- Value::False => {}
- Value::Expr(ne) => new_exprs.push(ne),
+ Expr::Or(es) => {
+ for e in es {
+ let value = eval(e, truthy, falsy);
+ if value == Value::True {
+ return Value::True;
}
}
- if new_exprs.is_empty() {
- Value::False
- } else {
- Value::Expr(Expr::Or(new_exprs))
- }
+ Value::False
}
}
}
+
+
#[test]
fn test_basic_simple_parser() {
// A & B
let mut simple_parser = SimpleExprParser::new();
let _ = simple_parser.push_atom('A');
let _ = simple_parser.push_op('&');
let _ = simple_parser.push_atom('B');
let expr = simple_parser.finish().unwrap();
eval(&expr, &['A'], &['B']);
}
#[test]
fn test_basic_expr_parser() {
// A & (B | !C)
let mut full_parser = ExprParser::new();
let _ = full_parser.push_atom('A');
let _ = full_parser.push_op('&');
let _ = full_parser.open_paren();
let _ = full_parser.push_atom('B');
let _ = full_parser.push_op('|');
let _ = full_parser.push_op('!');
let _ = full_parser.push_atom('C');
let _ = full_parser.close_paren();
let expr = full_parser.finish().unwrap();
eval(&expr, &['A'], &['B']);
}
#[test]
fn test_basic_errors() {
let mut simple_parser = SimpleExprParser::new();
let _ = simple_parser.push_atom('A');
let _ = simple_parser.push_op('&');
assert_eq!(simple_parser.push_op('&'), Err(ParseError::UnexpectedBinOp));
let mut simple_parser = SimpleExprParser::new();
let _ = simple_parser.push_atom('A');
let _ = simple_parser.push_op('&');
let _ = simple_parser.push_atom('B');
assert_eq!(simple_parser.push_atom('B'), Err(ParseError::UnexpectedExpr));
-}
-
+}
-fn main() {}