【问题标题】:Why does nom expect a &str when I pass a CompleteStr?当我通过 CompleteStr 时,为什么 nom 期望一个 &str?
【发布时间】:2018-11-20 01:22:07
【问题描述】:

解析器按预期工作,直到我想解析 h: 数字,它始终是字符串中的最后一个数字并且编译器给了我

^ expected &str, found struct `nom::types::CompleteStr`

我认为这是因为解析器正在向前看。我该如何阻止它,或者我如何表示它已经完成?

#[macro_use]
extern crate nom;

use nom::digit;
use nom::types::CompleteStr;
use std::str::FromStr;

#[derive(Debug, PartialEq)]
pub struct Order {
    pub l: u64,
    pub w: u64,
    pub h: u64,
}

named!(order_parser<CompleteStr, Order>,
    do_parse!(
        l: map_res!(digit, u64::from_str) >>
        tag!("x") >>
        w: map_res!(digit, u64::from_str) >>
        tag!("x") >>
        h: map_res!(digit, u64::from_str) >>
        (Order {l:  l, w: w, h: h })
    )
);

pub fn wrap_order(order: &str) -> Result<(CompleteStr, Order), nom::Err<&str>> {
    order_parser(order)
}

#[test]
fn test_order_parser() {
    assert_eq!(
        wrap_order(CompleteStr("2x3x4")),
        Ok((CompleteStr(""), Order { l: 2, w: 3, h: 4 }))
    );
}

【问题讨论】:

标签: rust nom


【解决方案1】:

错误不在最后一位解析器上,而是在每个解析器上(Rust 1.30.0 打印错误三遍)。那是因为 u64::from_str 适用于 &amp;str,而不是 CompleteStr

您可以通过这种方式修复解析器以正确使用u64::from_str

do_parse!(
    l: map_res!(digit, |CompleteStr(s)| u64::from_str(s)) >>
    tag!("x") >>
    w: map_res!(digit, |CompleteStr(s)| u64::from_str(s)) >>
    tag!("x") >>
    h: map_res!(digit, |CompleteStr(s)| u64::from_str(s)) >>
    (Order { l: l, w: w, h: h })
)

next函数也有一些不相关的错误,可以通过在签名中使用适当的类型来修复:

pub fn wrap_order(order: &str) -> Result<(CompleteStr, Order), nom::Err<CompleteStr>> {
    order_parser(CompleteStr(order))
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    相关资源
    最近更新 更多