Skip to content

Commit 1074a2a

Browse files
authored
fix(Kotlin): Number literals (#1139)
There are some quite a few ways numbers can be expressed in Kotlin which previously weren't supported and with this commit conforms to the grammar described in the [Kotlin Language Specification](https://kotlinlang.org/spec/syntax-and-grammar.html#literals). ### Separators Like Java Kotlin allows any amount of separators inside number literals, as long as they don't appear at the start or end. ```Kotlin 9_000 1__2 1_2.3_4E5_6 ``` ### Plus and minus in E-Notation is optional While plus and minus _can_ occur after the `e` or `E` it's not required. ```kotlin 123.123e123 123.123E123 123.123e+123 123.123E+123 123.123e-123 123.123E-123 ``` ### Binary Literals Just as in Java there are binary literals which start with the `0b` or `0B` prefix. ```Kotlin 0b011010 0B011010 ``` ### Suffixes Kotlin allows the suffixes `f`, `F`, `L`, `u`, `U`, `uL`, `UL`, though notably the previously supported suffix `l` is not allowed. ```Kotlin 123u 123U 123L 123uL 123UL 123f 0003f 0b01L 0xFF8800L 0XFF8800L 0b01uL 0xFF8800uL 0XFF8800uL 0b01UL 0xFF8800UL 0XFF8800UL ```
1 parent 9c8da0f commit 1074a2a

File tree

3 files changed

+77
-21
lines changed

3 files changed

+77
-21
lines changed

lexers/embedded/kotlin.xml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@
113113
<rule pattern="%=|&amp;&amp;|\*=|\+\+|\+=|--|-=|-&gt;|\.\.|\/=|::|&lt;=|==|&gt;=|!!|!=|\|\||\?[:.]">
114114
<token type="Operator"/>
115115
</rule>
116-
<rule pattern="[~!%^&amp;*()+=|\[\]:;,.&lt;&gt;\/?-]">
117-
<token type="Punctuation"/>
118-
</rule>
116+
119117
<rule pattern="[{}]">
120118
<token type="Punctuation"/>
121119
</rule>
@@ -137,8 +135,20 @@
137135
<rule pattern="&#39;\\.&#39;|&#39;[^\\]&#39;">
138136
<token type="LiteralStringChar"/>
139137
</rule>
140-
<rule pattern="0[xX][0-9a-fA-F]+[Uu]?[Ll]?|[0-9]+(\.[0-9]*)?([eE][+-][0-9]+)?[fF]?[Uu]?[Ll]?">
141-
<token type="LiteralNumber"/>
138+
<rule pattern="0[xX][0-9a-fA-F]+(_+[0-9a-fA-F]+)*[uU]?L?">
139+
<token type="LiteralNumberHex"/>
140+
</rule>
141+
<rule pattern="0[bB][01]+(_+[01]+)*[uU]?L?">
142+
<token type="LiteralNumberBin"/>
143+
</rule>
144+
<rule pattern="[0-9]+(_+[0-9]+)*\.[0-9]+(_+[0-9]+)*([eE][+-]?[0-9]+(_+[0-9]+)*)?[fF]?|\.[0-9]+(_+[0-9]+)*([eE][+-]?[0-9]+(_+[0-9]+)*)?[fF]?|[0-9]+(_+[0-9]+)*[eE][+-]?[0-9]+(_+[0-9]+)*[fF]?|[0-9]+(_+[0-9]+)*[fF]">
145+
<token type="LiteralNumberFloat"/>
146+
</rule>
147+
<rule pattern="[0-9]+(_+[0-9]+)*[uU]?L?">
148+
<token type="LiteralNumberInteger"/>
149+
</rule>
150+
<rule pattern="[~!%^&amp;*()+=|\[\]:;,.&lt;&gt;\/?-]">
151+
<token type="Punctuation"/>
142152
</rule>
143153
<rule pattern="(companion)(\s+)(object)">
144154
<bygroups>

lexers/testdata/kotlin.actual

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ fun main(args: Array<String>) {
1010
StringBuilder().apply {
1111
append(multiline)
1212
}
13-
val unsigned = 0x00UL + 123u + 76.54
13+
val ints = 9_000 + 1__2 + 0b0110_10 + 0B011010
14+
val floats = 1.0 + .45 + 1_2.3_4E5_6 + 56f + 90F + 1.2f
15+
val unsigned = 0x00UL + 123u
1416
}
1517
/*
1618
*/

lexers/testdata/kotlin.expected

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,63 @@
5656
{"type":"Text","value":"\n "},
5757
{"type":"Keyword","value":"val"},
5858
{"type":"Text","value":" "},
59-
{"type":"NameProperty","value":"unsigned"},
59+
{"type":"NameProperty","value":"ints"},
60+
{"type":"Text","value":" "},
61+
{"type":"Punctuation","value":"="},
62+
{"type":"Text","value":" "},
63+
{"type":"LiteralNumberInteger","value":"9_000"},
64+
{"type":"Text","value":" "},
65+
{"type":"Punctuation","value":"+"},
66+
{"type":"Text","value":" "},
67+
{"type":"LiteralNumberInteger","value":"1__2"},
68+
{"type":"Text","value":" "},
69+
{"type":"Punctuation","value":"+"},
70+
{"type":"Text","value":" "},
71+
{"type":"LiteralNumberBin","value":"0b0110_10"},
72+
{"type":"Text","value":" "},
73+
{"type":"Punctuation","value":"+"},
74+
{"type":"Text","value":" "},
75+
{"type":"LiteralNumberBin","value":"0B011010"},
76+
{"type":"Text","value":"\n "},
77+
{"type":"Keyword","value":"val"},
78+
{"type":"Text","value":" "},
79+
{"type":"NameProperty","value":"floats"},
6080
{"type":"Text","value":" "},
6181
{"type":"Punctuation","value":"="},
6282
{"type":"Text","value":" "},
63-
{"type":"LiteralNumber","value":"0x00UL"},
83+
{"type":"LiteralNumberFloat","value":"1.0"},
6484
{"type":"Text","value":" "},
6585
{"type":"Punctuation","value":"+"},
6686
{"type":"Text","value":" "},
67-
{"type":"LiteralNumber","value":"123u"},
87+
{"type":"LiteralNumberFloat","value":".45"},
88+
{"type":"Text","value":" "},
89+
{"type":"Punctuation","value":"+"},
90+
{"type":"Text","value":" "},
91+
{"type":"LiteralNumberFloat","value":"1_2.3_4E5_6"},
92+
{"type":"Text","value":" "},
93+
{"type":"Punctuation","value":"+"},
94+
{"type":"Text","value":" "},
95+
{"type":"LiteralNumberFloat","value":"56f"},
96+
{"type":"Text","value":" "},
97+
{"type":"Punctuation","value":"+"},
98+
{"type":"Text","value":" "},
99+
{"type":"LiteralNumberFloat","value":"90F"},
100+
{"type":"Text","value":" "},
101+
{"type":"Punctuation","value":"+"},
102+
{"type":"Text","value":" "},
103+
{"type":"LiteralNumberFloat","value":"1.2f"},
104+
{"type":"Text","value":"\n "},
105+
{"type":"Keyword","value":"val"},
106+
{"type":"Text","value":" "},
107+
{"type":"NameProperty","value":"unsigned"},
108+
{"type":"Text","value":" "},
109+
{"type":"Punctuation","value":"="},
110+
{"type":"Text","value":" "},
111+
{"type":"LiteralNumberHex","value":"0x00UL"},
68112
{"type":"Text","value":" "},
69113
{"type":"Punctuation","value":"+"},
70114
{"type":"Text","value":" "},
71-
{"type":"LiteralNumber","value":"76.54"},
115+
{"type":"LiteralNumberInteger","value":"123u"},
72116
{"type":"Text","value":"\n"},
73117
{"type":"Punctuation","value":"}"},
74118
{"type":"Text","value":"\n"},
@@ -94,7 +138,7 @@
94138
{"type":"Text","value":" "},
95139
{"type":"Operator","value":"?:"},
96140
{"type":"Text","value":" "},
97-
{"type":"LiteralNumber","value":"0"},
141+
{"type":"LiteralNumberInteger","value":"0"},
98142
{"type":"Text","value":"\n\n"},
99143
{"type":"Keyword","value":"fun"},
100144
{"type":"Text","value":" "},
@@ -120,11 +164,11 @@
120164
{"type":"Text","value":" "},
121165
{"type":"Punctuation","value":"{"},
122166
{"type":"Text","value":"\n "},
123-
{"type":"LiteralNumber","value":"1"},
167+
{"type":"LiteralNumberInteger","value":"1"},
124168
{"type":"Text","value":" "},
125169
{"type":"Punctuation","value":"+"},
126170
{"type":"Text","value":" "},
127-
{"type":"LiteralNumber","value":"2"},
171+
{"type":"LiteralNumberInteger","value":"2"},
128172
{"type":"Text","value":"\n"},
129173
{"type":"Punctuation","value":"}"},
130174
{"type":"Text","value":"\n\n"},
@@ -275,7 +319,7 @@
275319
{"type":"Text","value":" "},
276320
{"type":"Punctuation","value":"="},
277321
{"type":"Text","value":" "},
278-
{"type":"LiteralNumber","value":"123"},
322+
{"type":"LiteralNumberInteger","value":"123"},
279323
{"type":"Text","value":"\n "},
280324
{"type":"Name","value":"println"},
281325
{"type":"Punctuation","value":"("},
@@ -320,7 +364,7 @@
320364
{"type":"Text","value":" "},
321365
{"type":"Operator","value":"%="},
322366
{"type":"Text","value":" "},
323-
{"type":"LiteralNumber","value":"2"},
367+
{"type":"LiteralNumberInteger","value":"2"},
324368
{"type":"Text","value":"\n\t"},
325369
{"type":"Name","value":"a"},
326370
{"type":"Text","value":" "},
@@ -332,27 +376,27 @@
332376
{"type":"Text","value":" "},
333377
{"type":"Operator","value":"*="},
334378
{"type":"Text","value":" "},
335-
{"type":"LiteralNumber","value":"2"},
379+
{"type":"LiteralNumberInteger","value":"2"},
336380
{"type":"Text","value":"\n\t"},
337381
{"type":"Name","value":"a"},
338382
{"type":"Operator","value":"++"},
339383
{"type":"Text","value":"\n\t"},
340384
{"type":"Name","value":"b"},
341385
{"type":"Operator","value":"+="},
342-
{"type":"LiteralNumber","value":"2"},
386+
{"type":"LiteralNumberInteger","value":"2"},
343387
{"type":"Text","value":"\n\t"},
344388
{"type":"Name","value":"b"},
345389
{"type":"Operator","value":"--"},
346390
{"type":"Text","value":"\n\t"},
347391
{"type":"Name","value":"a"},
348392
{"type":"Operator","value":"-="},
349-
{"type":"LiteralNumber","value":"1"},
393+
{"type":"LiteralNumberInteger","value":"1"},
350394
{"type":"Text","value":"\n\t"},
351395
{"type":"Name","value":"a"},
352396
{"type":"Text","value":" "},
353397
{"type":"Operator","value":"/="},
354398
{"type":"Text","value":" "},
355-
{"type":"LiteralNumber","value":"2"},
399+
{"type":"LiteralNumberInteger","value":"2"},
356400
{"type":"Text","value":"\n\t"},
357401
{"type":"Name","value":"a"},
358402
{"type":"Text","value":" "},
@@ -562,7 +606,7 @@
562606
{"type":"Text","value":" "},
563607
{"type":"Punctuation","value":"="},
564608
{"type":"Text","value":" "},
565-
{"type":"LiteralNumber","value":"0"},
609+
{"type":"LiteralNumberInteger","value":"0"},
566610
{"type":"Text","value":"\n\n "},
567611
{"type":"Punctuation","value":"}"},
568612
{"type":"Text","value":"\n"},
@@ -594,7 +638,7 @@
594638
{"type":"Text","value":" "},
595639
{"type":"Punctuation","value":"="},
596640
{"type":"Text","value":" "},
597-
{"type":"LiteralNumber","value":"123"},
641+
{"type":"LiteralNumberInteger","value":"123"},
598642
{"type":"Text","value":"\n\n"},
599643
{"type":"Keyword","value":"class"},
600644
{"type":"Text","value":" "},

0 commit comments

Comments
 (0)