22 个版本

0.5.0 2023年3月31日
0.4.3 2022年11月30日
0.4.0 2022年7月9日
0.3.4 2021年12月20日
0.2.2 2017年11月16日

#3#生成

Download history 889/week @ 2024-04-23 627/week @ 2024-04-30 593/week @ 2024-05-07 800/week @ 2024-05-14 344/week @ 2024-05-21 517/week @ 2024-05-28 707/week @ 2024-06-04 550/week @ 2024-06-11 615/week @ 2024-06-18 827/week @ 2024-06-25 1254/week @ 2024-07-02 771/week @ 2024-07-09 871/week @ 2024-07-16 731/week @ 2024-07-23 708/week @ 2024-07-30 721/week @ 2024-08-06

3,176 每月下载量
3 crate 中使用

MIT 许可证

115KB
2.5K SLoC

bnf

.github/workflows/ci.yml coveralls Crates.io Version Crates.io LICENSE

Backus–Naur 形式上下文无关文法的解析库。

可解析的 BNF 语法看起来像什么?

以下来自 Wikipedia 页面上的 Backus–Naur 形式 的语法示例说明了一个兼容的语法。(*注意:解析器允许使用可选的 ';' 来表示生成的结束)

 <postal-address> ::= <name-part> <street-address> <zip-part>

      <name-part> ::= <personal-part> <last-name> <opt-suffix-part> <EOL>
                    | <personal-part> <name-part>

  <personal-part> ::= <initial> "." | <first-name>

 <street-address> ::= <house-num> <street-name> <opt-apt-num> <EOL>

       <zip-part> ::= <town-name> "," <state-code> <ZIP-code> <EOL>

<opt-suffix-part> ::= "Sr." | "Jr." | <roman-numeral> | ""
    <opt-apt-num> ::= <apt-num> | ""

输出

以下 DNA 序列语法用于输入到该库的 parse 函数。

<dna> ::= <base> | <base> <dna>
<base> ::= "A" | "C" | "G" | "T"

输出是一个表示类似下面这样的树的 Grammar 对象

Grammar {
    productions: [
        Production {
            lhs: Nonterminal(
                "dna"
            ),
            rhs: [
                Expression {
                    terms: [
                        Nonterminal(
                            "base"
                        )
                    ]
                },
                Expression {
                    terms: [
                        Nonterminal(
                            "base"
                        ),
                        Nonterminal(
                            "dna"
                        )
                    ]
                }
            ]
        },
        Production {
            lhs: Nonterminal(
                "base"
            ),
            rhs: [
                Expression {
                    terms: [
                        Terminal(
                            "A"
                        )
                    ]
                },
                Expression {
                    terms: [
                        Terminal(
                            "C"
                        )
                    ]
                },
                Expression {
                    terms: [
                        Terminal(
                            "G"
                        )
                    ]
                },
                Expression {
                    terms: [
                        Terminal(
                            "T"
                        )
                    ]
                }
            ]
        }
    ]
}

一旦 Grammar 对象被填充,要生成一个句子,可以调用对象的 generate 函数。 grammar.generate()。对于上述语法,可以期望得到类似 TGGCAG 的内容。

如果生成函数找不到非终端的生成式,它将尝试评估它,并将标识符打印为非终端,即 <identifier>

如果生成函数检测到由于生成式如 <PATTERN> ::= <PATTERN> 而引起的无限循环,它将返回错误。

解析示例

use bnf::Grammar;

let input =
    "<postal-address> ::= <name-part> <street-address> <zip-part>

        <name-part> ::= <personal-part> <last-name> <opt-suffix-part> <EOL>
                        | <personal-part> <name-part>

    <personal-part> ::= <initial> '.' | <first-name>

    <street-address> ::= <house-num> <street-name> <opt-apt-num> <EOL>

        <zip-part> ::= <town-name> ',' <state-code> <ZIP-code> <EOL>

    <opt-suffix-part> ::= 'Sr.' | 'Jr.' | <roman-numeral> | ''
        <opt-apt-num> ::= <apt-num> | ''";

let grammar: Result<Grammar, _> = input.parse();
match grammar {
    Ok(g) => println!("{:#?}", g),
    Err(e) => println!("Failed to make grammar from String: {}", e),
}

生成示例

use bnf::Grammar;

let input =
    "<dna> ::= <base> | <base> <dna>
    <base> ::= 'A' | 'C' | 'G' | 'T'";
let grammar: Grammar = input.parse().unwrap();
let sentence = grammar.generate();
match sentence {
    Ok(s) => println!("random sentence: {}", s),
    Err(e) => println!("something went wrong: {}!", e)
}

通过语法解析句子

use bnf::Grammar;

let input =
    "<dna> ::= <base> | <base> <dna>
    <base> ::= 'A' | 'C' | 'G' | 'T'";
let grammar: Grammar = input.parse().unwrap();

let sentence = "GATTACA";

let mut parse_trees = grammar.parse_input(sentence);
match parse_trees.next() {
    Some(parse_tree) => println!("{}", parse_tree),
    _ => println!("Grammar could not parse sentence"),
}

依赖

~1.7–4MB
~75K SLoC