3

我正在使用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暗示这种约束。

是否有另一种方法来完成我正在尝试做的事情并以与 nom 组合器兼容的方式表示令牌流?

一个可重现的示例游乐场

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>)`
4

0 回答 0