rouge 3.16.0 → 3.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rougify +2 -2
  3. data/lib/rouge.rb +67 -53
  4. data/lib/rouge/demos/augeas +16 -0
  5. data/lib/rouge/demos/bibtex +12 -0
  6. data/lib/rouge/demos/brightscript +6 -0
  7. data/lib/rouge/demos/cypher +5 -0
  8. data/lib/rouge/demos/datastudio +21 -0
  9. data/lib/rouge/demos/ecl +18 -0
  10. data/lib/rouge/demos/ghc-cmm +23 -0
  11. data/lib/rouge/demos/hlsl +20 -0
  12. data/lib/rouge/demos/isbl +4 -0
  13. data/lib/rouge/demos/janet +3 -0
  14. data/lib/rouge/demos/livescript +15 -0
  15. data/lib/rouge/demos/rego +8 -0
  16. data/lib/rouge/demos/solidity +13 -0
  17. data/lib/rouge/demos/ssh +4 -0
  18. data/lib/rouge/demos/vcl +12 -0
  19. data/lib/rouge/demos/velocity +9 -0
  20. data/lib/rouge/demos/yang +17 -0
  21. data/lib/rouge/demos/zig +6 -0
  22. data/lib/rouge/lexer.rb +2 -1
  23. data/lib/rouge/lexers/apache.rb +22 -12
  24. data/lib/rouge/lexers/apache/keywords.rb +24 -0
  25. data/lib/rouge/lexers/augeas.rb +93 -0
  26. data/lib/rouge/lexers/batchfile.rb +1 -1
  27. data/lib/rouge/lexers/bibtex.rb +115 -0
  28. data/lib/rouge/lexers/brightscript.rb +147 -0
  29. data/lib/rouge/lexers/cmake.rb +1 -0
  30. data/lib/rouge/lexers/coffeescript.rb +47 -15
  31. data/lib/rouge/lexers/console.rb +53 -37
  32. data/lib/rouge/lexers/cpp.rb +21 -7
  33. data/lib/rouge/lexers/css.rb +3 -1
  34. data/lib/rouge/lexers/cypher.rb +108 -0
  35. data/lib/rouge/lexers/datastudio.rb +138 -0
  36. data/lib/rouge/lexers/diff.rb +1 -1
  37. data/lib/rouge/lexers/docker.rb +1 -1
  38. data/lib/rouge/lexers/ecl.rb +175 -0
  39. data/lib/rouge/lexers/fsharp.rb +1 -0
  40. data/lib/rouge/lexers/ghc_cmm.rb +340 -0
  41. data/lib/rouge/lexers/gherkin.rb +1 -1
  42. data/lib/rouge/lexers/gherkin/keywords.rb +9 -6
  43. data/lib/rouge/lexers/haskell.rb +27 -19
  44. data/lib/rouge/lexers/hlsl.rb +166 -0
  45. data/lib/rouge/lexers/html.rb +7 -7
  46. data/lib/rouge/lexers/isbl.rb +97 -0
  47. data/lib/rouge/lexers/isbl/builtins.rb +17 -0
  48. data/lib/rouge/lexers/janet.rb +217 -0
  49. data/lib/rouge/lexers/javascript.rb +4 -4
  50. data/lib/rouge/lexers/jinja.rb +22 -7
  51. data/lib/rouge/lexers/json.rb +3 -0
  52. data/lib/rouge/lexers/json_doc.rb +1 -0
  53. data/lib/rouge/lexers/jsx.rb +47 -59
  54. data/lib/rouge/lexers/julia.rb +4 -2
  55. data/lib/rouge/lexers/kotlin.rb +14 -2
  56. data/lib/rouge/lexers/lasso.rb +11 -12
  57. data/lib/rouge/lexers/lasso/keywords.rb +20 -0
  58. data/lib/rouge/lexers/livescript.rb +310 -0
  59. data/lib/rouge/lexers/llvm.rb +6 -33
  60. data/lib/rouge/lexers/llvm/keywords.rb +25 -0
  61. data/lib/rouge/lexers/lua.rb +2 -2
  62. data/lib/rouge/lexers/lua/keywords.rb +28 -0
  63. data/lib/rouge/lexers/markdown.rb +9 -5
  64. data/lib/rouge/lexers/mathematica.rb +2 -2
  65. data/lib/rouge/lexers/mathematica/keywords.rb +17 -0
  66. data/lib/rouge/lexers/matlab.rb +3 -4
  67. data/lib/rouge/lexers/matlab/builtins.rb +11 -0
  68. data/lib/rouge/lexers/matlab/keywords.rb +15 -0
  69. data/lib/rouge/lexers/nasm.rb +42 -168
  70. data/lib/rouge/lexers/opentype_feature_file.rb +27 -42
  71. data/lib/rouge/lexers/pascal.rb +1 -1
  72. data/lib/rouge/lexers/perl.rb +21 -3
  73. data/lib/rouge/lexers/php.rb +48 -33
  74. data/lib/rouge/lexers/php/keywords.rb +202 -0
  75. data/lib/rouge/lexers/powershell.rb +5 -3
  76. data/lib/rouge/lexers/python.rb +58 -57
  77. data/lib/rouge/lexers/racket.rb +24 -1
  78. data/lib/rouge/lexers/rego.rb +60 -0
  79. data/lib/rouge/lexers/ruby.rb +16 -3
  80. data/lib/rouge/lexers/sass/common.rb +1 -0
  81. data/lib/rouge/lexers/scala.rb +1 -1
  82. data/lib/rouge/lexers/solidity.rb +185 -0
  83. data/lib/rouge/lexers/sparql.rb +5 -4
  84. data/lib/rouge/lexers/sqf.rb +2 -2
  85. data/lib/rouge/lexers/sqf/keywords.rb +12 -0
  86. data/lib/rouge/lexers/ssh.rb +33 -0
  87. data/lib/rouge/lexers/terraform.rb +15 -0
  88. data/lib/rouge/lexers/tsx.rb +10 -3
  89. data/lib/rouge/lexers/turtle.rb +1 -1
  90. data/lib/rouge/lexers/twig.rb +4 -4
  91. data/lib/rouge/lexers/typescript.rb +1 -8
  92. data/lib/rouge/lexers/typescript/common.rb +18 -4
  93. data/lib/rouge/lexers/varnish.rb +53 -16
  94. data/lib/rouge/lexers/velocity.rb +71 -0
  95. data/lib/rouge/lexers/viml.rb +6 -38
  96. data/lib/rouge/lexers/viml/keywords.rb +11 -4
  97. data/lib/rouge/lexers/vue.rb +4 -1
  98. data/lib/rouge/lexers/xml.rb +5 -3
  99. data/lib/rouge/lexers/yaml.rb +5 -3
  100. data/lib/rouge/lexers/yang.rb +147 -0
  101. data/lib/rouge/lexers/zig.rb +139 -0
  102. data/lib/rouge/version.rb +1 -1
  103. metadata +47 -10
  104. data/lib/rouge/demos/varnish +0 -55
  105. data/lib/rouge/lexers/apache/keywords.yml +0 -764
  106. data/lib/rouge/lexers/lasso/keywords.yml +0 -446
  107. data/lib/rouge/lexers/lua/builtins.rb +0 -24
  108. data/lib/rouge/lexers/mathematica/builtins.rb +0 -13
  109. data/lib/rouge/lexers/matlab/builtins.yml +0 -3515
  110. data/lib/rouge/lexers/php/builtins.rb +0 -203
  111. data/lib/rouge/lexers/sqf/commands.rb +0 -15
