Макро за изрази

Краен срок
22.12.2024 23:59
Точки
4

Срокът за предаване на решения е отминал

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[allow(dead_code)]
#[macro_use]
mod submod {
// HACK - include the solution code, so the macro is defined
// in the same crate and is thus visible to the testing code.
//
// I forgot to tell you to add `#[macro_use]`.
include!("../src/lib.rs");
}
#[test]
fn test_macro() {
expr!(atom('A'));
expr!(not(atom('A')));
expr!(and(atom('A'), atom('B'), atom('C')));
expr!(or(atom('A'), atom('B'), atom('C')));
expr!(not(and(atom('A'), atom('B'))));
expr!(not(or(atom('A'), atom('B'))));
expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
expr!(or(
atom('X'),
and(atom('A'), atom('B')),
not(and(atom('C'), atom('D'))),
not(not(not(atom('Y'))))
));
}

За тестване на домашното ще е нужно да си построите литерали от типа Expr.

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
    Atom(char),
    Not(Box<Expr>),
    And(Vec<Expr>),
    Or(Vec<Expr>),
}

Но това не е много удобно, защото синтаксиса става малко тежък - вложените енумерации, Box, Vec, много скоби.
Expr::Not(Box::new(Expr::Atom('A')))

От всичкия синтактичен шум става трудно да се прочете какъв е изразът. Едно макро би помогнало. (В случая и няколко свободни функции биха помогнали, но е добър пример, ако човек иска да се поупражни макроси.)

Напишете декларативно макро чрез macro_rules!, което конструира литерали от типа Expr.
Макрото трябва да поддържа следния синтаксис:

expr!(atom('A')),
expr!(not(atom('A'))),
expr!(and(atom('A'), atom('B'), atom('C'))),
expr!(or(atom('A'), atom('B'), atom('C'))),
expr!(not(and(atom('A'), atom('B')))),
expr!(not(or(atom('A'), atom('B')))),
expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D')))),
// и т.н.

Решения

Камен Младенов
  • Коректно
  • 1 успешни тест(а)
  • 0 неуспешни тест(а)
Камен Младенов

#[macro_export]
macro_rules! expr {
(atom ( $c:literal ) ) => {
Expr::Atom($c)
};
(not ( $name:tt $e:tt ) ) => {
Expr::Not(Box::new( expr!($name$e) ))
};
(and ( $($name:tt $e:tt),* ) ) => {
Expr::And(vec![$( expr!($name$e) ),*])
};
(or ( $($name:tt $e:tt),* ) ) => {
Expr::Or(vec![$( expr!($name$e) ),*])
};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-1e69npa/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.69s
     Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165)

running 1 test
test solution_test::test_macro ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Ясен Ефремов
  • Коректно
  • 1 успешни тест(а)
  • 0 неуспешни тест(а)
Ясен Ефремов

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[macro_export]
macro_rules! expr {
(atom ( $a:expr ) ) => (
Expr::Atom($a)
);
(not ( $i:ident $a:tt ) ) => (
Expr::Not(Box::new(expr!($i$a)))
);
(and ( $( $i:ident $a:tt ),+ $(,)? ) ) => {{
let mut ands = Vec::<Expr>::new();
$( ands.push(expr!($i$a)); )+
Expr::And(ands)
}};
(or ( $( $i:ident $a:tt ),+ $(,)? ) ) => {{
let mut ands = Vec::<Expr>::new();
$( ands.push(expr!($i$a)); )+
Expr::Or(ands)
}};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-caxrkq/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.68s
     Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165)

running 1 test
test solution_test::test_macro ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Станислав Иванов
  • Коректно
  • 1 успешни тест(а)
  • 0 неуспешни тест(а)
Станислав Иванов

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[macro_export]
macro_rules! expr {
(atom($char:literal)) => {
Expr::Atom($char)
};
(not($($inner:tt)*)) => {
Expr::Not(Box::new(expr!($($inner)*)))
};
(and($($inner:ident($($params:tt)*)),+)) => {
Expr::And(vec![$(expr!($inner($($params)*))),+])
};
(or($($inner:ident($($params:tt)*)),+)) => {
Expr::Or(vec![$(expr!($inner($($params)*))),+])
};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-on8ra9/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.79s
     Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165)

running 1 test
test solution_test::test_macro ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Василен Петков
  • Некоректно
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)
Василен Петков

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[macro_export]
macro_rules! expr {
(atom($x:expr)) => {
Expr::Atom($x)
};
(not($e:tt)) => {
Expr::Not(Box::new(expr!($e)))
};
(and($($e:tt),*)) => {
Expr::And(vec![$(expr!($e)),*])
};
(or($($e:tt),*)) => {
Expr::Or(vec![$(expr!($e)),*])
};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-1hi23o8/solution)
error: no rules expected the token `(`
  --> tests/solution_test.rs:23:19
   |
23 |     expr!(not(atom('A')));
   |                   ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:14:15
   |
14 |     (not($e:tt)) => {
   |               ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:24:19
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |                   ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:17:20
   |
17 |     (and($($e:tt),*)) => {
   |                    ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:25:18
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |                  ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:20:19
   |
20 |     (or($($e:tt),*)) => {
   |                   ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:27:18
   |
27 |     expr!(not(and(atom('A'), atom('B'))));
   |                  ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:14:15
   |
14 |     (not($e:tt)) => {
   |               ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:28:17
   |
28 |     expr!(not(or(atom('A'), atom('B'))));
   |                 ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:14:15
   |
14 |     (not($e:tt)) => {
   |               ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:29:17
   |
29 |     expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
   |                 ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:20:19
   |
20 |     (or($($e:tt),*)) => {
   |                   ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:32:13
   |
32 |         atom('X'),
   |             ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:20:19
   |
20 |     (or($($e:tt),*)) => {
   |                   ^

error: could not compile `solution` due to 7 previous errors
Александър Иванов
  • Коректно
  • 1 успешни тест(а)
  • 0 неуспешни тест(а)
Александър Иванов

#[macro_export]
macro_rules! expr {
{ atom($c:literal) } => { Expr::Atom($c) };
{ not($($inner:tt)*) } => { Expr::Not(Box::new(expr!($($inner)*))) };
{ and($($li:ident($($ex:tt)*)),+) } => { Expr::And(vec![$(expr!($li($($ex)*))),*]) };
{ or($($li:ident($($ex:tt)*)),+) } => { Expr::Or(vec![$(expr!($li($($ex)*))),*]) };
}
// втори вариант
// macro_rules! expr {
// { atom($c:literal) } => {
// Expr::Atom($c)
// };
// { not($($inner:tt)*) } => {
// Expr::Not(Box::new(expr!($($inner)*)))
// };
// { and($($li:ident($($ex:tt)*)),+) } => {
// {
// let mut v = Vec::new();
// $( v.push(expr!($li($($ex)*))); )*
// Expr::And(v)
// }
// };
// { or($($li:ident($($ex:tt)*)),+) } => {
// {
// let mut v = Vec::new();
// $( v.push(expr!($li($($ex)*))); )*
// Expr::Or(v)
// }
// };
// }
Compiling solution v0.1.0 (/tmp/d20241225-258381-1tj8q59/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.59s
     Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165)

running 1 test
test solution_test::test_macro ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Венцислав Монев
  • Коректно
  • 1 успешни тест(а)
  • 0 неуспешни тест(а)
Венцислав Монев

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[macro_export]
macro_rules! expr {
(atom($arg:expr)) => {
Expr::Atom($arg)
};
(not($inner:tt ($($args:tt)*))) => {
Expr::Not(Box::new(expr!($inner($($args)*))))
};
(and($($inner:tt($($args:tt)*)),* $(,)?)) => {
Expr::And(vec![$(expr!($inner($($args)*))),*])
};
(or($($inner:tt($($args:tt)*)),* $(,)?)) => {
Expr::Or(vec![$(expr!($inner($($args)*))),*])
};
}
fn main() {
let expr1 = expr!(atom('A'));
let expr2 = expr!(not(atom('A')));
let expr3 = expr!(and(atom('A'), atom('B'), atom('C')));
let expr4 = expr!(or(atom('A'), atom('B'), atom('C')));
let expr5 = expr!(not(and(atom('A'), atom('B'))));
let expr6 = expr!(not(or(atom('A'), atom('B'))));
let expr7 = expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
println!("{:?}",expr1);
println!("{:?}",expr2);
println!("{:?}",expr3);
println!("{:?}",expr4);
println!("{:?}",expr5);
println!("{:?}",expr6);
println!("{:?}",expr7);
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-atgc2q/solution)
warning: function `main` is never used
  --> src/lib.rs:28:4
   |
28 | fn main() {
   |    ^^^^
   |
   = note: `#[warn(dead_code)]` on by default

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

running 1 test
test solution_test::test_macro ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Юлиян Палов
  • Некоректно
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)
Юлиян Палов

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[macro_export]
macro_rules! expr {
(atom($c:expr)) => {
Expr::Atom($c)
};
(not($inner:tt)) => {
Expr::Not(Box::new(expr!($inner)))
};
(and($($rest:tt),+)) => {
Expr::And(vec![
$(expr!($rest)),+
])
};
(or($($rest:tt),+)) => {
Expr::Or(vec![
$(expr!($rest)),+
])
};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-cb7mlj/solution)
error: no rules expected the token `(`
  --> tests/solution_test.rs:23:19
   |
23 |     expr!(not(atom('A')));
   |                   ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:15:19
   |
15 |     (not($inner:tt)) => {
   |                   ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:24:19
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |                   ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:19:23
   |
19 |     (and($($rest:tt),+)) => {
   |                       ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:25:18
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |                  ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:25:22
   |
25 |     (or($($rest:tt),+)) => {
   |                      ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:27:18
   |
27 |     expr!(not(and(atom('A'), atom('B'))));
   |                  ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:15:19
   |
15 |     (not($inner:tt)) => {
   |                   ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:28:17
   |
28 |     expr!(not(or(atom('A'), atom('B'))));
   |                 ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:15:19
   |
15 |     (not($inner:tt)) => {
   |                   ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:29:17
   |
29 |     expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
   |                 ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:25:22
   |
25 |     (or($($rest:tt),+)) => {
   |                      ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:32:13
   |
32 |         atom('X'),
   |             ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:25:22
   |
25 |     (or($($rest:tt),+)) => {
   |                      ^

error: could not compile `solution` due to 7 previous errors
Александър Глушков
  • Некоректно
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)
Александър Глушков

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[macro_export]
macro_rules! expr {
(atom($ch:expr)) => {
Expr::Atom($ch)
};
(not($($inner:tt)*)) => {
Expr::Not(Box::new(expr!($($inner)*)))
};
(and($($e:tt),+)) => {
Expr::And(vec![$(expr!($e)),+])
};
(or($($e:tt),+)) => {
Expr::Or(vec![$(expr!($e)),+])
};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-yos83q/solution)
error: no rules expected the token `(`
  --> tests/solution_test.rs:24:19
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |                   ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:17:20
   |
17 |     (and($($e:tt),+)) => {
   |                    ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:25:18
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |                  ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:20:19
   |
20 |     (or($($e:tt),+)) => {
   |                   ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:27:23
   |
27 |     expr!(not(and(atom('A'), atom('B'))));
   |                       ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:17:20
   |
17 |     (and($($e:tt),+)) => {
   |                    ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:28:22
   |
28 |     expr!(not(or(atom('A'), atom('B'))));
   |                      ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:20:19
   |
20 |     (or($($e:tt),+)) => {
   |                   ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:29:17
   |
29 |     expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
   |                 ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:20:19
   |
20 |     (or($($e:tt),+)) => {
   |                   ^

error: no rules expected the token `(`
  --> tests/solution_test.rs:32:13
   |
32 |         atom('X'),
   |             ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:10:1
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:20:19
   |
20 |     (or($($e:tt),+)) => {
   |                   ^

error: could not compile `solution` due to 6 previous errors
Памела Славчева
  • Некоректно
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)
Памела Славчева

#[macro_export]
macro_rules! expr {
(atom($c:literal)) => {
Expr::Atom($c)
};
(not($some:expr)) => {
Expr::Not(Box::new(expr!($some)))
};
(and($($some:expr),+)) => {
Expr::And(vec![$(expr!($some)),+])
};
(or($($some:expr),+)) => {
Expr::Or(vec![$(expr!($some)),+])
};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-rdtrmp/solution)
error: no rules expected the token `atom('A')`
  --> tests/../src/lib.rs:8:34
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
8  |         Expr::Not(Box::new(expr!($some)))
   |                                  ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:23:5
   |
23 |     expr!(not(atom('A')));
   |     --------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('A')`
  --> tests/../src/lib.rs:12:32
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
12 |         Expr::And(vec![$(expr!($some)),+])
   |                                ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:24:5
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('B')`
  --> tests/../src/lib.rs:12:32
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
12 |         Expr::And(vec![$(expr!($some)),+])
   |                                ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:24:5
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('C')`
  --> tests/../src/lib.rs:12:32
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
12 |         Expr::And(vec![$(expr!($some)),+])
   |                                ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:24:5
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('A')`
  --> tests/../src/lib.rs:16:31
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
16 |         Expr::Or(vec![$(expr!($some)),+])
   |                               ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:25:5
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------ in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('B')`
  --> tests/../src/lib.rs:16:31
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
16 |         Expr::Or(vec![$(expr!($some)),+])
   |                               ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:25:5
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------ in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('C')`
  --> tests/../src/lib.rs:16:31
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
16 |         Expr::Or(vec![$(expr!($some)),+])
   |                               ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:25:5
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------ in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `and(atom('A'), atom('B'))`
  --> tests/../src/lib.rs:8:34
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
8  |         Expr::Not(Box::new(expr!($some)))
   |                                  ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:27:5
   |
27 |     expr!(not(and(atom('A'), atom('B'))));
   |     ------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `or(atom('A'), atom('B'))`
  --> tests/../src/lib.rs:8:34
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
8  |         Expr::Not(Box::new(expr!($some)))
   |                                  ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:28:5
   |
28 |     expr!(not(or(atom('A'), atom('B'))));
   |     ------------------------------------ in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `and(atom('A'), atom('B'))`
  --> tests/../src/lib.rs:16:31
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
16 |         Expr::Or(vec![$(expr!($some)),+])
   |                               ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:29:5
   |
29 |     expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
   |     --------------------------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `and(atom('C'), atom('D'))`
  --> tests/../src/lib.rs:16:31
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
...
16 |         Expr::Or(vec![$(expr!($some)),+])
   |                               ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:29:5
   |
29 |     expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
   |     --------------------------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('X')`
  --> tests/../src/lib.rs:16:31
   |
2  |   macro_rules! expr {
   |   ----------------- when calling this macro
...
16 |           Expr::Or(vec![$(expr!($some)),+])
   |                                 ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:31:5
   |
31 | /     expr!(or(
32 | |         atom('X'),
33 | |         and(atom('A'), atom('B')),
34 | |         not(and(atom('C'), atom('D'))),
35 | |         not(not(not(atom('Y'))))
36 | |     ));
   | |______- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `and(atom('A'), atom('B'))`
  --> tests/../src/lib.rs:16:31
   |
2  |   macro_rules! expr {
   |   ----------------- when calling this macro
...
16 |           Expr::Or(vec![$(expr!($some)),+])
   |                                 ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:31:5
   |
31 | /     expr!(or(
32 | |         atom('X'),
33 | |         and(atom('A'), atom('B')),
34 | |         not(and(atom('C'), atom('D'))),
35 | |         not(not(not(atom('Y'))))
36 | |     ));
   | |______- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `not(and(atom('C'), atom('D')))`
  --> tests/../src/lib.rs:16:31
   |
2  |   macro_rules! expr {
   |   ----------------- when calling this macro
...
16 |           Expr::Or(vec![$(expr!($some)),+])
   |                                 ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:31:5
   |
31 | /     expr!(or(
32 | |         atom('X'),
33 | |         and(atom('A'), atom('B')),
34 | |         not(and(atom('C'), atom('D'))),
35 | |         not(not(not(atom('Y'))))
36 | |     ));
   | |______- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `not(not(not(atom('Y'))))`
  --> tests/../src/lib.rs:16:31
   |
2  |   macro_rules! expr {
   |   ----------------- when calling this macro
...
16 |           Expr::Or(vec![$(expr!($some)),+])
   |                                 ^^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:31:5
   |
31 | /     expr!(or(
32 | |         atom('X'),
33 | |         and(atom('A'), atom('B')),
34 | |         not(and(atom('C'), atom('D'))),
35 | |         not(not(not(atom('Y'))))
36 | |     ));
   | |______- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:3:6
   |
3  |     (atom($c:literal)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `solution` due to 15 previous errors
Стоян Генчев
  • Коректно
  • 1 успешни тест(а)
  • 0 неуспешни тест(а)
Стоян Генчев

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[macro_export]
macro_rules! expr {
(atom( $c:expr )) => {{
Expr::Atom($c)
}};
(and( $( atom( $c:expr ) ),+ )) => {{
Expr::And(vec![$( Expr::Atom($c) ),+])
}};
(and( atom( $c:expr ), $($rest:tt)+ )) => {{
let mut v = Vec::new();
v.push(Expr::Atom($c));
if let Expr::And(vec) = expr!(and($($rest)+)) {
for e in vec {
v.push(e);
}
}
Expr::And(v)
}};
(and( $( and( $($and:tt)+ ) ),+ )) => {{
Expr::And(vec![$( expr!(and($($and)+)) ),+])
}};
(and( and( $( $and:tt )+ ), $( $rest:tt )+ )) => {{
let mut v = Vec::new();
v.push(expr!(and($($and)+)));
if let Expr::And(vec) = expr!(and($($rest)+)) {
for e in vec {
v.push(e);
}
}
Expr::And(v)
}};
(and( $( or( $($or:tt)+ ) ),+ )) => {{
Expr::And(vec![$( expr!(or($($or)+)) ),+])
}};
(and( or( $( $or:tt )+ ), $( $rest:tt )+ )) => {{
let mut v = Vec::new();
v.push(expr!(or($($or)+)));
if let Expr::And(vec) = expr!(and($($rest)+)) {
for e in vec {
v.push(e);
}
}
Expr::And(v)
}};
(and( $( not( $($expr:tt)+ ) ),+ )) => {{
Expr::And(vec![$( expr!(not($($expr)+)) ),+])
}};
(and( not( $( $expr:tt )+ ), $( $rest:tt )+ )) => {{
let mut v = Vec::new();
v.push(expr!(not($($expr)+)));
if let Expr::And(vec) = expr!(and($($rest)+)) {
for e in vec {
v.push(e);
}
}
Expr::And(v)
}};
(or( $( atom( $c:expr ) ),+ )) => {{
Expr::Or(vec![$( Expr::Atom($c) ),+])
}};
(or( atom( $c:expr ), $($rest:tt)+ )) => {{
let mut v = Vec::new();
v.push(Expr::Atom($c));
if let Expr::Or(vec) = expr!(or($($rest)+)) {
for e in vec {
v.push(e);
}
}
Expr::Or(v)
}};
(or( $( and( $($and:tt)+ ) ),+ )) => {{
Expr::Or(vec![$( expr!(and($($and)+)) ),+])
}};
(or( and( $( $and:tt )+ ), $( $rest:tt )+ )) => {{
let mut v = Vec::new();
v.push(expr!(and($($and)+)));
if let Expr::Or(vec) = expr!(or($($rest)+)) {
for e in vec {
v.push(e);
}
}
Expr::Or(v)
}};
(or( $( or( $($or:tt)+ ) ),+ )) => {{
Expr::Or(vec![$( expr!(or($($or)+)) ),+])
}};
(or( or( $( $or:tt )+ ), $( $rest:tt )+ )) => {{
let mut v = Vec::new();
v.push(expr!(or($($or)+)));
if let Expr::Or(vec) = expr!(or($($rest)+)) {
for e in vec {
v.push(e);
}
}
Expr::Or(v)
}};
(or( $( not( $($expr:tt)+ ) ),+ )) => {{
Expr::Or(vec![$( expr!(not($($expr)+)) ),+])
}};
(or( not( $( $expr:tt )+ ), $( $rest:tt )+ )) => {{
let mut v = Vec::new();
v.push(expr!(not($($expr)+)));
if let Expr::Or(vec) = expr!(or($($rest)+)) {
for e in vec {
v.push(e);
}
}
Expr::Or(v)
}};
(not(atom( $c:expr ))) => {{
Expr::Not(Box::new(Expr::Atom($c)))
}};
(not(and( $( $and:tt )+ ))) => {{
Expr::Not(Box::new(expr!(and($($and)+))))
}};
(not(or( $( $or:tt )+ ))) => {{
Expr::Not(Box::new(expr!(or($($or)+))))
}};
(not(not( $( $expr:tt )+ ))) => {{
Expr::Not(Box::new(expr!(not($($expr)+))))
}};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-oau4qi/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.71s
     Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165)

running 1 test
test solution_test::test_macro ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Петър Велков
  • Коректно
  • 1 успешни тест(а)
  • 0 неуспешни тест(а)
Петър Велков

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[macro_export]
macro_rules! expr {
(atom($c:expr)) => {
Expr::Atom($c)
};
(not($($inner:tt)*)) => {
Expr::Not(Box::new(expr!($($inner)*)))
};
(and($($op:ident($($argv:tt)*)),+)) => {
Expr::And(vec![$(expr!($op($($argv)*))),+])
};
(or($($op:ident($($argv:tt)*)),+)) => {
Expr::Or(vec![$(expr!($op($($argv)*))),+])
};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-1vx1xks/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.63s
     Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165)

running 1 test
test solution_test::test_macro ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Ивайло Генчев
  • Некоректно
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)
Ивайло Генчев

#[macro_export]
macro_rules! expr {
($op:ident ( $($inner: tt)?) ) => {
match (stringify!($op)) {
"atom" => {
Expr::Atom($($inner)?)
}
_ => {
panic!("Invalid atom expr syntax");
}
}
};
// TODO: something like this for and/or and then nested looping
// ($op: ident ( $( $inner: tt ),*)) => {
//
// };
($op:ident ( $($inner: tt)+ ) ) => {
match (stringify!($op)) {
"not" => {
Expr::Not(Box::new(expr! ($($inner)?)))
}
"and" => {
panic!("WIP");
}
"or" => {
panic!("WIP");
}
_ => {
panic!("Invalid not expr syntax");
}
}
};
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-1fx6jc5/solution)
error: no rules expected the token `,`
  --> tests/solution_test.rs:24:24
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |                        ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:2:1
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:3:32
   |
3  |     ($op:ident ( $($inner: tt)?) ) => {
   |                                ^

error: no rules expected the token `,`
  --> tests/solution_test.rs:25:23
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |                       ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:2:1
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:3:32
   |
3  |     ($op:ident ( $($inner: tt)?) ) => {
   |                                ^

error: no rules expected the token `,`
  --> tests/solution_test.rs:27:28
   |
27 |     expr!(not(and(atom('A'), atom('B'))));
   |                            ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:2:1
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:3:32
   |
3  |     ($op:ident ( $($inner: tt)?) ) => {
   |                                ^

error: no rules expected the token `,`
  --> tests/solution_test.rs:28:27
   |
28 |     expr!(not(or(atom('A'), atom('B'))));
   |                           ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:2:1
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:3:32
   |
3  |     ($op:ident ( $($inner: tt)?) ) => {
   |                                ^

error: no rules expected the token `,`
  --> tests/solution_test.rs:29:39
   |
29 |     expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
   |                                       ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:2:1
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:20:33
   |
20 |     ($op:ident ( $($inner: tt)+ ) ) => {
   |                                 ^

error: no rules expected the token `,`
  --> tests/solution_test.rs:32:18
   |
32 |         atom('X'),
   |                  ^ no rules expected this token in macro call
   |
  ::: tests/../src/lib.rs:2:1
   |
2  | macro_rules! expr {
   | ----------------- when calling this macro
   |
note: while trying to match `)`
  --> tests/../src/lib.rs:3:32
   |
3  |     ($op:ident ( $($inner: tt)?) ) => {
   |                                ^

error: could not compile `solution` due to 6 previous errors
Ангел Пенчев
  • Некоректно
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)
Ангел Пенчев

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Atom(char),
Not(Box<Expr>),
And(Vec<Expr>),
Or(Vec<Expr>),
}
#[macro_export]
macro_rules! expr {
(atom($ch:expr)) => {
Expr::Atom($ch)
};
(not($($inner:tt)*)) => {
Expr::Not(Box::new(expr!($($inner)*)))
};
(and($($arg:expr),*)) => {
Expr::And(vec![$(expr!($arg)),*])
};
(or($($arg:expr),*)) => {
Expr::Or(vec![$(expr!($arg)),*])
};
(($($inner:tt)*)) => {
expr!($($inner)*)
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let expr1 = expr!(atom('A'));
let expr2 = expr!(not(atom('A')));
println!("{:?}", expr1);
println!("{:?}", expr2);
}
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-mvfqsm/solution)
error: no rules expected the token `atom('A')`
  --> tests/../src/lib.rs:18:32
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
18 |         Expr::And(vec![$(expr!($arg)),*])
   |                                ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:24:5
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('B')`
  --> tests/../src/lib.rs:18:32
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
18 |         Expr::And(vec![$(expr!($arg)),*])
   |                                ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:24:5
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('C')`
  --> tests/../src/lib.rs:18:32
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
18 |         Expr::And(vec![$(expr!($arg)),*])
   |                                ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:24:5
   |
24 |     expr!(and(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('A')`
  --> tests/../src/lib.rs:21:31
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
21 |         Expr::Or(vec![$(expr!($arg)),*])
   |                               ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:25:5
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------ in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('B')`
  --> tests/../src/lib.rs:21:31
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
21 |         Expr::Or(vec![$(expr!($arg)),*])
   |                               ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:25:5
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------ in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('C')`
  --> tests/../src/lib.rs:21:31
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
21 |         Expr::Or(vec![$(expr!($arg)),*])
   |                               ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:25:5
   |
25 |     expr!(or(atom('A'), atom('B'), atom('C')));
   |     ------------------------------------------ in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('A')`
  --> tests/../src/lib.rs:18:32
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
18 |         Expr::And(vec![$(expr!($arg)),*])
   |                                ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:27:5
   |
27 |     expr!(not(and(atom('A'), atom('B'))));
   |     ------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('B')`
  --> tests/../src/lib.rs:18:32
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
18 |         Expr::And(vec![$(expr!($arg)),*])
   |                                ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:27:5
   |
27 |     expr!(not(and(atom('A'), atom('B'))));
   |     ------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('A')`
  --> tests/../src/lib.rs:21:31
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
21 |         Expr::Or(vec![$(expr!($arg)),*])
   |                               ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:28:5
   |
28 |     expr!(not(or(atom('A'), atom('B'))));
   |     ------------------------------------ in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('B')`
  --> tests/../src/lib.rs:21:31
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
21 |         Expr::Or(vec![$(expr!($arg)),*])
   |                               ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:28:5
   |
28 |     expr!(not(or(atom('A'), atom('B'))));
   |     ------------------------------------ in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `and(atom('A'), atom('B'))`
  --> tests/../src/lib.rs:21:31
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
21 |         Expr::Or(vec![$(expr!($arg)),*])
   |                               ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:29:5
   |
29 |     expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
   |     --------------------------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `and(atom('C'), atom('D'))`
  --> tests/../src/lib.rs:21:31
   |
10 | macro_rules! expr {
   | ----------------- when calling this macro
...
21 |         Expr::Or(vec![$(expr!($arg)),*])
   |                               ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:29:5
   |
29 |     expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
   |     --------------------------------------------------------------- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `atom('X')`
  --> tests/../src/lib.rs:21:31
   |
10 |   macro_rules! expr {
   |   ----------------- when calling this macro
...
21 |           Expr::Or(vec![$(expr!($arg)),*])
   |                                 ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:31:5
   |
31 | /     expr!(or(
32 | |         atom('X'),
33 | |         and(atom('A'), atom('B')),
34 | |         not(and(atom('C'), atom('D'))),
35 | |         not(not(not(atom('Y'))))
36 | |     ));
   | |______- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `and(atom('A'), atom('B'))`
  --> tests/../src/lib.rs:21:31
   |
10 |   macro_rules! expr {
   |   ----------------- when calling this macro
...
21 |           Expr::Or(vec![$(expr!($arg)),*])
   |                                 ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:31:5
   |
31 | /     expr!(or(
32 | |         atom('X'),
33 | |         and(atom('A'), atom('B')),
34 | |         not(and(atom('C'), atom('D'))),
35 | |         not(not(not(atom('Y'))))
36 | |     ));
   | |______- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `not(and(atom('C'), atom('D')))`
  --> tests/../src/lib.rs:21:31
   |
10 |   macro_rules! expr {
   |   ----------------- when calling this macro
...
21 |           Expr::Or(vec![$(expr!($arg)),*])
   |                                 ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:31:5
   |
31 | /     expr!(or(
32 | |         atom('X'),
33 | |         and(atom('A'), atom('B')),
34 | |         not(and(atom('C'), atom('D'))),
35 | |         not(not(not(atom('Y'))))
36 | |     ));
   | |______- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `not(not(not(atom('Y'))))`
  --> tests/../src/lib.rs:21:31
   |
10 |   macro_rules! expr {
   |   ----------------- when calling this macro
...
21 |           Expr::Or(vec![$(expr!($arg)),*])
   |                                 ^^^^ no rules expected this token in macro call
   |
  ::: tests/solution_test.rs:31:5
   |
31 | /     expr!(or(
32 | |         atom('X'),
33 | |         and(atom('A'), atom('B')),
34 | |         not(and(atom('C'), atom('D'))),
35 | |         not(not(not(atom('Y'))))
36 | |     ));
   | |______- in this macro invocation
   |
note: while trying to match `atom`
  --> tests/../src/lib.rs:11:6
   |
11 |     (atom($ch:expr)) => {
   |      ^^^^
   = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `solution` due to 16 previous errors
Виктор Веселинов
  • Некоректно
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)
Виктор Веселинов

#[macro_export]
macro_rules! expr {
(atom($c:expr)) => {
Expr::Atom($c)
};
(not($($e:tt)+)) => {
Expr::Not(Box::new(expr!($($e)+)))
};
(and $($e:tt)+) => {
Expr::And(vec![$e, *])
};
(or $($e:tt)+) => {
Expr::Or(vec![$e, *])
};
($op:ident($($e:tt),+)) => {
Expr::$op(vec![$(expr!($e)),+])
};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-1ig3fqt/solution)
error: variable 'e' is still repeating at this depth
  --> tests/../src/lib.rs:11:24
   |
11 |         Expr::And(vec![$e, *])
   |                        ^^

error: variable 'e' is still repeating at this depth
  --> tests/../src/lib.rs:15:23
   |
15 |         Expr::Or(vec![$e, *])
   |                       ^^

error: could not compile `solution` due to 2 previous errors
Йоанна Ненкова
  • Некоректно
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)
Йоанна Ненкова

#[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,
}
pub struct SimpleExprParser {
current_expr: Option<Expr>,
current_op: Option<char>,
}
impl SimpleExprParser {
pub fn new() -> SimpleExprParser {
SimpleExprParser {
current_expr: None,
current_op: None,
}
}
pub fn push_atom(&mut self, c: char) -> Result<(), ParseError> {
if self.current_op == Some('!') {
self.current_expr = Some(Expr::Not(Box::new(Expr::Atom(c))));
self.current_op = None;
} else if let Some(op) = self.current_op {
let new_expr = Expr::Atom(c);
self.current_expr = match op {
'&' => self.combine(&Expr::And, new_expr),
'|' => self.combine(&Expr::Or, new_expr),
_ => return Err(ParseError::UnexpectedBinOp),
};
self.current_op = None;
} else if self.current_expr.is_some() {
return Err(ParseError::UnexpectedExpr);
} else {
self.current_expr = Some(Expr::Atom(c));
}
Ok(())
}
pub fn push_op(&mut self, op: char) -> Result<(), ParseError> {
if self.current_op.is_some() {
return Err(ParseError::UnexpectedBinOp);
}
if self.current_expr.is_none() && op != '!' {
return Err(ParseError::UnexpectedExpr);
}
self.current_op = Some(op);
Ok(())
}
pub fn finish(self) -> Result<Expr, ParseError> {
self.current_expr.ok_or(ParseError::UnexpectedEnd)
}
fn combine<F>(&mut self, constructor: &F, new_expr: Expr) -> Option<Expr>
where
F: FnOnce(Vec<Expr>) -> Expr + Clone,
{
match self.current_expr.take() {
Some(Expr::And(mut vec)) if std::mem::discriminant(&constructor.clone()(vec![])) == std::mem::discriminant(&Expr::And(vec![]))
=> {
vec.push(new_expr);
Some(Expr::And(vec))
}
Some(Expr::Or(mut vec)) if std::mem::discriminant(&constructor.clone()(vec![])) == std::mem::discriminant(&Expr::Or(vec![]))
=> {
vec.push(new_expr);
Some(Expr::Or(vec))
}
Some(expr) => Some(constructor.clone()(vec![expr, new_expr])),
None => None,
}
}
}
pub struct ExprParser {
stack: Vec<(Option<char>, Option<Expr>)>,
}
impl ExprParser {
pub fn new() -> ExprParser {
ExprParser { stack: vec![] }
}
pub fn push_atom(&mut self, c: char) -> Result<(), ParseError> {
self.push_expr(Expr::Atom(c))
}
pub fn push_op(&mut self, op: char) -> Result<(), ParseError> {
if let Some((None, None)) = self.stack.last() {
self.stack.push((Some(op), None));
} else {
return Err(ParseError::UnexpectedUnaryOp);
}
Ok(())
}
pub fn open_paren(&mut self) -> Result<(), ParseError> {
self.stack.push((None, None));
Ok(())
}
pub fn close_paren(&mut self) -> Result<(), ParseError> {
if let Some((_op, expr)) = self.stack.pop() {
if let Some(e) = expr {
self.push_expr(e)?;
} else {
return Err(ParseError::UnexpectedParen);
}
} else {
return Err(ParseError::UnexpectedParen);
}
Ok(())
}
pub fn finish(mut self) -> Result<Expr, ParseError> {
if let Some((_, Some(expr))) = self.stack.pop() {
Ok(expr)
} else {
Err(ParseError::UnexpectedEnd)
}
}
fn push_expr(&mut self, expr: Expr) -> Result<(), ParseError> {
if let Some((op, current_expr)) = self.stack.last_mut() {
match op {
Some('&') => *current_expr = combine(&Expr::And, current_expr.take(), expr),
Some('|') => *current_expr = combine(&Expr::Or, current_expr.take(), expr),
Some('!') => *current_expr = Some(Expr::Not(Box::new(expr))),
_ => *current_expr = Some(expr),
}
} else {
self.stack.push((None, Some(expr)));
}
Ok(())
}
}
fn combine<F>(constructor: &F, current_expr: Option<Expr>, new_expr: Expr) -> Option<Expr>
where
F: FnOnce(Vec<Expr>) -> Expr + Clone,
{
match current_expr {
Some(Expr::And(mut vec)) if std::mem::discriminant(&constructor.clone()(vec![])) == std::mem::discriminant(&Expr::And(vec![]))
=> {
vec.push(new_expr);
Some(Expr::And(vec))
}
Some(Expr::Or(mut vec)) if std::mem::discriminant(&constructor.clone()(vec![])) == std::mem::discriminant(&Expr::Or(vec![]))
=> {
vec.push(new_expr);
Some(Expr::Or(vec))
}
Some(expr) => Some(constructor.clone()(vec![expr, new_expr])),
None => Some(new_expr),
}
}
#[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(operands) => {
let mut simplified = vec![];
for operand in operands {
match eval(operand, truthy, falsy) {
Value::True => continue,
Value::False => return Value::False,
Value::Expr(e) => simplified.push(e),
}
}
match simplified.len() {
0 => Value::True,
1 => Value::Expr(simplified.pop().unwrap()),
_ => Value::Expr(Expr::And(simplified)),
}
}
Expr::Or(operands) => {
let mut simplified = vec![];
for operand in operands {
match eval(operand, truthy, falsy) {
Value::True => return Value::True,
Value::False => continue,
Value::Expr(e) => simplified.push(e),
}
}
match simplified.len() {
0 => Value::False,
1 => Value::Expr(simplified.pop().unwrap()),
_ => Value::Expr(Expr::Or(simplified)),
}
}
}
}
#[macro_export]
macro_rules! expr {
(atom($c:expr)) => {
Expr::Atom($c)
};
(not($e:tt)) => {
Expr::Not(Box::new(expr!($e)))
};
(and($($e:tt),*)) => {
Expr::And(vec![$(expr!($e)),*])
};
(or($($e:tt),*)) => {
Expr::Or(vec![$(expr!($e)),*])
};
(($($e:tt)*)) => {
expr!($($e)*)
};
}
Compiling solution v0.1.0 (/tmp/d20241225-258381-184204k/solution)
error: no rules expected the token `(`
   --> tests/solution_test.rs:23:19
    |
23  |     expr!(not(atom('A')));
    |                   ^ no rules expected this token in macro call
    |
   ::: tests/../src/lib.rs:226:1
    |
226 | macro_rules! expr {
    | ----------------- when calling this macro
    |
note: while trying to match `)`
   --> tests/../src/lib.rs:231:15
    |
231 |     (not($e:tt)) => {
    |               ^

error: no rules expected the token `(`
   --> tests/solution_test.rs:24:19
    |
24  |     expr!(and(atom('A'), atom('B'), atom('C')));
    |                   ^ no rules expected this token in macro call
    |
   ::: tests/../src/lib.rs:226:1
    |
226 | macro_rules! expr {
    | ----------------- when calling this macro
    |
note: while trying to match `)`
   --> tests/../src/lib.rs:235:20
    |
235 |     (and($($e:tt),*)) => {
    |                    ^

error: no rules expected the token `(`
   --> tests/solution_test.rs:25:18
    |
25  |     expr!(or(atom('A'), atom('B'), atom('C')));
    |                  ^ no rules expected this token in macro call
    |
   ::: tests/../src/lib.rs:226:1
    |
226 | macro_rules! expr {
    | ----------------- when calling this macro
    |
note: while trying to match `)`
   --> tests/../src/lib.rs:239:19
    |
239 |     (or($($e:tt),*)) => {
    |                   ^

error: no rules expected the token `(`
   --> tests/solution_test.rs:27:18
    |
27  |     expr!(not(and(atom('A'), atom('B'))));
    |                  ^ no rules expected this token in macro call
    |
   ::: tests/../src/lib.rs:226:1
    |
226 | macro_rules! expr {
    | ----------------- when calling this macro
    |
note: while trying to match `)`
   --> tests/../src/lib.rs:231:15
    |
231 |     (not($e:tt)) => {
    |               ^

error: no rules expected the token `(`
   --> tests/solution_test.rs:28:17
    |
28  |     expr!(not(or(atom('A'), atom('B'))));
    |                 ^ no rules expected this token in macro call
    |
   ::: tests/../src/lib.rs:226:1
    |
226 | macro_rules! expr {
    | ----------------- when calling this macro
    |
note: while trying to match `)`
   --> tests/../src/lib.rs:231:15
    |
231 |     (not($e:tt)) => {
    |               ^

error: no rules expected the token `(`
   --> tests/solution_test.rs:29:17
    |
29  |     expr!(or(and(atom('A'), atom('B')), and(atom('C'), atom('D'))));
    |                 ^ no rules expected this token in macro call
    |
   ::: tests/../src/lib.rs:226:1
    |
226 | macro_rules! expr {
    | ----------------- when calling this macro
    |
note: while trying to match `)`
   --> tests/../src/lib.rs:239:19
    |
239 |     (or($($e:tt),*)) => {
    |                   ^

error: no rules expected the token `(`
   --> tests/solution_test.rs:32:13
    |
32  |         atom('X'),
    |             ^ no rules expected this token in macro call
    |
   ::: tests/../src/lib.rs:226:1
    |
226 | macro_rules! expr {
    | ----------------- when calling this macro
    |
note: while trying to match `)`
   --> tests/../src/lib.rs:239:19
    |
239 |     (or($($e:tt),*)) => {
    |                   ^

error: could not compile `solution` due to 7 previous errors