标签: nom

如何制作一个 nom 空白解析器来跳过面向行的注释?

我正在 nom 4.2.2 中为基于文本的格式编写解析器,并且我正在使用空格工具来跳过空格。我必须使用自定义解析器,因为这种格式将一些不寻常的字符视为空格。按照该页面上的示例,我使用eat_separator.

如何有效地扩展我的空间解析器以也使用从行注释#到行尾的行注释?这些注释可以出现在字符串之外的任何地方。我总是想扔掉评论的内容:没有什么比预处理器指令更好的了。

comments rust nom

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

如何在nom中匹配CSV样式的引用字符串?

出于此问题的目的,CSV样式引用的字符串是一个字符串,其中:

  1. 字符串以一个字符串开头和结尾".
  2. 字符串中的两个双引号折叠为一个双引号."Alo""ha"Alo"ha.
  3. ""本身就是一个空字符串.
  4. "A""" e"无法解析错误输入,例如.这是一个A",然后是垃圾e".

我尝试了几件事,其中没有一件完全有效.

我得到的最接近,感谢Mozilla IRC上#nom用户粉红色的一些帮助:

use std::error as stderror; /* Avoids needing nightly to compile */

named!(csv_style_string<&str, String>, map_res!(
   terminated!(tag!("\""), not!(peek!(char!('"')))),
   csv_string_to_string
));

fn csv_string_to_string(s: &str) -> Result<String, Box<stderror::Error>> {
   Ok(s.to_string().replace("\"\"", "\""))
}
Run Code Online (Sandbox Code Playgroud)

这不能正确捕获字符串的结尾.

我也试图使用re_match!r#""([^"]|"")*""#,但这总是导致Err::Incomplete(1).

我已经确定Nom 1.0给定CSV示例对于引用的CSV字符串不起作用,因为我正在描述它,但我知道实现不同.

csv rust nom

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

如何在 nom 中创建流解析器?

我已经在 nom 中创建了一些重要的解析器,所以我现在对它非常熟悉。到目前为止,我创建的所有解析器总是向解析器提供整个输入切片。

我想创建一个流解析器,我认为这意味着我可以继续将字节输入解析器,直到它完成。我很难找到任何说明这一点的文档或示例,而且我也质疑我对“流式解析器”是什么的假设。

我的问题是:

  • 我对流式解析器的理解是否正确?
  • 如果是这样,是否有使用这种技术的解析器的好例子?

rust nom

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

具有严格格式的可选字段

我正在尝试构建nom解析器来检查 ID 为 UUID 的 URL

rooms/e19c94cf-53eb-4048-9c94-7ae74ff6d912
Run Code Online (Sandbox Code Playgroud)

我创建了以下内容:

extern crate uuid;
use uuid::Uuid;

named!(room_uuid<&str, Option<Uuid>>,
    do_parse!(
        tag_s!("rooms") >>
        id: opt!(complete!(preceded!(
            tag_s!("/"),
            map_res!(take_s!(36), FromStr::from_str)
        ))) >>

        (id)
    )
);
Run Code Online (Sandbox Code Playgroud)

它几乎可以很好地处理所有情况:

assert_eq!(room_uuid("rooms"), Done("", None));
assert_eq!(room_uuid("rooms/"), Done("/", None));
assert_eq!(room_uuid("rooms/e19c94cf-53eb-4048-9c94-7ae74ff6d912"), Done("", Some(Uuid::parse_str("e19c94cf-53eb-4048-9c94-7ae74ff6d912").unwrap())));
Run Code Online (Sandbox Code Playgroud)

除了 ID 不是有效 UUID 的情况:

assert!(room_uuid("rooms/123").is_err()); # it fails
# room_uuid("rooms/123").to_result() => Ok(None)
Run Code Online (Sandbox Code Playgroud)

据我了解,这是因为opt!将内部转换ErrNone.

我想将 ID 作为可选部分,但如果它存在,它应该是一个有效的 UUID。
不幸的是,我不明白如何将这两件事结合起来:可选性和严格格式。

rust nom

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

nom的“ $ i”宏参数从何而来?

我试图了解Rust宏如何捕获工作,并正在查看nom解析器库。

位置nom / src / bytes.rs声明tag!使用捕获的宏($i:expr, $tag: expr)。但是,在使用的所有地方,tag!它仅使用一个参数,即tag!("+")。例如:NOM-lua52 / op.rs。我已经阅读了有关宏的教程,但是这种结构似乎很特殊。

似乎输入$i是某种隐式的

macros rust nom

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

为什么我的nom解析器不会消耗整个输入,而是留下最后一块未解析的?