@@ -165,6 +165,7 @@ module Rouge
165
165
  end
166
166
 
167
167
  state :parameters do
168
+ rule %r/`./m, Str::Escape
168
169
  rule %r/\s*?\n/, Text::Whitespace, :pop!
169
170
  rule %r/[;(){}\]]/, Punctuation, :pop!
170
171
  rule %r/[|=]/, Operator, :pop!
@@ -201,7 +202,7 @@ module Rouge
201
202
  rule %r/(?:#{KEYWORDS})\b(?![-.])/i, Keyword::Reserved
202
203
 
203
204
  rule %r/-{1,2}\w+/, Name::Tag
204
-
205
+
205
206
  rule %r/(\.)?([-\w]+)(\[)/ do |m|
206
207
  groups Operator, Name::Function, Punctuation
207
208
  push :bracket
@@ -209,14 +210,15 @@ module Rouge
209
210
 
210
211
  rule %r/([\/\\~\w][-.:\/\\~\w]*)(\n)?/ do |m|
211
212
  groups Name::Function, Text::Whitespace
212
- push :parameters unless m[2]
213
+ push :parameters
213
214
  end
214
215
 
215
216
  rule %r/(\.)?([-\w]+)(?:(\()|(\n))?/ do |m|
216
217
  groups Operator, Name::Function, Punctuation, Text::Whitespace
217
- push :parameters unless m[3]
218
+ push :parameters unless m[3].nil?
218
219
  end
219
220
 
221
+ rule %r/\?/, Name::Function, :parameters
220
222
  rule %r/[-+*\/%=!.&|]/, Operator
221
223
  rule %r/@\{/, Punctuation, :hasht
222
224
  rule %r/@\(/, Punctuation, :array
@@ -67,8 +67,13 @@ module Rouge
67
67
  )
68
68
  end
69
69
 
70
- identifier = /[a-z_][a-z0-9_]*/i
71
- dotted_identifier = /[a-z_.][a-z0-9_.]*/i
70
+ identifier = /[[:alpha:]_][[:alnum:]_]*/
71
+ dotted_identifier = /[[:alpha:]_.][[:alnum:]_.]*/
72
+
73
+ def current_string
74
+ @string_register ||= StringRegister.new
75
+ end
76
+
72
77
  state :root do
73
78
  rule %r/\n+/m, Text
74
79
  rule %r/^(:)(\s*)([ru]{,2}""".*?""")/mi do
@@ -77,14 +82,13 @@ module Rouge
77
82
 
78
83
  rule %r/[^\S\n]+/, Text
79
84
  rule %r(#(.*)?\n?), Comment::Single
80
- rule %r/[\[\]{}:(),;]/, Punctuation
85
+ rule %r/[\[\]{}:(),;.]/, Punctuation
81
86
  rule %r/\\\n/, Text
82
87
  rule %r/\\/, Text
83
88
 
84
89
  rule %r/(in|is|and|or|not)\b/, Operator::Word
85
90
  rule %r/(<<|>>|\/\/|\*\*)=?/, Operator
86
91
  rule %r/[-~+\/*%=<>&^|@]=?|!=/, Operator
87
- rule %r/\.(?![0-9])/, Operator # so it doesn't match float literals
88
92
 
89
93
  rule %r/(from)((?:\\\s|\s)+)(#{dotted_identifier})((?:\\\s|\s)+)(import)/ do
90
94
  groups Keyword::Namespace,
@@ -110,14 +114,11 @@ module Rouge
110
114
 
111
115
  # TODO: not in python 3
112
116
  rule %r/`.*?`/, Str::Backtick
113
- rule %r/(?:r|ur|ru)"""/i, Str, :raw_tdqs
114
- rule %r/(?:r|ur|ru)'''/i, Str, :raw_tsqs
115
- rule %r/(?:r|ur|ru)"/i, Str, :raw_dqs
116
- rule %r/(?:r|ur|ru)'/i, Str, :raw_sqs
117
- rule %r/u?"""/i, Str, :tdqs
118
- rule %r/u?'''/i, Str, :tsqs
119
- rule %r/u?"/i, Str, :dqs
120
- rule %r/u?'/i, Str, :sqs
117
+ rule %r/([rfbu]{0,2})('''|"""|['"])/i do |m|
118
+ token Str
119
+ current_string.register type: m[1].downcase, delim: m[2]
120
+ push :generic_string
121
+ end
121
122
 
122
123
  rule %r/@#{dotted_identifier}/i, Name::Decorator
123
124
 
@@ -173,76 +174,76 @@ module Rouge
173
174
  mixin :raise
174
175
  end
175
176
 
176
- state :strings do
177
- rule %r/%(\([a-z0-9_]+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?/i, Str::Interpol
178
- end
177
+ state :generic_string do
178
+ rule %r/[^'"\\{]+/, Str
179
+ rule %r/{{/, Str
179
180
 
180
- state :strings_double do
181
- rule %r/[^\\"%\n]+/, Str
182
- mixin :strings
183
- end
181
+ rule %r/'''|"""|['"]/ do |m|
182
+ token Str
183
+ if current_string.delim? m[0]
184
+ current_string.remove
185
+ pop!
186
+ end
187
+ end
184
188
 
185
- state :strings_single do
186
- rule %r/[^\\'%\n]+/, Str
187
- mixin :strings
188
- end
189
+ rule %r/(?=\\)/, Str, :generic_escape
189
190
 
190
- state :nl do
191
- rule %r/\n/, Str
191
+ rule %r/{/ do |m|
192
+ if current_string.type? "f"
193
+ token Str::Interpol
194
+ push :generic_interpol
195
+ else
196
+ token Str
197
+ end
198
+ end
192
199
  end
193
200
 
194
- state :escape do
201
+ state :generic_escape do
195
202
  rule %r(\\
196
203
  ( [\\abfnrtv"']
197
204
  | \n
205
+ | newline
198
206
  | N{[a-zA-Z][a-zA-Z ]+[a-zA-Z]}
199
207
  | u[a-fA-F0-9]{4}
200
208
  | U[a-fA-F0-9]{8}
201
209
  | x[a-fA-F0-9]{2}
202
210
  | [0-7]{1,3}
203
211
  )
204
- )x, Str::Escape
205
- end
212
+ )x do
213
+ current_string.type?("r") ? token(Str) : token(Str::Escape)
214
+ pop!
215
+ end
206
216
 
207
- state :raw_escape do
208
- rule %r/\\./, Str
217
+ rule %r/\\./, Str, :pop!
209
218
  end
210
219
 
211
- state :dqs do
212
- rule %r/"/, Str, :pop!
213
- mixin :escape
214
- mixin :strings_double
220
+ state :generic_interpol do
221
+ rule %r/[^{}]+/ do |m|
222
+ recurse m[0]
223
+ end
224
+ rule %r/{/, Str::Interpol, :generic_interpol
225
+ rule %r/}/, Str::Interpol, :pop!
215
226
  end
216
227
 
217
- state :sqs do
218
- rule %r/'/, Str, :pop!
219
- mixin :escape
220
- mixin :strings_single
221
- end
228
+ class StringRegister < Array
229
+ def delim?(delim)
230
+ self.last[1] == delim
231
+ end
222
232
 
223
- state :tdqs do
224
- rule %r/"""/, Str, :pop!
225
- rule %r/"/, Str
226
- mixin :escape
227
- mixin :strings_double
228
- mixin :nl
229
- end
233
+ def register(type: "u", delim: "'")
234
+ self.push [type, delim]
235
+ end
230
236
 
231
- state :tsqs do
232
- rule %r/'''/, Str, :pop!
233
- rule %r/'/, Str
234
- mixin :escape
235
- mixin :strings_single
236
- mixin :nl
237
- end
237
+ def remove
238
+ self.pop
239
+ end
238
240
 
239
- %w(tdqs tsqs dqs sqs).each do |qtype|
240
- state :"raw_#{qtype}" do
241
- mixin :raw_escape
242
- mixin :"#{qtype}"
241
+ def type?(type)
242
+ self.last[0].include? type
243
243
  end
244
244
  end
245
245
 
246
+ private_constant :StringRegister
246
247
  end
247
248
  end
248
249
  end
@@ -488,6 +488,9 @@ module Rouge
488
488
  state :root do
489
489
  # comments
490
490
  rule %r/;.*$/, Comment::Single
491
+ rule %r/#!.*/, Comment::Single
492
+ rule %r/#\|/, Comment::Multiline, :block_comment
493
+ rule %r/#;/, Comment::Multiline, :sexp_comment
491
494
  rule %r/\s+/m, Text
492
495
 
493
496
  rule %r/[+-]inf[.][f0]/, Num::Float
@@ -510,7 +513,7 @@ module Rouge
510
513
  rule %r/['`]#{id}/i, Str::Symbol
