lalrpop-lambda 0.6.1

A λ-calculus grammar writting with LALRPOP.
use crate::{Expression, Variable};

grammar;

pub Variable: Variable = {
    Id => Variable(<>.to_string(), None),
    <id:Id> ":" <ty:Id> => Variable(id, Some(ty)),
};

pub Expression: Expression = {
    Abstraction => <>,
    Application => <>,
}

Abstraction: Expression = {
    <ls:(Lambda)+> <ids:(Variable)*> <term:("." Expression?)?> => {
        let body = match term {
            Some((_, o @ Some(_))) => o,
            _ => None,
        };
        Expression::build_abs(ls.len(), ids, body)
    },
}

Application: Expression = {
    // NOTE: Base case of terminals is here to allow the `Application`
    // production to be left associative.
    Terminal => <>,
    <e1:Application> <e2:Terminal> => {
        app!({e1},{e2})
    }
}

Terminal: Expression = {
    Variable => Expression::Var(<>),
    "(" <e:Expression> ")" => e,
}

Lambda = {
    "λ",
    "\\",
}

Id: String = r"[a-zA-Z0-9-_]+" => {
    <>.to_string()
};