nom-rule

Crates.ionom-rule
lib.rsnom-rule
version0.4.0
sourcesrc
created_at2022-01-31 07:58:31.966376
updated_at2024-09-19 07:18:10.323828
descriptionA procedural macro for writing nom parsers using a grammar-like DSL.
homepagehttps://github.com/andylokandy/nom-rule
repositoryhttps://github.com/andylokandy/nom-rule
max_upload_size
id524457
size38,260
Andy Lok (andylokandy)

documentation

README

nom-rule

Documentation Crates.io LICENSE

A procedural macro for writing nom parsers using a grammar-like syntax.

Overview

The nom-rule crate provides the rule! macro, which allows you to define nom parsers using a domain-specific language (DSL) that resembles grammar rules. This makes your parsers more readable and easier to maintain.

Features

  • Define parsers using a grammar-like syntax.
  • Integrates seamlessly with nom combinators.
  • Supports sequences, choices, repetitions, optional parsing, and more.

Usage

use nom_rule::rule;

// Define your match functions
fn match_text<'a>(text: &'a str) -> impl FnMut(Input<'a>) -> IResult<Input<'a>, &'a Token<'a>> {
    // Implementation
}

fn match_token<'a>(kind: TokenKind) -> impl FnMut(Input<'a>) -> IResult<Input<'a>, &'a Token<'a>> {
    // Implementation
}

fn ident<'a>(input: Input<'a>) -> IResult<Input<'a>, &str> {
    // Implementation
}

// Use the `rule!` macro
let mut parser = rule!(
    CREATE ~ TABLE ~ #ident ~ ^"(" ~ (#ident ~ #ident ~ ","?)* ~ ")" ~ ";"
    : "CREATE TABLE statement"
);

Syntax

The rule! macro follows these rules:

Syntax Description Expanded to Operator Precedence
TOKEN Matches a token by kind. match_token(TOKEN) -
"(" Matches a token by its text. match_text("(") -
#fn_name Calls an external nom parser function fn_name. fn_name -
#fn_name(a, b, c) Calls an external nom parser function fn_name with arguments. fn_name(a, b, c) -
a ~ b ~ c Sequences parsers a, b, and c. nom::sequence::tuple((a, b, c)) 3 (Left Associative)
a+ One or more repetitions. nom::multi::many1(a) 4 (Postfix)
a* Zero or more repetitions. nom::multi::many0(a) 4 (Postfix)
a? Optional parser. nom::combinator::opt(a) 4 (Postfix)
a | b | c Choice between parsers a, b, and c. nom::branch::alt((a, b, c)) 1 (Left Associative)
&a Peeks at parser a without consuming input. nom::combinator::peek(a) 5 (Prefix)
!a Negative lookahead for parser a. nom::combinator::not(a) 5 (Prefix)
^a Cuts the parser a. nom::combinator::cut(a) 5 (Prefix)
... : "description" Adds a context description for error reporting. nom::error::context("description", a) 2 (Postfix)

Example

See the sqlparser.rs file for a complete example parsing a simplified SQL CREATE TABLE statement.

Commit count: 23

cargo fmt