rebol.py 18 KB

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