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 },
};