#nom #logo #lexer #parser

logos-nom-bridge

使用 logos 令牌实现 nom 解析器

1 个不稳定版本

0.1.0 2022年2月21日

解析工具 中排名 #292

MIT/Apache

17KB
264 行(不包括注释)

logos-nom-bridge

Crates.io License Documentation

一个可以作为 nom 输入使用的 logos Lexer 包装器。这使得使用 logos 令牌解析变得非常简单。

用法

请参阅 文档

贡献

您可以通过提交问题或发送拉取请求来做出贡献。如果您有任何问题,请创建一个问题。

许可证

MIT 许可证Apache 2.0 许可证 下双许可。


lib.rs:

logos-nom-bridge

一个可以作为 nom 输入使用的 logos logos::Lexer 包装器。

简单示例

// First, create a `logos` lexer:

#[derive(Clone, Debug, PartialEq, Eq, logos::Logos)]
enum Token {
    #[token("+")]
    Plus,

    #[token("-")]
    Minus,

    #[regex(r"-?[0-9]+", |lex| lex.slice().parse())]
    Number(i64),

    #[error]
    #[regex(r"[ \t\n\f]+", logos::skip)]
    Error,
}

// Then, write a nom parser that accepts a `Tokens<'_, Token>` as input:

use logos_nom_bridge::Tokens;

type Input<'source> = Tokens<'source, Token>;

#[derive(Debug, PartialEq, Eq)]
enum Op {
    Number(i64),
    Addition(Box<(Op, Op)>),
    Subtraction(Box<(Op, Op)>),
}

fn parse_expression(input: Input<'_>) -> nom::IResult<Input<'_>, Op> {
#
#
    // zip
}

// Finally, you can use it to parse a string:

let input = "10 + 3 - 4";
let tokens = Tokens::new(input);

let (rest, parsed) = parse_expression(tokens).unwrap();

assert!(rest.is_empty());
assert_eq!(
    parsed,
    Op::Addition(Box::new((
        Op::Number(10),
        Op::Subtraction(Box::new((
            Op::Number(3),
            Op::Number(4),
        ))),
    ))),
)

您可以使用 token_parser 宏为您自己的令牌类型实现 nom::Parser

#
logos_nom_bridge::token_parser!(token: Token);

如果您的令牌类型的一些枚举变体包含数据,您可以使用 data_variant_parser 宏为它们实现 nom::Parser

#
#[derive(Clone, Debug, PartialEq, Eq, logos::Logos)]
enum Token {
    #[regex(r"-?[0-9]+", |lex| lex.slice().parse())]
    Number(i64),

    // etc.
}

logos_nom_bridge::data_variant_parser! {
    fn parse_number(input) -> Result<Op>;
    pattern = Token::Number(n) => Op::Number(n);
}

依赖项

约2.5MB
约20K 行代码