diff --git a/lib/src/revset.pest b/lib/src/revset.pest index 292363e53..df370fb74 100644 --- a/lib/src/revset.pest +++ b/lib/src/revset.pest @@ -17,6 +17,7 @@ literal_string = { "\"" ~ (!"\"" ~ ANY)+ ~ "\"" } parents = { ":" } ancestors = { "*:" } +prefix_operator = _{ parents | ancestors } function_name = @{ (ASCII_ALPHANUMERIC | "_")+ } // The grammar accepts a string literal or an expression for function @@ -35,14 +36,15 @@ function_arguments = { | "" } + primary = { - symbol + function_name ~ "(" ~ function_arguments ~ ")" | "(" ~ expression ~ ")" + | symbol } +prefix_expression = { prefix_operator* ~ primary } + expression = { - parents ~ expression - | ancestors ~ expression - | function_name ~ "(" ~ function_arguments ~ ")" - | primary + prefix_expression } diff --git a/lib/src/revset.rs b/lib/src/revset.rs index 0e5a17a7d..70af6d4cf 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -111,26 +111,34 @@ pub enum RevsetExpression { fn parse_expression_rule(mut pairs: Pairs) -> Result { let first = pairs.next().unwrap(); match first.as_rule() { - Rule::primary => parse_primary_rule(first.into_inner()), - Rule::parents => { - let expression = pairs.next().unwrap(); - Ok(RevsetExpression::Parents(Box::new(parse_expression_rule( - expression.into_inner(), - )?))) - } - Rule::ancestors => { - let expression = pairs.next().unwrap(); - Ok(RevsetExpression::Ancestors(Box::new( - parse_expression_rule(expression.into_inner())?, - ))) - } - Rule::function_name => { - let name = first.as_str().to_owned(); - let argument_pairs = pairs.next().unwrap().into_inner(); - parse_function_expression(name, argument_pairs) - } + Rule::prefix_expression => parse_prefix_expression_rule(first.into_inner()), _ => { - panic!("unxpected revset parse rule: {:?}", first.as_str()); + panic!( + "unxpected revset parse rule {:?} in: {:?}", + first.as_rule(), + first.as_str() + ); + } + } +} + +fn parse_prefix_expression_rule( + mut pairs: Pairs, +) -> Result { + let first = pairs.next().unwrap(); + match first.as_rule() { + Rule::primary => parse_primary_rule(first.into_inner()), + Rule::parents => Ok(RevsetExpression::Parents(Box::new( + parse_prefix_expression_rule(pairs)?, + ))), + Rule::ancestors => Ok(RevsetExpression::Ancestors(Box::new( + parse_prefix_expression_rule(pairs)?, + ))), + _ => { + panic!( + "unxpected revset prefix operator rule {:?}", + first.as_rule() + ); } } } @@ -138,8 +146,13 @@ fn parse_expression_rule(mut pairs: Pairs) -> Result) -> Result { let first = pairs.next().unwrap(); match first.as_rule() { - Rule::symbol => Ok(RevsetExpression::Symbol(first.as_str().to_owned())), Rule::expression => parse_expression_rule(first.into_inner()), + Rule::function_name => { + let name = first.as_str().to_owned(); + let argument_pairs = pairs.next().unwrap().into_inner(); + parse_function_expression(name, argument_pairs) + } + Rule::symbol => Ok(RevsetExpression::Symbol(first.as_str().to_owned())), _ => { panic!("unxpected revset parse rule: {:?}", first.as_str()); } @@ -277,14 +290,17 @@ fn parse_function_argument_to_string( .unwrap() .strip_suffix('"') .unwrap() - .to_owned()) + .to_owned()); } Rule::expression => { let first = first.into_inner().next().unwrap(); - if first.as_rule() == Rule::primary { + if first.as_rule() == Rule::prefix_expression { let first = first.into_inner().next().unwrap(); - if first.as_rule() == Rule::symbol { - return Ok(first.as_str().to_owned()); + if first.as_rule() == Rule::primary { + let first = first.into_inner().next().unwrap(); + if first.as_rule() == Rule::symbol { + return Ok(first.as_str().to_owned()); + } } } }