mirror of
https://github.com/exoticorn/curlywas.git
synced 2026-01-20 11:46:43 +01:00
fix two exponential parse time blow-ups
This commit is contained in:
@@ -388,16 +388,6 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = Simple<Token>> + C
|
|||||||
})
|
})
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
let tee = identifier
|
|
||||||
.clone()
|
|
||||||
.then_ignore(just(Token::Op(":=".to_string())))
|
|
||||||
.then(expression.clone())
|
|
||||||
.map(|(name, value)| ast::Expr::LocalTee {
|
|
||||||
name,
|
|
||||||
value: Box::new(value),
|
|
||||||
})
|
|
||||||
.boxed();
|
|
||||||
|
|
||||||
let assign = identifier
|
let assign = identifier
|
||||||
.clone()
|
.clone()
|
||||||
.then_ignore(just(Token::Op("=".to_string())))
|
.then_ignore(just(Token::Op("=".to_string())))
|
||||||
@@ -443,7 +433,6 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = Simple<Token>> + C
|
|||||||
});
|
});
|
||||||
|
|
||||||
let atom = val
|
let atom = val
|
||||||
.or(tee)
|
|
||||||
.or(function_call)
|
.or(function_call)
|
||||||
.or(assign)
|
.or(assign)
|
||||||
.or(local_tee)
|
.or(local_tee)
|
||||||
@@ -560,23 +549,31 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = Simple<Token>> + C
|
|||||||
let memory_op = op_cast
|
let memory_op = op_cast
|
||||||
.clone()
|
.clone()
|
||||||
.or(short_memory_op.clone())
|
.or(short_memory_op.clone())
|
||||||
.then(mem_op.clone().repeated().at_least(1))
|
.then(
|
||||||
|
mem_op
|
||||||
|
.clone()
|
||||||
|
.repeated()
|
||||||
|
.at_least(1)
|
||||||
.then(
|
.then(
|
||||||
just(Token::Op("=".to_string()))
|
just(Token::Op("=".to_string()))
|
||||||
.ignore_then(expression.clone())
|
.ignore_then(expression.clone())
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
.map(|((left, mut peek_ops), poke_op)| {
|
.or_not(),
|
||||||
|
)
|
||||||
|
.map(|(left, ops)| {
|
||||||
|
if let Some((mut peek_ops, poke_op)) = ops {
|
||||||
if let Some(value) = poke_op {
|
if let Some(value) = poke_op {
|
||||||
let poke_op = Some((peek_ops.pop().unwrap(), value));
|
let poke_op = Some((peek_ops.pop().unwrap(), value));
|
||||||
make_memory_op(left, peek_ops, poke_op)
|
make_memory_op(left, peek_ops, poke_op)
|
||||||
} else {
|
} else {
|
||||||
make_memory_op(left, peek_ops, None)
|
make_memory_op(left, peek_ops, None)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
left
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.boxed()
|
.boxed();
|
||||||
.or(op_cast.clone())
|
|
||||||
.or(short_memory_op.clone());
|
|
||||||
|
|
||||||
let op_product = memory_op
|
let op_product = memory_op
|
||||||
.clone()
|
.clone()
|
||||||
@@ -715,10 +712,11 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = Simple<Token>> + C
|
|||||||
|
|
||||||
let block_expression = block_expression.unwrap();
|
let block_expression = block_expression.unwrap();
|
||||||
|
|
||||||
expression
|
block_expression
|
||||||
.clone()
|
.clone()
|
||||||
.then(just(Token::Ctrl(';')).to(false))
|
.then(just(Token::Ctrl(';')).or_not())
|
||||||
.or(block_expression.map_with_span(|expr, span| (expr.with_span(span), true)))
|
.map_with_span(|(expr, semi), span| (expr.with_span(span), semi.is_none()))
|
||||||
|
.or(expression.clone().then(just(Token::Ctrl(';')).to(false)))
|
||||||
.repeated()
|
.repeated()
|
||||||
.then(expression.clone().or_not())
|
.then(expression.clone().or_not())
|
||||||
.map_with_span(|(mut statements, mut final_expression), span| {
|
.map_with_span(|(mut statements, mut final_expression), span| {
|
||||||
|
|||||||
Reference in New Issue
Block a user