标签: nom

如何使用 nom take_while 和 is_digit 作为 &str 输入

我正在尝试学习 nom ,但遇到了take_while不接受is_digit或任何其他is_xxxx.

我想要解析的行看起来像这样

#123 = ABCDEF (...);
Run Code Online (Sandbox Code Playgroud)

我想得到“123”部分(最终还有 ABCDEF 和 (...) 部分。但当时我猜有一件事)。

我的解析器目前看起来像这样

use nom::{
  bytes::complete::take_while,
  character::is_digit,
  error::ParseError,
  IResult
};

// Get row id
fn id<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
    take_while(is_digit)(i)
}
Run Code Online (Sandbox Code Playgroud)

定义is_digit看起来像这样

pub fn is_digit(chr: u8) -> bool
Run Code Online (Sandbox Code Playgroud)

由于id解析器采用 a&str它会抱怨类型不匹配。但是是否有可能以某种方式使用 is_digit 呢?我可以在某处进行类型转换而无需分配任何内容吗?我真的希望它尽可能高效。

感觉提供的is_xxxx函数应该在这种情况下使用,但我可能是错的。

谢谢!

rust nom

4
推荐指数
1
解决办法
2277
查看次数

使用 Rust NOM 解析库迭代多行

我正在尝试为 Rust 项目学习 NOM。我有一个文本文件,其中包含: [tag="#43674"]char[/tag]每行有多个背靠背的标签。我试图拉出“#43674”和“char”,将它们存储在一个元组中(x, y),然后将它们推入Vec<(x, y)>文本文件每一行的向量中。到目前为止,我已经成功地将解析器组合成两个函数;一个用于“#43674”,一个用于“char”,然后我将它们组合在一起以返回<IResult<&str, (String, String)>。这是代码:

fn color_tag(i: &str) -> IResult<&str, &str> {
    delimited(tag("[color="), take_until("]"), tag("]"))(i)
}

fn char_take(i: &str) -> IResult<&str, &str> {
    terminated(take_until("[/color]"), tag("[/color]"))(i)
}

pub fn color_char(i: &str) -> IResult<&str, (String, String)> {
    let (i, color) = color_tag(i)?;
    let (i, chara) = char_take(i)?;
    let colors = color.to_string();
    let charas = chara.to_string();

    let tuple = (colors, charas);
    
    Ok((i, tuple))
}
Run Code Online (Sandbox Code Playgroud)

如何在文本文件的给定行上迭代此函数?我已经有一个将文本文件迭代为行的函数,但我需要color_char对该行中的每个闭包重复该操作。我完全没有抓住重点吗?

iteration rust nom

4
推荐指数
1
解决办法
1697
查看次数

如何在 nom 中使用带有可选终止分隔符的分隔符?

我想用 nom 来解析这两个:

[
   a, 
   b,  
   c
]
Run Code Online (Sandbox Code Playgroud)
[
   a, 
   b,  
   c,
]
Run Code Online (Sandbox Code Playgroud)

目前我有这段代码可以解析第一个,但不能解析第二个(第一个函数是 nom 文档中的一个配方,它只解析空格):

[
   a, 
   b,  
   c
]
Run Code Online (Sandbox Code Playgroud)

我是 nom 的新手,对当前的代码没有任何忠诚,所以很好地告诉我我做错了......

谢谢!

rust nom

4
推荐指数
1
解决办法
1444
查看次数

使用nom解析整数会导致不完整

我尝试的一切都给了我Incomplete(Size(1)).我现在最好的猜测是:

named!(my_u64(&str) -> u64,
    map_res!(recognize!(nom::digit), u64::from_str)
);
Run Code Online (Sandbox Code Playgroud)

测试:

#[cfg(test)]
mod test {
    #[test]
    fn my_u64() {
        assert_eq!(Ok(("", 0)), super::my_u64("0"));
    }
}
Run Code Online (Sandbox Code Playgroud)

有时在我的变体(例如添加complete!)中,如果我在最后添加一个字符,我已经能够解析它.

