#parser-combinator #parser

nom-whitespace

消耗空白字符的nom组合器

1 个不稳定版本

使用旧的Rust 2015

0.1.0 2019年4月11日

#117 in #parser-combinator

MIT 许可证

41KB
998

nom whitespace

nom-whitespace提供消耗空格的nom组合器。


lib.rs:

支持空白分隔的格式

许多文本格式允许在标记之间有空白和其他类型的分隔符。使用nom手动处理意味着将所有解析器像这样包裹起来

named!(token, delimited!(space, tk, space));

为了便于开发此类解析器,您可以使用空白解析功能,它的工作方式如下

named!(tuple<&[u8], (&[u8], &[u8]) >,
  ws!(tuple!( take!(3), tag!("de") ))
);

assert_eq!(
  tuple(&b" \t abc de fg"[..]),
 Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..])))
);

ws!组合器将修改解析器,使其在各个地方插入空间解析器。默认情况下,它将消耗以下字符: " \t\r\n"

如果您想修改这种行为,您可以创建自己的空白包装器。例如,如果您不想消耗行尾,只想消耗空白和制表符,您可以这样做

named!(pub space, eat_separator!(&b" \t"[..]));

#[macro_export]
macro_rules! sp (
  ($i:expr, $($args:tt)*) => (
    {
      use nom::Convert;
      use nom::Err;

      match sep!($i, space, $($args)*) {
        Err(e) => Err(e),
        Ok((i1,o))    => {
          match space(i1) {
            Err(e) => Err(Err::convert(e)),
            Ok((i2,_))    => Ok((i2, o))
          }
        }
      }
    }
  )
);

named!(tuple<&[u8], (&[u8], &[u8]) >,
  sp!(tuple!( take!(3), tag!("de") ))
);

assert_eq!(
  tuple(&b" \t abc de fg"[..]),
 Ok((&b"fg"[..], (&b"abc"[..], &b"de"[..])))
);

此组合器通过将每个组合器替换为支持与分隔符解析器包装的版本来工作。它不支持您在自身代码中编写的组合器。您仍然可以手动使用您想要的分隔符将其包装起来,或者您可以复制src/whitespace.rs中定义的宏并修改它们以支持新的组合器

  • 在此处复制组合器的代码,添加 _sep 后缀
  • $separator:expr作为第二个参数添加
  • 使用sep!($separator, $submac!($($args)*))包装任何子解析器
  • sep!的定义中引用它,如下所示
 ($i:expr,  $separator:path, my_combinator ! ($($rest:tt)*) ) => {
   wrap_sep!($i,
     $separator,
     my_combinator_sep!($separator, $($rest)*)
   )
 };

依赖项

~1MB
~17K SLoC