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

MIT 许可证

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)
  }
}

依赖关系