haxe.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. # -*- coding: utf-8 -*-
  2. """
  3. pygments.lexers.haxe
  4. ~~~~~~~~~~~~~~~~~~~~
  5. Lexers for Haxe and related stuff.
  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 ExtendedRegexLexer, RegexLexer, include, bygroups, \
  11. default
  12. from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
  13. Number, Punctuation, Generic, Whitespace
  14. __all__ = ['HaxeLexer', 'HxmlLexer']
  15. class HaxeLexer(ExtendedRegexLexer):
  16. """
  17. For Haxe source code (http://haxe.org/).
  18. .. versionadded:: 1.3
  19. """
  20. name = 'Haxe'
  21. aliases = ['hx', 'haxe', 'hxsl']
  22. filenames = ['*.hx', '*.hxsl']
  23. mimetypes = ['text/haxe', 'text/x-haxe', 'text/x-hx']
  24. # keywords extracted from lexer.mll in the haxe compiler source
  25. keyword = (r'(?:function|class|static|var|if|else|while|do|for|'
  26. r'break|return|continue|extends|implements|import|'
  27. r'switch|case|default|public|private|try|untyped|'
  28. r'catch|new|this|throw|extern|enum|in|interface|'
  29. r'cast|override|dynamic|typedef|package|'
  30. r'inline|using|null|true|false|abstract)\b')
  31. # idtype in lexer.mll
  32. typeid = r'_*[A-Z]\w*'
  33. # combined ident and dollar and idtype
  34. ident = r'(?:_*[a-z]\w*|_+[0-9]\w*|' + typeid + r'|_+|\$\w+)'
  35. binop = (r'(?:%=|&=|\|=|\^=|\+=|\-=|\*=|/=|<<=|>\s*>\s*=|>\s*>\s*>\s*=|==|'
  36. r'!=|<=|>\s*=|&&|\|\||<<|>>>|>\s*>|\.\.\.|<|>|%|&|\||\^|\+|\*|'
  37. r'/|\-|=>|=)')
  38. # ident except keywords
  39. ident_no_keyword = r'(?!' + keyword + ')' + ident
  40. flags = re.DOTALL | re.MULTILINE
  41. preproc_stack = []
  42. def preproc_callback(self, match, ctx):
  43. proc = match.group(2)
  44. if proc == 'if':
  45. # store the current stack
  46. self.preproc_stack.append(ctx.stack[:])
  47. elif proc in ['else', 'elseif']:
  48. # restore the stack back to right before #if
  49. if self.preproc_stack:
  50. ctx.stack = self.preproc_stack[-1][:]
  51. elif proc == 'end':
  52. # remove the saved stack of previous #if
  53. if self.preproc_stack:
  54. self.preproc_stack.pop()
  55. # #if and #elseif should follow by an expr
  56. if proc in ['if', 'elseif']:
  57. ctx.stack.append('preproc-expr')
  58. # #error can be optionally follow by the error msg
  59. if proc in ['error']:
  60. ctx.stack.append('preproc-error')
  61. yield match.start(), Comment.Preproc, u'#' + proc
  62. ctx.pos = match.end()
  63. tokens = {
  64. 'root': [
  65. include('spaces'),
  66. include('meta'),
  67. (r'(?:package)\b', Keyword.Namespace, ('semicolon', 'package')),
  68. (r'(?:import)\b', Keyword.Namespace, ('semicolon', 'import')),
  69. (r'(?:using)\b', Keyword.Namespace, ('semicolon', 'using')),
  70. (r'(?:extern|private)\b', Keyword.Declaration),
  71. (r'(?:abstract)\b', Keyword.Declaration, 'abstract'),
  72. (r'(?:class|interface)\b', Keyword.Declaration, 'class'),
  73. (r'(?:enum)\b', Keyword.Declaration, 'enum'),
  74. (r'(?:typedef)\b', Keyword.Declaration, 'typedef'),
  75. # top-level expression
  76. # although it is not supported in haxe, but it is common to write
  77. # expression in web pages the positive lookahead here is to prevent
  78. # an infinite loop at the EOF
  79. (r'(?=.)', Text, 'expr-statement'),
  80. ],
  81. # space/tab/comment/preproc
  82. 'spaces': [
  83. (r'\s+', Text),
  84. (r'//[^\n\r]*', Comment.Single),
  85. (r'/\*.*?\*/', Comment.Multiline),
  86. (r'(#)(if|elseif|else|end|error)\b', preproc_callback),
  87. ],
  88. 'string-single-interpol': [
  89. (r'\$\{', String.Interpol, ('string-interpol-close', 'expr')),
  90. (r'\$\$', String.Escape),
  91. (r'\$(?=' + ident + ')', String.Interpol, 'ident'),
  92. include('string-single'),
  93. ],
  94. 'string-single': [
  95. (r"'", String.Single, '#pop'),
  96. (r'\\.', String.Escape),
  97. (r'.', String.Single),
  98. ],
  99. 'string-double': [
  100. (r'"', String.Double, '#pop'),
  101. (r'\\.', String.Escape),
  102. (r'.', String.Double),
  103. ],
  104. 'string-interpol-close': [
  105. (r'\$'+ident, String.Interpol),
  106. (r'\}', String.Interpol, '#pop'),
  107. ],
  108. 'package': [
  109. include('spaces'),
  110. (ident, Name.Namespace),
  111. (r'\.', Punctuation, 'import-ident'),
  112. default('#pop'),
  113. ],
  114. 'import': [
  115. include('spaces'),
  116. (ident, Name.Namespace),
  117. (r'\*', Keyword), # wildcard import
  118. (r'\.', Punctuation, 'import-ident'),
  119. (r'in', Keyword.Namespace, 'ident'),
  120. default('#pop'),
  121. ],
  122. 'import-ident': [
  123. include('spaces'),
  124. (r'\*', Keyword, '#pop'), # wildcard import
  125. (ident, Name.Namespace, '#pop'),
  126. ],
  127. 'using': [
  128. include('spaces'),
  129. (ident, Name.Namespace),
  130. (r'\.', Punctuation, 'import-ident'),
  131. default('#pop'),
  132. ],
  133. 'preproc-error': [
  134. (r'\s+', Comment.Preproc),
  135. (r"'", String.Single, ('#pop', 'string-single')),
  136. (r'"', String.Double, ('#pop', 'string-double')),
  137. default('#pop'),
  138. ],
  139. 'preproc-expr': [
  140. (r'\s+', Comment.Preproc),
  141. (r'\!', Comment.Preproc),
  142. (r'\(', Comment.Preproc, ('#pop', 'preproc-parenthesis')),
  143. (ident, Comment.Preproc, '#pop'),
  144. # Float
  145. (r'\.[0-9]+', Number.Float),
  146. (r'[0-9]+[eE][+\-]?[0-9]+', Number.Float),
  147. (r'[0-9]+\.[0-9]*[eE][+\-]?[0-9]+', Number.Float),
  148. (r'[0-9]+\.[0-9]+', Number.Float),
  149. (r'[0-9]+\.(?!' + ident + r'|\.\.)', Number.Float),
  150. # Int
  151. (r'0x[0-9a-fA-F]+', Number.Hex),
  152. (r'[0-9]+', Number.Integer),
  153. # String
  154. (r"'", String.Single, ('#pop', 'string-single')),
  155. (r'"', String.Double, ('#pop', 'string-double')),
  156. ],
  157. 'preproc-parenthesis': [
  158. (r'\s+', Comment.Preproc),
  159. (r'\)', Comment.Preproc, '#pop'),
  160. default('preproc-expr-in-parenthesis'),
  161. ],
  162. 'preproc-expr-chain': [
  163. (r'\s+', Comment.Preproc),
  164. (binop, Comment.Preproc, ('#pop', 'preproc-expr-in-parenthesis')),
  165. default('#pop'),
  166. ],
  167. # same as 'preproc-expr' but able to chain 'preproc-expr-chain'
  168. 'preproc-expr-in-parenthesis': [
  169. (r'\s+', Comment.Preproc),
  170. (r'\!', Comment.Preproc),
  171. (r'\(', Comment.Preproc,
  172. ('#pop', 'preproc-expr-chain', 'preproc-parenthesis')),
  173. (ident, Comment.Preproc, ('#pop', 'preproc-expr-chain')),
  174. # Float
  175. (r'\.[0-9]+', Number.Float, ('#pop', 'preproc-expr-chain')),
  176. (r'[0-9]+[eE][+\-]?[0-9]+', Number.Float, ('#pop', 'preproc-expr-chain')),
  177. (r'[0-9]+\.[0-9]*[eE][+\-]?[0-9]+', Number.Float, ('#pop', 'preproc-expr-chain')),
  178. (r'[0-9]+\.[0-9]+', Number.Float, ('#pop', 'preproc-expr-chain')),
  179. (r'[0-9]+\.(?!' + ident + r'|\.\.)', Number.Float, ('#pop', 'preproc-expr-chain')),
  180. # Int
  181. (r'0x[0-9a-fA-F]+', Number.Hex, ('#pop', 'preproc-expr-chain')),
  182. (r'[0-9]+', Number.Integer, ('#pop', 'preproc-expr-chain')),
  183. # String
  184. (r"'", String.Single,
  185. ('#pop', 'preproc-expr-chain', 'string-single')),
  186. (r'"', String.Double,
  187. ('#pop', 'preproc-expr-chain', 'string-double')),
  188. ],
  189. 'abstract': [
  190. include('spaces'),
  191. default(('#pop', 'abstract-body', 'abstract-relation',
  192. 'abstract-opaque', 'type-param-constraint', 'type-name')),
  193. ],
  194. 'abstract-body': [
  195. include('spaces'),
  196. (r'\{', Punctuation, ('#pop', 'class-body')),
  197. ],
  198. 'abstract-opaque': [
  199. include('spaces'),
  200. (r'\(', Punctuation, ('#pop', 'parenthesis-close', 'type')),
  201. default('#pop'),
  202. ],
  203. 'abstract-relation': [
  204. include('spaces'),
  205. (r'(?:to|from)', Keyword.Declaration, 'type'),
  206. (r',', Punctuation),
  207. default('#pop'),
  208. ],
  209. 'meta': [
  210. include('spaces'),
  211. (r'@', Name.Decorator, ('meta-body', 'meta-ident', 'meta-colon')),
  212. ],
  213. # optional colon
  214. 'meta-colon': [
  215. include('spaces'),
  216. (r':', Name.Decorator, '#pop'),
  217. default('#pop'),
  218. ],
  219. # same as 'ident' but set token as Name.Decorator instead of Name
  220. 'meta-ident': [
  221. include('spaces'),
  222. (ident, Name.Decorator, '#pop'),
  223. ],
  224. 'meta-body': [
  225. include('spaces'),
  226. (r'\(', Name.Decorator, ('#pop', 'meta-call')),
  227. default('#pop'),
  228. ],
  229. 'meta-call': [
  230. include('spaces'),
  231. (r'\)', Name.Decorator, '#pop'),
  232. default(('#pop', 'meta-call-sep', 'expr')),
  233. ],
  234. 'meta-call-sep': [
  235. include('spaces'),
  236. (r'\)', Name.Decorator, '#pop'),
  237. (r',', Punctuation, ('#pop', 'meta-call')),
  238. ],
  239. 'typedef': [
  240. include('spaces'),
  241. default(('#pop', 'typedef-body', 'type-param-constraint',
  242. 'type-name')),
  243. ],
  244. 'typedef-body': [
  245. include('spaces'),
  246. (r'=', Operator, ('#pop', 'optional-semicolon', 'type')),
  247. ],
  248. 'enum': [
  249. include('spaces'),
  250. default(('#pop', 'enum-body', 'bracket-open',
  251. 'type-param-constraint', 'type-name')),
  252. ],
  253. 'enum-body': [
  254. include('spaces'),
  255. include('meta'),
  256. (r'\}', Punctuation, '#pop'),
  257. (ident_no_keyword, Name, ('enum-member', 'type-param-constraint')),
  258. ],
  259. 'enum-member': [
  260. include('spaces'),
  261. (r'\(', Punctuation,
  262. ('#pop', 'semicolon', 'flag', 'function-param')),
  263. default(('#pop', 'semicolon', 'flag')),
  264. ],
  265. 'class': [
  266. include('spaces'),
  267. default(('#pop', 'class-body', 'bracket-open', 'extends',
  268. 'type-param-constraint', 'type-name')),
  269. ],
  270. 'extends': [
  271. include('spaces'),
  272. (r'(?:extends|implements)\b', Keyword.Declaration, 'type'),
  273. (r',', Punctuation), # the comma is made optional here, since haxe2
  274. # requires the comma but haxe3 does not allow it
  275. default('#pop'),
  276. ],
  277. 'bracket-open': [
  278. include('spaces'),
  279. (r'\{', Punctuation, '#pop'),
  280. ],
  281. 'bracket-close': [
  282. include('spaces'),
  283. (r'\}', Punctuation, '#pop'),
  284. ],
  285. 'class-body': [
  286. include('spaces'),
  287. include('meta'),
  288. (r'\}', Punctuation, '#pop'),
  289. (r'(?:static|public|private|override|dynamic|inline|macro)\b',
  290. Keyword.Declaration),
  291. default('class-member'),
  292. ],
  293. 'class-member': [
  294. include('spaces'),
  295. (r'(var)\b', Keyword.Declaration,
  296. ('#pop', 'optional-semicolon', 'var')),
  297. (r'(function)\b', Keyword.Declaration,
  298. ('#pop', 'optional-semicolon', 'class-method')),
  299. ],
  300. # local function, anonymous or not
  301. 'function-local': [
  302. include('spaces'),
  303. (ident_no_keyword, Name.Function,
  304. ('#pop', 'optional-expr', 'flag', 'function-param',
  305. 'parenthesis-open', 'type-param-constraint')),
  306. default(('#pop', 'optional-expr', 'flag', 'function-param',
  307. 'parenthesis-open', 'type-param-constraint')),
  308. ],
  309. 'optional-expr': [
  310. include('spaces'),
  311. include('expr'),
  312. default('#pop'),
  313. ],
  314. 'class-method': [
  315. include('spaces'),
  316. (ident, Name.Function, ('#pop', 'optional-expr', 'flag',
  317. 'function-param', 'parenthesis-open',
  318. 'type-param-constraint')),
  319. ],
  320. # function arguments
  321. 'function-param': [
  322. include('spaces'),
  323. (r'\)', Punctuation, '#pop'),
  324. (r'\?', Punctuation),
  325. (ident_no_keyword, Name,
  326. ('#pop', 'function-param-sep', 'assign', 'flag')),
  327. ],
  328. 'function-param-sep': [
  329. include('spaces'),
  330. (r'\)', Punctuation, '#pop'),
  331. (r',', Punctuation, ('#pop', 'function-param')),
  332. ],
  333. 'prop-get-set': [
  334. include('spaces'),
  335. (r'\(', Punctuation, ('#pop', 'parenthesis-close',
  336. 'prop-get-set-opt', 'comma', 'prop-get-set-opt')),
  337. default('#pop'),
  338. ],
  339. 'prop-get-set-opt': [
  340. include('spaces'),
  341. (r'(?:default|null|never|dynamic|get|set)\b', Keyword, '#pop'),
  342. (ident_no_keyword, Text, '#pop'), # custom getter/setter
  343. ],
  344. 'expr-statement': [
  345. include('spaces'),
  346. # makes semicolon optional here, just to avoid checking the last
  347. # one is bracket or not.
  348. default(('#pop', 'optional-semicolon', 'expr')),
  349. ],
  350. 'expr': [
  351. include('spaces'),
  352. (r'@', Name.Decorator, ('#pop', 'optional-expr', 'meta-body',
  353. 'meta-ident', 'meta-colon')),
  354. (r'(?:\+\+|\-\-|~(?!/)|!|\-)', Operator),
  355. (r'\(', Punctuation, ('#pop', 'expr-chain', 'parenthesis')),
  356. (r'(?:static|public|private|override|dynamic|inline)\b',
  357. Keyword.Declaration),
  358. (r'(?:function)\b', Keyword.Declaration, ('#pop', 'expr-chain',
  359. 'function-local')),
  360. (r'\{', Punctuation, ('#pop', 'expr-chain', 'bracket')),
  361. (r'(?:true|false|null)\b', Keyword.Constant, ('#pop', 'expr-chain')),
  362. (r'(?:this)\b', Keyword, ('#pop', 'expr-chain')),
  363. (r'(?:cast)\b', Keyword, ('#pop', 'expr-chain', 'cast')),
  364. (r'(?:try)\b', Keyword, ('#pop', 'catch', 'expr')),
  365. (r'(?:var)\b', Keyword.Declaration, ('#pop', 'var')),
  366. (r'(?:new)\b', Keyword, ('#pop', 'expr-chain', 'new')),
  367. (r'(?:switch)\b', Keyword, ('#pop', 'switch')),
  368. (r'(?:if)\b', Keyword, ('#pop', 'if')),
  369. (r'(?:do)\b', Keyword, ('#pop', 'do')),
  370. (r'(?:while)\b', Keyword, ('#pop', 'while')),
  371. (r'(?:for)\b', Keyword, ('#pop', 'for')),
  372. (r'(?:untyped|throw)\b', Keyword),
  373. (r'(?:return)\b', Keyword, ('#pop', 'optional-expr')),
  374. (r'(?:macro)\b', Keyword, ('#pop', 'macro')),
  375. (r'(?:continue|break)\b', Keyword, '#pop'),
  376. (r'(?:\$\s*[a-z]\b|\$(?!'+ident+'))', Name, ('#pop', 'dollar')),
  377. (ident_no_keyword, Name, ('#pop', 'expr-chain')),
  378. # Float
  379. (r'\.[0-9]+', Number.Float, ('#pop', 'expr-chain')),
  380. (r'[0-9]+[eE][+\-]?[0-9]+', Number.Float, ('#pop', 'expr-chain')),
  381. (r'[0-9]+\.[0-9]*[eE][+\-]?[0-9]+', Number.Float, ('#pop', 'expr-chain')),
  382. (r'[0-9]+\.[0-9]+', Number.Float, ('#pop', 'expr-chain')),
  383. (r'[0-9]+\.(?!' + ident + r'|\.\.)', Number.Float, ('#pop', 'expr-chain')),
  384. # Int
  385. (r'0x[0-9a-fA-F]+', Number.Hex, ('#pop', 'expr-chain')),
  386. (r'[0-9]+', Number.Integer, ('#pop', 'expr-chain')),
  387. # String
  388. (r"'", String.Single, ('#pop', 'expr-chain', 'string-single-interpol')),
  389. (r'"', String.Double, ('#pop', 'expr-chain', 'string-double')),
  390. # EReg
  391. (r'~/(\\\\|\\/|[^/\n])*/[gimsu]*', String.Regex, ('#pop', 'expr-chain')),
  392. # Array
  393. (r'\[', Punctuation, ('#pop', 'expr-chain', 'array-decl')),
  394. ],
  395. 'expr-chain': [
  396. include('spaces'),
  397. (r'(?:\+\+|\-\-)', Operator),
  398. (binop, Operator, ('#pop', 'expr')),
  399. (r'(?:in)\b', Keyword, ('#pop', 'expr')),
  400. (r'\?', Operator, ('#pop', 'expr', 'ternary', 'expr')),
  401. (r'(\.)(' + ident_no_keyword + ')', bygroups(Punctuation, Name)),
  402. (r'\[', Punctuation, 'array-access'),
  403. (r'\(', Punctuation, 'call'),
  404. default('#pop'),
  405. ],
  406. # macro reification
  407. 'macro': [
  408. include('spaces'),
  409. include('meta'),
  410. (r':', Punctuation, ('#pop', 'type')),
  411. (r'(?:extern|private)\b', Keyword.Declaration),
  412. (r'(?:abstract)\b', Keyword.Declaration, ('#pop', 'optional-semicolon', 'abstract')),
  413. (r'(?:class|interface)\b', Keyword.Declaration, ('#pop', 'optional-semicolon', 'macro-class')),
  414. (r'(?:enum)\b', Keyword.Declaration, ('#pop', 'optional-semicolon', 'enum')),
  415. (r'(?:typedef)\b', Keyword.Declaration, ('#pop', 'optional-semicolon', 'typedef')),
  416. default(('#pop', 'expr')),
  417. ],
  418. 'macro-class': [
  419. (r'\{', Punctuation, ('#pop', 'class-body')),
  420. include('class')
  421. ],
  422. # cast can be written as "cast expr" or "cast(expr, type)"
  423. 'cast': [
  424. include('spaces'),
  425. (r'\(', Punctuation, ('#pop', 'parenthesis-close',
  426. 'cast-type', 'expr')),
  427. default(('#pop', 'expr')),
  428. ],
  429. # optionally give a type as the 2nd argument of cast()
  430. 'cast-type': [
  431. include('spaces'),
  432. (r',', Punctuation, ('#pop', 'type')),
  433. default('#pop'),
  434. ],
  435. 'catch': [
  436. include('spaces'),
  437. (r'(?:catch)\b', Keyword, ('expr', 'function-param',
  438. 'parenthesis-open')),
  439. default('#pop'),
  440. ],
  441. # do-while loop
  442. 'do': [
  443. include('spaces'),
  444. default(('#pop', 'do-while', 'expr')),
  445. ],
  446. # the while after do
  447. 'do-while': [
  448. include('spaces'),
  449. (r'(?:while)\b', Keyword, ('#pop', 'parenthesis',
  450. 'parenthesis-open')),
  451. ],
  452. 'while': [
  453. include('spaces'),
  454. (r'\(', Punctuation, ('#pop', 'expr', 'parenthesis')),
  455. ],
  456. 'for': [
  457. include('spaces'),
  458. (r'\(', Punctuation, ('#pop', 'expr', 'parenthesis')),
  459. ],
  460. 'if': [
  461. include('spaces'),
  462. (r'\(', Punctuation, ('#pop', 'else', 'optional-semicolon', 'expr',
  463. 'parenthesis')),
  464. ],
  465. 'else': [
  466. include('spaces'),
  467. (r'(?:else)\b', Keyword, ('#pop', 'expr')),
  468. default('#pop'),
  469. ],
  470. 'switch': [
  471. include('spaces'),
  472. default(('#pop', 'switch-body', 'bracket-open', 'expr')),
  473. ],
  474. 'switch-body': [
  475. include('spaces'),
  476. (r'(?:case|default)\b', Keyword, ('case-block', 'case')),
  477. (r'\}', Punctuation, '#pop'),
  478. ],
  479. 'case': [
  480. include('spaces'),
  481. (r':', Punctuation, '#pop'),
  482. default(('#pop', 'case-sep', 'case-guard', 'expr')),
  483. ],
  484. 'case-sep': [
  485. include('spaces'),
  486. (r':', Punctuation, '#pop'),
  487. (r',', Punctuation, ('#pop', 'case')),
  488. ],
  489. 'case-guard': [
  490. include('spaces'),
  491. (r'(?:if)\b', Keyword, ('#pop', 'parenthesis', 'parenthesis-open')),
  492. default('#pop'),
  493. ],
  494. # optional multiple expr under a case
  495. 'case-block': [
  496. include('spaces'),
  497. (r'(?!(?:case|default)\b|\})', Keyword, 'expr-statement'),
  498. default('#pop'),
  499. ],
  500. 'new': [
  501. include('spaces'),
  502. default(('#pop', 'call', 'parenthesis-open', 'type')),
  503. ],
  504. 'array-decl': [
  505. include('spaces'),
  506. (r'\]', Punctuation, '#pop'),
  507. default(('#pop', 'array-decl-sep', 'expr')),
  508. ],
  509. 'array-decl-sep': [
  510. include('spaces'),
  511. (r'\]', Punctuation, '#pop'),
  512. (r',', Punctuation, ('#pop', 'array-decl')),
  513. ],
  514. 'array-access': [
  515. include('spaces'),
  516. default(('#pop', 'array-access-close', 'expr')),
  517. ],
  518. 'array-access-close': [
  519. include('spaces'),
  520. (r'\]', Punctuation, '#pop'),
  521. ],
  522. 'comma': [
  523. include('spaces'),
  524. (r',', Punctuation, '#pop'),
  525. ],
  526. 'colon': [
  527. include('spaces'),
  528. (r':', Punctuation, '#pop'),
  529. ],
  530. 'semicolon': [
  531. include('spaces'),
  532. (r';', Punctuation, '#pop'),
  533. ],
  534. 'optional-semicolon': [
  535. include('spaces'),
  536. (r';', Punctuation, '#pop'),
  537. default('#pop'),
  538. ],
  539. # identity that CAN be a Haxe keyword
  540. 'ident': [
  541. include('spaces'),
  542. (ident, Name, '#pop'),
  543. ],
  544. 'dollar': [
  545. include('spaces'),
  546. (r'\{', Punctuation, ('#pop', 'expr-chain', 'bracket-close', 'expr')),
  547. default(('#pop', 'expr-chain')),
  548. ],
  549. 'type-name': [
  550. include('spaces'),
  551. (typeid, Name, '#pop'),
  552. ],
  553. 'type-full-name': [
  554. include('spaces'),
  555. (r'\.', Punctuation, 'ident'),
  556. default('#pop'),
  557. ],
  558. 'type': [
  559. include('spaces'),
  560. (r'\?', Punctuation),
  561. (ident, Name, ('#pop', 'type-check', 'type-full-name')),
  562. (r'\{', Punctuation, ('#pop', 'type-check', 'type-struct')),
  563. (r'\(', Punctuation, ('#pop', 'type-check', 'type-parenthesis')),
  564. ],
  565. 'type-parenthesis': [
  566. include('spaces'),
  567. default(('#pop', 'parenthesis-close', 'type')),
  568. ],
  569. 'type-check': [
  570. include('spaces'),
  571. (r'->', Punctuation, ('#pop', 'type')),
  572. (r'<(?!=)', Punctuation, 'type-param'),
  573. default('#pop'),
  574. ],
  575. 'type-struct': [
  576. include('spaces'),
  577. (r'\}', Punctuation, '#pop'),
  578. (r'\?', Punctuation),
  579. (r'>', Punctuation, ('comma', 'type')),
  580. (ident_no_keyword, Name, ('#pop', 'type-struct-sep', 'type', 'colon')),
  581. include('class-body'),
  582. ],
  583. 'type-struct-sep': [
  584. include('spaces'),
  585. (r'\}', Punctuation, '#pop'),
  586. (r',', Punctuation, ('#pop', 'type-struct')),
  587. ],
  588. # type-param can be a normal type or a constant literal...
  589. 'type-param-type': [
  590. # Float
  591. (r'\.[0-9]+', Number.Float, '#pop'),
  592. (r'[0-9]+[eE][+\-]?[0-9]+', Number.Float, '#pop'),
  593. (r'[0-9]+\.[0-9]*[eE][+\-]?[0-9]+', Number.Float, '#pop'),
  594. (r'[0-9]+\.[0-9]+', Number.Float, '#pop'),
  595. (r'[0-9]+\.(?!' + ident + r'|\.\.)', Number.Float, '#pop'),
  596. # Int
  597. (r'0x[0-9a-fA-F]+', Number.Hex, '#pop'),
  598. (r'[0-9]+', Number.Integer, '#pop'),
  599. # String
  600. (r"'", String.Single, ('#pop', 'string-single')),
  601. (r'"', String.Double, ('#pop', 'string-double')),
  602. # EReg
  603. (r'~/(\\\\|\\/|[^/\n])*/[gim]*', String.Regex, '#pop'),
  604. # Array
  605. (r'\[', Operator, ('#pop', 'array-decl')),
  606. include('type'),
  607. ],
  608. # type-param part of a type
  609. # ie. the <A,B> path in Map<A,B>
  610. 'type-param': [
  611. include('spaces'),
  612. default(('#pop', 'type-param-sep', 'type-param-type')),
  613. ],
  614. 'type-param-sep': [
  615. include('spaces'),
  616. (r'>', Punctuation, '#pop'),
  617. (r',', Punctuation, ('#pop', 'type-param')),
  618. ],
  619. # optional type-param that may include constraint
  620. # ie. <T:Constraint, T2:(ConstraintA,ConstraintB)>
  621. 'type-param-constraint': [
  622. include('spaces'),
  623. (r'<(?!=)', Punctuation, ('#pop', 'type-param-constraint-sep',
  624. 'type-param-constraint-flag', 'type-name')),
  625. default('#pop'),
  626. ],
  627. 'type-param-constraint-sep': [
  628. include('spaces'),
  629. (r'>', Punctuation, '#pop'),
  630. (r',', Punctuation, ('#pop', 'type-param-constraint-sep',
  631. 'type-param-constraint-flag', 'type-name')),
  632. ],
  633. # the optional constraint inside type-param
  634. 'type-param-constraint-flag': [
  635. include('spaces'),
  636. (r':', Punctuation, ('#pop', 'type-param-constraint-flag-type')),
  637. default('#pop'),
  638. ],
  639. 'type-param-constraint-flag-type': [
  640. include('spaces'),
  641. (r'\(', Punctuation, ('#pop', 'type-param-constraint-flag-type-sep',
  642. 'type')),
  643. default(('#pop', 'type')),
  644. ],
  645. 'type-param-constraint-flag-type-sep': [
  646. include('spaces'),
  647. (r'\)', Punctuation, '#pop'),
  648. (r',', Punctuation, 'type'),
  649. ],
  650. # a parenthesis expr that contain exactly one expr
  651. 'parenthesis': [
  652. include('spaces'),
  653. default(('#pop', 'parenthesis-close', 'flag', 'expr')),
  654. ],
  655. 'parenthesis-open': [
  656. include('spaces'),
  657. (r'\(', Punctuation, '#pop'),
  658. ],
  659. 'parenthesis-close': [
  660. include('spaces'),
  661. (r'\)', Punctuation, '#pop'),
  662. ],
  663. 'var': [
  664. include('spaces'),
  665. (ident_no_keyword, Text, ('#pop', 'var-sep', 'assign', 'flag', 'prop-get-set')),
  666. ],
  667. # optional more var decl.
  668. 'var-sep': [
  669. include('spaces'),
  670. (r',', Punctuation, ('#pop', 'var')),
  671. default('#pop'),
  672. ],
  673. # optional assignment
  674. 'assign': [
  675. include('spaces'),
  676. (r'=', Operator, ('#pop', 'expr')),
  677. default('#pop'),
  678. ],
  679. # optional type flag
  680. 'flag': [
  681. include('spaces'),
  682. (r':', Punctuation, ('#pop', 'type')),
  683. default('#pop'),
  684. ],
  685. # colon as part of a ternary operator (?:)
  686. 'ternary': [
  687. include('spaces'),
  688. (r':', Operator, '#pop'),
  689. ],
  690. # function call
  691. 'call': [
  692. include('spaces'),
  693. (r'\)', Punctuation, '#pop'),
  694. default(('#pop', 'call-sep', 'expr')),
  695. ],
  696. # after a call param
  697. 'call-sep': [
  698. include('spaces'),
  699. (r'\)', Punctuation, '#pop'),
  700. (r',', Punctuation, ('#pop', 'call')),
  701. ],
  702. # bracket can be block or object
  703. 'bracket': [
  704. include('spaces'),
  705. (r'(?!(?:\$\s*[a-z]\b|\$(?!'+ident+')))' + ident_no_keyword, Name,
  706. ('#pop', 'bracket-check')),
  707. (r"'", String.Single, ('#pop', 'bracket-check', 'string-single')),
  708. (r'"', String.Double, ('#pop', 'bracket-check', 'string-double')),
  709. default(('#pop', 'block')),
  710. ],
  711. 'bracket-check': [
  712. include('spaces'),
  713. (r':', Punctuation, ('#pop', 'object-sep', 'expr')), # is object
  714. default(('#pop', 'block', 'optional-semicolon', 'expr-chain')), # is block
  715. ],
  716. # code block
  717. 'block': [
  718. include('spaces'),
  719. (r'\}', Punctuation, '#pop'),
  720. default('expr-statement'),
  721. ],
  722. # object in key-value pairs
  723. 'object': [
  724. include('spaces'),
  725. (r'\}', Punctuation, '#pop'),
  726. default(('#pop', 'object-sep', 'expr', 'colon', 'ident-or-string'))
  727. ],
  728. # a key of an object
  729. 'ident-or-string': [
  730. include('spaces'),
  731. (ident_no_keyword, Name, '#pop'),
  732. (r"'", String.Single, ('#pop', 'string-single')),
  733. (r'"', String.Double, ('#pop', 'string-double')),
  734. ],
  735. # after a key-value pair in object
  736. 'object-sep': [
  737. include('spaces'),
  738. (r'\}', Punctuation, '#pop'),
  739. (r',', Punctuation, ('#pop', 'object')),
  740. ],
  741. }
  742. def analyse_text(text):
  743. if re.match(r'\w+\s*:\s*\w', text):
  744. return 0.3
  745. class HxmlLexer(RegexLexer):
  746. """
  747. Lexer for `haXe build <http://haxe.org/doc/compiler>`_ files.
  748. .. versionadded:: 1.6
  749. """
  750. name = 'Hxml'
  751. aliases = ['haxeml', 'hxml']
  752. filenames = ['*.hxml']
  753. tokens = {
  754. 'root': [
  755. # Seperator
  756. (r'(--)(next)', bygroups(Punctuation, Generic.Heading)),
  757. # Compiler switches with one dash
  758. (r'(-)(prompt|debug|v)', bygroups(Punctuation, Keyword.Keyword)),
  759. # Compilerswitches with two dashes
  760. (r'(--)(neko-source|flash-strict|flash-use-stage|no-opt|no-traces|'
  761. r'no-inline|times|no-output)', bygroups(Punctuation, Keyword)),
  762. # Targets and other options that take an argument
  763. (r'(-)(cpp|js|neko|x|as3|swf9?|swf-lib|php|xml|main|lib|D|resource|'
  764. r'cp|cmd)( +)(.+)',
  765. bygroups(Punctuation, Keyword, Whitespace, String)),
  766. # Options that take only numerical arguments
  767. (r'(-)(swf-version)( +)(\d+)',
  768. bygroups(Punctuation, Keyword, Number.Integer)),
  769. # An Option that defines the size, the fps and the background
  770. # color of an flash movie
  771. (r'(-)(swf-header)( +)(\d+)(:)(\d+)(:)(\d+)(:)([A-Fa-f0-9]{6})',
  772. bygroups(Punctuation, Keyword, Whitespace, Number.Integer,
  773. Punctuation, Number.Integer, Punctuation, Number.Integer,
  774. Punctuation, Number.Hex)),
  775. # options with two dashes that takes arguments
  776. (r'(--)(js-namespace|php-front|php-lib|remap|gen-hx-classes)( +)'
  777. r'(.+)', bygroups(Punctuation, Keyword, Whitespace, String)),
  778. # Single line comment, multiline ones are not allowed.
  779. (r'#.*', Comment.Single)
  780. ]
  781. }