3 个版本 (破坏性更新)
0.3.0 | 2024 年 5 月 12 日 |
---|---|
0.2.0 | 2024 年 5 月 1 日 |
0.1.0 | 2024 年 4 月 16 日 |
#1118 在 Rust patterns
37KB
655 行
Lexington
用于构建解析器和词法分析器的库。
示例
以下是一个简单的 S-Expression 解析器示例
/// A simple definition of the components of an S-expression.
#[derive(Copy,Clone,Debug,PartialEq)]
enum Kind {
WhiteSpace,
LeftBrace,
RightBrace,
Symbol
}
/// A simple definition of an S-expression.
#[derive(Clone,Debug,PartialEq)]
enum SExp<'a> {
Symbol(&'a str),
List(Vec<SExp<'a>>)
}
/// Parse an input string into an S-expression, or produce an error.
fn parse<'a>(input: &'a str) -> Result<SExp,()> {
// [ \n\t]+
let whitespace = Any([' ','\n','\t']).one_or_more();
// [0..9a..zA..Z_]+
let symbol = Within('0'..='9').or(Within('a'..='z'))
.or(Within('A'..='Z')).or('_').one_or_more();
// Construct scanner
let scanner = Match(whitespace,Kind::WhiteSpace)
.and_match(symbol,Kind::Symbol)
.and_match('(',Kind::LeftBrace)
.and_match(')',Kind::RightBrace);
// Construct lexer.
let lexer = Lexer::new(input,scanner);
// Rule for combining s-expressions
let reduction_rule = |mut l:SExp<'a>,r:SExp<'a>| {
match &mut l {
SExp::List(vs) => { vs.push(r); Ok(l) }
_ => Err(())
}
};
// Rule for parsing strings into numbers
ShiftReduceParser::new()
.apply(reduction_rule)
.terminate(Kind::Symbol,|tok| SExp::Symbol(&input[tok.range()]))
.skip(Kind::WhiteSpace)
.open(Kind::LeftBrace, SExp::List(Vec::new()))
.close(Kind::RightBrace)
.parse(lexer)
}