2 个版本
0.1.1 | 2024年6月9日 |
---|---|
0.1.0 | 2024年6月9日 |
129 在 解析器工具
每月 259 次下载
28KB
579 行
winnow-rule
一个用于在简单领域特定语言中定义 winnow 组合器的过程宏。需要 winnow
v0.6+。
winnow 是 nom 的一个分支,有关更多详细信息,请参阅 为什么是 winnow
?
因此,winnow-rule 也是 nom-rule 的一个分支,主要目的是创建一个支持 winnow 的类似 DSL,然后我们可能还会添加更多高级功能。
由于 nom
和 winnow
之间的差异,nom-rule
和 winnow-rule
之间的语法不完全兼容。然而,它们都是为了提供类似正则表达式的体验而设计的。
目前,该包处于积极开发中,语法尚不稳定。
依赖项
[dependencies]
winnow = "0.6.13"
winnow-rule = "0.1"
语法
此包提供的 rule!
过程宏旨在简化语法规范的编写并提高可维护性,它遵循以下简单规则
#fn_name
:一个外部winnow::Parser
。在以下示例中,ident
和TokenKind::*
是预定义的解析器。a ~ b ~ c
:按顺序取一个解析器序列。它将被展开为(a, b, c)
。(...)+
:一个或多个重复的模式。它将被展开为winnow::combinator::repeat(1.., #next)
。(...)*
:零个或多个重复的模式。它将被展开为winnow::combinator::repeat(0.., #next)
。(...)?
:可选解析器。它将被展开为winnow::combinator::opt
。a | b | c
:在a、b和c之间进行选择。它将被展开为winnow::combinator::alt
。&a
:窥视。它将被展开为winnow::combinator::peek(a)
。注意,它不会消耗输入。!a
:否定谓词。它将被展开为winnow::combinator::not
。注意,它不会消耗输入。^a
:裁剪解析器。它将被展开为winnow::combinator::cut_err
。... : "description"
:错误报告的上下文描述。它将被展开为winnow::Parser::context
。
示例
为您的 TokenKind
实现 winnow::Parser
,使其可以作为上述描述的外部解析器使用。
use winnow::{Parser, PResult, Stream};
#[derive(Clone, Debug, PartialEq)]
struct Token<'a> {
kind: TokenKind,
text: &'a str,
span: Span,
}
#[derive(Clone, Copy, Debug, PartialEq)]
enum TokenKind {
Whitespace,
// Keywords
CREATE,
TABLE,
// Symbols
LParen,
RParen,
Semicolon,
Comma,
Ident,
}
impl<'a, I, E> Parser<I, Token<'a>, E> for TokenKind
where
I: Stream<Token = Token<'a>> + StreamIsPartial,
E: ParserError<I>,
{
fn parse_next(&mut self, input: &mut I) -> PResult<Token<'a>, E> {
any.verify(|t: &Token<'a>| t.kind == *self)
.parse_next(input)
}
}
定义创建表的SQL解析器
use winnow_rule::rule;
use TokenKind::*;
let mut rule = rule!(
#CREATE ~ #TABLE ~ #ident ~ ^#LParen ~ (#ident ~ #ident ~ #Comma?)* ~ #RParen ~ #Semicolon : "CREATE TABLE statement"
);
它将被展开为
let mut rule = ((
CREATE,
TABLE,
ident,
winnow::combinator::cut_err(LParen),
winnow::combinator::repeat(
0..,
((ident, ident, winnow::combinator::opt(Comma))),
),
RParen,
Semicolon,
))
.context(winnow::error::StrContext::Label("CREATE TABLE statement"));
更多示例请参阅
tests/lib.rs
。
路线图
计划中有几个特性
依赖项
~2.5MB
~51K SLoC