24: Fix parser r=kdy1 a=kdy1
This commit is contained in:
bors[bot] 2018-01-18 03:23:54 +00:00
commit bab2b73483
8 changed files with 42 additions and 32 deletions

View File

@ -22,7 +22,7 @@ impl Debug for BytePos {
pub struct Span {
/// Inclusive
pub start: BytePos,
/// Inclusive
/// Exclusive
pub end: BytePos,
}
impl Debug for Span {
@ -30,7 +30,7 @@ impl Debug for Span {
if self.start == BytePos(0) && self.end == BytePos(0) {
write!(f, "_")
} else {
write!(f, "{}..{}", self.start, self.end.0 + 1)
write!(f, "{}..{}", self.start, self.end)
}
}
}

View File

@ -19,13 +19,12 @@ impl<I: Input> LexerInput<I> {
}
pub fn bump(&mut self) {
let pos = self.cur
.take()
.unwrap_or_else(|| unreachable!("bump called on eof"))
.0;
let pos = match self.cur.take() {
Some((p, prev_c)) => BytePos(p.0 + prev_c.len_utf8() as u32),
None => unreachable!("bump is called without knowing current character"),
};
self.cur = self.input.next();
self.last_pos = pos;
}

View File

@ -41,7 +41,9 @@ impl<I: Input> Lexer<I> {
// e.g. `0` is decimal (so it can be part of float)
//
// e.g. `000` is octal
if start != last_pos!() {
if start.0 != last_pos!().0 - 1 {
// `-1` is utf 8 length of `0`
return self.make_legacy_octal(start, 0f64);
}
} else {

View File

@ -25,7 +25,7 @@ impl SpanRange for usize {
fn into_span(self) -> Span {
Span {
start: BytePos(self as _),
end: BytePos(self as _),
end: BytePos((self + 1usize) as _),
}
}
}
@ -33,7 +33,7 @@ impl SpanRange for Range<usize> {
fn into_span(self) -> Span {
Span {
start: BytePos(self.start as _),
end: BytePos((self.end - 1) as _),
end: BytePos(self.end as _),
}
}
}
@ -109,7 +109,10 @@ fn test262_lexer_error_0001() {
#[test]
fn test262_lexer_error_0002() {
assert_eq!(
vec![Str("use strict".into(), false).span(0..15), Semi.span(15)],
vec![
Str("use strict".into(), false).span(0..15),
Semi.span(15..16),
],
lex(r#"'use\x20strict';"#)
);
}
@ -134,7 +137,7 @@ fn ident_escape_unicode() {
#[test]
fn ident_escape_unicode_2() {
assert_eq!(lex("℘℘"), vec!["℘℘".span(0..4)]);
assert_eq!(lex("℘℘"), vec!["℘℘".span(0..6)]);
assert_eq!(lex(r#"℘\u2118"#), vec!["℘℘".span(0..9)]);
}

View File

@ -85,20 +85,15 @@ macro_rules! token_including_semi {
/// This macro requires macro named 'last_pos' to be in scope.
macro_rules! span {
($p:expr, $start:expr) => {
Span { start: $start, end: last_pos!($p), }
};
}
/// Takes `(parser, start)`, Returns |t| { Spanned::from }
macro_rules! into_spanned {
($p:expr, $start:expr) => {{
|val| {
let start = $start;
let end = last_pos!($p);
return ::swc_common::Spanned::from_unspanned(val, Span { start, end });
let start: ::swc_common::BytePos = $start;
let end: ::swc_common::BytePos = last_pos!($p);
if cfg!(debug_assertions) && start > end {
unreachable!("assertion failed: (span.start <= span.end).
start = {}, end = {}", start, end)
}
}}
Span { start, end }
}};
}
macro_rules! spanned {
@ -110,8 +105,12 @@ macro_rules! spanned {
$($body)*
};
#[allow(unreachable_code)]
{
val.map(into_spanned!($p, start))
match val {
Ok(val) => {
let end = last_pos!($p);
Ok(::swc_common::Spanned::from_unspanned(val, Span { start, end }))
},
Err(err) => Err(err),
}
}};
}

View File

@ -198,7 +198,7 @@ impl<I: Input> Parser<I> {
spanned!({
assert_and_bump!('[');
let mut elems = vec![];
let mut comma = 0;
let mut comma = 1;
while !eof!() && !is!(']') {
if eat!(',') {
@ -206,7 +206,11 @@ impl<I: Input> Parser<I> {
continue;
}
elems.extend(iter::repeat(None).take(comma));
// Should have at least one comma between elements.
if comma == 0 {
expect!(',');
}
elems.extend(iter::repeat(None).take(comma - 1));
comma = 0;
elems.push(self.include_in_expr(true).parse_expr_or_spread().map(Some)?);
}

View File

@ -83,7 +83,6 @@ impl<I: Input> Parser<I> {
Keyword(Yield) if incl_yield => Ok(js_word!("yield")),
Keyword(Await) if incl_await => Ok(js_word!("await")),
Keyword(..) | Null | True | False => {
println!("Word: {:?}", w);
syntax_error!(SyntaxError::ExpectedIdent)
}
}

View File

@ -51,9 +51,13 @@ impl<I: Input> ParserInput<I> {
fn bump_inner(&mut self) -> Option<Token> {
let prev = self.cur.take();
self.last_pos = prev.as_ref()
.map(|item| item.span.end)
.unwrap_or(BytePos(0));
self.last_pos = match prev {
Some(Item {
span: Span { end, .. },
..
}) => end,
_ => self.last_pos,
};
// If we have peeked a token, take it instead of calling lexer.next()
self.cur = self.next.take().or_else(|| self.iter.next());