2 个版本
0.1.1 | 2019年7月16日 |
---|---|
0.1.0 | 2019年7月16日 |
#2828 in 解析器实现
36KB
648 行
nom5_locate
nom5 的 nom_locate 分支
nom 的一个用于定位标记的特殊输入类型
文档
该软件包的文档可以在 这里 查看。
如何使用它
该软件包提供 LocatedSpan
结构体 来封装数据。查看下面的示例和说明
#[macro_use]
extern crate nom;
#[macro_use]
extern crate nom_locate;
use nom::types::CompleteStr;
use nom_locate::LocatedSpan;
type Span<'a> = LocatedSpan<CompleteStr<'a>>;
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(CompleteStr("Lorem ipsum \n foobar"));
let output = parse_foobar(input);
let position = output.unwrap().1.position;
assert_eq!(position, Span {
offset: 14,
line: 2,
fragment: CompleteStr("")
});
assert_eq!(position.get_column(), 2);
}
导入
导入 nom 和 nom_locate。
#[macro_use]
extern crate nom;
extern crate nom_locate;
use nom_locate::LocatedSpan;
你也可以创建 类型别名 以便于使用,这样你就不需要每次都指定 fragment
类型
type Span = LocatedSpan<CompleteStr>;
注意,在大多数情况下,最好使用 CompleteStr 以优化你的解析器。
定义输出结构
你的解析器的输出结构可能包含作为 Span
的位置(它提供 index
、line
和 column
信息以定位你的标记)。
struct Token<'a> {
pub position: Span<'a>,
pub foo: String,
pub bar: String,
}
创建解析器
解析器必须接受一个 Span
作为输入。你可以在你的 nom 解析器中使用 position!()
,以捕获你的标记的位置
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()
})
));
调用解析器
解析器返回一个 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
~17K SLoC