|
|
@ -37,6 +37,22 @@ struct token { |
|
|
|
char *end; // one past end
|
|
|
|
char *end; // one past end
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned long long |
|
|
|
|
|
|
|
usec_now(void) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct timespec tp = { 0 }; |
|
|
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC_RAW, &tp); |
|
|
|
|
|
|
|
unsigned long long now = tp.tv_sec * 1000000ULL + tp.tv_nsec / 1000ULL; |
|
|
|
|
|
|
|
return(now); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static inline void |
|
|
|
|
|
|
|
advance(struct str *s, int by) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
s->text += by; |
|
|
|
|
|
|
|
s->size -= by; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
static int |
|
|
|
nondigit(struct str s) |
|
|
|
nondigit(struct str s) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -159,23 +175,19 @@ integer_suffix(struct str s) |
|
|
|
int sym = 0; |
|
|
|
int sym = 0; |
|
|
|
|
|
|
|
|
|
|
|
if ((sym = unsigned_suffix(s))) { |
|
|
|
if ((sym = unsigned_suffix(s))) { |
|
|
|
s.text += sym; |
|
|
|
advance(&s, sym); |
|
|
|
s.size -= sym; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ll = long_long_suffix(s); |
|
|
|
int ll = long_long_suffix(s); |
|
|
|
|
|
|
|
|
|
|
|
if (ll) { |
|
|
|
if (ll) { |
|
|
|
return(sym + ll); |
|
|
|
return(sym + ll); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return(sym + long_suffix(s)); |
|
|
|
return(sym + long_suffix(s)); |
|
|
|
} else if ((sym = long_long_suffix(s))) { |
|
|
|
} else if ((sym = long_long_suffix(s))) { |
|
|
|
s.text += sym; |
|
|
|
advance(&s, sym); |
|
|
|
s.size -= sym; |
|
|
|
|
|
|
|
return(sym + unsigned_suffix(s)); |
|
|
|
return(sym + unsigned_suffix(s)); |
|
|
|
} else if ((sym = long_suffix(s))) { |
|
|
|
} else if ((sym = long_suffix(s))) { |
|
|
|
s.text += sym; |
|
|
|
advance(&s, sym); |
|
|
|
s.size -= sym; |
|
|
|
|
|
|
|
return(sym + unsigned_suffix(s)); |
|
|
|
return(sym + unsigned_suffix(s)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -206,20 +218,16 @@ octal_escape_sequence(struct str s) |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
|
|
|
|
|
|
|
|
if (s.size && s.text[0] == '\\') { |
|
|
|
if (s.size && s.text[0] == '\\') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (octal_digit(s)) { |
|
|
|
if (octal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (octal_digit(s)) { |
|
|
|
if (octal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (octal_digit(s)) { |
|
|
|
if (octal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -237,17 +245,14 @@ hexadecimal_escape_sequence(struct str s) |
|
|
|
|
|
|
|
|
|
|
|
if (s.size >= 2) { |
|
|
|
if (s.size >= 2) { |
|
|
|
if (s.text[0] == '\\' && s.text[1] == 'x') { |
|
|
|
if (s.text[0] == '\\' && s.text[1] == 'x') { |
|
|
|
s.text += 2; |
|
|
|
advance(&s, 2); |
|
|
|
s.size -= 2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -266,14 +271,11 @@ hex_quad(struct str s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (s.size >= 4) { |
|
|
|
if (s.size >= 4) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
return(4); |
|
|
|
return(4); |
|
|
|
} |
|
|
|
} |
|
|
@ -293,19 +295,16 @@ universal_character_name(struct str s) |
|
|
|
|
|
|
|
|
|
|
|
if (s.text[0] == '\\') { |
|
|
|
if (s.text[0] == '\\') { |
|
|
|
if (s.text[1] == 'u') { |
|
|
|
if (s.text[1] == 'u') { |
|
|
|
s.text += 2; |
|
|
|
advance(&s, 2); |
|
|
|
s.size -= 2; |
|
|
|
|
|
|
|
int hq = hex_quad(s); |
|
|
|
int hq = hex_quad(s); |
|
|
|
if (hq) { |
|
|
|
if (hq) { |
|
|
|
return(2 + hq); |
|
|
|
return(2 + hq); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (s.text[1] == 'U') { |
|
|
|
} else if (s.text[1] == 'U') { |
|
|
|
s.text += 2; |
|
|
|
advance(&s, 2); |
|
|
|
s.size -= 2; |
|
|
|
|
|
|
|
int hq1 = hex_quad(s); |
|
|
|
int hq1 = hex_quad(s); |
|
|
|
if (hq1) { |
|
|
|
if (hq1) { |
|
|
|
s.text += hq1; |
|
|
|
advance(&s, hq1); |
|
|
|
s.size -= hq1; |
|
|
|
|
|
|
|
int hq2 = hex_quad(s); |
|
|
|
int hq2 = hex_quad(s); |
|
|
|
if (hq2) { |
|
|
|
if (hq2) { |
|
|
|
return(2 + hq1 + hq2); |
|
|
|
return(2 + hq1 + hq2); |
|
|
@ -336,15 +335,13 @@ identifier(struct str s) |
|
|
|
int in = identifier_nondigit(s); |
|
|
|
int in = identifier_nondigit(s); |
|
|
|
|
|
|
|
|
|
|
|
if (in) { |
|
|
|
if (in) { |
|
|
|
s.text += in; |
|
|
|
advance(&s, in); |
|
|
|
s.size -= in; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int sym = 0; |
|
|
|
int sym = 0; |
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if ((sym = identifier_nondigit(s)) || (sym = digit(s))) { |
|
|
|
if ((sym = identifier_nondigit(s)) || (sym = digit(s))) { |
|
|
|
s.text += sym; |
|
|
|
advance(&s, sym); |
|
|
|
s.size -= sym; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -362,13 +359,11 @@ decimal_constant(struct str s) |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
|
|
|
|
|
|
|
|
if (nonzero_digit(s)) { |
|
|
|
if (nonzero_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if (digit(s)) { |
|
|
|
if (digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -387,13 +382,11 @@ octal_constant(struct str s) |
|
|
|
|
|
|
|
|
|
|
|
if (s.size) { |
|
|
|
if (s.size) { |
|
|
|
if (s.text[0] == '0') { |
|
|
|
if (s.text[0] == '0') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if (octal_digit(s)) { |
|
|
|
if (octal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -413,17 +406,14 @@ hexadecimal_constant(struct str s) |
|
|
|
int hp = hexadecimal_prefix(s); |
|
|
|
int hp = hexadecimal_prefix(s); |
|
|
|
|
|
|
|
|
|
|
|
if (hp) { |
|
|
|
if (hp) { |
|
|
|
s.text += hp; |
|
|
|
advance(&s, hp); |
|
|
|
s.size -= hp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -442,8 +432,7 @@ integer_constant(struct str s) |
|
|
|
int sym = 0; |
|
|
|
int sym = 0; |
|
|
|
|
|
|
|
|
|
|
|
if ((sym = hexadecimal_constant(s)) || (sym = octal_constant(s)) || (sym = decimal_constant(s))) { |
|
|
|
if ((sym = hexadecimal_constant(s)) || (sym = octal_constant(s)) || (sym = decimal_constant(s))) { |
|
|
|
s.text += sym; |
|
|
|
advance(&s, sym); |
|
|
|
s.size -= sym; |
|
|
|
|
|
|
|
return(sym + integer_suffix(s)); |
|
|
|
return(sym + integer_suffix(s)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -456,13 +445,11 @@ digit_sequence(struct str s) |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
|
|
|
|
|
|
|
|
if (digit(s)) { |
|
|
|
if (digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if (digit(s)) { |
|
|
|
if (digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -484,13 +471,10 @@ fractional_constant(struct str s) |
|
|
|
|
|
|
|
|
|
|
|
if (s.size) { |
|
|
|
if (s.size) { |
|
|
|
if (s.text[0] == '.') { |
|
|
|
if (s.text[0] == '.') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ds2 = digit_sequence(s); |
|
|
|
int ds2 = digit_sequence(s); |
|
|
|
|
|
|
|
advance(&s, ds2); |
|
|
|
s.text += ds2; |
|
|
|
|
|
|
|
s.size -= ds2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ds1 > 0 || ds2 > 0) { |
|
|
|
if (ds1 > 0 || ds2 > 0) { |
|
|
|
return(ds1 + ds2 + 1); |
|
|
|
return(ds1 + ds2 + 1); |
|
|
@ -508,17 +492,14 @@ exponent_part(struct str s) |
|
|
|
|
|
|
|
|
|
|
|
if (s.size) { |
|
|
|
if (s.size) { |
|
|
|
if (s.text[0] == 'e' || s.text[0] == 'E') { |
|
|
|
if (s.text[0] == 'e' || s.text[0] == 'E') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int sgn = sign(s); |
|
|
|
int sgn = sign(s); |
|
|
|
s.text += sgn; |
|
|
|
advance(&s, sgn); |
|
|
|
s.size -= sgn; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ds = digit_sequence(s); |
|
|
|
int ds = digit_sequence(s); |
|
|
|
if (ds) { |
|
|
|
if (ds) { |
|
|
|
s.text += ds; |
|
|
|
advance(&s, ds); |
|
|
|
s.size -= ds; |
|
|
|
|
|
|
|
return(start - s.size); |
|
|
|
return(start - s.size); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -532,23 +513,19 @@ decimal_floating_constant(struct str s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int sym = 0; |
|
|
|
int sym = 0; |
|
|
|
if ((sym = fractional_constant(s))) { |
|
|
|
if ((sym = fractional_constant(s))) { |
|
|
|
s.text += sym; |
|
|
|
advance(&s, sym); |
|
|
|
s.size -= sym; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ep = exponent_part(s); |
|
|
|
int ep = exponent_part(s); |
|
|
|
s.text += ep; |
|
|
|
advance(&s, ep); |
|
|
|
s.size -= ep; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return(sym + ep + floating_suffix(s)); |
|
|
|
return(sym + ep + floating_suffix(s)); |
|
|
|
} else if ((sym = digit_sequence(s))) { |
|
|
|
} else if ((sym = digit_sequence(s))) { |
|
|
|
s.text += sym; |
|
|
|
advance(&s, sym); |
|
|
|
s.size -= sym; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ep = 0; |
|
|
|
int ep = 0; |
|
|
|
|
|
|
|
|
|
|
|
if ((ep = exponent_part(s))) { |
|
|
|
if ((ep = exponent_part(s))) { |
|
|
|
s.text += ep; |
|
|
|
advance(&s, ep); |
|
|
|
s.size -= ep; |
|
|
|
|
|
|
|
return(sym + ep + floating_suffix(s)); |
|
|
|
return(sym + ep + floating_suffix(s)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -562,13 +539,11 @@ hexadecimal_digit_sequence(struct str s) |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
|
|
|
|
|
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
if (hexadecimal_digit(s)) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -585,12 +560,10 @@ hexadecimal_fractional_constant(struct str s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int hds1 = hexadecimal_digit_sequence(s); |
|
|
|
int hds1 = hexadecimal_digit_sequence(s); |
|
|
|
|
|
|
|
|
|
|
|
s.text += hds1; |
|
|
|
advance(&s, hds1); |
|
|
|
s.size -= hds1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (s.size && s.text[0] == '.') { |
|
|
|
if (s.size && s.text[0] == '.') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int hds2 = hexadecimal_digit_sequence(s); |
|
|
|
int hds2 = hexadecimal_digit_sequence(s); |
|
|
|
|
|
|
|
|
|
|
@ -608,16 +581,14 @@ binary_exponent_part(struct str s) |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
|
|
|
|
|
|
|
|
if (s.size && (s.text[0] == 'p' || s.text[0] == 'P')) { |
|
|
|
if (s.size && (s.text[0] == 'p' || s.text[0] == 'P')) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int sgn = sign(s); |
|
|
|
int sgn = sign(s); |
|
|
|
s.text += sgn; |
|
|
|
advance(&s, sgn); |
|
|
|
s.size -= sgn; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ds = digit_sequence(s); |
|
|
|
int ds = digit_sequence(s); |
|
|
|
if (ds) { |
|
|
|
if (ds) { |
|
|
|
s.size -= ds; |
|
|
|
advance(&s, ds); |
|
|
|
return(start - s.size); |
|
|
|
return(start - s.size); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -632,28 +603,23 @@ hexadecimal_floating_constant(struct str s) |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
|
|
|
|
|
|
|
|
if ((hp = hexadecimal_prefix(s))) { |
|
|
|
if ((hp = hexadecimal_prefix(s))) { |
|
|
|
s.text += hp; |
|
|
|
advance(&s, hp); |
|
|
|
s.size -= hp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int hfc = 0; |
|
|
|
int hfc = 0; |
|
|
|
int hds = 0; |
|
|
|
int hds = 0; |
|
|
|
|
|
|
|
|
|
|
|
if ((hfc = hexadecimal_fractional_constant(s))) { |
|
|
|
if ((hfc = hexadecimal_fractional_constant(s))) { |
|
|
|
s.text += hfc; |
|
|
|
advance(&s, hfc); |
|
|
|
s.size -= hfc; |
|
|
|
|
|
|
|
int bep = binary_exponent_part(s); |
|
|
|
int bep = binary_exponent_part(s); |
|
|
|
if (bep) { |
|
|
|
if (bep) { |
|
|
|
s.text += bep; |
|
|
|
advance(&s, bep); |
|
|
|
s.size -= bep; |
|
|
|
|
|
|
|
return(start - s.size + floating_suffix(s)); |
|
|
|
return(start - s.size + floating_suffix(s)); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if ((hds = hexadecimal_digit_sequence(s))) { |
|
|
|
} else if ((hds = hexadecimal_digit_sequence(s))) { |
|
|
|
s.text += hds; |
|
|
|
advance(&s, hds); |
|
|
|
s.size -= hds; |
|
|
|
|
|
|
|
int bep = binary_exponent_part(s); |
|
|
|
int bep = binary_exponent_part(s); |
|
|
|
if (bep) { |
|
|
|
if (bep) { |
|
|
|
s.text += bep; |
|
|
|
advance(&s, bep); |
|
|
|
s.size -= bep; |
|
|
|
|
|
|
|
return(start - s.size + floating_suffix(s)); |
|
|
|
return(start - s.size + floating_suffix(s)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -742,13 +708,11 @@ c_char_sequence(struct str s) |
|
|
|
int sc = 0; |
|
|
|
int sc = 0; |
|
|
|
|
|
|
|
|
|
|
|
if ((sc = c_char(s))) { |
|
|
|
if ((sc = c_char(s))) { |
|
|
|
s.text += sc; |
|
|
|
advance(&s, sc); |
|
|
|
s.size -= sc; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if ((sc = c_char(s))) { |
|
|
|
if ((sc = c_char(s))) { |
|
|
|
s.text += sc; |
|
|
|
advance(&s, sc); |
|
|
|
s.size -= sc; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -767,30 +731,25 @@ character_constant(struct str s) |
|
|
|
int ok = 0; |
|
|
|
int ok = 0; |
|
|
|
|
|
|
|
|
|
|
|
if (s.size && s.text[0] == '\'') { |
|
|
|
if (s.size && s.text[0] == '\'') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
ok = 1; |
|
|
|
ok = 1; |
|
|
|
} else if (s.size >= 2 && s.text[0] == 'L' && s.text[1] == '\'') { |
|
|
|
} else if (s.size >= 2 && s.text[0] == 'L' && s.text[1] == '\'') { |
|
|
|
s.text += 2; |
|
|
|
advance(&s, 2); |
|
|
|
s.size -= 2; |
|
|
|
|
|
|
|
ok = 1; |
|
|
|
ok = 1; |
|
|
|
} else if (s.size >= 2 && s.text[0] == 'u' && s.text[1] == '\'') { |
|
|
|
} else if (s.size >= 2 && s.text[0] == 'u' && s.text[1] == '\'') { |
|
|
|
s.text += 2; |
|
|
|
advance(&s, 2); |
|
|
|
s.size -= 2; |
|
|
|
|
|
|
|
ok = 1; |
|
|
|
ok = 1; |
|
|
|
} else if (s.size >= 2 && s.text[0] == 'U' && s.text[1] == '\'') { |
|
|
|
} else if (s.size >= 2 && s.text[0] == 'U' && s.text[1] == '\'') { |
|
|
|
s.text += 2; |
|
|
|
advance(&s, 2); |
|
|
|
s.size -= 2; |
|
|
|
|
|
|
|
ok = 1; |
|
|
|
ok = 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (ok) { |
|
|
|
if (ok) { |
|
|
|
int ccs = c_char_sequence(s); |
|
|
|
int ccs = c_char_sequence(s); |
|
|
|
if (ccs) { |
|
|
|
if (ccs) { |
|
|
|
s.text += ccs; |
|
|
|
advance(&s, ccs); |
|
|
|
s.size -= ccs; |
|
|
|
|
|
|
|
if (s.size && s.text[0] == '\'') { |
|
|
|
if (s.size && s.text[0] == '\'') { |
|
|
|
s.size--; |
|
|
|
advance(&s, 1); |
|
|
|
return(start - s.size); |
|
|
|
return(start - s.size); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -818,8 +777,7 @@ whitespace(struct str s) |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
|
|
|
|
|
|
|
|
while (s.size && (s.text[0] == ' ' || s.text[0] == '\t' || s.text[0] == '\n' || s.text[0] == '\r')) { |
|
|
|
while (s.size && (s.text[0] == ' ' || s.text[0] == '\t' || s.text[0] == '\n' || s.text[0] == '\r')) { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return(start - s.size); |
|
|
|
return(start - s.size); |
|
|
@ -849,13 +807,11 @@ s_char_sequence(struct str s) |
|
|
|
int sc = 0; |
|
|
|
int sc = 0; |
|
|
|
|
|
|
|
|
|
|
|
if ((sc = s_char(s))) { |
|
|
|
if ((sc = s_char(s))) { |
|
|
|
s.text += sc; |
|
|
|
advance(&s, sc); |
|
|
|
s.size -= sc; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if ((sc = s_char(s))) { |
|
|
|
if ((sc = s_char(s))) { |
|
|
|
s.text += sc; |
|
|
|
advance(&s, sc); |
|
|
|
s.size -= sc; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -890,19 +846,16 @@ string_literal(struct str s) |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
|
|
|
|
|
|
|
|
int ep = encoding_prefix(s); |
|
|
|
int ep = encoding_prefix(s); |
|
|
|
s.text += ep; |
|
|
|
advance(&s, ep); |
|
|
|
s.size -= ep; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (s.size && s.text[0] == '\"') { |
|
|
|
if (s.size && s.text[0] == '\"') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int scs = s_char_sequence(s); |
|
|
|
int scs = s_char_sequence(s); |
|
|
|
s.text += scs; |
|
|
|
advance(&s, scs); |
|
|
|
s.size -= scs; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (s.size && s.text[0] == '\"') { |
|
|
|
if (s.size && s.text[0] == '\"') { |
|
|
|
s.size--; |
|
|
|
advance(&s, 1); |
|
|
|
return(start - s.size); |
|
|
|
return(start - s.size); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -974,16 +927,14 @@ static int |
|
|
|
h_char_sequence(struct str s) |
|
|
|
h_char_sequence(struct str s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
int sc = 0; |
|
|
|
int hc = 0; |
|
|
|
|
|
|
|
|
|
|
|
if ((sc = h_char(s))) { |
|
|
|
if ((hc = h_char(s))) { |
|
|
|
s.text += sc; |
|
|
|
advance(&s, hc); |
|
|
|
s.size -= sc; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if ((sc = h_char(s))) { |
|
|
|
if ((hc = h_char(s))) { |
|
|
|
s.text += sc; |
|
|
|
advance(&s, hc); |
|
|
|
s.size -= sc; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -999,16 +950,14 @@ static int |
|
|
|
q_char_sequence(struct str s) |
|
|
|
q_char_sequence(struct str s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int start = s.size; |
|
|
|
int start = s.size; |
|
|
|
int sc = 0; |
|
|
|
int qc = 0; |
|
|
|
|
|
|
|
|
|
|
|
if ((sc = q_char(s))) { |
|
|
|
if ((qc = q_char(s))) { |
|
|
|
s.text += sc; |
|
|
|
advance(&s, qc); |
|
|
|
s.size -= sc; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
if ((sc = q_char(s))) { |
|
|
|
if ((qc = q_char(s))) { |
|
|
|
s.text += sc; |
|
|
|
advance(&s, qc); |
|
|
|
s.size -= sc; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -1024,13 +973,11 @@ static int |
|
|
|
header_name(struct str s) |
|
|
|
header_name(struct str s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (s.size && s.text[0] == '<') { |
|
|
|
if (s.size && s.text[0] == '<') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int hcs = h_char_sequence(s); |
|
|
|
int hcs = h_char_sequence(s); |
|
|
|
if (hcs) { |
|
|
|
if (hcs) { |
|
|
|
s.text += hcs; |
|
|
|
advance(&s, hcs); |
|
|
|
s.size -= hcs; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (s.size && s.text[0] == '>') { |
|
|
|
if (s.size && s.text[0] == '>') { |
|
|
|
return(hcs + 2); |
|
|
|
return(hcs + 2); |
|
|
@ -1039,13 +986,11 @@ header_name(struct str s) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (s.size && s.text[0] == '\"') { |
|
|
|
if (s.size && s.text[0] == '\"') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int qcs = q_char_sequence(s); |
|
|
|
int qcs = q_char_sequence(s); |
|
|
|
if (qcs) { |
|
|
|
if (qcs) { |
|
|
|
s.text += qcs; |
|
|
|
advance(&s, qcs); |
|
|
|
s.size -= qcs; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (s.size && s.text[0] == '\"') { |
|
|
|
if (s.size && s.text[0] == '\"') { |
|
|
|
return(qcs + 2); |
|
|
|
return(qcs + 2); |
|
|
@ -1064,18 +1009,15 @@ comment(struct str s) |
|
|
|
if (s.size >= 2) { |
|
|
|
if (s.size >= 2) { |
|
|
|
if (s.text[0] == '/' && s.text[1] == '/') { |
|
|
|
if (s.text[0] == '/' && s.text[1] == '/') { |
|
|
|
/* single-line comment */ |
|
|
|
/* single-line comment */ |
|
|
|
s.text += 2; |
|
|
|
advance(&s, 2); |
|
|
|
s.size -= 2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (s.size) { |
|
|
|
while (s.size) { |
|
|
|
if (s.text[0] == '\n') { |
|
|
|
if (s.text[0] == '\n') { |
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return(start - s.size); |
|
|
|
return(start - s.size); |
|
|
@ -1086,13 +1028,11 @@ comment(struct str s) |
|
|
|
|
|
|
|
|
|
|
|
while (s.size) { |
|
|
|
while (s.size) { |
|
|
|
if (s.size >= 2 && s.text[0] == '*' && s.text[1] == '/') { |
|
|
|
if (s.size >= 2 && s.text[0] == '*' && s.text[1] == '/') { |
|
|
|
s.text += 2; |
|
|
|
advance(&s, 2); |
|
|
|
s.size -= 2; |
|
|
|
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
s.text++; |
|
|
|
advance(&s, 1); |
|
|
|
s.size--; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return(start - s.size); |
|
|
|
return(start - s.size); |
|
|
@ -1109,8 +1049,7 @@ lex(char *text, int size) |
|
|
|
|
|
|
|
|
|
|
|
while (s.size) { |
|
|
|
while (s.size) { |
|
|
|
int sym = whitespace(s); |
|
|
|
int sym = whitespace(s); |
|
|
|
s.text += sym; |
|
|
|
advance(&s, sym); |
|
|
|
s.size -= sym; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((sym = comment(s))) { |
|
|
|
if ((sym = comment(s))) { |
|
|
|
//printf("Comment: ");
|
|
|
|
//printf("Comment: ");
|
|
|
@ -1136,8 +1075,7 @@ lex(char *text, int size) |
|
|
|
//printf("%.*s\n", sym, s.text);
|
|
|
|
//printf("%.*s\n", sym, s.text);
|
|
|
|
|
|
|
|
|
|
|
|
if (sym) { |
|
|
|
if (sym) { |
|
|
|
s.text += sym; |
|
|
|
advance(&s, sym); |
|
|
|
s.size -= sym; |
|
|
|
|
|
|
|
} else if (s.size) { |
|
|
|
} else if (s.size) { |
|
|
|
fprintf(stderr, "Error!\n"); |
|
|
|
fprintf(stderr, "Error!\n"); |
|
|
|
break; |
|
|
|
break; |
|
|
@ -1168,22 +1106,17 @@ preprocess(char *data, int size) |
|
|
|
static void |
|
|
|
static void |
|
|
|
run(char *data, int size) |
|
|
|
run(char *data, int size) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct timespec tp = { 0 }; |
|
|
|
unsigned long long before = usec_now(); |
|
|
|
|
|
|
|
{ |
|
|
|
clock_gettime(CLOCK_MONOTONIC_RAW, &tp); |
|
|
|
preprocess(data, size); |
|
|
|
unsigned long long before = tp.tv_sec * 1000000ULL + tp.tv_nsec / 1000ULL; |
|
|
|
struct token *tokens = lex(data, size); |
|
|
|
|
|
|
|
(void) tokens; |
|
|
|
preprocess(data, size); |
|
|
|
} |
|
|
|
struct token *tokens = lex(data, size); |
|
|
|
unsigned long long after = usec_now(); |
|
|
|
(void) tokens; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC_RAW, &tp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long long after = tp.tv_sec * 1000000ULL + tp.tv_nsec / 1000ULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long long dt = after - before; |
|
|
|
float dt = after - before; |
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "%.2fms, %.2fMB/s\n", (float) dt / 1000, (float) size / dt); |
|
|
|
fprintf(stderr, "%.2fms, %.2fMB/s\n", dt / 1000, size / dt); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
int |
|
|
|