19
19
*/
20
20
package org .sonar .objectivec .lexer ;
21
21
22
+ import com .sonar .sslr .api .GenericTokenType ;
22
23
import com .sonar .sslr .impl .Lexer ;
23
24
import com .sonar .sslr .impl .channel .BlackHoleChannel ;
24
25
import com .sonar .sslr .impl .channel .IdentifierAndKeywordChannel ;
27
28
import org .sonar .objectivec .api .ObjectiveCKeyword ;
28
29
import org .sonar .objectivec .api .ObjectiveCPunctuator ;
29
30
30
- import static com .sonar .sslr .api .GenericTokenType .LITERAL ;
31
31
import static com .sonar .sslr .impl .channel .RegexpChannelBuilder .commentRegexp ;
32
32
import static com .sonar .sslr .impl .channel .RegexpChannelBuilder .regexp ;
33
+ import static org .sonar .objectivec .api .ObjectiveCTokenType .DOUBLE_LITERAL ;
34
+ import static org .sonar .objectivec .api .ObjectiveCTokenType .FLOAT_LITERAL ;
35
+ import static org .sonar .objectivec .api .ObjectiveCTokenType .INTEGER_LITERAL ;
36
+ import static org .sonar .objectivec .api .ObjectiveCTokenType .LONG_LITERAL ;
33
37
34
38
public class ObjectiveCLexer {
39
+ private static final String EXP_REGEXP = "(?:[Ee][+-]?+[0-9_]++)" ;
40
+ private static final String BINARY_EXP_REGEXP = "(?:[Pp][+-]?+[0-9_]++)" ;
41
+ private static final String FLOATING_LITERAL_WITHOUT_SUFFIX_REGEXP = "(?:" +
42
+ // Decimal
43
+ "[0-9][0-9_]*+\\ .([0-9_]++)?+" + EXP_REGEXP + "?+" +
44
+ "|" + "\\ .[0-9][0-9_]*+" + EXP_REGEXP + "?+" +
45
+ "|" + "[0-9][0-9_]*+" + EXP_REGEXP +
46
+ // Hexadecimal
47
+ "|" + "0[xX][0-9_a-fA-F]++\\ .[0-9_a-fA-F]*+" + BINARY_EXP_REGEXP +
48
+ "|" + "0[xX][0-9_a-fA-F]++" + BINARY_EXP_REGEXP +
49
+ ")" ;
50
+ private static final String INTEGER_LITERAL_REGEXP = "(?:" +
51
+ // Hexadecimal
52
+ "0[xX][0-9_a-fA-F]++" +
53
+ // Binary (Java 7)
54
+ "|" + "0[bB][01_]++" +
55
+ // Decimal and Octal
56
+ "|" + "[0-9][0-9_]*+" +
57
+ ")" ;
35
58
36
59
private ObjectiveCLexer () {
37
60
// prevents outside instantiation
@@ -44,23 +67,37 @@ public static Lexer create() {
44
67
public static Lexer create (ObjectiveCConfiguration conf ) {
45
68
return Lexer .builder ()
46
69
.withCharset (conf .getCharset ())
70
+ .withFailIfNoChannelToConsumeOneCharacter (true )
47
71
48
- .withFailIfNoChannelToConsumeOneCharacter (false )
72
+ /* Remove whitespace */
73
+ .withChannel (new BlackHoleChannel ("\\ s++" ))
49
74
50
75
/* Comments */
51
76
.withChannel (commentRegexp ("//[^\\ n\\ r]*+" ))
52
- .withChannel (commentRegexp ("/\\ *[\\ s\\ S]*?\\ */" ))
77
+ .withChannel (commentRegexp ("/\\ *" , "[\\ s\\ S]*?" , "\\ */" ))
78
+
79
+ /* Backslash at the end of the line: just throw away */
80
+ .withChannel (new BackslashChannel ())
81
+
82
+ /* Character literals */
83
+ .withChannel (new CharacterLiteralsChannel ())
84
+
85
+ /* String literals */
86
+ .withChannel (new StringLiteralsChannel ())
87
+
88
+ /* Number literals */
89
+ .withChannel (regexp (FLOAT_LITERAL , FLOATING_LITERAL_WITHOUT_SUFFIX_REGEXP + "[fF]|[0-9][0-9_]*+[fF]" ))
90
+ .withChannel (regexp (DOUBLE_LITERAL , FLOATING_LITERAL_WITHOUT_SUFFIX_REGEXP + "[dD]?+|[0-9][0-9_]*+[dD]" ))
91
+ .withChannel (regexp (LONG_LITERAL , INTEGER_LITERAL_REGEXP + "[lL]" ))
92
+ .withChannel (regexp (INTEGER_LITERAL , INTEGER_LITERAL_REGEXP ))
53
93
54
94
/* Identifiers, keywords, and punctuators */
55
- .withChannel (new IdentifierAndKeywordChannel ("(#|@) ?[a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?+((\\ s+)?\\ *)?" , true , ObjectiveCKeyword .values ()))
95
+ .withChannel (new IdentifierAndKeywordChannel ("[#@] ?[a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?+((\\ s+)?\\ *)?" , true , ObjectiveCKeyword .values ()))
56
96
.withChannel (new PunctuatorChannel (ObjectiveCPunctuator .values ()))
57
97
58
- /* All other tokens */
59
- .withChannel (regexp (LITERAL , "[^\r \n \\ s/]+" ))
60
-
61
- .withChannel (new BlackHoleChannel ("[\\ s]" ))
98
+ /* All other tokens -- must be last channel */
99
+ .withChannel (regexp (GenericTokenType .IDENTIFIER , "[^\r \n \\ s/]+" ))
62
100
63
101
.build ();
64
102
}
65
-
66
103
}
0 commit comments