nom-rule
A procedural macro for defining nom combinators in simple DSL. Requires nom v5.0+.
Dependencies
[]
= "7"
= "0.2"
Syntax
The procedural macro rule! provided by this crate is designed for the ease of writing grammar spec as well as to improve maintainability, it follows these simple rules:
TOKEN: match the token by token kind. You should provide a parser to eat the next token if the token kind matched. it will get expanded intomatch_token(TOKEN).";": match the token by token text. You should provide a parser to eat the next token if the token text matched. it will get expanded intomatch_text(";")in this example.#fn_name: an external nom parser function. In the example above,identis a predefined parser for identifiers.a ~ b ~ c: a sequence of parsers to take one by one. It'll get expanded intonom::sequence::tuple.(...)+: one or more repeated patterns. It'll get expanded intonom::multi::many1.(...)*: zero or more repeated patterns. It'll get expanded intonom::multi::many0.(...)?: Optional parser. It'll get expanded intonom::combinator::opt.a | b | c: Choices between a, b, and c. It'll get expanded intonom::branch::alt.&a: Positive predicate. It'll get expanded intonom::combinator::map(nom::combinator::peek(a), |_| ()). Note that it doesn't consume the input.!a: Negative predicate. It'll get expanded intonom::combinator::not. Note that it doesn't consume the input.... : "description": Context description for error reporting. It'll get expanded intonom::error::context.
Example
Define match_text parser and match_token parser for your custom token type. You can use nom::combinator::fail as match_token if your parser use &str or &[u8] as input because you won't match on token kinds.
Then give the two parser to nom_rule::rule! by wrapping it into a custom macro:
To define a parser for the SQL of creating table:
let mut rule = rule!;
It will get expanded into:
let mut rule =
context;
Auto Sequence (nightly only)
nom-rule is able to automatically insert ~ in the rule when necessary so that you get the example above working the same as the following:
let mut rule = rule!;
To enable this feature, you need to use a nightly channel rust complier, and add this to the Cargo.toml:
= { = "0.2", = ["auto-sequence"] }