From d8843cc8c707265fc611b82acc4602800653e93e Mon Sep 17 00:00:00 2001 From: Tartasprint <37597624+Tartasprint@users.noreply.github.com> Date: Sat, 19 Oct 2024 16:25:49 +0200 Subject: [PATCH] fix handling of very long sequences/choices (#20) --- core/src/choice.rs | 2 ++ core/src/sequence.rs | 2 ++ derive/tests/grammar.pest | 7 ++++++- generator/src/typed/output.rs | 32 +++++++++++++++++--------------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/core/src/choice.rs b/core/src/choice.rs index c8f8198..83b3856 100644 --- a/core/src/choice.rs +++ b/core/src/choice.rs @@ -100,6 +100,8 @@ macro_rules! choice_type { }; } +pub use choice_type; + choice_type! { Choice2, (Choice0, T0, choice_0), diff --git a/core/src/sequence.rs b/core/src/sequence.rs index 1615f16..45302ce 100644 --- a/core/src/sequence.rs +++ b/core/src/sequence.rs @@ -100,6 +100,8 @@ macro_rules! sequence_type { }; } +pub use sequence_type; + sequence_type! { Sequence2, (field_0, T0, TR0), diff --git a/derive/tests/grammar.pest b/derive/tests/grammar.pest index e387feb..da265d1 100644 --- a/derive/tests/grammar.pest +++ b/derive/tests/grammar.pest @@ -47,7 +47,12 @@ pop_ = pest::stack::push(range) - pest::stack::push(range) - pest::stack::pop - pop_all = pest::stack::push(range) - pest::stack::push(range) - pest::stack::pop_all pop_fail = pest::stack::push(range) - !pest::stack::pop - range - pest::stack::pop checkpoint_restore = pest::stack::push("") - (pest::stack::push("a") - "b" - pest::stack::pop | pest::stack::drop - "b" | pest::stack::pop - "a") - pest::EOI - +longchoice_builtin = ( "01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | "10" | "11" | "12" | "13" | "14" | "15" | "16") +longseq_builtin = ( "01" ~ "02" ~ "03" ~ "04" ~ "05" ~ "06" ~ "07" ~ "08" ~ "09" ~ "10" ~ "11" ~ "12" ~ "13" ~ "14" ~ "15" ~ "16") +longchoice_critical = ( "01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | "10" | "11" | "12" | "13" | "14" | "15" | "16" | "17") +longseq_critical = ( "01" ~ "02" ~ "03" ~ "04" ~ "05" ~ "06" ~ "07" ~ "08" ~ "09" ~ "10" ~ "11" ~ "12" ~ "13" ~ "14" ~ "15" ~ "16" ~ "17") +longchoice_jump = ( "01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | "10" | "11" | "12" | "13" | "14" | "15" | "16" | "17" | "18" | "19") +longseq_jump = ( "01" ~ "02" ~ "03" ~ "04" ~ "05" ~ "06" ~ "07" ~ "08" ~ "09" ~ "10" ~ "11" ~ "12" ~ "13" ~ "14" ~ "15" ~ "16" ~ "17" ~ "18" ~ "19") /* ascii_digits = ASCII_DIGIT+ ascii_nonzero_digits = ASCII_NONZERO_DIGIT+ diff --git a/generator/src/typed/output.rs b/generator/src/typed/output.rs index 4c05c5b..10a2491 100644 --- a/generator/src/typed/output.rs +++ b/generator/src/typed/output.rs @@ -94,23 +94,25 @@ impl<'g> Tracker<'g> { seq: bool| { for len in set.iter().cloned() { let generics_i = format_ident!("{}{}", prefix, len); - let (types, field): (Vec<_>, Vec<_>) = (0..len) - .map(|i| { - let field = if seq { - let i = Index::from(i); - let i = format_ident!("field_{}", i); - quote! {#i} - } else { - let i = format_ident!("Choice{}", i); - quote! {#i} - }; - (format_ident!("T{}", i), field) - }) - .unzip(); + let branch = (0..len).map(|i| { + if seq { + format_ident!("field_{}", i) + } else { + format_ident!("Choice{}", i) + } + }); + let the_type = (0..len).map(|i| format_ident!("T{}", i)); + let trivia_or_getter = (0..len).map(|i| { + if seq { + format_ident!("TR{}", i) + } else { + format_ident!("choice_{}", i) + } + }); // `pest` is already imported, so can be referred directly. - if len >= 16 { + if len > 16 { target.push(quote! { - #pest::#mac!(#generics_i, #(#types, #field, )*); + #pest::#module::#mac!(#generics_i, #((#branch, #the_type, #trivia_or_getter),)*); }); } else { target.push(quote! {