Я создаю синтаксический анализатор, используя nom , и я хотел бы использовать комбинаторы nom для обработки входных токенов.
Поток токенов представлен Vec<Token<S>>
, с Token
:
#[derive(Debug, Clone, PartialEq)]
pub enum Token<S> {
Identifier(S),
String(S),
}
Я попытался реализовать InputIter
для вектора произвольных значений:
impl<'a, T> InputIter for Vec<T> {
type Item = T;
type Iter = Enumerate<Self::IterElem>;
type IterElem = Iter<'a, Self::Item>;
fn iter_indices(&self) -> Self::Iter {
self.iter().enumerate()
}
fn iter_elements(&self) -> Self::IterElem {
self.iter()
}
}
Когда я столкнулся со следующей ошибкой:
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> src/lex/tokens.rs:37:6
|
37 | impl<'a, T> InputIter for Vec<T> {
| ^^ unconstrained lifetime parameter
Затем я попытался ограничить параметр времени жизни с помощью параметра типа Token<S>
:
impl<'a> InputIter for Vec<Token<&'a str>> {
type Item = Token<&'a str>;
type Iter = Enumerate<Self::IterElem>;
type IterElem = Iter<'a, Self::Item>;
fn iter_indices(&self) -> Self::Iter {
self.iter().enumerate()
}
fn iter_elements(&self) -> Self::IterElem {
self.iter()
}
}
, что привело к следующему:
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/lex/tokens.rs:51:1
|
51 | impl<'a> InputIter for Vec<Token<&'a str>> {
| ^^^^^^^^^^^^^^^^^^^^^^^-------------------
| | |
| | `std::vec::Vec` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
Ошибка, по-видимому, означает, что я могу не реализую внешнюю черту для внешнего типа, поэтому я пытаюсь заключить Vec<Token<S>>
в пользовательскую структуру:
struct Tokens<S> {
vec: Vec<Token<S>>,
}
impl<'a> InputIter for Tokens<&'a str> {
type Item = Token<&'a str>;
type Iter = Enumerate<Self::IterElem>;
type IterElem = Iter<'a, Self::Item>;
fn iter_indices(&self) -> Self::Iter {
self.vec.iter().enumerate()
}
fn iter_elements(&self) -> Self::IterElem {
self.vec.iter()
}
}
, что приводит к следующей ошибке:
error[E0271]: type mismatch resolving `<std::iter::Enumerate<std::slice::Iter<'_, lex::tokens::Token<&str>>> as std::iter::Iterator>::Item == (usize, lex::tokens::Token<&str>)`
--> src/lex/tokens.rs:56:3
|
55 | impl<'a> InputIter for Tokens<&'a str> {
| -------------------------------------- in this `impl` item
56 | type Item = Token<&'a str>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found enum `lex::tokens::Token`
|
= note: expected tuple `(_, &lex::tokens::Token<&str>)`
found tuple `(_, lex::tokens::Token<&str>)`
Означает ли это, что я ограничен использованием вектора ссылок в отличие от вектора, содержащего токены напрямую? Что дает? Кажется, в объявлении InputIter
нет ничего, что подразумевало бы это ограничение.
Есть ли другой способ выполнить sh то, что я пытаюсь сделать, и представить токен поток, совместимый с именованными комбинаторами?
Воспроизводимый пример детская площадка :
use std::iter::Enumerate;
use std::slice::Iter;
#[derive(Debug, Clone, PartialEq)]
pub enum Token<S> {
Identifier(S),
String(S),
}
struct Tokens<S> {
vec: Vec<Token<S>>,
}
pub trait InputIter {
type Item;
type Iter: Iterator<Item = (usize, Self::Item)>;
type IterElem: Iterator<Item = Self::Item>;
fn iter_indices(&self) -> Self::Iter;
fn iter_elements(&self) -> Self::IterElem;
}
impl<'a> InputIter for Tokens<&'a str> {
type Item = Token<&'a str>;
type Iter = Enumerate<Self::IterElem>;
type IterElem = Iter<'a, Token<&'a str>>;
fn iter_indices(&self) -> Self::Iter {
self.vec.iter().enumerate()
}
fn iter_elements(&self) -> Self::IterElem {
self.vec.iter()
}
}
fn main() {}
error[E0271]: type mismatch resolving `<std::slice::Iter<'_, Token<&str>> as std::iter::Iterator>::Item == Token<&str>`
--> src/main.rs:24:5
|
23 | impl<'a> InputIter for Tokens<&'a str> {
| -------------------------------------- in this `impl` item
24 | type Item = Token<&'a str>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found enum `Token`
|
= note: expected reference `&Token<&str>`
found enum `Token<&str>`
error[E0271]: type mismatch resolving `<std::iter::Enumerate<std::slice::Iter<'_, Token<&str>>> as std::iter::Iterator>::Item == (usize, Token<&str>)`
--> src/main.rs:24:5
|
23 | impl<'a> InputIter for Tokens<&'a str> {
| -------------------------------------- in this `impl` item
24 | type Item = Token<&'a str>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found enum `Token`
|
= note: expected tuple `(_, &Token<&str>)`
found tuple `(_, Token<&str>)`