#nom #locate #input #type #tokens #parser #nom5

no-std nom5_locate

nom 的一个用于定位标记的特殊输入类型

2 个版本

0.1.1 2019年7月16日
0.1.0 2019年7月16日

#2828 in 解析器实现

MIT 许可证

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 的位置(它提供 indexlinecolumn 信息以定位你的标记)。

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 属性包含 offsetlinecolumn

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