我想得到一个工作解析(最终我希望这将允许我为u64包装类型创建一个解析器)但更大的图片我想了解如何正确地自己构建一个解析器.

rust nom

3
推荐指数
2
解决办法
857
查看次数

使用 nom 5.0 解析二进制文件

问题

有一个文件里面有多个标题,但对我来说,它只重要一个和它后面的数据。此标头在文件中多次重复。

它的幻数是:ASCII 或0x65 0x51 0x48 0x54 0x52十六进制的A3046 。找到第一个字节后,解析器必须获取所有字节,直到0xffEOF,然后对剩余的头重复。

我的解决方案

首先我加载了文件:

let mut file = OpenOptions::new()
        .read(true)
        .open("../assets/sample")
        .unwrap();

    let mut full_file: Vec<u8> = Vec::new();
    file.read_to_end(&mut full_file);
Run Code Online (Sandbox Code Playgroud)

我用以下语句声明幻数:pub static QT_MAGIC: &[u8; 5] = b"A3046"; 作为测试,我编写了以下函数只是为了尝试它是否可以找到第一个标头。

fn parse_block(input: &[u8]) -> IResult<&[u8], &[u8]> {
    tag(QT_MAGIC)(input)
}
Run Code Online (Sandbox Code Playgroud)

但是,当测试运行时,Ok 有 None有价值。它肯定应该发现了什么。我做错了什么?

我没有发现使用 nom5 解析字节的例子,而且作为一个 rust 新手也无济于事。如何使用这些规则解析所有块?

rust nom

3
推荐指数
1
解决办法
1455
查看次数

使用 nom 解析时,无法推断函数“tuple”上声明的类型参数“I”的类型

我正在尝试使用nomtuple功能。该文档提供了以下示例:

use nom::sequence::tuple;
use nom::character::complete::{alpha1, digit1};
let parser = tuple((alpha1, digit1, alpha1));
Run Code Online (Sandbox Code Playgroud)

当我尝试时,出现编译错误:

    error[E0283]: type annotations needed
   --> src/main.rs:20:18
    |
20  |     let parser = tuple((alpha1, digit1, alpha1));
    |         ------   ^^^^^ cannot infer type for type parameter `I` declared on the function `tuple`
    |         |
    |         consider giving `parser` a type
    | 
Run Code Online (Sandbox Code Playgroud)

如果我想为变量添加一个类型,它会是什么?我知道它必须是 的某种变体FnMut,但我不确定它到底是如何工作的。

Cargo.toml

[dependencies]
nom = ">=5.0"
Run Code Online (Sandbox Code Playgroud)

rust nom

3
推荐指数
1
解决办法
1332
查看次数

解析 nom 中一定大小的数字

我可以很好地解析这样的数字:

map_res(digit1, |s: &str| s.parse::<u16>())
Run Code Online (Sandbox Code Playgroud)

但是如何仅解析某个范围内的数字呢?

rust nom

3
推荐指数
1
解决办法
620
查看次数

如何使用 Rust nom 为这种结构文本编写解析器?

我有以下数据

    let data = r#"title1
title1 line1
title1 line2
sep/
title2
title2 line1
title2 line2
title2 line3
sep/
title3
title3 line1
sep/"#;
Run Code Online (Sandbox Code Playgroud)

基本上它代表三个条目:

struct Entry {
    title: String,
    body: String,
}
Run Code Online (Sandbox Code Playgroud)

每个条目都有标题和正文。标题消耗单行(不包括行结尾),正文消耗以下所有行,直到遇到分隔线 ( sep/)。我想要的结果是一个条目向量。我如何使用 nom 来解析它?我对 nom 很陌生,我无法让各个部分一起工作并形成一个有效的解析器。以下是我所拥有的:


use nom::IResult;
use nom::branch::alt;
use nom::bytes::complete::{tag, take_until, is_not, is_a};
use nom::error::ErrorKind::ParseTo;
use nom::sequence::{pair, tuple, delimited, terminated};
use nom::combinator::opt;
use nom::error::{Error, ErrorKind};
use nom::character::complete::line_ending;
use nom::regexp::str::{re_find, re_match, re_matches, re_capture};
use nom::multi::many0;

