From d01281cafc8a0ec1f37db92d6b6cdc85006e1fb8 Mon Sep 17 00:00:00 2001 From: therealbnut <635596+therealbnut@users.noreply.github.com> Date: Sun, 7 Feb 2021 13:56:03 +1100 Subject: [PATCH 1/2] trace indent --- peg-macros/translate.rs | 78 +++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/peg-macros/translate.rs b/peg-macros/translate.rs index 82e3ec2..21f45a0 100644 --- a/peg-macros/translate.rs +++ b/peg-macros/translate.rs @@ -132,8 +132,39 @@ fn make_parse_state(grammar: &Grammar) -> TokenStream { } } + let (trace_def, trace_set, trace_push_pop) = if cfg!(feature = "trace") { + ( + quote! { __trace_depth: usize, }, + quote! { __trace_depth: 1, }, + quote! { + fn __indent_depth(&self) -> usize { + self.__trace_depth + } + fn __trace_print(&self) { + print!("[PEG_TRACE]"); + for _ in 0..self.__trace_depth { + print!(" "); + } + } + fn __trace_push(&mut self) { + self.__trace_depth += 1; + } + fn __trace_pop(&mut self) { + self.__trace_depth -= 1; + } + }, + ) + } else { + ( + quote! { }, + quote! { }, + quote! { }, + ) + }; + quote! { struct ParseState<'input> { + #trace_def _phantom: ::std::marker::PhantomData<&'input ()>, #(#cache_fields_def),* } @@ -141,10 +172,12 @@ fn make_parse_state(grammar: &Grammar) -> TokenStream { impl<'input> ParseState<'input> { fn new() -> ParseState<'input> { ParseState { + #trace_set _phantom: ::std::marker::PhantomData, #(#cache_fields: ::std::collections::HashMap::new()),* } } + #trace_push_pop } } } @@ -179,16 +212,20 @@ fn compile_rule(context: &Context, rule: &Rule) -> TokenStream { let str_rule_name = rule_name.to_string(); quote! {{ let loc = ::peg::Parse::position_repr(__input, __pos); - println!("[PEG_TRACE] Attempting to match rule `{}` at {}", #str_rule_name, loc); + let indent = __state.__indent_depth(); + __state.__trace_print(); + println!("Attempting to match rule `{}` at {} {{", #str_rule_name, loc); let __peg_result: ::peg::RuleResult<#ret_ty> = {#body}; match __peg_result { ::peg::RuleResult::Matched(epos, v) => { let eloc = ::peg::Parse::position_repr(__input, epos); - println!("[PEG_TRACE] Matched rule `{}` at {} to {}", #str_rule_name, loc, eloc); + __state.__trace_print(); + println!("}} Matched rule `{}` at {} to {}", #str_rule_name, loc, eloc); ::peg::RuleResult::Matched(epos, v) } ::peg::RuleResult::Failed => { - println!("[PEG_TRACE] Failed to match rule `{}` at {}", #str_rule_name, loc); + __state.__trace_print(); + println!("}} Failed to match rule `{}` at {}", #str_rule_name, loc); ::peg::RuleResult::Failed } } @@ -209,8 +246,14 @@ fn compile_rule(context: &Context, rule: &Rule) -> TokenStream { quote! { let loc = ::peg::Parse::position_repr(__input, __pos); match &entry { - &::peg::RuleResult::Matched(..) => println!("[PEG_TRACE] Cached match of rule {} at {}", #str_rule_name, loc), - &Failed => println!("[PEG_TRACE] Cached fail of rule {} at {}", #str_rule_name, loc), + &::peg::RuleResult::Matched(..) => { + __state.__trace_print(); + println!("Cached match of rule {} at {}", #str_rule_name, loc) + }, + &Failed => { + __state.__trace_print(); + println!("Cached fail of rule {} at {}", #str_rule_name, loc) + }, }; } } else { @@ -386,7 +429,14 @@ fn compile_expr(context: &Context, e: &Expr, result_used: bool) -> TokenStream { ); } - quote! { #rule_name(__input, __state, __err_state, __pos) } + let rule_name_call = quote! { #rule_name(__input, __state, __err_state, __pos) }; + if cfg!(feature = "trace") { + quote! { + (__state.__trace_push(), #rule_name_call, __state.__trace_pop()).1 + } + } else { + rule_name_call + } } RuleExpr(ref rule_name, ref rule_args) => { @@ -459,11 +509,19 @@ fn compile_expr(context: &Context, e: &Expr, result_used: bool) -> TokenStream { }) .collect(); + let call_func = quote! { + #func(__input, __state, __err_state, __pos #extra_args_call #(, #rule_args_call)*) + }; + let call_func = if cfg!(feature = "trace") { + quote! { (__state.__trace_push(), #call_func, __state.__trace_pop()).1 } + } else { + call_func + }; if result_used { - quote! { #func(__input, __state, __err_state, __pos #extra_args_call #(, #rule_args_call)*) } + call_func } else { quote! { - match #func(__input, __state, __err_state, __pos #extra_args_call #(, #rule_args_call)*){ + match #call_func { ::peg::RuleResult::Matched(pos, _) => ::peg::RuleResult::Matched(pos, ()), ::peg::RuleResult::Failed => ::peg::RuleResult::Failed, } @@ -774,8 +832,8 @@ fn compile_expr(context: &Context, e: &Expr, result_used: bool) -> TokenStream { let (enter, leave) = if cfg!(feature = "trace") { ( - quote! {println!("[PEG_TRACE] Entering level {}", min_prec);}, - quote! {println!("[PEG_TRACE] Leaving level {}", min_prec);}, + quote! {{ __state.__trace_print(); println!("Entering level {}", min_prec); }}, + quote! {{ __state.__trace_print(); println!("Leaving level {}", min_prec); }}, ) } else { (quote!(), quote!()) From 47e3e21968741f970668785cb7065f5c80841335 Mon Sep 17 00:00:00 2001 From: therealbnut <635596+therealbnut@users.noreply.github.com> Date: Sun, 7 Feb 2021 15:16:25 +1100 Subject: [PATCH 2/2] Compact empty trace scopes --- peg-macros/translate.rs | 69 +++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/peg-macros/translate.rs b/peg-macros/translate.rs index 21f45a0..a1ce344 100644 --- a/peg-macros/translate.rs +++ b/peg-macros/translate.rs @@ -134,23 +134,43 @@ fn make_parse_state(grammar: &Grammar) -> TokenStream { let (trace_def, trace_set, trace_push_pop) = if cfg!(feature = "trace") { ( - quote! { __trace_depth: usize, }, - quote! { __trace_depth: 1, }, + quote! { __trace_depth: usize, __trace_want_prefix: bool, __trace_follows_start: bool, }, + quote! { __trace_depth: 0, __trace_want_prefix: true, __trace_follows_start: false, }, quote! { - fn __indent_depth(&self) -> usize { - self.__trace_depth - } - fn __trace_print(&self) { - print!("[PEG_TRACE]"); - for _ in 0..self.__trace_depth { - print!(" "); + fn __trace_print_impl(&mut self) { + if self.__trace_want_prefix { + if self.__trace_follows_start { + print!(" {{\n"); + } + print!("[PEG_TRACE] "); + for _ in 0..self.__trace_depth { + print!(" "); + } } } - fn __trace_push(&mut self) { + fn __trace_print(&mut self) { + self.__trace_want_prefix = true; + self.__trace_print_impl(); + self.__trace_follows_start = false; + self.__trace_want_prefix = true; + } + fn __trace_print_start(&mut self) { + self.__trace_want_prefix = true; + self.__trace_print_impl(); + self.__trace_follows_start = true; + self.__trace_want_prefix = false; self.__trace_depth += 1; } - fn __trace_pop(&mut self) { + fn __trace_print_end(&mut self) { self.__trace_depth -= 1; + self.__trace_print_impl(); + if self.__trace_want_prefix { + print!("}} "); + } else { + print!(", "); + } + self.__trace_follows_start = false; + self.__trace_want_prefix = true; } }, ) @@ -212,20 +232,19 @@ fn compile_rule(context: &Context, rule: &Rule) -> TokenStream { let str_rule_name = rule_name.to_string(); quote! {{ let loc = ::peg::Parse::position_repr(__input, __pos); - let indent = __state.__indent_depth(); - __state.__trace_print(); - println!("Attempting to match rule `{}` at {} {{", #str_rule_name, loc); + __state.__trace_print_start(); + print!("Attempting rule `{}` at {}", #str_rule_name, loc); let __peg_result: ::peg::RuleResult<#ret_ty> = {#body}; match __peg_result { ::peg::RuleResult::Matched(epos, v) => { let eloc = ::peg::Parse::position_repr(__input, epos); - __state.__trace_print(); - println!("}} Matched rule `{}` at {} to {}", #str_rule_name, loc, eloc); + __state.__trace_print_end(); + println!("matched `{}` from {} to {}", #str_rule_name, loc, eloc); ::peg::RuleResult::Matched(epos, v) } ::peg::RuleResult::Failed => { - __state.__trace_print(); - println!("}} Failed to match rule `{}` at {}", #str_rule_name, loc); + __state.__trace_print_end(); + println!("failed `{}` at {}", #str_rule_name, loc); ::peg::RuleResult::Failed } } @@ -429,14 +448,7 @@ fn compile_expr(context: &Context, e: &Expr, result_used: bool) -> TokenStream { ); } - let rule_name_call = quote! { #rule_name(__input, __state, __err_state, __pos) }; - if cfg!(feature = "trace") { - quote! { - (__state.__trace_push(), #rule_name_call, __state.__trace_pop()).1 - } - } else { - rule_name_call - } + quote! { #rule_name(__input, __state, __err_state, __pos) } } RuleExpr(ref rule_name, ref rule_args) => { @@ -512,11 +524,6 @@ fn compile_expr(context: &Context, e: &Expr, result_used: bool) -> TokenStream { let call_func = quote! { #func(__input, __state, __err_state, __pos #extra_args_call #(, #rule_args_call)*) }; - let call_func = if cfg!(feature = "trace") { - quote! { (__state.__trace_push(), #call_func, __state.__trace_pop()).1 } - } else { - call_func - }; if result_used { call_func } else {