1
1
module CodeRay
2
2
module Scanners
3
-
3
+
4
4
# Scanner for Go, copy from c
5
5
class Go < Scanner
6
-
6
+
7
7
register_for :go
8
8
file_extension 'go'
9
-
9
+
10
10
# http://golang.org/ref/spec#Keywords
11
11
KEYWORDS = [
12
12
'break' , 'default' , 'func' , 'interface' , 'select' ,
@@ -15,7 +15,7 @@ class Go < Scanner
15
15
'const' , 'fallthrough' , 'if' , 'range' , 'type' ,
16
16
'continue' , 'for' , 'import' , 'return' , 'var' ,
17
17
] # :nodoc:
18
-
18
+
19
19
# http://golang.org/ref/spec#Types
20
20
PREDEFINED_TYPES = [
21
21
'bool' ,
@@ -26,59 +26,59 @@ class Go < Scanner
26
26
'byte' , 'rune' ,
27
27
'uint' , 'int' , 'uintptr' ,
28
28
] # :nodoc:
29
-
29
+
30
30
PREDEFINED_CONSTANTS = [
31
31
'nil' , 'iota' ,
32
32
'true' , 'false' ,
33
33
] # :nodoc:
34
-
34
+
35
35
DIRECTIVES = [
36
36
'go_no_directive' , # Seems no directive concept in Go?
37
37
] # :nodoc:
38
-
38
+
39
39
IDENT_KIND = WordList . new ( :ident ) .
40
40
add ( KEYWORDS , :keyword ) .
41
41
add ( PREDEFINED_TYPES , :predefined_type ) .
42
42
add ( DIRECTIVES , :directive ) .
43
43
add ( PREDEFINED_CONSTANTS , :predefined_constant ) # :nodoc:
44
-
44
+
45
45
ESCAPE = / [rbfntv\n \\ '"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc:
46
46
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc:
47
-
48
- protected
49
-
47
+
48
+ protected
49
+
50
50
def scan_tokens encoder , options
51
-
51
+
52
52
state = :initial
53
53
label_expected = true
54
54
case_expected = false
55
55
label_expected_before_preproc_line = nil
56
56
in_preproc_line = false
57
-
57
+
58
58
until eos?
59
-
59
+
60
60
case state
61
-
61
+
62
62
when :initial
63
-
63
+
64
64
if match = scan ( / \s + | \\ \n /x )
65
65
if in_preproc_line && match != "\\ \n " && match . index ( ?\n)
66
66
in_preproc_line = false
67
67
label_expected = label_expected_before_preproc_line
68
68
end
69
69
encoder . text_token match , :space
70
-
70
+
71
71
elsif match = scan ( %r! // [^\n \\ ]* (?: \\ . [^\n \\ ]* )* | /\* (?: .*? \* / | .* ) !mx )
72
72
encoder . text_token match , :comment
73
-
73
+
74
74
elsif match = scan ( / [-+*=<>?:;,!&^|()\[ \] {}~%]+ | \/ =? | \. (?!\d ) /x )
75
75
label_expected = match =~ /[;\{ \} ]/
76
76
if case_expected
77
77
label_expected = true if match == ':'
78
78
case_expected = false
79
79
end
80
80
encoder . text_token match , :operator
81
-
81
+
82
82
elsif match = scan ( / [A-Za-z_][A-Za-z_0-9]* /x )
83
83
kind = IDENT_KIND [ match ]
84
84
if kind == :ident && label_expected && !in_preproc_line && scan ( /:(?!:)/ )
@@ -94,7 +94,7 @@ def scan_tokens encoder, options
94
94
end
95
95
end
96
96
encoder . text_token match , kind
97
-
97
+
98
98
elsif match = scan ( /L?"/ )
99
99
encoder . begin_group :string
100
100
if match [ 0 ] == ?L
@@ -107,41 +107,41 @@ def scan_tokens encoder, options
107
107
elsif match = scan ( / \# \s * if \s * 0 /x )
108
108
match << scan_until ( / ^\# (?:elif|else|endif) .*? $ | \z /xm ) unless eos?
109
109
encoder . text_token match , :comment
110
-
110
+
111
111
elsif match = scan ( /#[ \t ]*(\w *)/ )
112
112
encoder . text_token match , :preprocessor
113
113
in_preproc_line = true
114
114
label_expected_before_preproc_line = label_expected
115
115
state = :include_expected if self [ 1 ] == 'include'
116
-
116
+
117
117
elsif match = scan ( / L?' (?: [^\' \n \\ ] | \\ #{ ESCAPE } )? '? /ox )
118
118
label_expected = false
119
119
encoder . text_token match , :char
120
-
120
+
121
121
elsif match = scan ( /\$ / )
122
122
encoder . text_token match , :ident
123
-
123
+
124
124
elsif match = scan ( /0[xX][0-9A-Fa-f]+/ )
125
125
label_expected = false
126
126
encoder . text_token match , :hex
127
-
127
+
128
128
elsif match = scan ( /(?:0[0-7]+)(?![89.eEfF])/ )
129
129
label_expected = false
130
130
encoder . text_token match , :octal
131
-
131
+
132
132
elsif match = scan ( /(?:\d +)(?![.eEfF])L?L?/ )
133
133
label_expected = false
134
134
encoder . text_token match , :integer
135
-
135
+
136
136
elsif match = scan ( /\d [fF]?|\d *\. \d +(?:[eE][+-]?\d +)?[fF]?|\d +[eE][+-]?\d +[fF]?/ )
137
137
label_expected = false
138
138
encoder . text_token match , :float
139
-
139
+
140
140
else
141
141
encoder . text_token getch , :error
142
-
142
+
143
143
end
144
-
144
+
145
145
when :string
146
146
if match = scan ( /[^\\ \n "]+/ )
147
147
encoder . text_token match , :content
@@ -160,36 +160,36 @@ def scan_tokens encoder, options
160
160
else
161
161
raise_inspect "else case \" reached; %p not handled." % peek ( 1 ) , encoder
162
162
end
163
-
163
+
164
164
when :include_expected
165
165
if match = scan ( /<[^>\n ]+>?|"[^"\n \\ ]*(?:\\ .[^"\n \\ ]*)*"?/ )
166
166
encoder . text_token match , :include
167
167
state = :initial
168
-
168
+
169
169
elsif match = scan ( /\s +/ )
170
170
encoder . text_token match , :space
171
171
state = :initial if match . index ?\n
172
-
172
+
173
173
else
174
174
state = :initial
175
-
175
+
176
176
end
177
-
177
+
178
178
else
179
179
raise_inspect 'Unknown state' , encoder
180
-
180
+
181
181
end
182
-
182
+
183
183
end
184
-
184
+
185
185
if state == :string
186
186
encoder . end_group :string
187
187
end
188
-
188
+
189
189
encoder
190
190
end
191
-
191
+
192
192
end
193
-
193
+
194
194
end
195
195
end
0 commit comments