jsscan.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. // WARNING: See Bug 1335253
  6. // This file will not generate Trie branches when symbols share prefixes under certain circumstances (thus skipping cases).
  7. objArgs = WScript.Arguments;
  8. function emitToken(token, d, indent) {
  9. r = "";
  10. indent += " ";
  11. if (d)
  12. r += indent + "p += " + d + ";\r\n";
  13. if (token.res == 1) {
  14. if (token.tk === "tkYIELD") {
  15. r += indent + "if (this->m_fYieldIsKeyword || !this->m_parser || this->m_parser->IsStrictMode()) {" + "\r\n";
  16. r += indent + " token = " + token.tk + ";\r\n";
  17. r += indent + " goto LReserved;\r\n";
  18. r += indent + "}\r\n";
  19. r += indent + "goto LIdentifier;\r\n";
  20. } else if (token.tk === "tkAWAIT") {
  21. r += indent + "if (this->m_fAwaitIsKeyword || !this->m_parser || this->m_parser->IsStrictMode()) {" + "\r\n";
  22. r += indent + " token = " + token.tk + ";\r\n";
  23. r += indent + " goto LReserved;\r\n";
  24. r += indent + "}\r\n";
  25. r += indent + "goto LIdentifier;\r\n";
  26. } else {
  27. r += indent + "token = " + token.tk + ";\r\n";
  28. r += indent + "goto LReserved;\r\n";
  29. }
  30. } else if (token.res == 2) {
  31. r += indent + "if (!this->m_parser || this->m_parser->IsStrictMode()) {" + "\r\n";
  32. r += indent + " " + "token = " + token.tk + ";\r\n";
  33. r += indent + " " + "goto LReserved;\r\n";
  34. r += indent + "}\r\n";
  35. r += indent + "goto LIdentifier;\r\n";
  36. } else if (token.res == 3) {
  37. // These are special case of identifiers that we have a well known PID for and always want to be filled
  38. // whether or not we have suppressed generated pids. (e.g. eval and arguments)
  39. r += indent + "goto " + token.tk + ";\r\n";
  40. } else {
  41. WScript.Echo("Error: Unsupported Keyword type");
  42. }
  43. return r;
  44. }
  45. function noMoreBranches(token) {
  46. for (var c = token; c.length; c = c[0]) {
  47. if (c.length > 1) return false;
  48. }
  49. return true;
  50. }
  51. function emit(token, d, indent) {
  52. var r = "";
  53. if (token.length > 1) {
  54. r += indent + "switch (";
  55. if (d < 0) r += "ch";
  56. else r += "p[" + d + "]";
  57. r += ") {\r\n";
  58. for (var i = 0; i < token.length; i++) {
  59. var tk = token[i];
  60. r += indent + "case '" + tk.char + "':\r\n";
  61. r += emit(tk, d + 1, indent + " ");
  62. if (tk.tk && tk.length) {
  63. r += indent + " if (!IsIdContinueNext(p+" +(d + 1) + ",last)) {\r\n" + emitToken(tk, d + 1, indent + " ") + indent + " }\r\n";
  64. }
  65. r += indent + " break;\r\n";
  66. }
  67. r += indent + "}\r\n";
  68. }
  69. else if (noMoreBranches(token)) {
  70. r += indent + "if (";
  71. for (var c = token; c.length; c = c[0]) {
  72. r += "p[" + d++ + "] == '" + c[0].char + "' && ";
  73. }
  74. r += "!IsIdContinueNext(p+" + d + ", last)) {\r\n";
  75. r += emitToken(c, d, indent);
  76. r += indent + "}\r\n";
  77. }
  78. else {
  79. r += indent + "if (p[" + d + "] == '" + token[0].char + "') {\r\n";
  80. r += emit(token[0], d + 1, indent + " ");
  81. r += indent + "}\r\n";
  82. }
  83. return r;
  84. }
  85. if (objArgs.length != 1 && objArgs.length != 2) {
  86. WScript.Echo("Supply the header file name and optional output file");
  87. }
  88. else {
  89. var fso = new ActiveXObject("Scripting.FileSystemObject");
  90. var file = fso.OpenTextFile(objArgs(0), 1);
  91. var text = file.ReadAll();
  92. file.Close();
  93. var reg = /KEYWORD\((tk[A-Z]+)\s*,([1-2]),.*,\s*([a-z]+)\)/g;
  94. var s_reg = /S_KEYWORD\((L[A-Z][a-z]+)\s*,(3),\s*([a-z]+)\)/g;
  95. var t = [];
  96. var s = text.replace(reg, function (a, p1, p2, p3, offset) {
  97. t.push({ tk: p1, res: p2, word: p3 });
  98. });
  99. var s_s = text.replace(s_reg, function (a, p1, p2, p3, offset) {
  100. t.push({ tk: p1, res: p2, word: p3 });
  101. });
  102. var tokens = [];
  103. var counter = 0;
  104. for (var i = 0; i < t.length; i++) {
  105. var token = t[i];
  106. var current = tokens;
  107. for (var j = 0; j < token.word.length; j++) {
  108. l = token.word.substring(j, j + 1);
  109. var n = current[l];
  110. if (n)
  111. current = n;
  112. else {
  113. var nt = [];
  114. nt.char = l;
  115. current[l] = nt;
  116. current.push(nt);
  117. current = nt;
  118. }
  119. counter++;
  120. }
  121. current.tk = token.tk;
  122. current.res = token.res;
  123. }
  124. var indent = " ";
  125. var r = "";
  126. r += "//-------------------------------------------------------------------------------------------------------\r\n";
  127. r += "// Copyright (C) Microsoft. All rights reserved.\r\n";
  128. r += "// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.\r\n";
  129. r += "//-------------------------------------------------------------------------------------------------------\r\n";
  130. r += "// GENERATED FILE, DO NOT HAND-MODIFY!\r\n";
  131. r += "// Generated with the following command line: wscript jsscan.js " + objArgs(0) + " " + objArgs(1) + "\r\n";
  132. r += "// This should be regenerated whenever the keywords change.\r\n";
  133. r += "\r\n";
  134. // Generate the reserved word recognizer
  135. for (var i = 0; i < tokens.length; i++) {
  136. var tk = tokens[i];
  137. r += indent + "case '" + tk.char + "':\r\n";
  138. r += indent + " if (identifyKwds)\r\n";
  139. r += indent + " {\r\n";
  140. var simple = tk.length == 1 && noMoreBranches(tk);
  141. r += emit(tk, 0, indent + " ");
  142. r += indent + " }\r\n";
  143. r += indent + " goto LIdentifier;\r\n";
  144. }
  145. r += "\r\n";
  146. // Generate lower case letters that are not part of the recognizer
  147. r += indent + "// characters not in a reserved word\r\n";
  148. var c = 0;
  149. var chars = "abcdefghijklmnopqrstuvwxyz";
  150. for (var i = 0; i < chars.length; i++) {
  151. if (c == 0) r += indent;
  152. var ch = chars.substring(i, i + 1);
  153. if (!tokens[ch])
  154. r += "case '" + ch + "': ";
  155. else
  156. r += " ";
  157. if (++c == 5) {
  158. c = 0;
  159. r += "\r\n";
  160. }
  161. }
  162. r += "\r\n";
  163. r += indent + " goto LIdentifier;\r\n";
  164. if (objArgs.length == 2) {
  165. var outfile = fso.CreateTextFile(objArgs(1), true);
  166. outfile.Write(r);
  167. outfile.Close();
  168. } else {
  169. WScript.Echo(r);
  170. }
  171. }