15 个版本 (9 个稳定版)
4.2.0 | 2023年8月22日 |
---|---|
4.1.0 | 2023年1月17日 |
4.0.0 | 2021年8月29日 |
3.0.2 | 2021年7月14日 |
0.1.0 | 2017年6月24日 |
在 解析器实现 中排名 #22
每月下载量 164,311
被 223 个crate(91 个直接使用)使用
文件大小 47KB
代码行数 977 行(不含注释)
nom_locate
为 nom 定位标记的特殊输入类型
文档
该crate的文档可在此处找到。
如何使用
该crate提供了封装数据的LocatedSpan
结构体。查看以下示例及其说明。
#[macro_use]
extern crate nom;
#[macro_use]
extern crate nom_locate;
use nom_locate::LocatedSpan;
type Span<'a> = LocatedSpan<&'a str>;
struct Token<'a> {
pub position: Span<'a>,
pub foo: String,
pub bar: String,
}
named!(parse_foobar( Span ) -> Token, do_parse!(
take_until!("foo") >>
position: position!() >>
foo: tag!("foo") >>
bar: tag!("bar") >>
(Token {
position: position,
foo: foo.to_string(),
bar: bar.to_string()
})
));
fn main () {
let input = Span::new("Lorem ipsum \n foobar");
let output = parse_foobar(input);
let position = output.unwrap().1.position;
assert_eq!(position.location_offset(), 14);
assert_eq!(position.location_line(), 2);
assert_eq!(position.fragment(), &"");
assert_eq!(position.get_column(), 2);
}
导入
导入 nom 和 nom_locate。
extern crate nom;
extern crate nom_locate;
use nom::bytes::complete::{tag, take_until};
use nom::IResult;
use nom_locate::{position, LocatedSpan};
同时,您可能需要创建类型别名以方便使用,这样您就不必每次都指定 fragment
类型。
type Span<'a> = LocatedSpan<&'a str>;
定义输出结构
您的解析器输出结构可能包含作为 Span
的位置信息(它提供了 index
,line
和 column
信息以定位您的标记)。
struct Token<'a> {
pub position: Span<'a>,
pub foo: &'a str,
pub bar: &'a str,
}
创建解析器
解析器必须接受一个 Span
作为输入。您可以在 nom 解析器中使用 position()
,以便捕获标记的位置。
fn parse_foobar(s: Span) -> IResult<Span, Token> {
let (s, _) = take_until("foo")(s)?;
let (s, pos) = position(s)?;
let (s, foo) = tag("foo")(s)?;
let (s, bar) = tag("bar")(s)?;
Ok((
s,
Token {
position: pos,
foo: foo.fragment,
bar: bar.fragment,
},
))
}
调用解析器
解析器返回一个 nom::IResult<Token, _>
(因此有 unwrap().1
)。属性 position
包含了 offset
、line
和 column
。
fn main () {
let input = Span::new("Lorem ipsum \n foobar");
let output = parse_foobar(input);
let position = output.unwrap().1.position;
assert_eq!(position, Span {
offset: 14,
line: 2,
fragment: ""
});
assert_eq!(position.get_column(), 2);
}
依赖关系
~1MB
~20K SLoC