mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
FEATURE: Allow tuples and lists as the head of a selector.
This commit is contained in:
parent
988698fc01
commit
cefb307783
@ -216,15 +216,25 @@ named!(empty_value<TokenIter, Value, error::Error>,
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
named!(value<TokenIter, Value, error::Error>,
|
named!(compound_value<TokenIter, Value, error::Error>,
|
||||||
|
alt!(list_value | tuple)
|
||||||
|
);
|
||||||
|
|
||||||
|
named!(scalar_value<TokenIter, Value, error::Error>,
|
||||||
alt!(
|
alt!(
|
||||||
boolean_value |
|
boolean_value |
|
||||||
empty_value |
|
empty_value |
|
||||||
number |
|
number |
|
||||||
quoted_value |
|
quoted_value
|
||||||
list_value |
|
)
|
||||||
tuple |
|
);
|
||||||
selector_value )
|
|
||||||
|
named!(value<TokenIter, Value, error::Error>,
|
||||||
|
alt!(
|
||||||
|
selector_value
|
||||||
|
| compound_value
|
||||||
|
| scalar_value
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
fn value_to_expression(v: Value) -> ParseResult<Expression> {
|
fn value_to_expression(v: Value) -> ParseResult<Expression> {
|
||||||
@ -382,18 +392,38 @@ named!(grouped_expression<TokenIter, Expression, error::Error>,
|
|||||||
);
|
);
|
||||||
|
|
||||||
fn symbol_or_expression(input: TokenIter) -> NomResult<Expression> {
|
fn symbol_or_expression(input: TokenIter) -> NomResult<Expression> {
|
||||||
let sym = do_parse!(input, sym: symbol >> (sym));
|
let scalar_head = do_parse!(input, sym: alt!(symbol | compound_value) >> (sym));
|
||||||
|
|
||||||
match sym {
|
match scalar_head {
|
||||||
IResult::Incomplete(i) => {
|
IResult::Incomplete(i) => IResult::Incomplete(i),
|
||||||
return IResult::Incomplete(i);
|
IResult::Error(_) => grouped_expression(input),
|
||||||
}
|
|
||||||
IResult::Error(_) => {
|
|
||||||
// TODO(jwall): Still missing some. But we need to avoid recursion
|
|
||||||
return grouped_expression(input);
|
|
||||||
}
|
|
||||||
IResult::Done(rest, val) => {
|
IResult::Done(rest, val) => {
|
||||||
return IResult::Done(rest, Expression::Simple(val));
|
let res = peek!(rest.clone(), punct!("."));
|
||||||
|
match val {
|
||||||
|
Value::Tuple(_) => {
|
||||||
|
if res.is_done() {
|
||||||
|
IResult::Done(rest, Expression::Simple(val))
|
||||||
|
} else {
|
||||||
|
return IResult::Error(nom::ErrorKind::Custom(error::Error::new(
|
||||||
|
"Expected (.) but no dot found".to_string(),
|
||||||
|
error::ErrorType::IncompleteParsing,
|
||||||
|
val.pos().clone(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::List(_) => {
|
||||||
|
if res.is_done() {
|
||||||
|
IResult::Done(rest, Expression::Simple(val))
|
||||||
|
} else {
|
||||||
|
return IResult::Error(nom::ErrorKind::Custom(error::Error::new(
|
||||||
|
"Expected (.) but no dot found".to_string(),
|
||||||
|
error::ErrorType::IncompleteParsing,
|
||||||
|
val.pos().clone(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => IResult::Done(rest, Expression::Simple(val)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,6 +362,37 @@ fn test_expression_parse() {
|
|||||||
[ make_tok!("bar", 1, 5) ] =>
|
[ make_tok!("bar", 1, 5) ] =>
|
||||||
1, 1)))
|
1, 1)))
|
||||||
);
|
);
|
||||||
|
assert_parse!(
|
||||||
|
expression("{foo=1}.foo "),
|
||||||
|
Expression::Simple(Value::Selector(
|
||||||
|
make_selector!(Expression::Simple(Value::Tuple(
|
||||||
|
value_node!(vec![
|
||||||
|
(
|
||||||
|
make_tok!("foo", 1, 2),
|
||||||
|
Expression::Simple(Value::Int(value_node!(1, 1, 6))),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
1, 1),
|
||||||
|
)) =>
|
||||||
|
[ make_tok!("foo", 1, 9) ] =>
|
||||||
|
1, 1)
|
||||||
|
))
|
||||||
|
);
|
||||||
|
assert_parse!(
|
||||||
|
expression("[1, 2].1 "),
|
||||||
|
Expression::Simple(Value::Selector(
|
||||||
|
make_selector!(Expression::Simple(Value::List(
|
||||||
|
ListDef{
|
||||||
|
elems: vec![
|
||||||
|
Expression::Simple(Value::Int(value_node!(1, 1, 2))),
|
||||||
|
Expression::Simple(Value::Int(value_node!(2, 1, 5))),
|
||||||
|
],
|
||||||
|
pos: Position::new(1, 1),
|
||||||
|
})) =>
|
||||||
|
[ make_tok!(DIGIT => "1", 1, 8) ] =>
|
||||||
|
1, 1)
|
||||||
|
))
|
||||||
|
);
|
||||||
assert_parse!(
|
assert_parse!(
|
||||||
expression("1 + 1"),
|
expression("1 + 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user