forked from mirrors/jj
revsets: restructure grammar to prepare for operator precedences
This commit is contained in:
parent
d9ae7cdd6d
commit
e733b074e1
2 changed files with 47 additions and 29 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue