mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-24 18:39:50 -04:00
FEATURE: Better parsing errors.
More specific reports about what is wrong when we know the correct next tokens to expect.
This commit is contained in:
parent
5bfe38140a
commit
b6c2a08c8f
@ -237,7 +237,7 @@ make_fn!(
|
|||||||
_ => punct!("{"),
|
_ => punct!("{"),
|
||||||
v => optional!(field_list),
|
v => optional!(field_list),
|
||||||
_ => optional!(punct!(",")),
|
_ => optional!(punct!(",")),
|
||||||
_ => punct!("}"),
|
_ => must!(punct!("}")),
|
||||||
(vec_to_tuple(pos, v))
|
(vec_to_tuple(pos, v))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -255,7 +255,7 @@ make_fn!(
|
|||||||
start => punct!("["),
|
start => punct!("["),
|
||||||
elements => optional!(separated!(punct!(","), expression)),
|
elements => optional!(separated!(punct!(","), expression)),
|
||||||
_ => optional!(punct!(",")),
|
_ => optional!(punct!(",")),
|
||||||
_ => punct!("]"),
|
_ => must!(punct!("]")),
|
||||||
(tuple_to_list(start.pos, elements))
|
(tuple_to_list(start.pos, elements))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -309,7 +309,7 @@ make_fn!(
|
|||||||
_ => punct!("("),
|
_ => punct!("("),
|
||||||
expr => do_each!(
|
expr => do_each!(
|
||||||
expr => trace_parse!(expression),
|
expr => trace_parse!(expression),
|
||||||
_ => punct!(")"),
|
_ => must!(punct!(")")),
|
||||||
(expr)
|
(expr)
|
||||||
),
|
),
|
||||||
(expression_to_grouped_expression(expr))
|
(expression_to_grouped_expression(expr))
|
||||||
@ -332,12 +332,11 @@ fn tuple_to_copy(sym: Value, fields: Option<FieldList>) -> Expression {
|
|||||||
make_fn!(
|
make_fn!(
|
||||||
copy_expression<SliceIter<Token>, Expression>,
|
copy_expression<SliceIter<Token>, Expression>,
|
||||||
do_each!(
|
do_each!(
|
||||||
// TODO This should become just a bareword symbol now
|
|
||||||
sym => trace_parse!(symbol),
|
sym => trace_parse!(symbol),
|
||||||
_ => punct!("{"),
|
_ => punct!("{"),
|
||||||
fields => optional!(trace_parse!(field_list)),
|
fields => optional!(trace_parse!(field_list)),
|
||||||
_ => optional!(punct!(",")), // noms opt! macro does not preserve error types properly but this one does.
|
_ => optional!(punct!(",")),
|
||||||
_ => punct!("}"),
|
_ => must!(punct!("}")),
|
||||||
(tuple_to_copy(sym, fields))
|
(tuple_to_copy(sym, fields))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -452,16 +451,16 @@ fn select_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, Expres
|
|||||||
let parsed = do_each!(input,
|
let parsed = do_each!(input,
|
||||||
_ => word!("select"),
|
_ => word!("select"),
|
||||||
val => do_each!(
|
val => do_each!(
|
||||||
expr => trace_parse!(expression),
|
expr => trace_parse!(must!(expression)),
|
||||||
_ => must!(punct!(",")),
|
_ => must!(punct!(",")),
|
||||||
(expr)
|
(expr)
|
||||||
),
|
),
|
||||||
default => do_each!(
|
default => do_each!(
|
||||||
expr => trace_parse!(expression),
|
expr => trace_parse!(must!(expression)),
|
||||||
_ => must!(punct!(",")),
|
_ => must!(punct!(",")),
|
||||||
(expr)
|
(expr)
|
||||||
),
|
),
|
||||||
map => trace_parse!(tuple),
|
map => trace_parse!(must!(tuple)),
|
||||||
(val, default, map)
|
(val, default, map)
|
||||||
);
|
);
|
||||||
match parsed {
|
match parsed {
|
||||||
@ -537,11 +536,10 @@ fn tuple_to_call<'a>(
|
|||||||
|
|
||||||
fn call_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, Expression> {
|
fn call_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, Expression> {
|
||||||
let parsed = do_each!(input.clone(),
|
let parsed = do_each!(input.clone(),
|
||||||
// TODO This should become just a bareword symbol now
|
|
||||||
callee_name => trace_parse!(symbol),
|
callee_name => trace_parse!(symbol),
|
||||||
_ => punct!("("),
|
_ => punct!("("),
|
||||||
args => optional!(separated!(punct!(","), trace_parse!(expression))),
|
args => optional!(separated!(punct!(","), trace_parse!(expression))),
|
||||||
_ => punct!(")"),
|
_ => must!(punct!(")")),
|
||||||
(callee_name, args)
|
(callee_name, args)
|
||||||
);
|
);
|
||||||
match parsed {
|
match parsed {
|
||||||
@ -564,10 +562,10 @@ make_fn!(
|
|||||||
do_each!(
|
do_each!(
|
||||||
pos => pos,
|
pos => pos,
|
||||||
_ => word!("reduce"),
|
_ => word!("reduce"),
|
||||||
macroname => match_type!(BAREWORD),
|
macroname => must!(match_type!(BAREWORD)),
|
||||||
acc => trace_parse!(non_op_expression),
|
acc => must!(trace_parse!(non_op_expression)),
|
||||||
_ => punct!(","),
|
_ => must!(punct!(",")),
|
||||||
tgt => trace_parse!(non_op_expression),
|
tgt => must!(trace_parse!(non_op_expression)),
|
||||||
(Expression::FuncOp(FuncOpDef::Reduce(ReduceOpDef{
|
(Expression::FuncOp(FuncOpDef::Reduce(ReduceOpDef{
|
||||||
mac: (¯oname).into(),
|
mac: (¯oname).into(),
|
||||||
acc: Box::new(acc),
|
acc: Box::new(acc),
|
||||||
@ -582,9 +580,8 @@ make_fn!(
|
|||||||
do_each!(
|
do_each!(
|
||||||
pos => pos,
|
pos => pos,
|
||||||
_ => word!("map"),
|
_ => word!("map"),
|
||||||
// TODO This should become just a bareword symbol now
|
macroname => must!(match_type!(BAREWORD)),
|
||||||
macroname => match_type!(BAREWORD),
|
list => must!(trace_parse!(non_op_expression)),
|
||||||
list => trace_parse!(non_op_expression),
|
|
||||||
(Expression::FuncOp(FuncOpDef::Map(MapFilterOpDef{
|
(Expression::FuncOp(FuncOpDef::Map(MapFilterOpDef{
|
||||||
mac: (¯oname).into(),
|
mac: (¯oname).into(),
|
||||||
target: Box::new(list),
|
target: Box::new(list),
|
||||||
@ -598,9 +595,8 @@ make_fn!(
|
|||||||
do_each!(
|
do_each!(
|
||||||
pos => pos,
|
pos => pos,
|
||||||
_ => word!("filter"),
|
_ => word!("filter"),
|
||||||
// TODO This should become just a bareword symbol now
|
macroname => must!(match_type!(BAREWORD)),
|
||||||
macroname => match_type!(BAREWORD),
|
list => must!(trace_parse!(non_op_expression)),
|
||||||
list => trace_parse!(non_op_expression),
|
|
||||||
(Expression::FuncOp(FuncOpDef::Filter(MapFilterOpDef{
|
(Expression::FuncOp(FuncOpDef::Filter(MapFilterOpDef{
|
||||||
mac: (¯oname).into(),
|
mac: (¯oname).into(),
|
||||||
target: Box::new(list),
|
target: Box::new(list),
|
||||||
@ -627,7 +623,7 @@ make_fn!(
|
|||||||
(Box::new(step))
|
(Box::new(step))
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
end => either!(simple_expression, grouped_expression),
|
end => must!(wrap_err!(either!(simple_expression, grouped_expression), "Expected simple or grouped expression")),
|
||||||
(Expression::Range(RangeDef{
|
(Expression::Range(RangeDef{
|
||||||
pos: pos,
|
pos: pos,
|
||||||
start: Box::new(start),
|
start: Box::new(start),
|
||||||
@ -713,7 +709,7 @@ make_fn!(
|
|||||||
do_each!(
|
do_each!(
|
||||||
e => do_each!(
|
e => do_each!(
|
||||||
expr => trace_parse!(expression),
|
expr => trace_parse!(expression),
|
||||||
_ => punct!(";"),
|
_ => must!(punct!(";")),
|
||||||
(expr)
|
(expr)
|
||||||
),
|
),
|
||||||
(Statement::Expression(e))
|
(Statement::Expression(e))
|
||||||
|
@ -250,6 +250,12 @@ fn parse_operand_list<'a>(i: SliceIter<'a, Token>) -> ParseResult<'a, Vec<Elemen
|
|||||||
Result::Fail(e) => {
|
Result::Fail(e) => {
|
||||||
// A failure to parse an expression
|
// A failure to parse an expression
|
||||||
// is always an error.
|
// is always an error.
|
||||||
|
if !firstrun {
|
||||||
|
// if we have successfully parsed an element and an operator then
|
||||||
|
// failing to parse a second expression is an abort since we know
|
||||||
|
// for sure now that the next expression is supposed to be there.
|
||||||
|
return Result::Abort(e);
|
||||||
|
}
|
||||||
return Result::Fail(e);
|
return Result::Fail(e);
|
||||||
}
|
}
|
||||||
Result::Abort(e) => {
|
Result::Abort(e) => {
|
||||||
@ -284,7 +290,7 @@ fn parse_operand_list<'a>(i: SliceIter<'a, Token>) -> ParseResult<'a, Vec<Elemen
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Result::Abort(e) => {
|
Result::Abort(e) => {
|
||||||
// A failure to parse an expression
|
// A failure to parse an operator
|
||||||
// is always an error.
|
// is always an error.
|
||||||
return Result::Abort(e);
|
return Result::Abort(e);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user