Crates.io | cfg |
lib.rs | cfg |
version | 0.9.0 |
source | src |
created_at | 2014-11-13 13:23:02.931507 |
updated_at | 2024-07-10 11:01:33.134014 |
description | Library for manipulating context-free grammars. |
homepage | https://github.com/pczarn/cfg |
repository | https://github.com/pczarn/cfg |
max_upload_size | |
id | 95 |
size | 40,075 |
Rust library for manipulating context-free grammars. You can check the documentation here.
Add this to your Cargo.toml:
[dependencies]
cfg = "0.9"
If you want grammar serialization support with miniserde
, include the feature like this:
[dependencies]
cfg = { version = "0.9", features = ["serialize"] }
If you want weighted generation support, include the feature like this:
[dependencies]
cfg = { version = "0.9", features = ["weighted-generation"] }
If you want LL(1) classification support, include the feature like this:
[dependencies]
cfg = { version = "0.9", features = ["ll"] }
The following features are implemented thus far:
cfg
includes an interface that simplifies grammar construction.
The easiest way of generating symbols is with the sym
method. The library is unaware
of the start symbol.
let mut grammar: Cfg = Cfg::new();
let (start, expr, identifier, number,
plus, multiply, power, l_paren, r_paren, digit) = grammar.sym();
Rules have a LHS symbol and zero or more RHS symbols.
Example BNF:
start ::= expr | identifier l_paren expr r_paren
With our library:
grammar.rule(start).rhs([expr])
.rhs([identifier, l_paren, expr, r_paren]);
Sequence rules have a LHS symbol, a RHS symbol, a range of repetitions, and optional separation. Aside from separation, they closely resemble regular expression repetitions.
Example BNF:
number ::= digit+
With our library:
SequencesToProductions::new(&mut grammar).sequence(number).inclusive(1, None).rhs(digit);
Precedenced rules are the most convenient way to describe operators. Once
built, they are immediately rewritten into basic grammar rules, and unique
symbols are generated. Operator associativity can be set to Right
or
Group
. It's Left
by default.
use cfg::precedence::Associativity::{Right, Group};
grammar.precedenced_rule(expr)
.rhs([number])
.rhs([identifier])
.associativity(Group)
.rhs([l_paren, expr, r_paren])
.lower_precedence()
.associativity(Right)
.rhs([expr, power, expr])
.lower_precedence()
.rhs([expr, multiply, expr])
.lower_precedence()
.rhs([expr, plus, expr]);
Your grammar type has to implement the RuleContainer
trait.
Dual-licensed for compatibility with the Rust project.
Licensed under the Apache License Version 2.0: http://www.apache.org/licenses/LICENSE-2.0, or the MIT license: http://opensource.org/licenses/MIT, at your option.