haxe.py 30 KB

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