Я хочу написать парсер. Мне кажется практичным иметь изменяемый Iterator
, который я могу передавать различным функциям синтаксического анализатора.
Я попытался проиллюстрировать упрощенный подход, который компилируется, но еще не идеален.
fn main() {
let tokens = vec!["fIrSt".to_string(), "SeConD".to_string(), "tHiRd".to_string(), "FoUrTh".to_string()];
let parsed = parse_input(tokens);
println!("{}", parsed);
}
fn parse_input(tokens: Vec<String>) -> String {
let mut tokens_iter = tokens.iter();
let upps = parse_upper(&mut tokens_iter);
let lowers = parse_lower(&mut tokens_iter);
upps + &lowers
}
fn parse_upper(tokens_iter: &mut Iterator<Item=&String>) -> String {
let mut result = String::new();
let token_1 = tokens_iter.next().unwrap().to_uppercase();
let token_2 = tokens_iter.next().unwrap().to_uppercase();
result.push_str(&token_1);
result.push_str(&token_2);
result
}
fn parse_lower(tokens_iter: &mut Iterator<Item=&String>) -> String {
let mut result = String::new();
let token_1 = tokens_iter.next().unwrap().to_lowercase();
let token_2 = tokens_iter.next().unwrap().to_lowercase();
result.push_str(&token_1);
result.push_str(&token_2);
result
}
Как работает пример: Допустим, у меня есть некоторые данные, которые уже были токенизированы. Здесь он представлен вектором tokens
(Vec<String>
). Внутри внешней функции parse_input
Vec
преобразуется в Iterator
, а затем передается в другие, специфические c функции синтаксического анализатора. Здесь: parse_upper
и parse_lower
. В реальной жизни это могут быть "parse_if_statement" или "parse_ while_l oop", но над какой частью работы Iterator
работают, это не относится к вопросу. Важно то, что при каждом следующем вызове курсор перемещается на Iterator
. Так что каждая функция потребляет части, которые ей нужны. Этот пример компилирует и выдает: FIRSTSECONDthirdfourth
Я хотел бы иметь возможность peek()
в Iterator
, прежде чем передать его функции. Это необходимо определить, какая функция должна быть вызвана. Но все, что я пробовал с использованием Peekable
вместо Iterator
, привело к полному времени жизни и заимствованию хаоса.
Любые предложения о том, как передать Peekable
вместо Iterator
в этом случае?
Возможно, использование Peekable
в качестве параметра функции - плохая идея. Или, возможно, мой Iterator
подход уже неверен. Все предложения / советы приветствуются.