diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wast-lexer.cc | 32 | ||||
-rw-r--r-- | src/wast-parser.cc | 5 |
2 files changed, 22 insertions, 15 deletions
diff --git a/src/wast-lexer.cc b/src/wast-lexer.cc index c37f5af3..59bc0d71 100644 --- a/src/wast-lexer.cc +++ b/src/wast-lexer.cc @@ -175,7 +175,9 @@ Token WastLexer::GetToken(WastParser* parser) { } Location WastLexer::GetLocation() { - auto column = [=](const char* p) { return p - line_start_ + 1; }; + auto column = [=](const char* p) { + return std::max(1, static_cast<int>(p - line_start_ + 1)); + }; return Location(filename_, line_, column(token_start_), column(cursor_)); } @@ -288,9 +290,10 @@ void WastLexer::ReadWhitespace() { } Token WastLexer::GetStringToken(WastParser* parser) { - auto saved_loc = GetLocation(); - ReadChar(); + const char* saved_token_start = token_start_; + bool has_error = false; bool in_string = true; + ReadChar(); while (in_string) { switch (ReadChar()) { case kEof: @@ -299,6 +302,7 @@ Token WastLexer::GetStringToken(WastParser* parser) { case '\n': token_start_ = cursor_ - 1; ERROR("newline in string"); + has_error = true; Newline(); continue; @@ -339,8 +343,10 @@ Token WastLexer::GetStringToken(WastParser* parser) { case 'D': case 'E': case 'F': // Hex byte escape. - if (!IsHexDigit(ReadChar())) { - token_start_ = cursor_ - 3; + if (IsHexDigit(PeekChar())) { + ReadChar(); + } else { + token_start_ = cursor_ - 2; goto error; } break; @@ -352,19 +358,19 @@ Token WastLexer::GetStringToken(WastParser* parser) { error: ERROR("bad escape \"%.*s\"", static_cast<int>(cursor_ - token_start_), token_start_); + has_error = true; break; } break; } } } - auto token = TextToken(TokenType::Text); - // Use line and first_column from the saved location instead. Otherwise, the - // beginning of the string may not start with a quote if the string contains - // a newline. - token.loc.line = saved_loc.line; - token.loc.first_column = saved_loc.first_column; - return token; + token_start_ = saved_token_start; + if (has_error) { + return Token(GetLocation(), TokenType::Invalid); + } + + return TextToken(TokenType::Text); } // static @@ -466,7 +472,7 @@ Token WastLexer::GetHexNumberToken(TokenType token_type) { if (MatchChar('p') || MatchChar('P')) { token_type = TokenType::Float; ReadSign(); - if (!ReadHexNum()) { + if (!ReadNum()) { return GetReservedToken(); } } diff --git a/src/wast-parser.cc b/src/wast-parser.cc index bdbba00c..6be18464 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -396,10 +396,11 @@ TokenType WastParser::Peek(size_t n) { if (cur.token_type() != TokenType::LparAnn) { tokens_.push_back(cur); } else { - // Custom annotation. For now, discard until matching Rpar + // Custom annotation. For now, discard until matching Rpar. if (!options_->features.annotations_enabled()) { Error(cur.loc, "annotations not enabled: %s", cur.to_string().c_str()); - return TokenType::Invalid; + tokens_.push_back(Token(cur.loc, TokenType::Invalid)); + continue; } int indent = 1; while (indent > 0) { |