Index: test/cctest/test-parsing.cc |
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc |
new file mode 100755 |
index 0000000000000000000000000000000000000000..eec7677d0518f885cb424320f66f82f043d690e0 |
--- /dev/null |
+++ b/test/cctest/test-parsing.cc |
@@ -0,0 +1,128 @@ |
+// Copyright 2006-2009 the V8 project authors. All rights reserved. |
+// Redistribution and use in source and binary forms, with or without |
+// modification, are permitted provided that the following conditions are |
+// met: |
+// |
+// * Redistributions of source code must retain the above copyright |
+// notice, this list of conditions and the following disclaimer. |
+// * Redistributions in binary form must reproduce the above |
+// copyright notice, this list of conditions and the following |
+// disclaimer in the documentation and/or other materials provided |
+// with the distribution. |
+// * Neither the name of Google Inc. nor the names of its |
+// contributors may be used to endorse or promote products derived |
+// from this software without specific prior written permission. |
+// |
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+#include <stdlib.h> |
+ |
+#include "v8.h" |
+ |
+#include "token.h" |
+#include "scanner.h" |
+ |
+#include "cctest.h" |
+ |
+namespace i = ::v8::internal; |
+ |
+TEST(KeywordMatcher) { |
+ struct KeywordToken { |
+ const char* keyword; |
+ i::Token::Value token; |
+ }; |
+ |
+ static const KeywordToken keywords[] = { |
+#define KEYWORD(t, s, d) { s, i::Token::t }, |
+#define IGNORE(t, s, d) /* */ |
+ TOKEN_LIST(IGNORE, KEYWORD, IGNORE) |
+#undef KEYWORD |
+ { NULL, i::Token::IDENTIFIER } |
+ }; |
+ |
+ static const char* future_keywords[] = { |
+#define FUTURE(t, s, d) s, |
+ TOKEN_LIST(IGNORE, IGNORE, FUTURE) |
+#undef FUTURE |
+#undef IGNORE |
+ NULL |
+ }; |
+ |
+ KeywordToken key_token; |
+ for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) { |
+ i::KeywordMatcher matcher; |
+ const char* keyword = key_token.keyword; |
+ int length = strlen(keyword); |
+ for (int j = 0; j < length; j++) { |
+ if (key_token.token == i::Token::INSTANCEOF && j == 2) { |
+ // "in" is a prefix of "instanceof". It's the only keyword |
+ // that is a prefix of another. |
+ CHECK_EQ(i::Token::IN, matcher.token()); |
+ } else { |
+ CHECK_EQ(i::Token::IDENTIFIER, matcher.token()); |
+ } |
+ matcher.AddChar(keyword[j]); |
+ } |
+ CHECK_EQ(key_token.token, matcher.token()); |
+ // Adding more characters will make keyword matching fail. |
+ matcher.AddChar('z'); |
+ CHECK_EQ(i::Token::IDENTIFIER, matcher.token()); |
+ // Adding a keyword later will not make it match again. |
+ matcher.AddChar('i'); |
+ matcher.AddChar('f'); |
+ CHECK_EQ(i::Token::IDENTIFIER, matcher.token()); |
+ } |
+ |
+ // Future keywords are not recognized. |
+ const char* future_keyword; |
+ for (int i = 0; (future_keyword = future_keywords[i]) != NULL; i++) { |
+ i::KeywordMatcher matcher; |
+ int length = strlen(future_keyword); |
+ for (int j = 0; j < length; j++) { |
+ matcher.AddChar(future_keyword[j]); |
+ } |
+ CHECK_EQ(i::Token::IDENTIFIER, matcher.token()); |
+ } |
+ |
+ // Zero isn't ignored at first. |
+ i::KeywordMatcher bad_start; |
+ bad_start.AddChar(0); |
+ CHECK_EQ(i::Token::IDENTIFIER, bad_start.token()); |
+ bad_start.AddChar('i'); |
+ bad_start.AddChar('f'); |
+ CHECK_EQ(i::Token::IDENTIFIER, bad_start.token()); |
+ |
+ // Zero isn't ignored at end. |
+ i::KeywordMatcher bad_end; |
+ bad_end.AddChar('i'); |
+ bad_end.AddChar('f'); |
+ CHECK_EQ(i::Token::IF, bad_end.token()); |
+ bad_end.AddChar(0); |
+ CHECK_EQ(i::Token::IDENTIFIER, bad_end.token()); |
+ |
+ // Case isn't ignored. |
+ i::KeywordMatcher bad_case; |
+ bad_case.AddChar('i'); |
+ bad_case.AddChar('F'); |
+ CHECK_EQ(i::Token::IDENTIFIER, bad_case.token()); |
+ |
+ // If we mark it as failure, continuing won't help. |
+ i::KeywordMatcher full_stop; |
+ full_stop.AddChar('i'); |
+ CHECK_EQ(i::Token::IDENTIFIER, full_stop.token()); |
+ full_stop.Fail(); |
+ CHECK_EQ(i::Token::IDENTIFIER, full_stop.token()); |
+ full_stop.AddChar('f'); |
+ CHECK_EQ(i::Token::IDENTIFIER, full_stop.token()); |
+} |
+ |