revsets: restructure grammar to prepare for operator precedences

This commit is contained in:
Martin von Zweigbergk 2021-04-17 15:25:52 -07:00
parent d9ae7cdd6d
commit e733b074e1
2 changed files with 47 additions and 29 deletions

View file

@ -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
}

View file

@ -111,26 +111,34 @@ pub enum RevsetExpression {
fn parse_expression_rule(mut pairs: Pairs<Rule>) -> Result<RevsetExpression, RevsetParseError> {
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<Rule>,
) -> Result<RevsetExpression, RevsetParseError> {
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<Rule>) -> Result<RevsetExpression, Rev
fn parse_primary_rule(mut pairs: Pairs<Rule>) -> Result<RevsetExpression, RevsetParseError> {
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());
}
}
}
}