Recursion 在Rust中的迭代期间将迭代器传递到递归调用

Recursion 在Rust中的迭代期间将迭代器传递到递归调用,recursion,rust,borrow-checker,Recursion,Rust,Borrow Checker,我正在为一个简单的树语法编写一个解析器。在这样做时,我需要从一系列标记构建一棵树 由于借款人检查人的原因,代码的内容目前陷入了问题的泥潭: 使用std::vec; fn parse_iter(token_iter:vec::IntoIter)->结果 { 让mut节点:Vec=Vec![]; 让mut cur_节点:Option=None; 对于token_iter中的token{ 匹配令牌{ 令牌::ParenOpen=>{ 如果让一些(多个节点)=cur_节点{ 让mut children=

我正在为一个简单的树语法编写一个解析器。在这样做时,我需要从一系列标记构建一棵树

由于借款人检查人的原因,代码的内容目前陷入了问题的泥潭:

使用std::vec;
fn parse_iter(token_iter:vec::IntoIter)->结果
{
让mut节点:Vec=Vec![];
让mut cur_节点:Option=None;
对于token_iter中的token{
匹配令牌{
令牌::ParenOpen=>{
如果让一些(多个节点)=cur_节点{
让mut children=parse_iter(token_iter)?;
node.children.append(&mut children);
}否则{
返回Err(“无效的令牌序列”.to_string());
}
}
令牌::ParenClose=>{
打破
}
令牌::名称(名称)=>{
让节点=节点::新建(名称);
nodes.push(节点);
cur_node=Some(node);
}
标记::逗号=>{}
}
}
Ok(节点)
}
发布枚举令牌{
帕雷诺本,
软糖,
逗号,
名称(字符串),
}
发布结构节点{
酒吧名称:String,
酒吧儿童:Vec,
}
impl节点{

pub fn new我认为在token\u iter
中对token\u iter进行迭代,并尝试在循环中对
token\u iter
进行操作是一个坏主意。因此,我建议将
token\u iter
作为
&mut
进行手动迭代

此外,同时拥有
cur\u节点
节点
似乎是多余的(如果我没有弄错的话,
cur\u节点
本质上是
节点。最后一个
)。因此,我尝试以下方法:

use std::vec;

fn parse_iter(token_iter: &mut vec::IntoIter<Token>) -> Result<(Vec<Node>, &mut vec::IntoIter<Token>), String>
{
    let mut nodes: Vec<Node> = vec![];
    while let Some(token)=token_iter.next() {
        match token {
            Token::ParenOpen => {
                if let Some(ref mut node) = nodes.last_mut() {
                    let mut children_and_iter = parse_iter(token_iter)?;
                    node.children.append(&mut children_and_iter.0);
                } else {
                    return Err("invalid token sequence".to_string());
                }
            }
            Token::ParenClose => {
                break;
            }
            Token::Name(name) => {
                nodes.push(Node::new(name));
            }
            Token::Comma => {}
        }
    }
    Ok((nodes, token_iter))
}


pub enum Token {
    ParenOpen,
    ParenClose,
    Comma,
    Name(String),
}

pub struct Node {
    pub name: String,
    pub children: Vec<Node>,
}

impl Node {
    pub fn new<'a>(name: String) -> Node {
        Node { name: name, children: vec![] }
    }
}
使用std::vec;
fn parse_iter(token_iter:&mut vec::IntoIter)->结果
{
让mut节点:Vec=Vec![];
而让一些(token)=token_iter.next(){
匹配令牌{
令牌::ParenOpen=>{
如果let Some(ref mut node)=nodes.last_mut(){
让mut children_和_iter=parse_iter(token_iter)?;
node.children.append(&mut children_和_iter.0);
}否则{
返回Err(“无效的令牌序列”.to_string());
}
}
令牌::ParenClose=>{
打破
}
令牌::名称(名称)=>{
nodes.push(Node::new(name));
}
标记::逗号=>{}
}
}
正常((节点、令牌)
}
发布枚举令牌{
帕雷诺本,
软糖,
逗号,
名称(字符串),
}
发布结构节点{
酒吧名称:String,
酒吧儿童:Vec,
}
impl节点{

pub fn newBy the power of,stop do this in Rust.是否有其他数据结构可用于解决此问题?这是一个固有的递归问题。如果您能为我们介绍一下您的问题,这将非常有帮助。现在很难说从何处开始修复您的问题,因为我们没有所有相关的导入/定义。我编辑了这个问题的例子。希望它现在提供了足够的上下文。如果他们在上面运行代码,就可以得到发布的错误消息。我刚刚编写了一个几乎相同的解决方案,这是我在得到一些关于生锈不和谐的帮助后得出的。令人欣慰的是,两个人得出了类似的结论!顺便说一句,我编辑了这个问题以删除tuple返回值,因为这只是试图绕过借阅检查器的另一种方式。
use std::vec;

fn parse_iter(token_iter: &mut vec::IntoIter<Token>) -> Result<(Vec<Node>, &mut vec::IntoIter<Token>), String>
{
    let mut nodes: Vec<Node> = vec![];
    while let Some(token)=token_iter.next() {
        match token {
            Token::ParenOpen => {
                if let Some(ref mut node) = nodes.last_mut() {
                    let mut children_and_iter = parse_iter(token_iter)?;
                    node.children.append(&mut children_and_iter.0);
                } else {
                    return Err("invalid token sequence".to_string());
                }
            }
            Token::ParenClose => {
                break;
            }
            Token::Name(name) => {
                nodes.push(Node::new(name));
            }
            Token::Comma => {}
        }
    }
    Ok((nodes, token_iter))
}


pub enum Token {
    ParenOpen,
    ParenClose,
    Comma,
    Name(String),
}

pub struct Node {
    pub name: String,
    pub children: Vec<Node>,
}

impl Node {
    pub fn new<'a>(name: String) -> Node {
        Node { name: name, children: vec![] }
    }
}