我想,以创造一个分裂的空间和逗号日志行VectorTokenFieldSeparator显示在下面的代码.

我的问题是nom似乎没有消耗整个日志行,它留下了最后一部分 - 在这种情况下08:33:58).

main.rs

#![feature(rust_2018_preview)]

#[macro_use] extern crate nom;

#[derive(Debug, PartialEq)]
pub enum Token<'a> {
    Separator(&'a [u8]),
    Field(&'a [u8]),    
}

named!(separator, is_a!(" ,"));

named!(not_sep, is_not!(" ,"));

named!(
    token<Token>,
    alt_complete!(
        separator => { |s| Token::Separator(s) } |
        not_sep =>   { |n| Token::Field(n) }
    )
);

named!(sequence<Vec<Token>>, many1!(token));


pub fn scan(input: &[u8]) -> Vec<Token> {
    let (_, seq) = sequence(input).unwrap();

    seq
}

fn main() {
}

#[cfg(test)]
mod tests {
    use …
Run Code Online (Sandbox Code Playgroud)

rust nom

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

如何使用 nom 将带符号的字符串解析为 i32?

使用nom crate,我正在尝试编写一个解析器,它可以i32从 a 中识别有符号数String,即可以将字符串-42转换为i32表示形式。

到目前为止,我想出了以下内容,但我无法解析负数:

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

named!(
    i32_parser<CompleteStr, i32>,
    map_res!(nom::digit, |CompleteStr(s)| i32::from_str(s))
);

#[test]
fn parse_i32_positive() {
    assert_eq!(
        i32_parser(CompleteStr::from("42")),
        Ok((CompleteStr::from(""), 42))
    );
}

#[test]
fn parse_i32_negative() {
    assert_eq!(
        i32_parser(CompleteStr::from("-42")),
        Ok((CompleteStr::from(""), -42))
    );
}
Run Code Online (Sandbox Code Playgroud)

我也试过以下,但有一个神秘的编译错误:

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

named!(
    i32_parser<CompleteStr, i32>,
    map_res!(nom::digit, |CompleteStr(s)| i32::from_str(s))
);

#[test]
fn parse_i32_positive() {
    assert_eq!(
        i32_parser(CompleteStr::from("42")),
        Ok((CompleteStr::from(""), 42))
    );
}

#[test]
fn parse_i32_negative() {
    assert_eq!(
        i32_parser(CompleteStr::from("-42")),
        Ok((CompleteStr::from(""), -42))
    );
}
Run Code Online (Sandbox Code Playgroud)

关于如何修复它的任何建议?或者用 nom 实现这一目标的更简单方法? …

parsing rust nom

5
推荐指数
2
解决办法
1075
查看次数

如何在 rust 中使用 nom 解析对称带引号的字符串?

我应该如何使用nom解析类似于 rust 原始字符串的带引号的字符串?我想解析以下内容:

"A standard string"
#"A string containing ["] a quote"#
##"A string containing ["#] a quote and hash "##
Run Code Online (Sandbox Code Playgroud)

我将如何做到这一点,在开始和结束时需要相同数量的“#”符号,同时允许 #'ed 字符串包含未转义的引号和哈希?

rust nom

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

如何使用 nom 解析直到找到字符串?

使用 nom 解析字符串直到找到字符很容易。如何使用 nom 吞噬字符串直到分隔符或结尾?处理这个问题。

如何使用字符串(多个字符)而不是单个分隔符执行相同的操作?

例如,为了解析abchello,我想解析所有内容,直到hello找到为止。

rust nom

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

nom 解析器借用检查器问题

我有这个使用 nom 4.2.2 的 Rust 程序。(我冒昧地扩展了 nom 解析器功能。)

extern crate failure;
extern crate nom;

use failure::Error;
use std::fs::File;
use std::io::Read;

fn nom_parser(i: &[u8]) -> ::nom::IResult<&[u8], String, u32> {
    { ::nom::lib::std::result::Result::Ok((i, ("foo".to_owned()))) }
}

fn my_parser(buf: &[u8]) -> Result<(&[u8], String), Error> {
  Ok((buf, "foo".to_owned()))
}

fn main() -> Result<(), Error> {
  let handler = |mut entries: String| { entries.clear() };
  loop {
    let mut buf = Vec::new();
    File::open("/etc/hosts")?.read_to_end(&mut buf)?;
    let res = nom_parser(&buf)?.1;
    // let res = my_parser(&buf)?.1;
    handler(res);
  }
} …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker nom

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

标签 统计

nom ×10

rust ×10

borrow-checker ×1

comments ×1

csv ×1

macros ×1

parsing ×1