Skip to content

DavePearce/Lexington

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

About

Parser library

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages