fix quadratic parsing of expression
This commit is contained in:
parent
a69c6ab0b3
commit
dfc74b4b24
|
@ -2,7 +2,7 @@ use super::tokens::{token, Token, TokenKind as tk, TokenSpan};
|
||||||
use super::{IResult, Span};
|
use super::{IResult, Span};
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
combinator::map,
|
combinator::{map, opt},
|
||||||
multi::separated_list0,
|
multi::separated_list0,
|
||||||
sequence::{delimited, preceded, separated_pair, tuple},
|
sequence::{delimited, preceded, separated_pair, tuple},
|
||||||
};
|
};
|
||||||
|
@ -88,12 +88,18 @@ fn bitop_kind(input: TokenSpan) -> IResult<TokenSpan, BinOpKind> {
|
||||||
/// bit and, or, xor e.g. a ^ b & c
|
/// bit and, or, xor e.g. a ^ b & c
|
||||||
/// TODO: make precedence rules for bit ops
|
/// TODO: make precedence rules for bit ops
|
||||||
fn bitop(input: TokenSpan) -> IResult<TokenSpan, Expression> {
|
fn bitop(input: TokenSpan) -> IResult<TokenSpan, Expression> {
|
||||||
alt((
|
// special care is given to avoid parsing `unary` twice, as that would
|
||||||
map(tuple((unary, bitop_kind, bitop)), |(a, kind, b)| {
|
// make this parser quadratic
|
||||||
Expression::BinOp(Box::new(BinOp { a, b, kind }))
|
map(
|
||||||
}),
|
tuple((unary, opt(tuple((bitop_kind, bitop))))),
|
||||||
unary,
|
|(a, rest)| {
|
||||||
))(input)
|
if let Some((kind, b)) = rest {
|
||||||
|
Expression::BinOp(Box::new(BinOp { a, b, kind }))
|
||||||
|
} else {
|
||||||
|
a
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_item(input: TokenSpan) -> IResult<TokenSpan, Call> {
|
pub fn call_item(input: TokenSpan) -> IResult<TokenSpan, Call> {
|
||||||
|
@ -140,6 +146,10 @@ mod test {
|
||||||
fn test_atoms() {
|
fn test_atoms() {
|
||||||
fullexpr(TokenSpan::new(&tok("a"))).unwrap();
|
fullexpr(TokenSpan::new(&tok("a"))).unwrap();
|
||||||
fullexpr(TokenSpan::new(&tok("(a)"))).unwrap();
|
fullexpr(TokenSpan::new(&tok("(a)"))).unwrap();
|
||||||
|
fullexpr(TokenSpan::new(&tok(
|
||||||
|
"(((((((((((((((((((a)))))))))))))))))))",
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -147,7 +157,7 @@ mod test {
|
||||||
fullexpr(TokenSpan::new(&tok("asdf"))).unwrap();
|
fullexpr(TokenSpan::new(&tok("asdf"))).unwrap();
|
||||||
fullexpr(TokenSpan::new(&tok("~(asdf)"))).unwrap();
|
fullexpr(TokenSpan::new(&tok("~(asdf)"))).unwrap();
|
||||||
fullexpr(TokenSpan::new(&tok("!asdf"))).unwrap();
|
fullexpr(TokenSpan::new(&tok("!asdf"))).unwrap();
|
||||||
// unary(TokenSpan::new(&tok("~!(asdf)"))).unwrap();
|
fullexpr(TokenSpan::new(&tok("~!(asdf)"))).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue