lexington

Crates.iolexington
lib.rslexington
version0.3.0
sourcesrc
created_at2024-04-16 23:29:05.776356
updated_at2024-05-12 22:43:50.447425
descriptionA very simple library for lexing / parsing
homepage
repositoryhttps://github.com/DavePearce/Lexington
max_upload_size
id1210824
size86,500
David Pearce (DavePearce)

documentation

README

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<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)    
}
Commit count: 31

cargo fmt