9个版本
0.2.6 | 2022年3月24日 |
---|---|
0.2.4 | 2022年3月11日 |
0.2.2 | 2020年1月20日 |
0.2.1 | 2019年7月17日 |
0.1.5 | 2018年8月4日 |
#149 in 解析工具
用于 fluxcap
215KB
2.5K SLoC
文档
Abackus存储库在earlgrey存储库之上添加了一层,以简化编写语法。您可以简单地使用EBNF风格的字符串,而不是手动添加规则。
您可以像这样描述您的语法
let grammar = r#"
S := S '+' N | N ;
N := '[0-9]' ;
"#;
ParserBuilder::default()
.plug_terminal("[0-9]", |n| "1234567890".contains(n))
.plug_terminal("[+]", |c| c == "+")
.into_parser("S")
而不是更冗长的
// Gramar: S -> S + N | N; N -> [0-9];
let g = earlgrey::GrammarBuilder::default()
.nonterm("S")
.nonterm("N")
.terminal("[+]", |c| c == "+")
.terminal("[0-9]", |n| "1234567890".contains(n))
.rule("S", &["S", "[+]", "N"])
.rule("S", &["N"])
.rule("N", &["[0-9]"])
.into_grammar("S")
.unwrap();
earlgrey::EarleyParser::new(g)
工作原理
在幕后,使用 earlgrey::EarleyParser
来为EBNF语法构建解析器。(有关详细信息,请参阅 earlgrey/ebnf.rs
)。然后使用该解析器为用户提供的语法构建最终的解析器。
示例
// NOTE: extract from abackus/examples/ebnftree.rs
fn main() {
let grammar = r#"
expr := expr ('+'|'-') term | term ;
term := term ('*'|'/') factor | factor ;
factor := '-' factor | power ;
power := ufact '^' factor | ufact ;
ufact := ufact '!' | group ;
group := num | '(' expr ')' ;
"#;
// Build a parser for our grammar and while at it, plug in an
// evaluator to extract the resulting tree as S-expressions.
use std::str::FromStr;
let trif = abackus::ParserBuilder::default()
.plug_terminal("num", |n| f64::from_str(n).is_ok())
.sexprificator(&grammar, "expr");
// Read some input from command-line
let input = std::env::args().skip(1).
collect::<Vec<String>>().join(" ");
// Print resulting parse trees
match trif(&mut tokenizer(input.chars())) {
Ok(trees) => for t in trees { println!("{}", t.print()); },
Err(e) => println!("{:?}", e)
}
}