rebol.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. """
  2. pygments.lexers.rebol
  3. ~~~~~~~~~~~~~~~~~~~~~
  4. Lexers for the REBOL and related languages.
  5. :copyright: Copyright 2006-2021 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'[^R]+', Comment),
  110. (r'REBOL\s+\[', Generic.Strong, 'script'),
  111. (r'R', Comment)
  112. ],
  113. 'script': [
  114. (r'\s+', Text),
  115. (r'#"', String.Char, 'char'),
  116. (r'#\{[0-9a-f]*\}', Number.Hex),
  117. (r'2#\{', Number.Hex, 'bin2'),
  118. (r'64#\{[0-9a-z+/=\s]*\}', Number.Hex),
  119. (r'"', String, 'string'),
  120. (r'\{', String, 'string2'),
  121. (r';#+.*\n', Comment.Special),
  122. (r';\*+.*\n', Comment.Preproc),
  123. (r';.*\n', Comment),
  124. (r'%"', Name.Decorator, 'stringFile'),
  125. (r'%[^(^{")\s\[\]]+', Name.Decorator),
  126. (r'[+-]?([a-z]{1,3})?\$\d+(\.\d+)?', Number.Float), # money
  127. (r'[+-]?\d+\:\d+(\:\d+)?(\.\d+)?', String.Other), # time
  128. (r'\d+[\-/][0-9a-z]+[\-/]\d+(\/\d+\:\d+((\:\d+)?'
  129. r'([.\d+]?([+-]?\d+:\d+)?)?)?)?', String.Other), # date
  130. (r'\d+(\.\d+)+\.\d+', Keyword.Constant), # tuple
  131. (r'\d+X\d+', Keyword.Constant), # pair
  132. (r'[+-]?\d+(\'\d+)?([.,]\d*)?E[+-]?\d+', Number.Float),
  133. (r'[+-]?\d+(\'\d+)?[.,]\d*', Number.Float),
  134. (r'[+-]?\d+(\'\d+)?', Number),
  135. (r'[\[\]()]', Generic.Strong),
  136. (r'[a-z]+[^(^{"\s:)]*://[^(^{"\s)]*', Name.Decorator), # url
  137. (r'mailto:[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # url
  138. (r'[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # email
  139. (r'comment\s"', Comment, 'commentString1'),
  140. (r'comment\s\{', Comment, 'commentString2'),
  141. (r'comment\s\[', Comment, 'commentBlock'),
  142. (r'comment\s[^(\s{"\[]+', Comment),
  143. (r'/[^(^{")\s/[\]]*', Name.Attribute),
  144. (r'([^(^{")\s/[\]]+)(?=[:({"\s/\[\]])', word_callback),
  145. (r'<[\w:.-]*>', Name.Tag),
  146. (r'<[^(<>\s")]+', Name.Tag, 'tag'),
  147. (r'([^(^{")\s]+)', Text),
  148. ],
  149. 'string': [
  150. (r'[^(^")]+', String),
  151. (escape_re, String.Escape),
  152. (r'[(|)]+', String),
  153. (r'\^.', String.Escape),
  154. (r'"', String, '#pop'),
  155. ],
  156. 'string2': [
  157. (r'[^(^{})]+', String),
  158. (escape_re, String.Escape),
  159. (r'[(|)]+', String),
  160. (r'\^.', String.Escape),
  161. (r'\{', String, '#push'),
  162. (r'\}', String, '#pop'),
  163. ],
  164. 'stringFile': [
  165. (r'[^(^")]+', Name.Decorator),
  166. (escape_re, Name.Decorator),
  167. (r'\^.', Name.Decorator),
  168. (r'"', Name.Decorator, '#pop'),
  169. ],
  170. 'char': [
  171. (escape_re + '"', String.Char, '#pop'),
  172. (r'\^."', String.Char, '#pop'),
  173. (r'."', String.Char, '#pop'),
  174. ],
  175. 'tag': [
  176. (escape_re, Name.Tag),
  177. (r'"', Name.Tag, 'tagString'),
  178. (r'[^(<>\r\n")]+', Name.Tag),
  179. (r'>', Name.Tag, '#pop'),
  180. ],
  181. 'tagString': [
  182. (r'[^(^")]+', Name.Tag),
  183. (escape_re, Name.Tag),
  184. (r'[(|)]+', Name.Tag),
  185. (r'\^.', Name.Tag),
  186. (r'"', Name.Tag, '#pop'),
  187. ],
  188. 'tuple': [
  189. (r'(\d+\.)+', Keyword.Constant),
  190. (r'\d+', Keyword.Constant, '#pop'),
  191. ],
  192. 'bin2': [
  193. (r'\s+', Number.Hex),
  194. (r'([01]\s*){8}', Number.Hex),
  195. (r'\}', Number.Hex, '#pop'),
  196. ],
  197. 'commentString1': [
  198. (r'[^(^")]+', Comment),
  199. (escape_re, Comment),
  200. (r'[(|)]+', Comment),
  201. (r'\^.', Comment),
  202. (r'"', Comment, '#pop'),
  203. ],
  204. 'commentString2': [
  205. (r'[^(^{})]+', Comment),
  206. (escape_re, Comment),
  207. (r'[(|)]+', Comment),
  208. (r'\^.', Comment),
  209. (r'\{', Comment, '#push'),
  210. (r'\}', Comment, '#pop'),
  211. ],
  212. 'commentBlock': [
  213. (r'\[', Comment, '#push'),
  214. (r'\]', Comment, '#pop'),
  215. (r'"', Comment, "commentString1"),
  216. (r'\{', Comment, "commentString2"),
  217. (r'[^(\[\]"{)]+', Comment),
  218. ],
  219. }
  220. def analyse_text(text):
  221. """
  222. Check if code contains REBOL header and so it probably not R code
  223. """
  224. if re.match(r'^\s*REBOL\s*\[', text, re.IGNORECASE):
  225. # The code starts with REBOL header
  226. return 1.0
  227. elif re.search(r'\s*REBOL\s*\[', text, re.IGNORECASE):
  228. # The code contains REBOL header but also some text before it
  229. return 0.5
  230. class RedLexer(RegexLexer):
  231. """
  232. A `Red-language <http://www.red-lang.org/>`_ lexer.
  233. .. versionadded:: 2.0
  234. """
  235. name = 'Red'
  236. aliases = ['red', 'red/system']
  237. filenames = ['*.red', '*.reds']
  238. mimetypes = ['text/x-red', 'text/x-red-system']
  239. flags = re.IGNORECASE | re.MULTILINE
  240. escape_re = r'(?:\^\([0-9a-f]{1,4}\)*)'
  241. def word_callback(lexer, match):
  242. word = match.group()
  243. if re.match(".*:$", word):
  244. yield match.start(), Generic.Subheading, word
  245. elif re.match(r'(if|unless|either|any|all|while|until|loop|repeat|'
  246. r'foreach|forall|func|function|does|has|switch|'
  247. r'case|reduce|compose|get|set|print|prin|equal\?|'
  248. r'not-equal\?|strict-equal\?|lesser\?|greater\?|lesser-or-equal\?|'
  249. r'greater-or-equal\?|same\?|not|type\?|stats|'
  250. r'bind|union|replace|charset|routine)$', word):
  251. yield match.start(), Name.Builtin, word
  252. elif re.match(r'(make|random|reflect|to|form|mold|absolute|add|divide|multiply|negate|'
  253. r'power|remainder|round|subtract|even\?|odd\?|and~|complement|or~|xor~|'
  254. r'append|at|back|change|clear|copy|find|head|head\?|index\?|insert|'
  255. r'length\?|next|pick|poke|remove|reverse|select|sort|skip|swap|tail|tail\?|'
  256. r'take|trim|create|close|delete|modify|open|open\?|query|read|rename|'
  257. r'update|write)$', word):
  258. yield match.start(), Name.Function, word
  259. elif re.match(r'(yes|on|no|off|true|false|tab|cr|lf|newline|escape|slash|sp|space|null|'
  260. r'none|crlf|dot|null-byte)$', word):
  261. yield match.start(), Name.Builtin.Pseudo, word
  262. elif re.match(r'(#system-global|#include|#enum|#define|#either|#if|#import|#export|'
  263. r'#switch|#default|#get-definition)$', word):
  264. yield match.start(), Keyword.Namespace, word
  265. elif re.match(r'(system|halt|quit|quit-return|do|load|q|recycle|call|run|ask|parse|'
  266. r'raise-error|return|exit|break|alias|push|pop|probe|\?\?|spec-of|body-of|'
  267. r'quote|forever)$', word):
  268. yield match.start(), Name.Exception, word
  269. elif re.match(r'(action\?|block\?|char\?|datatype\?|file\?|function\?|get-path\?|zero\?|'
  270. r'get-word\?|integer\?|issue\?|lit-path\?|lit-word\?|logic\?|native\?|'
  271. r'op\?|paren\?|path\?|refinement\?|set-path\?|set-word\?|string\?|unset\?|'
  272. r'any-struct\?|none\?|word\?|any-series\?)$', word):
  273. yield match.start(), Keyword, word
  274. elif re.match(r'(JNICALL|stdcall|cdecl|infix)$', word):
  275. yield match.start(), Keyword.Namespace, word
  276. elif re.match("to-.*", word):
  277. yield match.start(), Keyword, word
  278. elif re.match(r'(\+|-\*\*|-|\*\*|//|/|\*|and|or|xor|=\?|===|==|=|<>|<=|>=|'
  279. r'<<<|>>>|<<|>>|<|>%)$', word):
  280. yield match.start(), Operator, word
  281. elif re.match(r".*\!$", word):
  282. yield match.start(), Keyword.Type, word
  283. elif re.match("'.*", word):
  284. yield match.start(), Name.Variable.Instance, word # lit-word
  285. elif re.match("#.*", word):
  286. yield match.start(), Name.Label, word # issue
  287. elif re.match("%.*", word):
  288. yield match.start(), Name.Decorator, word # file
  289. elif re.match(":.*", word):
  290. yield match.start(), Generic.Subheading, word # get-word
  291. else:
  292. yield match.start(), Name.Variable, word
  293. tokens = {
  294. 'root': [
  295. (r'[^R]+', Comment),
  296. (r'Red/System\s+\[', Generic.Strong, 'script'),
  297. (r'Red\s+\[', Generic.Strong, 'script'),
  298. (r'R', Comment)
  299. ],
  300. 'script': [
  301. (r'\s+', Text),
  302. (r'#"', String.Char, 'char'),
  303. (r'#\{[0-9a-f\s]*\}', Number.Hex),
  304. (r'2#\{', Number.Hex, 'bin2'),
  305. (r'64#\{[0-9a-z+/=\s]*\}', Number.Hex),
  306. (r'([0-9a-f]+)(h)((\s)|(?=[\[\]{}"()]))',
  307. bygroups(Number.Hex, Name.Variable, Whitespace)),
  308. (r'"', String, 'string'),
  309. (r'\{', String, 'string2'),
  310. (r';#+.*\n', Comment.Special),
  311. (r';\*+.*\n', Comment.Preproc),
  312. (r';.*\n', Comment),
  313. (r'%"', Name.Decorator, 'stringFile'),
  314. (r'%[^(^{")\s\[\]]+', Name.Decorator),
  315. (r'[+-]?([a-z]{1,3})?\$\d+(\.\d+)?', Number.Float), # money
  316. (r'[+-]?\d+\:\d+(\:\d+)?(\.\d+)?', String.Other), # time
  317. (r'\d+[\-/][0-9a-z]+[\-/]\d+(/\d+:\d+((:\d+)?'
  318. r'([\.\d+]?([+-]?\d+:\d+)?)?)?)?', String.Other), # date
  319. (r'\d+(\.\d+)+\.\d+', Keyword.Constant), # tuple
  320. (r'\d+X\d+', Keyword.Constant), # pair
  321. (r'[+-]?\d+(\'\d+)?([.,]\d*)?E[+-]?\d+', Number.Float),
  322. (r'[+-]?\d+(\'\d+)?[.,]\d*', Number.Float),
  323. (r'[+-]?\d+(\'\d+)?', Number),
  324. (r'[\[\]()]', Generic.Strong),
  325. (r'[a-z]+[^(^{"\s:)]*://[^(^{"\s)]*', Name.Decorator), # url
  326. (r'mailto:[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # url
  327. (r'[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator), # email
  328. (r'comment\s"', Comment, 'commentString1'),
  329. (r'comment\s\{', Comment, 'commentString2'),
  330. (r'comment\s\[', Comment, 'commentBlock'),
  331. (r'comment\s[^(\s{"\[]+', Comment),
  332. (r'/[^(^{^")\s/[\]]*', Name.Attribute),
  333. (r'([^(^{^")\s/[\]]+)(?=[:({"\s/\[\]])', word_callback),
  334. (r'<[\w:.-]*>', Name.Tag),
  335. (r'<[^(<>\s")]+', Name.Tag, 'tag'),
  336. (r'([^(^{")\s]+)', Text),
  337. ],
  338. 'string': [
  339. (r'[^(^")]+', String),
  340. (escape_re, String.Escape),
  341. (r'[(|)]+', String),
  342. (r'\^.', String.Escape),
  343. (r'"', String, '#pop'),
  344. ],
  345. 'string2': [
  346. (r'[^(^{})]+', String),
  347. (escape_re, String.Escape),
  348. (r'[(|)]+', String),
  349. (r'\^.', String.Escape),
  350. (r'\{', String, '#push'),
  351. (r'\}', String, '#pop'),
  352. ],
  353. 'stringFile': [
  354. (r'[^(^")]+', Name.Decorator),
  355. (escape_re, Name.Decorator),
  356. (r'\^.', Name.Decorator),
  357. (r'"', Name.Decorator, '#pop'),
  358. ],
  359. 'char': [
  360. (escape_re + '"', String.Char, '#pop'),
  361. (r'\^."', String.Char, '#pop'),
  362. (r'."', String.Char, '#pop'),
  363. ],
  364. 'tag': [
  365. (escape_re, Name.Tag),
  366. (r'"', Name.Tag, 'tagString'),
  367. (r'[^(<>\r\n")]+', Name.Tag),
  368. (r'>', Name.Tag, '#pop'),
  369. ],
  370. 'tagString': [
  371. (r'[^(^")]+', Name.Tag),
  372. (escape_re, Name.Tag),
  373. (r'[(|)]+', Name.Tag),
  374. (r'\^.', Name.Tag),
  375. (r'"', Name.Tag, '#pop'),
  376. ],
  377. 'tuple': [
  378. (r'(\d+\.)+', Keyword.Constant),
  379. (r'\d+', Keyword.Constant, '#pop'),
  380. ],
  381. 'bin2': [
  382. (r'\s+', Number.Hex),
  383. (r'([01]\s*){8}', Number.Hex),
  384. (r'\}', Number.Hex, '#pop'),
  385. ],
  386. 'commentString1': [
  387. (r'[^(^")]+', Comment),
  388. (escape_re, Comment),
  389. (r'[(|)]+', Comment),
  390. (r'\^.', Comment),
  391. (r'"', Comment, '#pop'),
  392. ],
  393. 'commentString2': [
  394. (r'[^(^{})]+', Comment),
  395. (escape_re, Comment),
  396. (r'[(|)]+', Comment),
  397. (r'\^.', Comment),
  398. (r'\{', Comment, '#push'),
  399. (r'\}', Comment, '#pop'),
  400. ],
  401. 'commentBlock': [
  402. (r'\[', Comment, '#push'),
  403. (r'\]', Comment, '#pop'),
  404. (r'"', Comment, "commentString1"),
  405. (r'\{', Comment, "commentString2"),
  406. (r'[^(\[\]"{)]+', Comment),
  407. ],
  408. }