511
514
  rule %r/#\\([()\/'"._!\$%& ?=+-]{1}|[a-z0-9]+)/i,
512
515
  Str::Char
513
- rule %r/#t|#f/, Name::Constant
516
+ rule %r/#t(rue)?|#f(alse)?/i, Name::Constant
514
517
  rule %r/(?:'|#|`|,@|,|\.)/, Operator
515
518
 
516
519
  rule %r/(['#])(\s*)(\()/m do
@@ -524,6 +527,26 @@ module Rouge
524
527
  rule id, Name::Variable
525
528
  end
526
529
 
530
+ state :block_comment do
531
+ rule %r/[^|#]+/, Comment::Multiline
532
+ rule %r/\|#/, Comment::Multiline, :pop!
533
+ rule %r/#\|/, Comment::Multiline, :block_comment
534
+ rule %r/[|#]/, Comment::Multiline
535
+ end
536
+
537
+ state :sexp_comment do
538
+ rule %r/[({\[]/, Comment::Multiline, :sexp_comment_inner
539
+ rule %r/"(?:\\"|[^"])*?"/, Comment::Multiline, :pop!
540
+ rule %r/[^\s]+/, Comment::Multiline, :pop!
541
+ rule(//) { pop! }
542
+ end
543
+
544
+ state :sexp_comment_inner do
545
+ rule %r/[^(){}\[\]]+/, Comment::Multiline
546
+ rule %r/[)}\]]/, Comment::Multiline, :pop!
547
+ rule %r/[({\[]/, Comment::Multiline, :sexp_comment_inner
548
+ end
549
+
527
550
  state :command do
528
551
  rule id, Name::Function do |m|
529
552
  if self.class.keywords.include? m[0]
@@ -0,0 +1,60 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ class Rego < RegexLexer
7
+ title "Rego"
8
+ desc "The Rego open-policy-agent (OPA) policy language (openpolicyagent.org)"
9
+ tag 'rego'
10
+ filenames '*.rego'
11
+
12
+ def self.constants
13
+ @constants ||= Set.new %w(
14
+ true false null
15
+ )
16
+ end
17
+
18
+ def self.operators
19
+ @operators ||= Set.new %w(
20
+ as default else import not package some with
21
+ )
22
+ end
23
+
24
+ state :basic do
25
+ rule %r/\s+/, Text
26
+ rule %r/#.*/, Comment::Single
27
+
28
+ rule %r/[\[\](){}|.,;!]/, Punctuation
29
+
30
+ rule %r/"[^"]*"/, Str::Double
31
+
32
+ rule %r/-?\d+\.\d+([eE][+-]?\d+)?/, Num::Float
33
+ rule %r/-?\d+([eE][+-]?\d+)?/, Num
34
+
35
+ rule %r/\\u[0-9a-fA-F]{4}/, Num::Hex
36
+ rule %r/\\["\/bfnrt]/, Str::Escape
37
+ end
38
+
39
+ state :operators do
40
+ rule %r/(=|!=|>=|<=|>|<|\+|-|\*|%|\/|\||&|:=)/, Operator
41
+ rule %r/[\/:?@^~]+/, Operator
42
+ end
43
+
44
+ state :root do
45
+ mixin :basic
46
+ mixin :operators
47
+
48
+ rule %r/[[:word:]]+/ do |m|
49
+ if self.class.constants.include? m[0]
50
+ token Keyword::Constant
51
+ elsif self.class.operators.include? m[0]
52
+ token Operator::Word
53
+ else
54
+ token Name
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -170,8 +170,11 @@ module Rouge
170
170
  rule %r/0_?[0-7]+(?:_[0-7]+)*/, Num::Oct
171
171
  rule %r/0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/, Num::Hex
172
172
  rule %r/0b[01]+(?:_[01]+)*/, Num::Bin
173
- rule %r/\d+\.\d+(e[\+\-]?\d+)?/, Num::Float
174
- rule %r/[\d]+(?:_\d+)*/, Num::Integer
173
+
174
+ decimal = %r/[\d]+(?:_\d+)*/
175
+ exp = %r/e[+-]?\d+/i
176
+ rule %r/#{decimal}(?:\.#{decimal}#{exp}?|#{exp})/, Num::Float
177
+ rule decimal, Num::Integer
175
178
 
176
179
  # names
177
180
  rule %r/@@[a-z_]\w*/i, Name::Variable::Class
@@ -306,6 +309,8 @@ module Rouge
306
309
 
307
310
  state :classname do
308
311
  rule %r/\s+/, Text
312
+ rule %r/\w+(::\w+)+/, Name::Class
313
+
309
314
  rule %r/\(/ do
310
315
  token Punctuation
311
316
  push :defexpr
@@ -324,7 +329,15 @@ module Rouge
324
329
  end
325
330
 
326
331
  state :ternary do
327
- rule(/:(?!:)/) { token Punctuation; goto :expr_start }
332
+ rule %r/(:)(\s+)/ do
333
+ groups Punctuation, Text
334
+ goto :expr_start
335
+ end
336
+
337
+ rule %r/:(?![^#\n]*?[:\\])/ do
338
+ token Punctuation
339
+ goto :expr_start
340
+ end
328
341
 
329
342
  mixin :root
330
343
  end
@@ -29,6 +29,7 @@ module Rouge
29
29
  end
30
30
 
31
31
  rule %r/@#{id}/, Keyword, :selector
32
+ rule %r/&/, Keyword, :selector
32
33
 
33
34
  # $variable: assignment
34
35
  rule %r/([$]#{id})([ \t]*)(:)/ do
@@ -40,7 +40,7 @@ module Rouge
40
40
  groups Keyword, Text
41
41
  push :class
42
42
  end
43
- rule %r/'#{idrest}[^']/, Str::Symbol
43
+ rule %r/'#{idrest}(?!')/, Str::Symbol
44
44
  rule %r/[^\S\n]+/, Text
45
45
 
46
46
  rule %r(//.*), Comment::Single
@@ -0,0 +1,185 @@
1
+ # -*- coding: utf-8 -*- #
2
+
3
+ module Rouge
4
+ module Lexers
5
+ class Solidity < RegexLexer
6
+ title "Solidity"
7
+ desc "Solidity, an Ethereum smart contract programming language"
8
+ tag 'solidity'
9
+ filenames '*.sol', '*.solidity'
10
+ mimetypes 'text/x-solidity'
11
+
12
+ # optional comment or whitespace
13
+ ws = %r((?:\s|//.*?\n|/[*].*?[*]/)+)
14
+ id = /[a-zA-Z$_][\w$_]*/
15
+
16
+ def self.detect?(text)
17
+ return true if text.start_with? 'pragma solidity'
18
+ end
19
+
20
+ # TODO: seperate by "type"
21
+ def self.keywords
22
+ @keywords ||= Set.new %w(
23
+ abstract anonymous as assembly break catch calldata constant
24
+ constructor continue contract do delete else emit enum event
25
+ external fallback for function hex if indexed interface
26
+ internal import is library mapping memory modifier new
27
+ override payable public pure pragma private receive return
28
+ returns storage struct throw try type using var view virtual
29
+ while
30
+ )
31
+ end
32
+
33
+ def self.builtins
34
+ return @builtins if @builtins
35
+
36
+ @builtins = Set.new %w(
37
+ now
38
+ false true
39
+ balance now selector super this
40
+ blockhash gasleft
41
+ assert require revert
42
+ selfdestruct suicide
43
+ call callcode delegatecall
44
+ send transfer
45
+ addmod ecrecover keccak256 mulmod sha256 sha3 ripemd160
46
+ )
47
+
48
+ # TODO: use (currently shadowed by catch-all in :statements)
49
+ abi = %w(decode encode encodePacked encodeWithSelector encodeWithSignature)
50
+ @builtins.merge( abi.map { |i| "abi.#{i}" } )
51
+ block = %w(coinbase difficulty gaslimit hash number timestamp)
52
+ @builtins.merge( block.map { |i| "block.#{i}" } )
53
+ msg = %w(data gas sender sig value)
54
+ @builtins.merge( msg.map { |i| "msg.#{i}" } )
55
+ tx = %w(gasprice origin)
56
+ @builtins.merge( tx.map { |i| "tx.#{i}" } )
57
+ end
58
+
59
+ def self.constants
60
+ @constants ||= Set.new %w(
61
+ wei finney szabo ether
62
+ seconds minutes hours days weeks years
63
+ )
64
+ end
65
+
66
+ def self.keywords_type
67
+ @keywords_type ||= Set.new %w(
68
+ address bool byte bytes int string uint
69
+ )
70
+ end
71
+
72
+ def self.reserved
73
+ @reserved ||= Set.new %w(
74
+ alias after apply auto case copyof default define final fixed
75
+ immutable implements in inline let macro match mutable null of
76
+ partial promise reference relocatable sealed sizeof static
77
+ supports switch typedef typeof ufixed unchecked
78
+ )
79
+ end
80
+
81
+ start { push :bol }
82
+
83
+ state :expr_bol do
84
+ mixin :inline_whitespace
85
+
86
+ rule(//) { pop! }
87
+ end
88
+
89
+ # :expr_bol is the same as :bol but without labels, since
90
+ # labels can only appear at the beginning of a statement.
91
+ state :bol do
92
+ mixin :expr_bol
93
+ end
94
+
95
+ # TODO: natspec in comments
96
+ state :inline_whitespace do
97
+ rule %r/[ \t\r]+/, Text
98
+ rule %r/\\\n/, Text # line continuation
99
+ rule %r(/\*), Comment::Multiline, :comment_multi
100
+ end
101
+
102
+ state :whitespace do
103
+ rule %r/\n+/m, Text, :bol
104
+ rule %r(//(\\.|.)*?\n), Comment::Single, :bol
105
+ mixin :inline_whitespace
106
+ end
107
+
108
+ state :expr_whitespace do
109
+ rule %r/\n+/m, Text, :expr_bol
110
+ mixin :whitespace
111
+ end
112
+
113
+ state :statements do
114
+ mixin :whitespace
115
+ rule %r/(hex)?\"/, Str, :string_double
116
+ rule %r/(hex)?\'/, Str, :string_single
117
+ rule %r('(\\.|\\[0-7]{1,3}|\\x[a-f0-9]{1,2}|[^\\'\n])')i, Str::Char
118
+ rule %r/\d\d*\.\d+([eE]\d+)?/i, Num::Float
119
+ rule %r/0x[0-9a-f]+/i, Num::Hex
120
+ rule %r/\d+([eE]\d+)?/i, Num::Integer
121
+ rule %r(\*/), Error
122
+ rule %r([~!%^&*+=\|?:<>/-]), Operator
123
+ rule %r/[()\[\],.]/, Punctuation
124
+ rule %r/u?fixed\d+x\d+/, Keyword::Reserved
125
+ rule %r/bytes\d+/, Keyword::Type
126
+ rule %r/u?int\d+/, Keyword::Type
127
+ rule id do |m|
128
+ name = m[0]
129
+
130
+ if self.class.keywords.include? name
131
+ token Keyword
132
+ elsif self.class.builtins.include? name
133
+ token Name::Builtin
134
+ elsif self.class.constants.include? name
135
+ token Keyword::Constant
136
+ elsif self.class.keywords_type.include? name
137
+ token Keyword::Type
138
+ elsif self.class.reserved.include? name
139
+ token Keyword::Reserved
140
+ else
141
+ token Name
142
+ end
143
+ end
144
+ end
145
+
146
+ state :root do
147
+ mixin :expr_whitespace
148
+ rule(//) { push :statement }
149
+ # TODO: function declarations
150
+ end
151
+
152
+ state :statement do
153
+ rule %r/;/, Punctuation, :pop!
154
+ mixin :expr_whitespace
155
+ mixin :statements
156
+ rule %r/[{}]/, Punctuation
157
+ end
158
+
159
+ state :string_common do
160
+ rule %r/\\(u[a-fA-F0-9]{4}|x..|[^x])/, Str::Escape
161
+ rule %r/[^\\\"\'\n]+/, Str
162
+ rule %r/\\\n/, Str # line continuation
163
+ rule %r/\\/, Str # stray backslash
164
+ end
165
+
166
+ state :string_double do
167
+ mixin :string_common
168
+ rule %r/\"/, Str, :pop!
169
+ rule %r/\'/, Str
170
+ end
171
+
172
+ state :string_single do
173
+ mixin :string_common
174
+ rule %r/\'/, Str, :pop!
175
+ rule %r/\"/, Str
176
+ end
177
+
178
+ state :comment_multi do
179
+ rule %r(\*/), Comment::Multiline, :pop!
180
+ rule %r([^*/]+), Comment::Multiline
181
+ rule %r([*/]), Comment::Multiline
182
+ end
183
+ end
184
+ end
185
+ end