//! Parser and associated types
use crate::errors::{ExprErrorS, SyntaxError};
use crate::ast;
use crate::lexer::Token;
use crate::span::Spanned;
grammar<'err>(source: &str, errors: &'err mut Vec<ExprErrorS>);
pub Expr: ast::Expr = {
ExprIdentifier,
ExprCall,
ExprString,
ExprBool,
<e:!> => {
errors.push(SyntaxError::from_parser_error(e.error, source));
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>: Spanned<T> = <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 = ExprErrorS;
enum Token {
"(" => Token::LParan,
")" => Token::RParan,
"true" => Token::True,
"false" => Token::False,
string => Token::String(<String>),
identifier => Token::Identifier(<String>),
}
}