rust - 使用 nom errorkind 返回简单自定义错误的正确方法是什么?

标签 rust parser-combinators nom

添加到 nom 的简单错误处理程序

第一个编译没有错误,第二个出错

use nom::*;
use std::str;
// This works
named!(
    field<&str>,
    map!(
        complete!(add_return_error!(
            ErrorKind::Custom(1),
            preceded!(
                tag!("."),
                recognize!(many1!(
                    alt!(alphanumeric => { |_| true } | char!('_') => {|_| true})
                ))
            )
        )),
        |v| str::from_utf8(v).unwrap()
    )
);

// This doesn't compile
named!(
    entity<&str>,
    add_return_error!(
        ErrorKind::Custom(2),
        map!(
            recognize!(many1!(
                alt!(alphanumeric => { |_| true } | char!('_') => {|_| true})
            )),
            |v| str::from_utf8(v).unwrap()
        )
    )
);

错误是

cargo build
   Compiling pdl_parser v0.1.0 (file:///H:/parser)
error[E0282]: type annotations needed
  --> src\pdl_parser.rs:72:1
   |
72 | / named!(
73 | |     entity<&str>,
74 | |     add_return_error!(
75 | |         ErrorKind::Custom(2),
...  |
82 | |     )
83 | | );
   | |__^ cannot infer type for `E`
   |
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

为什么第一个有效而第二个无效?我能做些什么来解决它?我尝试将第二个签名更改为 entity<&[u8],&str,ErrorKind>然后到i32u32但没有成功。

最佳答案

cannot infer type for E 错误的解决方案是将解析步骤分开,这样编译器就不会变得如此困惑。

将解析器组合器重写为

named!(
    entity_name<Vec<u8>>,
    many1!(alt!(alphanumeric => { |x : &[u8]| x[0] } | char!('_') => {|_| b'_'}))
);
named!(
    entity<&[u8],&str,i32>,
    add_return_error!(
        ErrorKind::Custom(2),
        map!(recognize!(entity_name),|v| str::from_utf8(v).unwrap())
    )
);

以及相应的测试

#[test]
fn parse_pdl_error_test() {
    assert_eq!(entity(b"_error_stack").to_result(), Ok("_error_stack"));
    assert_eq!(entity(b"[];']").to_result(), Err(ErrorKind::Custom(2)));
}

关于rust - 使用 nom errorkind 返回简单自定义错误的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49395281/

相关文章:

rust - 使用 Nom 将整数解析为 float

rust - 封装可变切片修改

algorithm - 如何迭代生成 de Bruijn 序列?

scala - 理解 Scala 解析器组合器中的波形符

haskell - parsec:解析嵌套代码块

rust 标称 : many and end of input

使用rust :错误:非左值的生命周期太短,无法保证其内容可以安全地重新借用

rust - 在 Rust 中将 float 转换为整数

用于递归 bnf 的 Scala Parser Combinators 技巧?

parsing - 使用 `nom` 处理自定义枚举类型是否有意义?