php.ts 13 KB

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