struct Entry {
    title: String,
    body: String,
}

fn get_entry_title(i: &str) …
Run Code Online (Sandbox Code Playgroud)

rust nom

3
推荐指数
1
解决办法
1287
查看次数

使用转义单引号解析字符串

我想解析一个包含单引号之间的 ASCII 字符的字符串,该字符串可以包含连续两个 ' 的转义单引号。

'包含在单引号之间的字符串值 -> '' 等等...'

这应该导致:

包含在单引号之间的字符串值 -> ' 等等...

use nom::{
    bytes::complete::{tag, take_while},
    error::{ErrorKind, ParseError},
    sequence::delimited,
    IResult,
};

fn main() {
    let res = string_value::<(&str, ErrorKind)>("'abc''def'");

    assert_eq!(res, Ok(("", "abc\'def")));
}

pub fn is_ascii_char(chr: char) -> bool {
    chr.is_ascii()
}

fn string_value<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
    delimited(tag("'"), take_while(is_ascii_char), tag("'"))(i)
}
Run Code Online (Sandbox Code Playgroud)

如何检测转义引号而不是字符串的结尾?

parsing rust nom

2
推荐指数
1
解决办法
602
查看次数

无法推断类型参数的类型 使用 nom 进行解析时出错

nom我用7.1版本进行了测试:

use nom::bytes::complete::tag;

#[test]
fn test() {
    let (s, t) = tag("1")("123").unwrap();
}
Run Code Online (Sandbox Code Playgroud)

跑步cargo test给予

use nom::bytes::complete::tag;

#[test]
fn test() {
    let (s, t) = tag("1")("123").unwrap();
}
Run Code Online (Sandbox Code Playgroud)

它建议我指定tag::<T, Input, Error>()

我该如何处理这个问题?我还没有完全理解为什么会出现这个问题。

我尝试指定一些类型nom

error[E0283]: type annotations needed
  --> src/main.rs:5:18
   |
5  |     let (s, t) = tag("1")("123").unwrap();
   |                  ^^^ cannot infer type for type parameter `Error` declared on the function `tag`
   |
   = note: cannot satisfy `_: ParseError<&str>`
note: required by a bound in `nom::bytes::complete::tag` …
Run Code Online (Sandbox Code Playgroud)

types rust nom

1
推荐指数
1
解决办法
1492
查看次数

为什么在我通过CompleteStr时nom期望&str?

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

^ expected &str, found struct `nom::types::CompleteStr`
Run Code Online (Sandbox Code Playgroud)

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

#[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() { …
Run Code Online (Sandbox Code Playgroud)

rust nom

0
推荐指数
1
解决办法
292
查看次数

规范 5:多次使用另一个解析器创建组合器

假设我想创建一个多次使用另一个解析器的组合器,例如,解析由两种引号分隔的字符串:

fn quoted<'a, F: 'a, O, E: ParseError<&'a str>>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, O, E>
where
    F: Fn(&'a str) -> IResult<&'a str, O, E>,
{
    map(
        alt((
            tuple((tag("'"), f, tag("'"))),
            tuple((tag("\""), f, tag("\"")))
        )),
        |(_, res, _)| res,
    )
}
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,该解析器无法编译并出现“使用移动值”错误:

fn quoted<'a, F: 'a, O, E: ParseError<&'a str>>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, O, E>
where
    F: Fn(&'a str) -> IResult<&'a str, O, E>,
{
    map(
        alt((
            tuple((tag("'"), f, tag("'"))),
            tuple((tag("\""), f, …
Run Code Online (Sandbox Code Playgroud)

parsing parser-combinators rust nom

0
推荐指数
1
解决办法
1116
查看次数

标签 统计

nom ×12

rust ×12

parsing ×2

iteration ×1

parser-combinators ×1

types ×1