From 2ae892efab9a1a0ce8735201c6d9641324d35524 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Fri, 27 Jan 2023 18:41:54 +0900 Subject: [PATCH] templater: reuse function rule to represent a method chain A method call is typically parsed as (obj.meth)(), not as obj.(meth()), but the latter is good enough for our needs. It's unlikely we'll add a first-class function support. .into_inner().next().unwrap() mess will be cleaned up by the next commit. --- src/template.pest | 2 +- src/template_parser.rs | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/template.pest b/src/template.pest index 71a641c67..c0baeed87 100644 --- a/src/template.pest +++ b/src/template.pest @@ -28,7 +28,7 @@ identifier = @{ (ASCII_ALPHANUMERIC | "_")+ } function = { identifier ~ "(" ~ template ~ ("," ~ template)* ~ ")" } -method = { "." ~ identifier ~ "(" ~ template ~ ("," ~ template)* ~ ")" ~ maybe_method } +method = { "." ~ function ~ maybe_method } maybe_method = { method | "" } diff --git a/src/template_parser.rs b/src/template_parser.rs index 0cc9ad507..8900bd891 100644 --- a/src/template_parser.rs +++ b/src/template_parser.rs @@ -162,6 +162,9 @@ fn parse_method_chain<'a, I: 'a>( .into_inner() .next() .unwrap() + .into_inner() + .next() + .unwrap() .as_str() .to_string(); let (property, mut labels) = match input_property { @@ -181,7 +184,9 @@ fn parse_method_chain<'a, I: 'a>( fn parse_string_method<'a>(method: Pair) -> PropertyAndLabels<'a, String> { assert_eq!(method.as_rule(), Rule::method); let mut inner = method.into_inner(); - let name = inner.next().unwrap(); + let func = inner.next().unwrap(); + assert_eq!(func.as_rule(), Rule::function); + let name = func.into_inner().next().unwrap(); // TODO: validate arguments let this_function = match name.as_str() { @@ -193,9 +198,11 @@ fn parse_string_method<'a>(method: Pair) -> PropertyAndLabels<'a, String> } fn parse_boolean_method<'a>(method: Pair) -> PropertyAndLabels<'a, bool> { - assert_eq!(method.as_rule(), Rule::maybe_method); + assert_eq!(method.as_rule(), Rule::method); let mut inner = method.into_inner(); - let name = inner.next().unwrap(); + let func = inner.next().unwrap(); + assert_eq!(func.as_rule(), Rule::function); + let name = func.into_inner().next().unwrap(); // TODO: validate arguments panic!("no such boolean method: {}", name.as_str()); @@ -206,7 +213,9 @@ fn parse_commit_or_change_id_method<'a>( ) -> PropertyAndLabels<'a, CommitOrChangeId<'a>> { assert_eq!(method.as_rule(), Rule::method); let mut inner = method.into_inner(); - let name = inner.next().unwrap(); + let func = inner.next().unwrap(); + assert_eq!(func.as_rule(), Rule::function); + let name = func.into_inner().next().unwrap(); // TODO: validate arguments let this_function = match name.as_str() { @@ -223,7 +232,9 @@ fn parse_commit_or_change_id_method<'a>( fn parse_signature_method<'a>(method: Pair) -> PropertyAndLabels<'a, Signature> { assert_eq!(method.as_rule(), Rule::method); let mut inner = method.into_inner(); - let name = inner.next().unwrap(); + let func = inner.next().unwrap(); + assert_eq!(func.as_rule(), Rule::function); + let name = func.into_inner().next().unwrap(); // TODO: validate arguments let this_function: Property<'a, Signature> = match name.as_str() { @@ -239,7 +250,9 @@ fn parse_signature_method<'a>(method: Pair) -> PropertyAndLabels<'a, Signa fn parse_timestamp_method<'a>(method: Pair) -> PropertyAndLabels<'a, Timestamp> { assert_eq!(method.as_rule(), Rule::method); let mut inner = method.into_inner(); - let name = inner.next().unwrap(); + let func = inner.next().unwrap(); + assert_eq!(func.as_rule(), Rule::function); + let name = func.into_inner().next().unwrap(); // TODO: validate arguments let this_function = match name.as_str() {