From f2455ee9adfe106a5e18797e553bef992ed461cf Mon Sep 17 00:00:00 2001 From: lmittmann <3458786+lmittmann@users.noreply.github.com> Date: Fri, 18 Oct 2024 11:41:50 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A5=A2=20Simplify=20parser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: lmittmann Co-authored-by: Philippe Dumonet --- crates/ast/src/parser.rs | 101 ++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 54 deletions(-) diff --git a/crates/ast/src/parser.rs b/crates/ast/src/parser.rs index abfc6da..00ff048 100644 --- a/crates/ast/src/parser.rs +++ b/crates/ast/src/parser.rs @@ -64,11 +64,12 @@ fn root<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Root<'src>> } fn root_section<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::RootSection<'src>> { + let definition = definition().map(ast::RootSection::Definition); let include = just(Keyword("include")) .ignore_then(select! {String(s) => s}.map_with(|s, ex| (s, ex.span()))) .map(ast::RootSection::Include); - choice((definition().map(ast::RootSection::Definition), include)) + choice((definition, include)) } fn definition<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Definition<'src>> { @@ -83,28 +84,25 @@ fn definition<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Defin } fn r#macro<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Definition<'src>> { - let macro_args = ident().separated_by(just(Punct(','))).collect::>(); + let macro_args = ident().separated_by(punct(',')).collect::>(); just(Ident("macro")) .ignore_then(ident()) - .then_ignore(just(Punct('('))) - .then(macro_args) - .then_ignore(just(Punct(')'))) - .then_ignore(just(Punct('='))) + .then(macro_args.delimited_by(punct('('), punct(')'))) + .then_ignore(punct('=')) .then( just(Ident("takes")) - .ignore_then(just(Punct('('))) - .ignore_then(dec()) - .then_ignore(just(Punct(')'))) + .ignore_then(dec().delimited_by(punct('('), punct(')'))) .then_ignore(just(Ident("returns"))) - .then_ignore(just(Punct('('))) - .then(dec()) - .then_ignore(just(Punct(')'))) + .then(dec().delimited_by(punct('('), punct(')'))) .or_not(), ) - .then_ignore(just(Punct('{'))) - .then(macro_statement().repeated().collect::>()) - .then_ignore(just(Punct('}'))) + .then( + macro_statement() + .repeated() + .collect::>() + .delimited_by(punct('{'), punct('}')), + ) .map(|(((name, args), takes_returns), body)| ast::Macro { name, args: args.into_boxed_slice(), @@ -117,7 +115,7 @@ fn r#macro<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Definiti fn macro_statement<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::MacroStatement<'src>> { let label = ident() - .then_ignore(just(Punct(':'))) + .then_ignore(punct(':')) .map(ast::MacroStatement::LabelDefinition); let instruction = instruction().map(ast::MacroStatement::Instruction); let invoke = invoke().map(ast::MacroStatement::Invoke); @@ -212,26 +210,21 @@ fn instruction<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Inst ast::Instruction::LabelReference((ident, span)) } }); - let macro_arg_ref = just(Punct('<')) - .ignore_then(ident()) - .then_ignore(just(Punct('>'))) + let macro_arg_ref = ident() + .delimited_by(punct('<'), punct('>')) .map(ast::Instruction::MacroArgReference); - let constant_ref = just(Punct('[')) - .ignore_then(ident()) - .then_ignore(just(Punct(']'))) + let constant_ref = ident() + .delimited_by(punct('['), punct(']')) .map(ast::Instruction::ConstantReference); choice((push_auto, push, op, macro_arg_ref, constant_ref)) } fn invoke<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Invoke<'src>> { - let invoke_macro_args = just(Punct('(')) - .ignore_then( - instruction() - .separated_by(just(Punct(','))) - .collect::>(), - ) - .then_ignore(just(Punct(')'))) + let invoke_macro_args = instruction() + .separated_by(punct(',')) + .collect::>() + .delimited_by(punct('('), punct(')')) .map(|args| args.into_boxed_slice()); let invoke_macro = ident() @@ -240,9 +233,9 @@ fn invoke<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Invoke<'s let invoke_builtin = |name, constructor: fn((_, Span)) -> ast::Invoke<'src>| { just(Ident(name)) - .ignore_then(just(Punct('('))) + .ignore_then(punct('(')) .ignore_then(ident()) - .then_ignore(just(Punct(')'))) + .then_ignore(punct(')')) .map(constructor) }; @@ -269,7 +262,7 @@ fn constant<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Definit just(Ident("constant")) .ignore_then(ident()) - .then_ignore(just(Punct('='))) + .then_ignore(punct('=')) .then(const_expr) .map(|(name, expr)| ast::Definition::Constant { name, expr }) } @@ -277,9 +270,12 @@ fn constant<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Definit fn table<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Definition<'src>> { just(Ident("table")) .ignore_then(ident()) - .then_ignore(just(Punct('{'))) - .then(code().repeated().collect::>()) - .then_ignore(just(Punct('}'))) + .then( + code() + .repeated() + .collect::>() + .delimited_by(punct('{'), punct('}')), + ) .map(|(name, code)| ast::Definition::Table { name, data: code @@ -330,41 +326,34 @@ fn sol_error<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, ast::Defini fn sol_type_list<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, Box<[Spanned]>> { - just(Punct('(')) - .ignore_then( - sol_type() - .separated_by(just(Punct(','))) - .collect::>(), - ) - .then_ignore(just(Punct(')'))) + sol_type() + .separated_by(punct(',')) + .collect::>() + .delimited_by(punct('('), punct(')')) .map(|args| args.into_boxed_slice()) } fn sol_type<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, Spanned> { recursive(|sol_raw_type| { - let sol_raw_primitive_type = ident().map(|(typ, _)| typ.to_string()).boxed(); + let sol_raw_primitive_type = ident().map(|(typ, _)| typ.to_string()); - let sol_raw_tuple_type = just(Punct('(')) - .ignore_then( - sol_raw_type - .separated_by(just(Punct(','))) - .collect::>(), - ) - .then_ignore(just(Punct(')'))) + let sol_raw_tuple_type = sol_raw_type + .separated_by(punct(',')) + .collect::>() + .delimited_by(punct('('), punct(')')) .map(|types| { let mut result = "(".to_string(); let types = types.into_iter().collect::>().join(","); result.push_str(&types); result.push(')'); result - }) - .boxed(); + }); choice((sol_raw_primitive_type, sol_raw_tuple_type)) .then( - just(Punct('[')) + punct('[') .ignore_then(dec().or_not()) - .then_ignore(just(Punct(']'))) + .then_ignore(punct(']')) .or_not(), ) .then_ignore(ident().or_not()) @@ -414,6 +403,10 @@ fn code<'tokens, 'src: 'tokens>() -> impl Parser<'tokens, 'src, Vec> { .map(|code| code.to_vec()) } +fn punct<'tokens, 'src: 'tokens>(c: char) -> impl Parser<'tokens, 'src, Token<'src>> { + just(Punct(c)) +} + #[cfg(test)] mod tests { use super::*;