Skip to content
This repository has been archived by the owner on Dec 18, 2019. It is now read-only.

Commit

Permalink
feat(parser) Re-implement coalesce.
Browse files Browse the repository at this point in the history
In php/php-langspec#201, it has been pointed
out that the `coalesce-expression` was not correctly described in the
grammar. While waiting to have an Internet connection to submit a PR
that is already ready, we can re-implement it.

A new macro: `right_to_left_binary_operation!` is proposed, and is used
to re-implement the `coalese-expression` parser.
  • Loading branch information
Hywan committed Sep 19, 2017
1 parent 9ab0eb0 commit b80736e
Showing 1 changed file with 39 additions and 25 deletions.
64 changes: 39 additions & 25 deletions source/rules/expressions/assignment.rs
Expand Up @@ -53,10 +53,7 @@ named_attr!(
"],
pub assignment<Span, Expression>,
map_res!(
alt_complete!(
coalesce
| conditional
),
conditional,
nary_expression_mapper
)
);
Expand All @@ -69,13 +66,13 @@ fn nary_expression_mapper<'a>(nary_operation: NAryOperation<'a>) -> Result<Expre
named!(
conditional<Span, NAryOperation>,
do_parse!(
left_operand: logical_or >>
left_operand: coalesce >>
result: fold_many0!(
do_parse!(
first!(tag!(tokens::TERNARY_THEN)) >>
middle_operand: opt!(first!(expression)) >>
first!(tag!(tokens::TERNARY_ELSE)) >>
right_operand: first!(logical_or) >>
right_operand: first!(coalesce) >>
(middle_operand, right_operand)
),
left_operand,
Expand Down Expand Up @@ -105,22 +102,6 @@ named!(
)
);

named!(
coalesce<Span, NAryOperation>,
do_parse!(
left_operand: logical_or >>
first!(tag!(tokens::COALESCE)) >>
right_operand: first!(expression) >>
(
NAryOperation::Binary {
operator : BinaryOperator::Coalesce,
left_operand : Box::new(left_operand),
right_operand: Box::new(NAryOperation::Nullary(Box::new(right_operand)))
}
)
)
);

macro_rules! left_to_right_binary_operation {
(
$parser_name:ident:
Expand Down Expand Up @@ -188,6 +169,35 @@ macro_rules! left_to_right_binary_operation {
)
}

macro_rules! right_to_left_binary_operation {
(
$parser_name:ident:
$operand:ident with
$operator_token:ident as $operator_representation:ident
) => (
named!(
$parser_name<Span, NAryOperation>,
alt_complete!(
do_parse!(
left_operand: $operand >>
right_operand: preceded!(
first!(tag!(tokens::$operator_token)),
first!($parser_name)
) >>
(
NAryOperation::Binary {
operator : BinaryOperator::$operator_representation,
left_operand : Box::new(left_operand),
right_operand: Box::new(right_operand)
}
)
)
| $operand
)
);
)
}

right_to_left_binary_operation!(coalesce : logical_or with COALESCE as Coalesce);
left_to_right_binary_operation!(logical_or : logical_and with BOOLEAN_OR as LogicalOr);
left_to_right_binary_operation!(logical_and: bitwise_or with BOOLEAN_AND as LogicalAnd);
Expand Down Expand Up @@ -907,14 +917,18 @@ mod tests {

#[test]
fn case_coalesce() {
let input = Span::new(b"1 ?? 2");
let input = Span::new(b"1 ?? 2 ?? 3");
let output = Result::Done(
Span::new_at(b"", 6, 1, 7),
Span::new_at(b"", 11, 1, 12),
Expression::NAryOperation(
binary_operation!(
Coalesce,
nullary_operation!(integer!(1, Span::new(b"1"))),
nullary_operation!(integer!(2, Span::new_at(b"2", 5, 1, 6)))
binary_operation!(
Coalesce,
nullary_operation!(integer!(2, Span::new_at(b"2", 5, 1, 6))),
nullary_operation!(integer!(3, Span::new_at(b"3", 10, 1, 11)))
)
)
)
);
Expand Down

0 comments on commit b80736e

Please sign in to comment.