Я пытаюсь придумать макрос, который я бы назвал как
create_states!(S0, S1, final S2, final S3);
. Он создаст перечисление для представления состояний конечных автоматов, и некоторые из них будут конечными (принимающими) состояниями - S2
, S3
.Полученное перечисление и его impl
должны выглядеть следующим образом:
enum State {
S0,
S1,
S2,
S3,
}
impl State {
fn is_final(&self) -> bool {
match self {
Self::S2 => true,
Self::S3 => true,
_ => false,
}
}
}
Моя наивная попытка:
macro_rules! create_states {
($($r:ident),+, $(final $f:ident),*) => {
#[derive(Copy, Clone)]
enum State {
$($s),*
$($f),*
}
impl State {
fn is_final(&self) -> bool {
match self {
$(Self::$f => true,)*
_ => false,
}
}
}
}
}
заканчивается следующей ошибкой:
error: local ambiguity: multiple parsing options: built-in NTs ident ('r') or 1 other option.
--> src/lib.rs:20:24
|
20 | create_states!(S0, S1, final S2, final S3);
| ^^^^^
Попытка удалить запятую между шаблонами во второй строке:
($($r:ident),+ $(final $f:ident),*) => { ...
создает другую:
error: no rules expected the token `S2`
--> src/lib.rs:20:30
|
1 | macro_rules! create_states {
| -------------------------- when calling this macro
...
20 | create_states!(S0, S1, final S2, final S3);
| ^^ no rules expected this token in macro call
Я думаю Я понимаю, что вызывает этиошибки - он думает, что final
- это другой идентификатор, соответствующий r
.Но как правильно написать такой макрос (если это вообще возможно, без чрезмерного усложнения)?
Я обладаю полной гибкостью при вызове макросов, так как это мое личное упражнение.Основная цель - научиться правильно делать вещи.Было бы неплохо, чтобы этот макрос принимал final
в любой позиции, если это возможно.