3个不稳定版本

0.2.1 2019年7月14日
0.2.0 2019年7月14日
0.1.0 2018年10月13日

#244解析工具

Download history 9/week @ 2024-03-11 10/week @ 2024-03-18 4/week @ 2024-03-25 76/week @ 2024-04-01 6/week @ 2024-04-15 7/week @ 2024-04-22 18/week @ 2024-04-29 54/week @ 2024-05-06 2/week @ 2024-05-13 12/week @ 2024-05-20 5/week @ 2024-05-27 5/week @ 2024-06-03 4/week @ 2024-06-10 10/week @ 2024-06-17 94/week @ 2024-06-24

114 每月下载量

MIT 许可证

21KB
411

nom-trace

此crate提供了一种跟踪解析器执行的方法,存储输入数据中的位置、解析器树中的位置和解析器结果。

例如,如果您运行以下代码

#[macro_use] extern crate nom;
#[macro_use] extern crate nom_trace;

pub fn main() {
  named!(parser<&str, Vec<&str>>,
    //wrap a parser with tr!() to add a trace point
    tr!(preceded!(
      tr!(tag!("data: ")),
      tr!(delimited!(
        tag!("("),
        separated_list!(
          tr!(tag!(",")),
          tr!(nom::digit)
        ),
        tr!(tag!(")"))
      ))
    ))
  );

  println!("parsed: {:?}", parser("data: (1,2,3)"));

  // prints the last parser trace
  print_trace!();

  // the list of trace events can be cleared
  reset_trace!();
}

您将得到以下结果

parsed: Ok(("", ["1", "2", "3"]))
preceded        "data: (1,2,3)"

        tag     "data: (1,2,3)"

        -> Ok("data: ")
        delimited       "(1,2,3)"

                digit   "1,2,3)"

                -> Ok("1")
                tag     ",2,3)"

                -> Ok(",")
                digit   "2,3)"

                -> Ok("2")
                tag     ",3)"

                -> Ok(",")
                digit   "3)"

                -> Ok("3")
                tag     ")"

                -> Error(Code(")", Tag))
                tag     ")"

                -> Ok(")")
        -> Ok(["1", "2", "3"])
-> Ok(["1", "2", "3"])

通过缩进来指示解析器级别。对于每个跟踪点,我们都有

  • 缩进级别,然后是解析器或组合器名称,然后是输入位置
  • 子解析器的跟踪
  • -> 然后跟随解析器的结果

您可以为跟踪添加中间名称而不是组合器名称,如下所示:tr!(PARENS, delimited!( ... )) 这将替换跟踪打印中的名称 delimited,用 PARENS 替换

此跟踪器与基于 &[u8]&str 输入类型的解析器一起工作。对于 &[u8],输入位置将显示为十六进制转储。

记录多个跟踪

直接使用,宏将在“默认”标签下记录跟踪。但如果您想同时记录多个跟踪,请添加一个静态字符串作为第一个参数。

例如,在以下代码中,根跟踪将在“默认”中记录,而 separated_list 内的跟踪将进入“in list”跟踪。

然后您可以通过执行 print_trace!("in list") 来打印它。

  named!(parser<Vec<&[u8]>>,
    //wrap a parser with tr!() to add a trace point
    tr!(preceded!(
      tag!("data: "),
      delimited!(
        tag!("("),
        separated_list!(
          tr!("in list", tag!(",")),
          tr!("in list", digit)
        ),
        tag!(")")
      )
   ))
  );

nom 5函数支持

tr 函数支持与nom 5中介绍的相同组合器设计。不幸的是,它不能像宏那样从代码内部直接操作其参数,因此必须显式地接收 tag 参数,以及此跟踪点的 name(在宏中,该名称由 tr! 的参数的 stringify 调用生成)。

因此,直接使用 tr,您需要这样做 tr("default", "name", parser1)。建议您创建自己的跟踪解析器,如下所示

fn t<I,O,E,F>(name: &'static str, f: F) -> impl Fn(I) -> IResult<I,O,E>
  where Input: From<I>,
        F: Fn(I) -> IResult<I,O,E>,
        I: Clone,
        O: Debug,
        E: Debug {
  tr(name, f)
}

依赖项

~1MB
~18K SLoC