mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
Refactor: Improved expression parsing organization.
Any non-operator expression can be a part of an operator expression. This cleans up and makes clearer the precendence relationships for parsing.
This commit is contained in:
parent
79bee4e2b4
commit
988698fc01
@ -254,7 +254,7 @@ fn tuple_to_binary_expression(
|
|||||||
/// the most tightly bound expressions.
|
/// the most tightly bound expressions.
|
||||||
macro_rules! do_binary_expr {
|
macro_rules! do_binary_expr {
|
||||||
($i:expr, $oprule:ident!( $($args:tt)* ), $typ:expr) => {
|
($i:expr, $oprule:ident!( $($args:tt)* ), $typ:expr) => {
|
||||||
do_binary_expr!($i, $oprule!($($args)*), $typ, alt!(grouped_expression | simple_expression))
|
do_binary_expr!($i, $oprule!($($args)*), $typ, non_op_expression)
|
||||||
};
|
};
|
||||||
|
|
||||||
($i:expr, $oprule:ident!( $($args:tt)* ), $typ:expr, $lowerrule:ident) => {
|
($i:expr, $oprule:ident!( $($args:tt)* ), $typ:expr, $lowerrule:ident) => {
|
||||||
@ -275,14 +275,6 @@ macro_rules! do_binary_expr {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
named!(math_expression<TokenIter, Expression, error::Error>,
|
|
||||||
alt!(sum_expression | product_expression)
|
|
||||||
);
|
|
||||||
|
|
||||||
named!(sum_expression<TokenIter, Expression, error::Error>,
|
|
||||||
alt!(add_expression | sub_expression)
|
|
||||||
);
|
|
||||||
|
|
||||||
// trace_macros!(true);
|
// trace_macros!(true);
|
||||||
named!(add_expression<TokenIter, Expression, error::Error>,
|
named!(add_expression<TokenIter, Expression, error::Error>,
|
||||||
do_binary_expr!(punct!("+"), BinaryExprType::Add, alt!(product_expression | simple_expression | grouped_expression))
|
do_binary_expr!(punct!("+"), BinaryExprType::Add, alt!(product_expression | simple_expression | grouped_expression))
|
||||||
@ -293,8 +285,8 @@ named!(sub_expression<TokenIter, Expression, error::Error>,
|
|||||||
do_binary_expr!(punct!("-"), BinaryExprType::Sub, alt!(product_expression | simple_expression | grouped_expression))
|
do_binary_expr!(punct!("-"), BinaryExprType::Sub, alt!(product_expression | simple_expression | grouped_expression))
|
||||||
);
|
);
|
||||||
|
|
||||||
named!(product_expression<TokenIter, Expression, error::Error>,
|
named!(sum_expression<TokenIter, Expression, error::Error>,
|
||||||
alt!(mul_expression | div_expression)
|
alt!(add_expression | sub_expression)
|
||||||
);
|
);
|
||||||
|
|
||||||
named!(mul_expression<TokenIter, Expression, error::Error>,
|
named!(mul_expression<TokenIter, Expression, error::Error>,
|
||||||
@ -305,6 +297,14 @@ named!(div_expression<TokenIter, Expression, error::Error>,
|
|||||||
do_binary_expr!(punct!("/"), BinaryExprType::Div)
|
do_binary_expr!(punct!("/"), BinaryExprType::Div)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
named!(product_expression<TokenIter, Expression, error::Error>,
|
||||||
|
alt!(mul_expression | div_expression)
|
||||||
|
);
|
||||||
|
|
||||||
|
named!(math_expression<TokenIter, Expression, error::Error>,
|
||||||
|
alt!(sum_expression | product_expression)
|
||||||
|
);
|
||||||
|
|
||||||
// TODO(jwall): Change comparison operators to use the do_binary_expr! with precedence?
|
// TODO(jwall): Change comparison operators to use the do_binary_expr! with precedence?
|
||||||
fn tuple_to_compare_expression(
|
fn tuple_to_compare_expression(
|
||||||
tpl: (Position, CompareType, Expression, Expression),
|
tpl: (Position, CompareType, Expression, Expression),
|
||||||
@ -356,6 +356,20 @@ named!(lt_expression<TokenIter, Expression, error::Error>,
|
|||||||
do_compare_expr!(punct!("<"), CompareType::LT)
|
do_compare_expr!(punct!("<"), CompareType::LT)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
named!(compare_expression<TokenIter, Expression, error::Error>,
|
||||||
|
alt!(
|
||||||
|
eqeq_expression |
|
||||||
|
not_eqeq_expression |
|
||||||
|
lt_eqeq_expression |
|
||||||
|
gt_eqeq_expression |
|
||||||
|
lt_expression |
|
||||||
|
gt_expression)
|
||||||
|
);
|
||||||
|
|
||||||
|
named!(op_expression<TokenIter, Expression, error::Error>,
|
||||||
|
alt!(math_expression | compare_expression)
|
||||||
|
);
|
||||||
|
|
||||||
fn expression_to_grouped_expression(e: Expression) -> ParseResult<Expression> {
|
fn expression_to_grouped_expression(e: Expression) -> ParseResult<Expression> {
|
||||||
Ok(Expression::Grouped(Box::new(e)))
|
Ok(Expression::Grouped(Box::new(e)))
|
||||||
}
|
}
|
||||||
@ -704,6 +718,17 @@ named!(list_op_expression<TokenIter, Expression, error::Error>,
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
named!(non_op_expression<TokenIter, Expression, error::Error>,
|
||||||
|
alt!(list_op_expression |
|
||||||
|
macro_expression |
|
||||||
|
format_expression |
|
||||||
|
select_expression |
|
||||||
|
call_expression |
|
||||||
|
copy_expression |
|
||||||
|
grouped_expression |
|
||||||
|
simple_expression)
|
||||||
|
);
|
||||||
|
|
||||||
// NOTE(jwall): HERE THERE BE DRAGONS. The order for these matters
|
// NOTE(jwall): HERE THERE BE DRAGONS. The order for these matters
|
||||||
// a lot. We need to process alternatives in order of decreasing
|
// a lot. We need to process alternatives in order of decreasing
|
||||||
// specificity. Unfortunately this means we are required to go in a
|
// specificity. Unfortunately this means we are required to go in a
|
||||||
@ -715,26 +740,7 @@ named!(list_op_expression<TokenIter, Expression, error::Error>,
|
|||||||
// It also means this combinator is risky when used with partial
|
// It also means this combinator is risky when used with partial
|
||||||
// inputs. So handle with care.
|
// inputs. So handle with care.
|
||||||
named!(expression<TokenIter, Expression, error::Error>,
|
named!(expression<TokenIter, Expression, error::Error>,
|
||||||
do_parse!(
|
alt!(complete!(op_expression) | complete!(non_op_expression))
|
||||||
expr: alt!(
|
|
||||||
complete!(list_op_expression) |
|
|
||||||
complete!(math_expression) |
|
|
||||||
complete!(eqeq_expression) |
|
|
||||||
complete!(not_eqeq_expression) |
|
|
||||||
complete!(lt_eqeq_expression) |
|
|
||||||
complete!(gt_eqeq_expression) |
|
|
||||||
complete!(gt_expression) |
|
|
||||||
complete!(lt_expression) |
|
|
||||||
complete!(macro_expression) |
|
|
||||||
complete!(format_expression) |
|
|
||||||
complete!(select_expression) |
|
|
||||||
complete!(call_expression) |
|
|
||||||
complete!(copy_expression) |
|
|
||||||
complete!(grouped_expression) |
|
|
||||||
simple_expression
|
|
||||||
) >>
|
|
||||||
(expr)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn expression_to_statement(v: Expression) -> ParseResult<Statement> {
|
fn expression_to_statement(v: Expression) -> ParseResult<Statement> {
|
||||||
|
@ -363,7 +363,7 @@ fn test_expression_parse() {
|
|||||||
1, 1)))
|
1, 1)))
|
||||||
);
|
);
|
||||||
assert_parse!(
|
assert_parse!(
|
||||||
math_expression("1 + 1"),
|
expression("1 + 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Add,
|
kind: BinaryExprType::Add,
|
||||||
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
@ -381,7 +381,7 @@ fn test_expression_parse() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_parse!(
|
assert_parse!(
|
||||||
expression("1 * 1"),
|
mul_expression("1 * 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Mul,
|
kind: BinaryExprType::Mul,
|
||||||
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user