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

Download history 36453/week @ 2024-04-12 38346/week @ 2024-04-19 43263/week @ 2024-04-26 45368/week @ 2024-05-03 44261/week @ 2024-05-10 59505/week @ 2024-05-17 56716/week @ 2024-05-24 62851/week @ 2024-05-31 61895/week @ 2024-06-07 62455/week @ 2024-06-14 63834/week @ 2024-06-21 51958/week @ 2024-06-28 43999/week @ 2024-07-05 37666/week @ 2024-07-12 39588/week @ 2024-07-19 37188/week @ 2024-07-26

每月下载量 164,311
223crate(91 个直接使用)使用

MIT 许可协议

文件大小 47KB
代码行数 977 行(不含注释)

nom_locate

Coverage Status

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

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 包含了 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
~20K SLoC