#parser #parser-combinator #nom

nom-methods

将nom解析器作为方法使用

2个不稳定版本

使用旧的Rust 2015

0.2.0 2019年6月24日
0.1.0 2019年4月11日

#parser-combinator 中排名 115


用于 ms-oforms

MIT 协议

22KB
493

nom方法

nom-methods提供nom组合器,可以将解析器作为方法使用,而不是独立的函数。


lib.rs:

方法宏组合器

这些宏将解析器作为结构体的方法,并可以接受将结构体的方法作为解析器。

为了便于组装,组合器是这样定义的

macro_rules! tag (
  ($i:expr, $inp: expr) => (
    {
      ...
    }
  );
);

但当作为其他组合器中的方法使用时,是这样使用的

method!(my_function<Parser<'a> >, self, tag!("abcd"));

内部,其他组合器将重写该调用以将输入作为第二个参数传递

macro_rules! method (
  ($name:ident<$a:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
    fn $name( $self_: $a, i: &[u8] ) -> IResult<&[u8], &[u8]> {
      $submac!(i, $($args)*)
    }
  );
);

method! 宏与宏模块中的 named! 宏类似。虽然 named! 将创建一个解析器函数,但 method! 将在定义它的结构体上创建一个解析器方法。

named! 宏相比,它们在调用方式上略有不同。一个 method! 调用必须声明 self 的类型,并且由于Rust的借用生命周期限制,它不能是引用

//                  -`self`'s type-
method!(method_name<  Parser<'a> >, ...);

self 的类型始终位于第一位。下一个不同之处在于你必须输入 self 结构体。由于Rust的宏卫生,宏不能自行声明它。

//                                                 -self-
method!(method_name<Parser<'a>, &'a str, &'a str>, self, ...);

在创建具有解析器方法的解析器结构体时,由于静态借用检查器,调用 self(或任何其他解析器结构体)上的任何解析器方法将导致 self 在整个方法中移动。为了绕过这个限制,所有 self 都被移动到被调用的方法中,然后被调用的方法将返回 self 给调用者。

要调用 self 上的方法,你需要使用 call_m! 宏。例如

struct<'a> Parser<'a> {
  parsed: &'a str,
}
impl<'a> Parser<'a> {
  // Constructor omitted for brevity
  method!(take4<Parser<'a>, &'a str, &'a str>, self, take!(4));
  method!(caller<Parser<'a>, &'a str, &'a str>, self, call_m!(self.take4));
}

更复杂的组合仍然基本上与它们的 named! 对应物看起来一样

   method!(pub simple_chain<&mut Parser<'a>, &'a str, &'a str>, self,
     do_parse!(
            call_m!(self.tag_abc)                                        >>
            call_m!(self.tag_def)                                        >>
            call_m!(self.tag_ghi)                                        >>
      last: map!(call_m!(self.simple_peek), |parsed| sb.parsed = parsed) >>
      (last)
     )
   );

在方法定义中需要记住三个添加项

  1. 指定 self 的类型
  2. self 传递给宏
  3. 使用 call_m! 宏调用解析器方法。

依赖关系

~1MB
~18K SLoC