Skip to content

Commit 49bcd8b

Browse files
committed
Fix parsing to support uppercase 0X hex literals
Previously, literals with uppercase 0X prefix (e.g., "0XABC") were misparsed as invalid. This commit fixes that and improves compatibility with C99-style numeric constants. - Removed incorrect inclusion of 'x' as a hex digit in is_hex() - Updated is_numeric() to skip 0x/0X prefix when validating hex digits - Adjusted read_numeric_constant() to consistently handle both 0x and 0X prefixes
1 parent a39f318 commit 49bcd8b

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

src/lexer.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,19 @@ bool is_digit(char c)
4242

4343
bool is_hex(char c)
4444
{
45-
return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || c == 'x' ||
46-
(c >= 'A' && c <= 'F'));
45+
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
46+
(c >= 'A' && c <= 'F');
4747
}
4848

4949
bool is_numeric(char buffer[])
5050
{
5151
bool hex = false;
5252
int size = strlen(buffer);
5353

54-
if (size > 2)
55-
hex = !strncmp(buffer, "0x", 2);
54+
if (size > 2 && buffer[0] == '0' && (buffer[1] | 32) == 'x')
55+
hex = true;
5656

57-
for (int i = 0; i < size; i++) {
57+
for (int i = hex ? 2 : 0; i < size; i++) {
5858
if (hex && !is_hex(buffer[i]))
5959
return false;
6060
if (!hex && !is_digit(buffer[i]))
@@ -177,9 +177,38 @@ token_t lex_token_internal(bool aliasing)
177177

178178
if (is_digit(next_char)) {
179179
int i = 0;
180-
do {
180+
token_str[i++] = next_char;
181+
read_char(false);
182+
183+
if (token_str[0] == '0' && ((next_char | 32) == 'x')) {
184+
/* Hexadecimal: starts with 0x or 0X */
181185
token_str[i++] = next_char;
182-
} while (is_hex(read_char(false)));
186+
187+
read_char(false);
188+
if (!is_hex(next_char))
189+
error("Invalid hex literal: expected hex digit after 0x");
190+
191+
do {
192+
token_str[i++] = next_char;
193+
} while (is_hex(read_char(false)));
194+
195+
} else if (token_str[0] == '0') {
196+
/* Octal: starts with 0 but not followed by 'x' */
197+
while (is_digit(next_char)) {
198+
if (next_char >= '8')
199+
error("Invalid octal digit: must be in range 0-7");
200+
token_str[i++] = next_char;
201+
read_char(false);
202+
}
203+
204+
} else {
205+
/* Decimal */
206+
while (is_digit(next_char)) {
207+
token_str[i++] = next_char;
208+
read_char(false);
209+
}
210+
}
211+
183212
token_str[i] = 0;
184213
skip_whitespace();
185214
return T_numeric;

src/parser.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ int read_numeric_constant(char buffer[])
295295
int i = 0;
296296
int value = 0;
297297
while (buffer[i]) {
298-
if (i == 1 && (buffer[i] == 'x')) { /* hexadecimal */
298+
if (i == 1 && (buffer[i] | 32) == 'x') { /* hexadecimal */
299299
value = 0;
300300
i = 2;
301301
while (buffer[i]) {
@@ -784,7 +784,7 @@ void read_numeric_param(block_t *parent, basic_block_t *bb, int is_neg)
784784
i++;
785785
}
786786
if (token[0] == '0') {
787-
if (token[1] == 'x') { /* hexdecimal */
787+
if ((token[1] | 32) == 'x') { /* hexdecimal */
788788
i = 2;
789789
do {
790790
c = token[i++];

0 commit comments

Comments
 (0)