#!/bin/awk -f
#
-# Copyright © 2023 Nick Bowler
+# Copyright © 2023-2024 Nick Bowler
#
# Hackjob to improve the horrible yytname array generated by Bison.
#
# At the end of the yytname definition, output our replacement function.
in_table && $0 ~ /^};/ {
print "#if !defined(UINT_LEAST8_MAX) || !defined(UINT_LEAST16_MAX)";
- print "# include <stdint.h>";
+ print "# include <inttypes.h>";
print "#endif";
print "#ifndef assert";
print "# include <assert.h>";
- print "#endif\n";
+ print "#endif";
+ print "#ifndef offsetof";
+ print "# include <stddef.h>";
+ print "#endif\n"
print "static const char *tname(unsigned x)";
print "{";
count = bucketsort(sorted_tokens, tokens);
- table = build_strtab(sorted_tokens, count, token_offsets);
- token_offset_max = TMAX;
- nterm_offset = TLEN;
-
- sub("\1$", "", table);
- gsub("\1", "\"\n\t\t\"\\0\" \"", table);
- gsub("\2", "\\", table);
-
- print "\tstatic const char tname_strings[] =";
- print "\t\t \"" table "\"";
+ token_table = build_strtab(sorted_tokens, count, token_offsets);
+ token_size = TLEN;
+ offset_max = TMAX;
if ((count = bucketsort(sorted_nterms, nterms))) {
- table = build_strtab(sorted_nterms, count, nterm_offsets);
- offset_max = nterm_offset + TMAX;
- offset_chk = "(YYDEBUG ? " offset_max " : " token_offset_max ")";
+ nterm_table = build_strtab(sorted_nterms, count, nterm_offsets);
+ offset_max = token_size + TMAX;
+ nterm_size = TLEN;
+ } else {
+ nterm_table = "";
+ nterm_size = 0;
+ }
- sub("\1$", "", table);
- gsub("\1", "\"\n\t\t\"\\0\" \"", table);
- gsub("\2", "\\", table);
+ print "\tstruct tname_data {";
+ print "#if YYDEBUG";
+ print "\t\tuint_least16_t map[" num_tokens + num_nterms "];";
+ print "\t\tchar tab[" token_size + nterm_size "];";
+ print "#else"
+ print "\t\tuint_least16_t map[" num_tokens "];";
+ print "\t\tchar tab[" token_size "];";
+ print "#endif";
+ print "\t};";
+ print "\n\tenum { O = offsetof(struct tname_data, tab) };";
+ print "\tstatic const struct tname_data data = {";
+ print "\t\t{";
+ print_offsets(token_offsets, tokens, num_tokens, log10(offset_max));
+ if (num_nterms) {
print "#if YYDEBUG";
- if (nterm_offset)
- print "\t\t\"\\0\" \"" table "\"";
- else
- print "\t\t \"" table "\"";
+ print_offsets(nterm_offsets, nterms, num_nterms, log10(offset_max), token_size);
print "#endif";
- } else {
- offset_chk = offset_max = token_offset_max;
}
- print "\t\t;\n";
-
- print "\tstatic const";
- print "#if UINT_LEAST8_MAX >= " offset_chk;
- print "\tuint_least8_t";
- print "#elif UINT_LEAST16_MAX >= " offset_chk;
- print "\tuint_least16_t";
- print "#else";
- print "\tuint_least32_t";
- print "#endif";
- print "\ttname_offsets[] = {";
- print_offsets(token_offsets, tokens, num_tokens, log10(offset_max));
+ sub("\1$", "\"", token_table);
+ gsub("\1", "\"\n\t\t\"\\0\" \"", token_table);
+ gsub("\2", "\\", token_table);
+ print "\t\t}, \"" token_table;
+
if (num_nterms) {
print "#if YYDEBUG";
- print_offsets(nterm_offsets, nterms, num_nterms, log10(offset_max), nterm_offset);
+ sub("\1$", "\"", nterm_table);
+ gsub("\1", "\"\n\t\t\"\\0\" \"", nterm_table);
+ gsub("\2", "\\", nterm_table);
+ print "\t\t\"\\0\" \"" nterm_table;
print "#endif";
}
- print "\t};\n";
- print "\tassert(x < sizeof tname_offsets / sizeof tname_offsets[0]);";
- print "\treturn tname_strings + tname_offsets[x];";
+ print "\t};";
+
+ print "\n\tassert(x < sizeof data.map / sizeof data.map[0]);"
+ print "\treturn (char *)&data + data.map[x];";
print "}";
in_table = 0;
s = "";
for (i = 0; i < in_count; i++) {
- s = s sprintf("%" (in_w+1) "d,", (in_offsets[in_strings[i]] + in_adj));
+ s = s sprintf("%" (in_w+1) "d+O,", (in_offsets[in_strings[i]] + in_adj));
if (i+1 == in_count)
sub(/,$/, "", s);
}
}
- print t s;
+ if (i%8 != 0)
+ print t s;
}
# bucketsort(dst, src)