# Lexington A library for building parsers and lexers. ## Example A simple parser for S-Expressions is as follows: ``` /// 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>) } /// Parse an input string into an S-expression, or produce an error. fn parse<'a>(input: &'a str) -> Result { // [ \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) } ```