Почему nom ожидает & str, когда я передаю CompleteStr? - PullRequest
0 голосов
/ 20 ноября 2018

Парсер работает, как и ожидалось, пока я не захочу проанализировать цифру 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 }))
    );
}

1 Ответ

0 голосов
/ 20 ноября 2018

Ошибка не в последнем анализаторе цифр, а в каждом из них (Rust 1.30.0 печатает ошибку три раза). Это потому, что u64::from_str работает на &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 })
)

Есть также некоторая несвязанная ошибка со следующей функцией, которую можно исправить, используя соответствующие типы в сигнатуре:

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