rebol.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. # -*- coding: utf-8 -*-
  2. """
  3. pygments.lexers.rebol
  4. ~~~~~~~~~~~~~~~~~~~~~
  5. Lexers for the REBOL and related languages.
  6. :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
  7. :license: BSD, see LICENSE for details.
  8. """
  9. import re
  10. from pygments.lexer import RegexLexer, bygroups
  11. from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
  12. Number, Generic, Whitespace
  13. __all__ = ['RebolLexer', 'RedLexer']
  14. class RebolLexer(RegexLexer):
  15. """
  16. A `REBOL <http://www.rebol.com/>`_ lexer.
  17. .. versionadded:: 1.1
  18. """
  19. name = 'REBOL'
  20. aliases = ['rebol']
  21. filenames = ['*.r', '*.r3', '*.reb']
  22. mimetypes = ['text/x-rebol']
  23. flags = re.IGNORECASE | re.MULTILINE
  24. escape_re = r'(?:\^\([0-9a-f]{1,4}\)*)'
  25. def word_callback(lexer, match):
  26. word = match.group()
  27. if re.match(".*:$", word):
  28. yield match.start(), Generic.Subheading, word
  29. elif re.match(
  30. r'(native|alias|all|any|as-string|as-binary|bind|bound\?|case|'
  31. r'catch|checksum|comment|debase|dehex|exclude|difference|disarm|'
  32. r'either|else|enbase|foreach|remove-each|form|free|get|get-env|if|'
  33. r'in|intersect|loop|minimum-of|maximum-of|mold|new-line|'
  34. r'new-line\?|not|now|prin|print|reduce|compose|construct|repeat|'
  35. r'reverse|save|script\?|set|shift|switch|throw|to-hex|trace|try|'
  36. r'type\?|union|unique|unless|unprotect|unset|until|use|value\?|'
  37. r'while|compress|decompress|secure|open|close|read|read-io|'
  38. r'write-io|write|update|query|wait|input\?|exp|log-10|log-2|'
  39. r'log-e|square-root|cosine|sine|tangent|arccosine|arcsine|'
  40. r'arctangent|protect|lowercase|uppercase|entab|detab|connected\?|'
  41. r'browse|launch|stats|get-modes|set-modes|to-local-file|'
  42. r'to-rebol-file|encloak|decloak|create-link|do-browser|bind\?|'
  43. r'hide|draw|show|size-text|textinfo|offset-to-caret|'
  44. r'caret-to-offset|local-request-file|rgb-to-hsv|hsv-to-rgb|'
  45. r'crypt-strength\?|dh-make-key|dh-generate-key|dh-compute-key|'
  46. r'dsa-make-key|dsa-generate-key|dsa-make-signature|'
  47. r'dsa-verify-signature|rsa-make-key|rsa-generate-key|'
  48. r'rsa-encrypt)$', word):
  49. yield match.start(), Name.Builtin, word
  50. elif re.match(
  51. r'(add|subtract|multiply|divide|remainder|power|and~|or~|xor~|'
  52. r'minimum|maximum|negate|complement|absolute|random|head|tail|'
  53. r'next|back|skip|at|pick|first|second|third|fourth|fifth|sixth|'
  54. r'seventh|eighth|ninth|tenth|last|path|find|select|make|to|copy\*|'
  55. r'insert|remove|change|poke|clear|trim|sort|min|max|abs|cp|'
  56. r'copy)$', word):
  57. yield match.start(), Name.Function, word
  58. elif re.match(
  59. r'(error|source|input|license|help|install|echo|Usage|with|func|'
  60. r'throw-on-error|function|does|has|context|probe|\?\?|as-pair|'
  61. r'mod|modulo|round|repend|about|set-net|append|join|rejoin|reform|'
  62. r'remold|charset|array|replace|move|extract|forskip|forall|alter|'
  63. r'first+|also|take|for|forever|dispatch|attempt|what-dir|'
  64. r'change-dir|clean-path|list-dir|dirize|rename|split-path|delete|'
  65. r'make-dir|delete-dir|in-dir|confirm|dump-obj|upgrade|what|'
  66. r'build-tag|process-source|build-markup|decode-cgi|read-cgi|'
  67. r'write-user|save-user|set-user-name|protect-system|parse-xml|'
  68. r'cvs-date|cvs-version|do-boot|get-net-info|desktop|layout|'
  69. r'scroll-para|get-face|alert|set-face|uninstall|unfocus|'
  70. r'request-dir|center-face|do-events|net-error|decode-url|'
  71. r'parse-header|parse-header-date|parse-email-addrs|import-email|'
  72. r'send|build-attach-body|resend|show-popup|hide-popup|open-events|'
  73. r'find-key-face|do-face|viewtop|confine|find-window|'
  74. r'insert-event-func|remove-event-func|inform|dump-pane|dump-face|'
  75. r'flag-face|deflag-face|clear-fields|read-net|vbug|path-thru|'
  76. r'read-thru|load-thru|do-thru|launch-thru|load-image|'
  77. r'request-download|do-face-alt|set-font|set-para|get-style|'
  78. r'set-style|make-face|stylize|choose|hilight-text|hilight-all|'
  79. r'unlight-text|focus|scroll-drag|clear-face|reset-face|scroll-face|'
  80. r'resize-face|load-stock|load-stock-block|notify|request|flash|'
  81. r'request-color|request-pass|request-text|request-list|'
  82. r'request-date|request-file|dbug|editor|link-relative-path|'
  83. r'emailer|parse-error)$', word):
  84. yield match.start(), Keyword.Namespace, word
  85. elif re.match(
  86. r'(halt|quit|do|load|q|recycle|call|run|ask|parse|view|unview|'
  87. r'return|exit|break)$', word):
  88. yield match.start(), Name.Exception, word
  89. elif re.match('REBOL$', word):
  90. yield match.start(), Generic.Heading, word
  91. elif re.match("to-.*", word):
  92. yield match.start(), Keyword, word
  93. elif re.match(r'(\+|-|\*|/|//|\*\*|and|or|xor|=\?|=|==|<>|<|>|<=|>=)$',
  94. word):
  95. yield match.start(), Operator, word
  96. elif re.match(r".*\?$", word):
  97. yield match.start(), Keyword, word
  98. elif re.match(r".*\!$", word):
  99. yield match.start(), Keyword.Type, word
  100. elif re.match("'.*", word):
  101. yield match.start(), Name.Variable.Instance, word # lit-word
  102. elif re.match("#.*", word):
  103. yield match.start(), Name.Label, word # issue
  104. elif re.match("%.*", word):
  105. yield match.start(), Name.Decorator, word # file
  106. else:
  107. yield match.start(), Name.Variable, word
  108. tokens = {
  109. 'root': [
  110. (r'[^R]+', Comment),
  111. (r'REBOL\s+\[', Generic.Strong, 'script'),
  112. (r'R', Comment)
  113. ],
  114. 'script': [
  115. (r'\s+', Text),
  116. (r'#"', String.Char, 'char'),
  117. (r'#\{[0-9a-f]*\}', Number.Hex),
  118. (r'2#\{', Number.Hex, 'bin2'),
  119. (r'64#\{[0-9a-z+/=\s]*\}', Number.Hex),
  120. (r'"', String, 'string'),
  121. (r'\{', String, 'string2'),
  122. (r';#+.*\n', Comment.Special),
  123. (r';\*+.*\n', Comment.Preproc),
  124. (r';.*\n', Comment),
  125. (r'%"', Name.Decorator, 'stringFile'),
  126. (r'%[^(^{")\s\[\]]+', Name.Decorator),
  127. (r'[+-]?([a-z]{1,3})?\$\d+(\.\d+)?', Number.Float), # money
  128. (r'[+-]?\d+\:\d+(\:\d+)?(\.\d+)?', String.Other), # time
  129. (r'\d+[\-/][0-9a-z]+[\-/]\d+(\/\d+\:\d+((\:\d+)?'
  130. r'([.\d+]?([+-]?\d+:\d+)?)?)?)?', String.Other), # date
  131. (r'\d+(\.\d+)+\.\d+', Keyword.Constant), # tuple
  132. (r'\d+X\d+', Keyword.Constant), # pair
  133. (r'[+-]?\d+(\'\d+)?([.,]\d*)?E[+-]?\d+', Number.Float),
  134. (r'[+-]?\d+(\'\d+)?[.,]\d*', Number.Float),
  135. (r'[+-]?\d+(\'\d+)?', Number),
  136. (r'[\[\]()]', Generic.Strong),
  137. (r'[a-z]+[^(^{"\s:)]*://[^(^{"\s)]*', Name.Decorator), # url
  138. (r'mailto:[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # url
  139. (r'[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # email
  140. (r'comment\s"', Comment, 'commentString1'),
  141. (r'comment\s\{', Comment, 'commentString2'),
  142. (r'comment\s\[', Comment, 'commentBlock'),
  143. (r'comment\s[^(\s{"\[]+', Comment),
  144. (r'/[^(^{")\s/[\]]*', Name.Attribute),
  145. (r'([^(^{")\s/[\]]+)(?=[:({"\s/\[\]])', word_callback),
  146. (r'<[\w:.-]*>', Name.Tag),
  147. (r'<[^(<>\s")]+', Name.Tag, 'tag'),
  148. (r'([^(^{")\s]+)', Text),
  149. ],
  150. 'string': [
  151. (r'[^(^")]+', String),
  152. (escape_re, String.Escape),
  153. (r'[(|)]+', String),
  154. (r'\^.', String.Escape),
  155. (r'"', String, '#pop'),
  156. ],
  157. 'string2': [
  158. (r'[^(^{})]+', String),
  159. (escape_re, String.Escape),
  160. (r'[(|)]+', String),
  161. (r'\^.', String.Escape),
  162. (r'\{', String, '#push'),
  163. (r'\}', String, '#pop'),
  164. ],
  165. 'stringFile': [
  166. (r'[^(^")]+', Name.Decorator),
  167. (escape_re, Name.Decorator),
  168. (r'\^.', Name.Decorator),
  169. (r'"', Name.Decorator, '#pop'),
  170. ],
  171. 'char': [
  172. (escape_re + '"', String.Char, '#pop'),
  173. (r'\^."', String.Char, '#pop'),
  174. (r'."', String.Char, '#pop'),
  175. ],
  176. 'tag': [
  177. (escape_re, Name.Tag),
  178. (r'"', Name.Tag, 'tagString'),
  179. (r'[^(<>\r\n")]+', Name.Tag),
  180. (r'>', Name.Tag, '#pop'),
  181. ],
  182. 'tagString': [
  183. (r'[^(^")]+', Name.Tag),
  184. (escape_re, Name.Tag),
  185. (r'[(|)]+', Name.Tag),
  186. (r'\^.', Name.Tag),
  187. (r'"', Name.Tag, '#pop'),
  188. ],
  189. 'tuple': [
  190. (r'(\d+\.)+', Keyword.Constant),
  191. (r'\d+', Keyword.Constant, '#pop'),
  192. ],
  193. 'bin2': [
  194. (r'\s+', Number.Hex),
  195. (r'([01]\s*){8}', Number.Hex),
  196. (r'\}', Number.Hex, '#pop'),
  197. ],
  198. 'commentString1': [
  199. (r'[^(^")]+', Comment),
  200. (escape_re, Comment),
  201. (r'[(|)]+', Comment),
  202. (r'\^.', Comment),
  203. (r'"', Comment, '#pop'),
  204. ],
  205. 'commentString2': [
  206. (r'[^(^{})]+', Comment),
  207. (escape_re, Comment),
  208. (r'[(|)]+', Comment),
  209. (r'\^.', Comment),
  210. (r'\{', Comment, '#push'),
  211. (r'\}', Comment, '#pop'),
  212. ],
  213. 'commentBlock': [
  214. (r'\[', Comment, '#push'),
  215. (r'\]', Comment, '#pop'),
  216. (r'"', Comment, "commentString1"),
  217. (r'\{', Comment, "commentString2"),
  218. (r'[^(\[\]"{)]+', Comment),
  219. ],
  220. }
  221. def analyse_text(text):
  222. """
  223. Check if code contains REBOL header and so it probably not R code
  224. """
  225. if re.match(r'^\s*REBOL\s*\[', text, re.IGNORECASE):
  226. # The code starts with REBOL header
  227. return 1.0
  228. elif re.search(r'\s*REBOL\s*\[', text, re.IGNORECASE):
  229. # The code contains REBOL header but also some text before it
  230. return 0.5
  231. class RedLexer(RegexLexer):
  232. """
  233. A `Red-language <http://www.red-lang.org/>`_ lexer.
  234. .. versionadded:: 2.0
  235. """
  236. name = 'Red'
  237. aliases = ['red', 'red/system']
  238. filenames = ['*.red', '*.reds']
  239. mimetypes = ['text/x-red', 'text/x-red-system']
  240. flags = re.IGNORECASE | re.MULTILINE
  241. escape_re = r'(?:\^\([0-9a-f]{1,4}\)*)'
  242. def word_callback(lexer, match):
  243. word = match.group()
  244. if re.match(".*:$", word):
  245. yield match.start(), Generic.Subheading, word
  246. elif re.match(r'(if|unless|either|any|all|while|until|loop|repeat|'
  247. r'foreach|forall|func|function|does|has|switch|'
  248. r'case|reduce|compose|get|set|print|prin|equal\?|'
  249. r'not-equal\?|strict-equal\?|lesser\?|greater\?|lesser-or-equal\?|'
  250. r'greater-or-equal\?|same\?|not|type\?|stats|'
  251. r'bind|union|replace|charset|routine)$', word):
  252. yield match.start(), Name.Builtin, word
  253. elif re.match(r'(make|random|reflect|to|form|mold|absolute|add|divide|multiply|negate|'
  254. r'power|remainder|round|subtract|even\?|odd\?|and~|complement|or~|xor~|'
  255. r'append|at|back|change|clear|copy|find|head|head\?|index\?|insert|'
  256. r'length\?|next|pick|poke|remove|reverse|select|sort|skip|swap|tail|tail\?|'
  257. r'take|trim|create|close|delete|modify|open|open\?|query|read|rename|'
  258. r'update|write)$', word):
  259. yield match.start(), Name.Function, word
  260. elif re.match(r'(yes|on|no|off|true|false|tab|cr|lf|newline|escape|slash|sp|space|null|'
  261. r'none|crlf|dot|null-byte)$', word):
  262. yield match.start(), Name.Builtin.Pseudo, word
  263. elif re.match(r'(#system-global|#include|#enum|#define|#either|#if|#import|#export|'
  264. r'#switch|#default|#get-definition)$', word):
  265. yield match.start(), Keyword.Namespace, word
  266. elif re.match(r'(system|halt|quit|quit-return|do|load|q|recycle|call|run|ask|parse|'
  267. r'raise-error|return|exit|break|alias|push|pop|probe|\?\?|spec-of|body-of|'
  268. r'quote|forever)$', word):
  269. yield match.start(), Name.Exception, word
  270. elif re.match(r'(action\?|block\?|char\?|datatype\?|file\?|function\?|get-path\?|zero\?|'
  271. r'get-word\?|integer\?|issue\?|lit-path\?|lit-word\?|logic\?|native\?|'
  272. r'op\?|paren\?|path\?|refinement\?|set-path\?|set-word\?|string\?|unset\?|'
  273. r'any-struct\?|none\?|word\?|any-series\?)$', word):
  274. yield match.start(), Keyword, word
  275. elif re.match(r'(JNICALL|stdcall|cdecl|infix)$', word):
  276. yield match.start(), Keyword.Namespace, word
  277. elif re.match("to-.*", word):
  278. yield match.start(), Keyword, word
  279. elif re.match(r'(\+|-\*\*|-|\*\*|//|/|\*|and|or|xor|=\?|===|==|=|<>|<=|>=|'
  280. r'<<<|>>>|<<|>>|<|>%)$', word):
  281. yield match.start(), Operator, word
  282. elif re.match(r".*\!$", word):
  283. yield match.start(), Keyword.Type, word
  284. elif re.match("'.*", word):
  285. yield match.start(), Name.Variable.Instance, word # lit-word
  286. elif re.match("#.*", word):
  287. yield match.start(), Name.Label, word # issue
  288. elif re.match("%.*", word):
  289. yield match.start(), Name.Decorator, word # file
  290. elif re.match(":.*", word):
  291. yield match.start(), Generic.Subheading, word # get-word
  292. else:
  293. yield match.start(), Name.Variable, word
  294. tokens = {
  295. 'root': [
  296. (r'[^R]+', Comment),
  297. (r'Red/System\s+\[', Generic.Strong, 'script'),
  298. (r'Red\s+\[', Generic.Strong, 'script'),
  299. (r'R', Comment)
  300. ],
  301. 'script': [
  302. (r'\s+', Text),
  303. (r'#"', String.Char, 'char'),
  304. (r'#\{[0-9a-f\s]*\}', Number.Hex),
  305. (r'2#\{', Number.Hex, 'bin2'),
  306. (r'64#\{[0-9a-z+/=\s]*\}', Number.Hex),
  307. (r'([0-9a-f]+)(h)((\s)|(?=[\[\]{}"()]))',
  308. bygroups(Number.Hex, Name.Variable, Whitespace)),
  309. (r'"', String, 'string'),
  310. (r'\{', String, 'string2'),
  311. (r';#+.*\n', Comment.Special),
  312. (r';\*+.*\n', Comment.Preproc),
  313. (r';.*\n', Comment),
  314. (r'%"', Name.Decorator, 'stringFile'),
  315. (r'%[^(^{")\s\[\]]+', Name.Decorator),
  316. (r'[+-]?([a-z]{1,3})?\$\d+(\.\d+)?', Number.Float), # money
  317. (r'[+-]?\d+\:\d+(\:\d+)?(\.\d+)?', String.Other), # time
  318. (r'\d+[\-/][0-9a-z]+[\-/]\d+(/\d+:\d+((:\d+)?'
  319. r'([\.\d+]?([+-]?\d+:\d+)?)?)?)?', String.Other), # date
  320. (r'\d+(\.\d+)+\.\d+', Keyword.Constant), # tuple
  321. (r'\d+X\d+', Keyword.Constant), # pair
  322. (r'[+-]?\d+(\'\d+)?([.,]\d*)?E[+-]?\d+', Number.Float),
  323. (r'[+-]?\d+(\'\d+)?[.,]\d*', Number.Float),
  324. (r'[+-]?\d+(\'\d+)?', Number),
  325. (r'[\[\]()]', Generic.Strong),
  326. (r'[a-z]+[^(^{"\s:)]*://[^(^{"\s)]*', Name.Decorator), # url
  327. (r'mailto:[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # url
  328. (r'[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # email
  329. (r'comment\s"', Comment, 'commentString1'),
  330. (r'comment\s\{', Comment, 'commentString2'),
  331. (r'comment\s\[', Comment, 'commentBlock'),
  332. (r'comment\s[^(\s{"\[]+', Comment),
  333. (r'/[^(^{^")\s/[\]]*', Name.Attribute),
  334. (r'([^(^{^")\s/[\]]+)(?=[:({"\s/\[\]])', word_callback),
  335. (r'<[\w:.-]*>', Name.Tag),
  336. (r'<[^(<>\s")]+', Name.Tag, 'tag'),
  337. (r'([^(^{")\s]+)', Text),
  338. ],
  339. 'string': [
  340. (r'[^(^")]+', String),
  341. (escape_re, String.Escape),
  342. (r'[(|)]+', String),
  343. (r'\^.', String.Escape),
  344. (r'"', String, '#pop'),
  345. ],
  346. 'string2': [
  347. (r'[^(^{})]+', String),
  348. (escape_re, String.Escape),
  349. (r'[(|)]+', String),
  350. (r'\^.', String.Escape),
  351. (r'\{', String, '#push'),
  352. (r'\}', String, '#pop'),
  353. ],
  354. 'stringFile': [
  355. (r'[^(^")]+', Name.Decorator),
  356. (escape_re, Name.Decorator),
  357. (r'\^.', Name.Decorator),
  358. (r'"', Name.Decorator, '#pop'),
  359. ],
  360. 'char': [
  361. (escape_re + '"', String.Char, '#pop'),
  362. (r'\^."', String.Char, '#pop'),
  363. (r'."', String.Char, '#pop'),
  364. ],
  365. 'tag': [
  366. (escape_re, Name.Tag),
  367. (r'"', Name.Tag, 'tagString'),
  368. (r'[^(<>\r\n")]+', Name.Tag),
  369. (r'>', Name.Tag, '#pop'),
  370. ],
  371. 'tagString': [
  372. (r'[^(^")]+', Name.Tag),
  373. (escape_re, Name.Tag),
  374. (r'[(|)]+', Name.Tag),
  375. (r'\^.', Name.Tag),
  376. (r'"', Name.Tag, '#pop'),
  377. ],
  378. 'tuple': [
  379. (r'(\d+\.)+', Keyword.Constant),
  380. (r'\d+', Keyword.Constant, '#pop'),
  381. ],
  382. 'bin2': [
  383. (r'\s+', Number.Hex),
  384. (r'([01]\s*){8}', Number.Hex),
  385. (r'\}', Number.Hex, '#pop'),
  386. ],
  387. 'commentString1': [
  388. (r'[^(^")]+', Comment),
  389. (escape_re, Comment),
  390. (r'[(|)]+', Comment),
  391. (r'\^.', Comment),
  392. (r'"', Comment, '#pop'),
  393. ],
  394. 'commentString2': [
  395. (r'[^(^{})]+', Comment),
  396. (escape_re, Comment),
  397. (r'[(|)]+', Comment),
  398. (r'\^.', Comment),
  399. (r'\{', Comment, '#push'),
  400. (r'\}', Comment, '#pop'),
  401. ],
  402. 'commentBlock': [
  403. (r'\[', Comment, '#push'),
  404. (r'\]', Comment, '#pop'),
  405. (r'"', Comment, "commentString1"),
  406. (r'\{', Comment, "commentString2"),
  407. (r'[^(\[\]"{)]+', Comment),
  408. ],
  409. }