3个不稳定版本
0.2.1 | 2019年7月14日 |
---|---|
0.2.0 | 2019年7月14日 |
0.1.0 | 2018年10月13日 |
#244 在 解析工具
114 每月下载量
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