Create each main parser only once

This commit is contained in:
Joscha 2022-11-19 20:50:26 +01:00
parent b291619d10
commit ea7518b183
10 changed files with 346 additions and 222 deletions

View file

@ -1,11 +1,19 @@
//! Parse the ast over at [`crate::ast`].
//!
//! Rules of thumb:
//! - Everything `pub` should return a [`BoxedParser`].
//! - Everything not used outside a module should not be `pub`. It can always be
//! made public later.
//! # Rules
//!
//! - Public parser functions must return [`basic::EParser`].
//! - Public parser functions must receive public subparsers via their arguments.
//! - Each public parser function must be called exactly once, inside this file.
//! - Non-public parser functions may receive and return `impl Parser<...>`.
//!
//! # Warning
//!
//! `clippy::redundant_clone` has stopped working in this module and its
//! submodules. I have no idea why.
// TODO Turn multiple calls to subparsers into clone-s
// TODO https://github.com/rust-lang/rust/issues/63063
// TODO Find out why clippy::redundant_clone stopped working
mod basic;
mod expr;
@ -24,5 +32,45 @@ use crate::ast::Expr;
use self::basic::Error;
pub fn parser() -> impl Parser<char, Expr, Error = Error> {
recursive(expr::expr).padded().then_ignore(end())
let space = basic::space();
let ident = basic::ident();
let local = basic::local(space.clone());
let table_pattern = table_destr::table_pattern(space.clone(), ident.clone());
let expr = recursive(|expr| {
let expr = expr.boxed();
let table_lit_elem = lit::table_lit_elem(space.clone(), ident.clone(), expr.clone());
let lit = lit::lit(space.clone(), table_lit_elem.clone());
let var = var::var(space.clone(), ident.clone(), local.clone(), expr.clone());
let table_constr = table_constr::table_constr(space.clone(), table_lit_elem, expr.clone());
let table_destr = table_destr::table_destr(
space.clone(),
local.clone(),
table_pattern.clone(),
expr.clone(),
);
let func_def = func_defs::func_def(
space.clone(),
ident.clone(),
local,
table_pattern,
expr.clone(),
);
let atom = expr::atom(
space.clone(),
lit,
var,
table_constr.clone(),
table_destr,
func_def,
expr.clone(),
);
let suffixed = suffix::suffixed(space.clone(), ident, table_constr, atom, expr);
let prefixed = prefix::prefixed(space.clone(), suffixed);
expr::expr(space, prefixed)
});
expr.padded().then_ignore(end())
}