lalrproc 0.0.8

Procedural macro built on LALRPOP
Documentation
use crate::ast::{Type, Path, Reference, Expr, BinOp, Lifetime};
use crate::error::NoUserError;
use crate::token::Token;
use crate::span::Span;
use proc_macro::Literal;

grammar;

extern {
    type Error = NoUserError;
    type Location = Span;

    enum Token {
        // The delimiters needed by our grammar
        "(" => Token::Open(proc_macro::Delimiter::Parenthesis),
        ")" => Token::Close(proc_macro::Delimiter::Parenthesis),

        // The punctuation needed by our grammar
        "+" => Token::Punct('+'),
        "-" => Token::Punct('-'),
        "*" => Token::Punct('*'),
        "/" => Token::Punct('/'),
        "&" => Token::Punct('&'),
        ":" => Token::Punct(':'),
        "'" => Token::Punct('\''),
        Punct => Token::Punct(<char>),
        Joint => Token::Joint,

        // The keywords needed by our grammar
        "mut" => Token::Keyword(crate::token::Keyword::Mut),

        // Other terminals in the grammar
        Ident => Token::Ident(<proc_macro::Ident>),
        Literal => Token::Literal(<Literal>),
    }
}

pub Type: Box<Type> = {
    Path => Box::new(Type::Path(<>)),
    Reference => Box::new(Type::Reference(<>)),
};

Path: Path = {
    <v:(<Ident> ":" Joint ":")*> <e:Ident> => {
        let mut v = v;
        v.push(e);
        Path { segments: v }
    }
};

Reference: Reference = {
    "&" <lifetime:Lifetime?> <mutable:Mutable> <elem:Type> => Reference {<>}
};

Mutable: bool = {
    "mut" => true,
    => false,
};

pub Expr: Box<Expr> = {
    Expr ExprOp Factor => Box::new(Expr::Binary(<>)),
    Factor,
};

ExprOp: BinOp = {
    "+" => BinOp::Add,
    "-" => BinOp::Sub,
};

Factor: Box<Expr> = {
    Factor FactorOp Component => Box::new(Expr::Binary(<>)),
    Component,
};

FactorOp: BinOp = {
    "*" => BinOp::Mul,
    "/" => BinOp::Div,
};

Component: Box<Expr> = {
    Literal => Box::new(Expr::Lit(<>)),
    Path => Box::new(Expr::Path(<>)),
    "(" <Expr> ")",
};

Lifetime: Lifetime = {
    <span:@L> "'" Joint <ident:Ident> => Lifetime { span, ident },
};