Skip to content

Commit 747f536

Browse files
syntax: better error message for missing repetition quantifier
1 parent 5951745 commit 747f536

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

regex-syntax/src/ast/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ pub enum ErrorKind {
153153
/// The range provided in a counted repetition operator is invalid. The
154154
/// range is invalid if the start is greater than the end.
155155
RepetitionCountInvalid,
156+
/// An opening `{` was not followed by a valid decimal value.
157+
/// For example, `x{}` or `x{]}` would fail.
158+
RepetitionQuantifierDecimalMissing,
156159
/// An opening `{` was found with no corresponding closing `}`.
157160
RepetitionCountUnclosed,
158161
/// A repetition operator was applied to a missing sub-expression. This
@@ -307,6 +310,9 @@ impl fmt::Display for ErrorKind {
307310
write!(f, "invalid repetition count range, \
308311
the start must be <= the end")
309312
}
313+
RepetitionQuantifierDecimalMissing => {
314+
write!(f, "Repetition quantifier expects a valid decimal")
315+
}
310316
RepetitionCountUnclosed => {
311317
write!(f, "unclosed counted repetition")
312318
}

regex-syntax/src/ast/parse.rs

+33-5
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,15 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
11131113
ast::ErrorKind::RepetitionCountUnclosed,
11141114
));
11151115
}
1116-
let count_start = self.parse_decimal()?;
1116+
let count_start = match self.parse_decimal() {
1117+
Err(ast::Error {kind: ast::ErrorKind::DecimalEmpty, span, pattern}) => return Err(ast::Error {
1118+
kind: ast::ErrorKind::RepetitionQuantifierDecimalMissing,
1119+
pattern,
1120+
span,
1121+
}),
1122+
Err(e) => return Err(e),
1123+
Ok(value) => value,
1124+
};
11171125
let mut range = ast::RepetitionRange::Exactly(count_start);
11181126
if self.is_eof() {
11191127
return Err(self.error(
@@ -1129,7 +1137,15 @@ impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
11291137
));
11301138
}
11311139
if self.char() != '}' {
1132-
let count_end = self.parse_decimal()?;
1140+
let count_end = match self.parse_decimal() {
1141+
Err(ast::Error {kind: ast::ErrorKind::DecimalEmpty, span, pattern}) => return Err(ast::Error {
1142+
kind: ast::ErrorKind::RepetitionQuantifierDecimalMissing,
1143+
pattern,
1144+
span,
1145+
}),
1146+
Err(e) => return Err(e),
1147+
Ok(value) => value,
1148+
};
11331149
range = ast::RepetitionRange::Bounded(count_start, count_end);
11341150
} else {
11351151
range = ast::RepetitionRange::AtLeast(count_start);
@@ -3143,6 +3159,18 @@ bar
31433159
span: span(4..4),
31443160
kind: ast::ErrorKind::RepetitionMissing,
31453161
});
3162+
assert_eq!(
3163+
parser(r"a{]}").parse().unwrap_err(),
3164+
TestError {
3165+
span: span(2..2),
3166+
kind: ast::ErrorKind::RepetitionQuantifierDecimalMissing,
3167+
});
3168+
assert_eq!(
3169+
parser(r"a{1,]}").parse().unwrap_err(),
3170+
TestError {
3171+
span: span(4..4),
3172+
kind: ast::ErrorKind::RepetitionQuantifierDecimalMissing,
3173+
});
31463174
assert_eq!(
31473175
parser(r"a{").parse().unwrap_err(),
31483176
TestError {
@@ -3153,13 +3181,13 @@ bar
31533181
parser(r"a{}").parse().unwrap_err(),
31543182
TestError {
31553183
span: span(2..2),
3156-
kind: ast::ErrorKind::DecimalEmpty,
3184+
kind: ast::ErrorKind::RepetitionQuantifierDecimalMissing,
31573185
});
31583186
assert_eq!(
31593187
parser(r"a{a").parse().unwrap_err(),
31603188
TestError {
31613189
span: span(2..2),
3162-
kind: ast::ErrorKind::DecimalEmpty,
3190+
kind: ast::ErrorKind::RepetitionQuantifierDecimalMissing,
31633191
});
31643192
assert_eq!(
31653193
parser(r"a{9999999999}").parse().unwrap_err(),
@@ -3177,7 +3205,7 @@ bar
31773205
parser(r"a{9,a").parse().unwrap_err(),
31783206
TestError {
31793207
span: span(4..4),
3180-
kind: ast::ErrorKind::DecimalEmpty,
3208+
kind: ast::ErrorKind::RepetitionQuantifierDecimalMissing,
31813209
});
31823210
assert_eq!(
31833211
parser(r"a{9,9999999999}").parse().unwrap_err(),

0 commit comments

Comments
 (0)