Skip to content

Commit 8ace688

Browse files
committed
Fix VerbatimNotSupported error spans and corner case.
In the first case, the `end()` of VerbatimNotSupported's span was continuing to the _next_ line because `parse_ws` matches newlines. VerbatimNotSupported was triggering in one case where spaces occur between `%%` and a newline. It should only trigger when spaces occur at the beginning of a line.
1 parent 5135a01 commit 8ace688

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

lrlex/src/lib/parser.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ lazy_static! {
2727
static ref RE_LEADING_LINE_SEPS: Regex = Regex::new(r"^[\p{Pattern_White_Space}&&[\p{Zl}\p{Zp}\n\r\v]]*").unwrap();
2828
// Horizontal space separators
2929
static ref RE_SPACE_SEP: Regex = Regex::new(r"[\p{Pattern_White_Space}&&[\p{Zs}\t]]").unwrap();
30+
static ref RE_LEADING_SPACE_SEPS: Regex = Regex::new(r"^[\p{Pattern_White_Space}&&[\p{Zs}\t]]*").unwrap();
3031
static ref RE_LEADING_WS: Regex = Regex::new(r"^[\p{Pattern_White_Space}]*").unwrap();
3132
static ref RE_WS: Regex = Regex::new(r"\p{Pattern_White_Space}").unwrap();
3233
}
@@ -232,7 +233,7 @@ where
232233
break Err(self.mk_error(LexErrorKind::PrematureEnd, i));
233234
}
234235
if let Some(j) = self.lookahead_is("%%", i) {
235-
break Ok(j);
236+
break Ok(self.parse_spaces(j)?);
236237
}
237238
i = self.parse_declaration(i, errs)?;
238239
}
@@ -365,15 +366,15 @@ where
365366
let j = self.parse_ws(i)?;
366367
if j != i {
367368
let line_len = RE_LINE_SEP
368-
.find(&self.src[j..])
369+
.find(&self.src[i..])
369370
.map(|m| m.start())
370371
.unwrap_or(self.src.len() - j);
371372
let err = LexBuildError {
372373
kind: LexErrorKind::VerbatimNotSupported,
373374
spans: vec![Span::new(i, i + line_len)],
374375
};
375376
errs.push(err);
376-
i = j + line_len;
377+
i += line_len;
377378
continue;
378379
}
379380
if i == self.src.len() {
@@ -632,6 +633,13 @@ where
632633
.unwrap_or(i))
633634
}
634635

636+
fn parse_spaces(&mut self, i: usize) -> LexInternalBuildResult<usize> {
637+
Ok(RE_LEADING_SPACE_SEPS
638+
.find(&self.src[i..])
639+
.map(|m| m.end() + i)
640+
.unwrap_or(i))
641+
}
642+
635643
fn lookahead_is(&self, s: &'static str, i: usize) -> Option<usize> {
636644
if self.src[i..].starts_with(s) {
637645
Some(i + s.len())
@@ -1638,9 +1646,25 @@ b "A"
16381646
"#;
16391647
LRNonStreamingLexerDef::<DefaultLexerTypes<u8>>::from_str(src).unwrap();
16401648
let src = r#"
1649+
%%
1650+
. "SpacesAfterPercentsDontError"
1651+
"#;
1652+
LRNonStreamingLexerDef::<DefaultLexerTypes<u8>>::from_str(src).unwrap();
1653+
let src = r#"
16411654
%%
16421655
// Historical practice is that in the rules section entries starting with whitespace are copied verbatim into generated code. This is not supported.
16431656
. "InitialWhitespaceDoError"
1657+
"#;
1658+
LRNonStreamingLexerDef::<DefaultLexerTypes<u8>>::from_str(src).expect_error_at_line_col(
1659+
src,
1660+
LexErrorKind::VerbatimNotSupported,
1661+
3,
1662+
1,
1663+
);
1664+
let src = r#"
1665+
%%
1666+
1667+
. "SpacesOnlyDoError"
16441668
"#;
16451669
LRNonStreamingLexerDef::<DefaultLexerTypes<u8>>::from_str(src).expect_error_at_line_col(
16461670
src,

0 commit comments

Comments
 (0)