//! Parser and associated types
use crate::errors::ExprError;
use crate::ast;
use crate::lexer::Token;
use lalrpop_util::ParseError;
grammar<'err>(errors: &'err mut Vec<ParseError<usize, Token, (ExprError, std::ops::Range<usize>)>>);
pub Expr: ast::Expr = {
ExprIdentifier,
ExprCall,
ExprString,
ExprBool,
<e:!> => {
errors.push(e.error);
ast::Expr::Error
}
};
// Boolean Expressions
ExprBool: ast::Expr = {
"true" => ast::Expr::Bool(ast::ExprBool(true).into()),
"false" => ast::Expr::Bool(ast::ExprBool(false).into()),
};
// String Expressions
ExprString: ast::Expr = {
string => ast::Expr::String(ast::ExprString(<>).into())
};
// Call Expressions
CallCallee = ExprS;
CallArgs = Args<ExprS>;
ExprCall: ast::Expr = {
"(" <callee:CallCallee> <args:CallArgs> ")" => ast::Expr::Call(ast::ExprCall {
callee,
args
}.into())
}
// Identifier Expressions
ExprIdentifier: ast::Expr = <name:identifier> =>
ast::Expr::Identifier(ast::ExprIdentifier(name).into());
// Utility Types
ExprS = Spanned<Expr>;
Spanned<T>: (T, std::ops::Range<usize>) = <l:@L> <t:T> <r:@R> =>
(t, l..r);
#[inline]
Args<E>: Vec<E> = {
<first:E> <mut args:(<E>)*> => {
args.insert(0, first);
args
},
() => Vec::new(),
}
extern {
type Location = usize;
type Error = (ExprError, std::ops::Range<usize>);
enum Token {
"(" => Token::LParan,
")" => Token::RParan,
"true" => Token::True,
"false" => Token::False,
string => Token::String(<String>),
identifier => Token::Identifier(<String>),
}
}