php.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. define(["require", "exports"], function (require, exports) {
  6. 'use strict';
  7. Object.defineProperty(exports, "__esModule", { value: true });
  8. exports.conf = {
  9. wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
  10. comments: {
  11. lineComment: '//',
  12. blockComment: ['/*', '*/']
  13. },
  14. brackets: [
  15. ['{', '}'],
  16. ['[', ']'],
  17. ['(', ')']
  18. ],
  19. autoClosingPairs: [
  20. { open: '{', close: '}', notIn: ['string'] },
  21. { open: '[', close: ']', notIn: ['string'] },
  22. { open: '(', close: ')', notIn: ['string'] },
  23. { open: '"', close: '"', notIn: ['string'] },
  24. { open: '\'', close: '\'', notIn: ['string', 'comment'] }
  25. ],
  26. folding: {
  27. markers: {
  28. start: new RegExp("^\\s*(#|\/\/)region\\b"),
  29. end: new RegExp("^\\s*(#|\/\/)endregion\\b")
  30. }
  31. }
  32. };
  33. exports.language = {
  34. defaultToken: '',
  35. tokenPostfix: '',
  36. // ignoreCase: true,
  37. // The main tokenizer for our languages
  38. tokenizer: {
  39. root: [
  40. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.root' }],
  41. [/<!DOCTYPE/, 'metatag.html', '@doctype'],
  42. [/<!--/, 'comment.html', '@comment'],
  43. [/(<)(\w+)(\/>)/, ['delimiter.html', 'tag.html', 'delimiter.html']],
  44. [/(<)(script)/, ['delimiter.html', { token: 'tag.html', next: '@script' }]],
  45. [/(<)(style)/, ['delimiter.html', { token: 'tag.html', next: '@style' }]],
  46. [/(<)([:\w]+)/, ['delimiter.html', { token: 'tag.html', next: '@otherTag' }]],
  47. [/(<\/)(\w+)/, ['delimiter.html', { token: 'tag.html', next: '@otherTag' }]],
  48. [/</, 'delimiter.html'],
  49. [/[^<]+/] // text
  50. ],
  51. doctype: [
  52. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.comment' }],
  53. [/[^>]+/, 'metatag.content.html'],
  54. [/>/, 'metatag.html', '@pop'],
  55. ],
  56. comment: [
  57. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.comment' }],
  58. [/-->/, 'comment.html', '@pop'],
  59. [/[^-]+/, 'comment.content.html'],
  60. [/./, 'comment.content.html']
  61. ],
  62. otherTag: [
  63. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.otherTag' }],
  64. [/\/?>/, 'delimiter.html', '@pop'],
  65. [/"([^"]*)"/, 'attribute.value'],
  66. [/'([^']*)'/, 'attribute.value'],
  67. [/[\w\-]+/, 'attribute.name'],
  68. [/=/, 'delimiter'],
  69. [/[ \t\r\n]+/],
  70. ],
  71. // -- BEGIN <script> tags handling
  72. // After <script
  73. script: [
  74. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.script' }],
  75. [/type/, 'attribute.name', '@scriptAfterType'],
  76. [/"([^"]*)"/, 'attribute.value'],
  77. [/'([^']*)'/, 'attribute.value'],
  78. [/[\w\-]+/, 'attribute.name'],
  79. [/=/, 'delimiter'],
  80. [/>/, { token: 'delimiter.html', next: '@scriptEmbedded.text/javascript', nextEmbedded: 'text/javascript' }],
  81. [/[ \t\r\n]+/],
  82. [/(<\/)(script\s*)(>)/, ['delimiter.html', 'tag.html', { token: 'delimiter.html', next: '@pop' }]]
  83. ],
  84. // After <script ... type
  85. scriptAfterType: [
  86. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.scriptAfterType' }],
  87. [/=/, 'delimiter', '@scriptAfterTypeEquals'],
  88. [/>/, { token: 'delimiter.html', next: '@scriptEmbedded.text/javascript', nextEmbedded: 'text/javascript' }],
  89. [/[ \t\r\n]+/],
  90. [/<\/script\s*>/, { token: '@rematch', next: '@pop' }]
  91. ],
  92. // After <script ... type =
  93. scriptAfterTypeEquals: [
  94. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.scriptAfterTypeEquals' }],
  95. [/"([^"]*)"/, { token: 'attribute.value', switchTo: '@scriptWithCustomType.$1' }],
  96. [/'([^']*)'/, { token: 'attribute.value', switchTo: '@scriptWithCustomType.$1' }],
  97. [/>/, { token: 'delimiter.html', next: '@scriptEmbedded.text/javascript', nextEmbedded: 'text/javascript' }],
  98. [/[ \t\r\n]+/],
  99. [/<\/script\s*>/, { token: '@rematch', next: '@pop' }]
  100. ],
  101. // After <script ... type = $S2
  102. scriptWithCustomType: [
  103. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.scriptWithCustomType.$S2' }],
  104. [/>/, { token: 'delimiter.html', next: '@scriptEmbedded.$S2', nextEmbedded: '$S2' }],
  105. [/"([^"]*)"/, 'attribute.value'],
  106. [/'([^']*)'/, 'attribute.value'],
  107. [/[\w\-]+/, 'attribute.name'],
  108. [/=/, 'delimiter'],
  109. [/[ \t\r\n]+/],
  110. [/<\/script\s*>/, { token: '@rematch', next: '@pop' }]
  111. ],
  112. scriptEmbedded: [
  113. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInEmbeddedState.scriptEmbedded.$S2', nextEmbedded: '@pop' }],
  114. [/<\/script/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }]
  115. ],
  116. // -- END <script> tags handling
  117. // -- BEGIN <style> tags handling
  118. // After <style
  119. style: [
  120. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.style' }],
  121. [/type/, 'attribute.name', '@styleAfterType'],
  122. [/"([^"]*)"/, 'attribute.value'],
  123. [/'([^']*)'/, 'attribute.value'],
  124. [/[\w\-]+/, 'attribute.name'],
  125. [/=/, 'delimiter'],
  126. [/>/, { token: 'delimiter.html', next: '@styleEmbedded.text/css', nextEmbedded: 'text/css' }],
  127. [/[ \t\r\n]+/],
  128. [/(<\/)(style\s*)(>)/, ['delimiter.html', 'tag.html', { token: 'delimiter.html', next: '@pop' }]]
  129. ],
  130. // After <style ... type
  131. styleAfterType: [
  132. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.styleAfterType' }],
  133. [/=/, 'delimiter', '@styleAfterTypeEquals'],
  134. [/>/, { token: 'delimiter.html', next: '@styleEmbedded.text/css', nextEmbedded: 'text/css' }],
  135. [/[ \t\r\n]+/],
  136. [/<\/style\s*>/, { token: '@rematch', next: '@pop' }]
  137. ],
  138. // After <style ... type =
  139. styleAfterTypeEquals: [
  140. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.styleAfterTypeEquals' }],
  141. [/"([^"]*)"/, { token: 'attribute.value', switchTo: '@styleWithCustomType.$1' }],
  142. [/'([^']*)'/, { token: 'attribute.value', switchTo: '@styleWithCustomType.$1' }],
  143. [/>/, { token: 'delimiter.html', next: '@styleEmbedded.text/css', nextEmbedded: 'text/css' }],
  144. [/[ \t\r\n]+/],
  145. [/<\/style\s*>/, { token: '@rematch', next: '@pop' }]
  146. ],
  147. // After <style ... type = $S2
  148. styleWithCustomType: [
  149. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInSimpleState.styleWithCustomType.$S2' }],
  150. [/>/, { token: 'delimiter.html', next: '@styleEmbedded.$S2', nextEmbedded: '$S2' }],
  151. [/"([^"]*)"/, 'attribute.value'],
  152. [/'([^']*)'/, 'attribute.value'],
  153. [/[\w\-]+/, 'attribute.name'],
  154. [/=/, 'delimiter'],
  155. [/[ \t\r\n]+/],
  156. [/<\/style\s*>/, { token: '@rematch', next: '@pop' }]
  157. ],
  158. styleEmbedded: [
  159. [/<\?((php)|=)?/, { token: '@rematch', switchTo: '@phpInEmbeddedState.styleEmbedded.$S2', nextEmbedded: '@pop' }],
  160. [/<\/style/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }]
  161. ],
  162. // -- END <style> tags handling
  163. phpInSimpleState: [
  164. [/<\?((php)|=)?/, 'metatag.php'],
  165. [/\?>/, { token: 'metatag.php', switchTo: '@$S2.$S3' }],
  166. { include: 'phpRoot' }
  167. ],
  168. phpInEmbeddedState: [
  169. [/<\?((php)|=)?/, 'metatag.php'],
  170. [/\?>/, { token: 'metatag.php', switchTo: '@$S2.$S3', nextEmbedded: '$S3' }],
  171. { include: 'phpRoot' }
  172. ],
  173. phpRoot: [
  174. [/[a-zA-Z_]\w*/, {
  175. cases: {
  176. '@phpKeywords': { token: 'keyword.php' },
  177. '@phpCompileTimeConstants': { token: 'constant.php' },
  178. '@default': 'identifier.php'
  179. }
  180. }],
  181. [/[$a-zA-Z_]\w*/, {
  182. cases: {
  183. '@phpPreDefinedVariables': { token: 'variable.predefined.php' },
  184. '@default': 'variable.php'
  185. }
  186. }],
  187. // brackets
  188. [/[{}]/, 'delimiter.bracket.php'],
  189. [/[\[\]]/, 'delimiter.array.php'],
  190. [/[()]/, 'delimiter.parenthesis.php'],
  191. // whitespace
  192. [/[ \t\r\n]+/],
  193. // comments
  194. [/(#|\/\/)$/, 'comment.php'],
  195. [/(#|\/\/)/, 'comment.php', '@phpLineComment'],
  196. // block comments
  197. [/\/\*/, 'comment.php', '@phpComment'],
  198. // strings
  199. [/"/, 'string.php', '@phpDoubleQuoteString'],
  200. [/'/, 'string.php', '@phpSingleQuoteString'],
  201. // delimiters
  202. [/[\+\-\*\%\&\|\^\~\!\=\<\>\/\?\;\:\.\,\@]/, 'delimiter.php'],
  203. // numbers
  204. [/\d*\d+[eE]([\-+]?\d+)?/, 'number.float.php'],
  205. [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float.php'],
  206. [/0[xX][0-9a-fA-F']*[0-9a-fA-F]/, 'number.hex.php'],
  207. [/0[0-7']*[0-7]/, 'number.octal.php'],
  208. [/0[bB][0-1']*[0-1]/, 'number.binary.php'],
  209. [/\d[\d']*/, 'number.php'],
  210. [/\d/, 'number.php'],
  211. ],
  212. phpComment: [
  213. [/\*\//, 'comment.php', '@pop'],
  214. [/[^*]+/, 'comment.php'],
  215. [/./, 'comment.php']
  216. ],
  217. phpLineComment: [
  218. [/\?>/, { token: '@rematch', next: '@pop' }],
  219. [/.$/, 'comment.php', '@pop'],
  220. [/[^?]+$/, 'comment.php', '@pop'],
  221. [/[^?]+/, 'comment.php'],
  222. [/./, 'comment.php']
  223. ],
  224. phpDoubleQuoteString: [
  225. [/[^\\"]+/, 'string.php'],
  226. [/@escapes/, 'string.escape.php'],
  227. [/\\./, 'string.escape.invalid.php'],
  228. [/"/, 'string.php', '@pop']
  229. ],
  230. phpSingleQuoteString: [
  231. [/[^\\']+/, 'string.php'],
  232. [/@escapes/, 'string.escape.php'],
  233. [/\\./, 'string.escape.invalid.php'],
  234. [/'/, 'string.php', '@pop']
  235. ],
  236. },
  237. phpKeywords: [
  238. 'abstract', 'and', 'array', 'as', 'break',
  239. 'callable', 'case', 'catch', 'cfunction', 'class', 'clone',
  240. 'const', 'continue', 'declare', 'default', 'do',
  241. 'else', 'elseif', 'enddeclare', 'endfor', 'endforeach',
  242. 'endif', 'endswitch', 'endwhile', 'extends', 'false', 'final',
  243. 'for', 'foreach', 'function', 'global', 'goto',
  244. 'if', 'implements', 'interface', 'instanceof', 'insteadof',
  245. 'namespace', 'new', 'null', 'object', 'old_function', 'or', 'private',
  246. 'protected', 'public', 'resource', 'static', 'switch', 'throw', 'trait',
  247. 'try', 'true', 'use', 'var', 'while', 'xor',
  248. 'die', 'echo', 'empty', 'exit', 'eval',
  249. 'include', 'include_once', 'isset', 'list', 'require',
  250. 'require_once', 'return', 'print', 'unset', 'yield',
  251. '__construct'
  252. ],
  253. phpCompileTimeConstants: [
  254. '__CLASS__',
  255. '__DIR__',
  256. '__FILE__',
  257. '__LINE__',
  258. '__NAMESPACE__',
  259. '__METHOD__',
  260. '__FUNCTION__',
  261. '__TRAIT__'
  262. ],
  263. phpPreDefinedVariables: [
  264. '$GLOBALS',
  265. '$_SERVER',
  266. '$_GET',
  267. '$_POST',
  268. '$_FILES',
  269. '$_REQUEST',
  270. '$_SESSION',
  271. '$_ENV',
  272. '$_COOKIE',
  273. '$php_errormsg',
  274. '$HTTP_RAW_POST_DATA',
  275. '$http_response_header',
  276. '$argc',
  277. '$argv'
  278. ],
  279. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  280. };
  281. });
  282. // TESTED WITH
  283. // <style type="text/css" >
  284. // .boo { background: blue;
  285. // <?=''?>
  286. // }
  287. // .boo { background: blue; <?=''?> }
  288. // </style>
  289. // <!--
  290. // <?= '' ?>
  291. // -->
  292. // <?php
  293. // // The next line contains a syntax error:
  294. // __construct
  295. // if () {
  296. // return "The parser recovers from this type of syntax error";
  297. // }
  298. // ?>
  299. // <html>
  300. // <head>
  301. // <title <?=''?>>Example page</title>
  302. // <style <?=''?>>
  303. // .boo { background: blue; <?=''?> }
  304. // </style>
  305. // </head>
  306. // <body>
  307. // <script <?=''?> type<?=''?>=<?=''?>"text/javascript"<?=''?>>
  308. // // Some PHP embedded inside JS
  309. // // Generated <?=date('l, F jS, Y')?>
  310. // var server_token = <?=rand(5, 10000)?>
  311. // if (typeof server_token === 'number') {
  312. // alert('token: ' + server_token);
  313. // }
  314. // </script>
  315. // <div>
  316. // Hello
  317. // <? if (isset($user)) { ?>
  318. // <b><?=$user?></b>
  319. // <? } else { ?>
  320. // <i>guest</i>
  321. // <? } ?>
  322. // !
  323. // </div>
  324. // <?php
  325. // /* Example PHP file
  326. // multiline comment
  327. // */
  328. // # Another single line comment
  329. // $cards = array("ah", "ac", "ad", "as",
  330. // "2h", "2c", "2d", "2s",
  331. // "3h", "3c", "3d", "3s",
  332. // "4h", "4c", "4d", "4s",
  333. // "5h", "5c", "5d", "5s",
  334. // "6h", "6c", "6d", "6s",
  335. // "7h", "7c", "7d", "7s",
  336. // "8h", "8c", "8d", "8s",
  337. // "9h", "9c", "9d", "9s",
  338. // "th", "tc", "td", "ts",
  339. // "jh", "jc", "jd", "js",
  340. // "qh", "qc", "qd", "qs",
  341. // "kh", "kc", "kd", "ks");
  342. // srand(time());
  343. // for($i = 0; $i < 52; $i++) {
  344. // $count = count($cards);
  345. // $random = (rand()%$count);
  346. // if($cards[$random] == "") {
  347. // $i--;
  348. // } else {
  349. // $deck[] = $cards[$random];
  350. // $cards[$random] = "";
  351. // }
  352. // }
  353. // $_GET
  354. // __CLASS__
  355. // srand(time());
  356. // $starting_point = (rand()%51);
  357. // print("Starting point for cut cards is: $starting_point<p>");
  358. // // display shuffled cards (EXAMPLE ONLY)
  359. // for ($index = 0; $index < 52; $index++) {
  360. // if ($starting_point == 52) { $starting_point = 0; }
  361. // print("Uncut Point: <strong>$deck[$index]</strong> ");
  362. // print("Starting Point: <strong>$deck[$starting_point]</strong><br>");
  363. // $starting_point++;
  364. // }
  365. // ?>
  366. // </body>
  367. // </html>