JsScan.js 6.8 KB

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