wgsl-reader: give better diagnostic for bad token at end of input

Change-Id: I332229fc4ad3ffef4d75c8e9a7d83a06a2c034dd
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/69360
Auto-Submit: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 28e9cf0..1aa16db 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -469,6 +469,12 @@
     next();
   }
 
+  // The token might itself be an error.
+  if (t.IsError()) {
+    next();  // Consume it.
+    return add_error(t.source(), t.to_str());
+  }
+
   // Exhausted all attempts to make sense of where we're at.
   // Spew a generic error.
 
diff --git a/src/reader/wgsl/parser_impl_test.cc b/src/reader/wgsl/parser_impl_test.cc
index 588967e..4573ede 100644
--- a/src/reader/wgsl/parser_impl_test.cc
+++ b/src/reader/wgsl/parser_impl_test.cc
@@ -48,6 +48,43 @@
   EXPECT_EQ(p->error(), "2:15: unable to determine function return type");
 }
 
+TEST_F(ParserImplTest, HandlesUnexpectedToken) {
+  auto p = parser(R"(
+fn main() {
+}
+foobar
+)");
+
+  ASSERT_FALSE(p->Parse());
+  ASSERT_TRUE(p->has_error());
+  EXPECT_EQ(p->error(), "4:1: unexpected token");
+}
+
+TEST_F(ParserImplTest, HandlesBadToken_InMiddle) {
+  auto p = parser(R"(
+fn main() {
+  let f = 0x1p500000000000; // Exponent too big for hex float
+  return;
+})");
+
+  ASSERT_FALSE(p->Parse());
+  ASSERT_TRUE(p->has_error());
+  EXPECT_EQ(p->error(), "3:11: exponent is too large for hex float");
+}
+
+TEST_F(ParserImplTest, HandlesBadToken_AtModuleScope) {
+  auto p = parser(R"(
+fn main() {
+  return;
+}
+0x1p5000000000000
+)");
+
+  ASSERT_FALSE(p->Parse());
+  ASSERT_TRUE(p->has_error());
+  EXPECT_EQ(p->error(), "5:1: exponent is too large for hex float");
+}
+
 TEST_F(ParserImplTest, Comments) {
   auto p = parser(R"(
 /**