Skip to content
This repository has been archived by the owner on Oct 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #22 from abusalimov/15-num-literals
Browse files Browse the repository at this point in the history
numbers: Add GNU features, improve error reporting
  • Loading branch information
abusalimov committed Oct 25, 2015
2 parents 40c09f1 + d4364ca commit 2fe62d6
Show file tree
Hide file tree
Showing 2 changed files with 288 additions and 8 deletions.
202 changes: 194 additions & 8 deletions C Improved.tmLanguage
Original file line number Diff line number Diff line change
Expand Up @@ -1192,31 +1192,217 @@
<key>patterns</key>
<array>
<dict>
<key>match</key> <string>\s*(\b(0[xX][0-9a-fA-F]*|0[0-7]*|[1-9][0-9]*)[uU]?(ll?|LL?)?\b)</string>
<key>match</key> <string>(?ix) # hexadecimal float
(?&lt;!\.) \b
(0x)
# significand
(?: (\.) (?=p) # invalid
| [0-9a-f]*+ ([0-9a-z]*?) [0-9a-f]*+
(?: \. [0-9a-f]*+ ([0-9a-z.]*?) [0-9a-f]*+ )? )
# exponent (required)
(?: (p) (?: [+\-] [0-9]++ ([0-9a-z]*?)
| (?=[0-9a-z.]) [0-9]*+ ([0-9a-z.]*?) )
| (p) )
# remaining valid chars and type
[0-9]*+ ([fl]?)
\b (?!\.)
</string>
<key>name</key> <string>constant.numeric.float.hexadecimal.c</string>
<key>captures</key>
<dict>
<key>1</key> <dict> <key>name</key> <string>string.other.number.prefix.hexadecimal.c</string> </dict>
<key>2</key> <dict> <key>name</key> <string>invalid.illegal.number.missing-fragment.significand.c</string> </dict>
<key>3</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.whole-number.c</string> </dict>
<key>4</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.fraction.c</string> </dict>
<key>5</key> <dict> <key>name</key> <string>keyword.other.exponent.hexadecimal.c</string> </dict>
<key>6</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.exponent.c</string> </dict>
<key>7</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.exponent.c</string> </dict>
<key>8</key> <dict> <key>name</key> <string>invalid.illegal.number.missing-fragment.exponent.c</string> </dict>
<key>9</key> <dict> <key>name</key> <string>string.other.number.suffix.float.c</string> </dict>
</dict>
</dict>
<dict>
<key>match</key> <string>(?ix) # hexadecimal float without required exponent
(?&lt;!\.) \b
(0x)
# significand (at least a period)
[0-9a-f]*+ ([0-9a-z&amp;&amp;[^p]]*?) [0-9a-f]*+
(\.) [0-9a-f]*+ ([0-9a-z.&amp;&amp;[^p]]*?) [0-9a-f]*+
# type
(l?)
(?:(?&lt;=\.)|\b) (?!\.)
</string>
<key>name</key> <string>constant.numeric.float.hexadecimal.c</string>
<key>captures</key>
<dict>
<key>1</key> <dict> <key>name</key> <string>string.other.number.prefix.hexadecimal.c</string> </dict>
<key>2</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.whole-number.c</string> </dict>
<key>3</key> <dict> <key>name</key> <string>invalid.illegal.number.hexadecimal-float-requires-exponent.c</string> </dict>
<key>4</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.fraction.c</string> </dict>
<key>5</key> <dict> <key>name</key> <string>string.other.number.suffix.float.c</string> </dict>
</dict>
</dict>
<dict>
<key>match</key> <string>(?ix) # decimal float literal
(?&lt;!\.) (?:(?=\.)|\b)
(?!0x)
# significand
(?: (?: [0-9]++ ([0-9a-z&amp;&amp;[^e]]*?) [0-9]+* )?
\. [0-9]++ ([0-9a-z.&amp;&amp;[^e]]*?) [0-9]+*
| [0-9]++ ([0-9a-z&amp;&amp;[^e]]*?) [0-9]+* (?: \. | (?=e)) )
# exponent (optional)
(?: (e) (?: [+\-] [0-9]++ ([0-9a-z]*?)
| [0-9]++ ([0-9a-z.]*?) )
| ( p [+\-]? [0-9]++
| [ep] [0-9a-z.]*?) )?
# any invalid chars and type
([0-9a-z]*?) [0-9]*+ ([fl]?)
(?:(?&lt;=\.)|\b) (?!\.)
</string>
<key>name</key> <string>constant.numeric.float.c</string>
<key>captures</key>
<dict>
<key>1</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.whole-number.c</string> </dict>
<key>2</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.fraction.c</string> </dict>
<key>3</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.whole-number.c</string> </dict>
<key>4</key> <dict> <key>name</key> <string>keyword.other.exponent.c</string> </dict>
<key>5</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.exponent.c</string> </dict>
<key>6</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.exponent.c</string> </dict>
<key>7</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.exponent.c</string> </dict>
<key>8</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.float.exponent.c</string> </dict>
<key>9</key> <dict> <key>name</key> <string>string.other.number.suffix.float.c</string> </dict>
</dict>
</dict>
<dict>
<key>match</key> <string>(?ix)
(?&lt;!\.) \b
(0x)? 0++
(u?l{0,2}|lul?|llu)
\b (?!\.)
</string>
<key>name</key> <string>constant.numeric.integer.zero.c</string>
<key>captures</key>
<dict>
<key>1</key> <dict> <key>name</key> <string>constant.numeric.integer.c</string> </dict>
<key>1</key> <dict> <key>name</key> <string>string.other.number.prefix.hexadecimal.c</string> </dict>
<key>2</key> <dict> <key>name</key> <string>string.other.number.suffix.c</string> </dict>
</dict>
</dict>
<dict>
<key>match</key> <string>\s*(\b(([0-9]+\.[0-9]*)|(\.[0-9]+))([eE][+\-]?[0-9]+)?[fF]?\b)</string>
<key>match</key> <string>(?ix)
(?&lt;!\.) \b
(?: (0x) | (0b) )
(u?l{0,2}|lul?|llu)
\b (?!\.)
</string>
<key>name</key> <string>invalid.illegal.invalid-number-literal.c</string>
<key>captures</key>
<dict>
<key>1</key> <dict> <key>name</key> <string>constant.numeric.float.c</string> </dict>
<key>1</key> <dict> <key>name</key> <string>string.other.number.prefix.hexadecimal.c</string> </dict>
<key>2</key> <dict> <key>name</key> <string>string.other.number.prefix.binary.c</string> </dict>
<key>3</key> <dict> <key>name</key> <string>string.other.number.suffix.c</string> </dict>
</dict>
</dict>
<dict>
<key>match</key> <string>\s*(\b(?i:(0b[01]+)U?L{1,2})\b)</string>
<key>match</key> <string>(?ix)
(?&lt;!\.) \b
(0x) [0-9a-f]++
# any invalid chars
([0-9a-z]*?)
# the remainder (after invalid chars, if any) and a type
[0-9a-f]* (u?l{0,2}|lul?|llu)
\b (?!\.)
</string>
<key>name</key> <string>constant.numeric.integer.hexadecimal.c</string>
<key>captures</key>
<dict>
<key>1</key> <dict> <key>name</key> <string>constant.numeric.integer.long.binary.c</string> </dict>
<key>1</key> <dict> <key>name</key> <string>string.other.number.prefix.hexadecimal.c</string> </dict>
<key>2</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.integer.c</string> </dict>
<key>3</key> <dict> <key>name</key> <string>string.other.number.suffix.c</string> </dict>
</dict>
</dict>
<dict>
<key>match</key> <string>\s*(\b(?i:(0b[01]+)U?)\b)</string>
<key>match</key> <string>(?ix)
(?&lt;!\.) \b
(0b) [01]++
# any invalid chars
([0-9a-z]*?)
# the remainder (after invalid chars, if any) and a type
[01]* (u?l{0,2}|lul?|llu)
\b (?!\.)
</string>
<key>name</key> <string>constant.numeric.integer.binary.c</string>
<key>captures</key>
<dict>
<key>1</key> <dict> <key>name</key> <string>string.other.number.prefix.binary.c</string> </dict>
<key>2</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.integer.c</string> </dict>
<key>3</key> <dict> <key>name</key> <string>string.other.number.suffix.c</string> </dict>
</dict>
</dict>
<dict>
<key>match</key> <string>(?ix)
(?&lt;!\.) \b
(0) [0-7]++
# any invalid chars
([0-9a-z]*?)
# the remainder (after invalid chars, if any) and a type
[0-7]* (u?l{0,2}|lul?|llu)
\b (?!\.)
</string>
<key>name</key> <string>constant.numeric.integer.octal.c</string>
<key>captures</key>
<dict>
<key>1</key> <dict> <key>name</key> <string>string.other.number.prefix.octal.c</string> </dict>
<key>2</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.integer.c</string> </dict>
<key>3</key> <dict> <key>name</key> <string>string.other.number.suffix.c</string> </dict>
</dict>
</dict>
<dict>
<key>match</key> <string>(?ix)
(?&lt;!\.) \b
[0-9]++
# any invalid chars
([0-9a-z]*?)
# the remainder (after invalid chars, if any) and a type
[0-9]* (u?l{0,2}|lul?|llu)
\b (?!\.)
</string>
<key>name</key> <string>constant.numeric.integer.decimal.c</string>
<key>captures</key>
<dict>
<key>1</key> <dict> <key>name</key> <string>constant.numeric.integer.binary.c</string> </dict>
<key>1</key> <dict> <key>name</key> <string>invalid.illegal.numeric-literal-character.integer.c</string> </dict>
<key>2</key> <dict> <key>name</key> <string>string.other.number.suffix.c</string> </dict>
</dict>
</dict>
</array>
Expand Down
94 changes: 94 additions & 0 deletions tests/test_numbers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
int main(int argc, char const *argv[])
{
GOOD = {
0,
0.0l,
.0,
0.f,
0UL,
0x0ull,
7e5,
7.3,
7.3E+5,
7.E+5,
.3E+5f,
7.3+5,
7.3+E,
0x73e5f,
0x7.3p5f,
0x7.3p-5f,
0x7p5f,
029e3l,

2,
256,
0.015625,
0.857421875,
0x1p-1074,
3.1415926,
0.1,
0x3.334p-5,
0xcc.cdp-11,
};

BAD = {
0x7A.3,
0x7A.3E-.5,
0x7A.3E-5.,
0x7A.3E-5.0,
0x7A.,
0x7s.,
0x7A.p,
0x7.3df,
0x7.3dl,
0x7.3sdsdsdf,
0x7.3e1sdf,
0x7.3p,
0x7.3ppl,
0x7s7s7d3.3dsdfsdp1.2df3l,
0x7.3,
0x7.3p-5u,
0x7.3p-5.0,
0x7.3p5.0,
0x7.3p,
0x7.3pe,
0x7p,
0xp,
0x.,
0x.p,
0x.p1,
07.3p5,
07.3p+5,
07.3e+Du,
07.3e+Eu,
07.3p+Eu,
07.3p1,
7e5fu,
7.3uf,
7f.3u,
7f.3f,
7f.3fu,
7.3uf,
0293ull,
029e3ull,
029f3ull,
029g3ull,
0293ulql,
0xA293sull,
0xA29g3ull,
0xA293q2ll,
0xA293uqll,
0xA293ulqlq,
29e3ull,
29f3ull,
29g3ull,
293ulql,
293ulqlq,
0x,
0xl,
0b,
0b1210ul,
0b1a10,
0b1z10,
};
}

0 comments on commit 2fe62d6

Please sign in to comment.