namespace re2c
{
-void Skeleton::emit_prolog (OutputFile & o, uint32_t maxfill)
+static void exact_uint (OutputFile & o, size_t width)
{
- std::string yyctype;
- switch (encoding.szCodeUnit ())
+ switch (width)
{
- case 1:
- yyctype = "unsigned char";
+ case sizeof (char):
+ o << "unsigned char";
break;
- case 2:
- yyctype = "unsigned short";
+ case sizeof (short):
+ o << "unsigned short";
break;
- case 4:
- yyctype = "unsigned int";
+ case sizeof (int):
+ o << "unsigned int";
+ break;
+ case sizeof (long):
+ o << "unsigned long";
+ break;
+ default:
+ o << "uint" << width * 8 << "_t";
break;
}
+}
+void Skeleton::emit_prolog (OutputFile & o, uint32_t maxfill) const
+{
o << "\n" << "#include <stdio.h>";
o << "\n" << "#include <stdlib.h> // malloc, free";
o << "\n" << "#include <string.h> // memset";
o << "\n";
- o << "\n" << "typedef " << yyctype << " YYCTYPE;";
- o << "\n" << "typedef unsigned int YYKEYTYPE;";
+
+ o << "\n" << "typedef ";
+ exact_uint (o, encoding.szCodeUnit ());
+ o << " YYCTYPE;";
+
+ o << "\n" << "typedef ";
+ exact_uint (o, sizeof_key);
+ o << " YYKEYTYPE;";
+
o << "\n";
o << "\n" << "#define YYPEEK() *cursor";
o << "\n" << "#define YYSKIP() ++cursor";
o << "\n" << indString << "}";
o << "\n" << indString << "else";
o << "\n" << indString << "{";
- o << "\n" << indString << indString << "const char * fmt = \"error at position %ld (iteration %u):\\n\"";
- o << "\n" << indString << indString << indString << "\"\\texpected: match length %ld, rule %u\\n\"";
- o << "\n" << indString << indString << indString << "\"\\tactual: match length %ld, rule %u\\n\";";
- o << "\n" << indString << indString << "fprintf (stderr, fmt, pos, i, len_exp, rule_exp, len_act, rule_act);";
+ o << "\n" << indString << indString << "fprintf";
+ o << "\n" << indString << indString << indString << "( stderr";
+ o << "\n" << indString << indString << indString << ", \"error at position %ld (iteration %u):\\n\"";
+ o << "\n" << indString << indString << indString << indString << "\"\\texpected: match length %ld, rule %u\\n\"";
+ o << "\n" << indString << indString << indString << indString << "\"\\tactual: match length %ld, rule %u\\n\"";
+ o << "\n" << indString << indString << indString << ", pos";
+ o << "\n" << indString << indString << indString << ", i";
+ o << "\n" << indString << indString << indString << ", len_exp";
+ o << "\n" << indString << indString << indString << ", rule_exp";
+ o << "\n" << indString << indString << indString << ", len_act";
+ o << "\n" << indString << indString << indString << ", rule_act";
+ o << "\n" << indString << indString << indString << ");";
o << "\n" << indString << indString << "return 1;";
o << "\n" << indString << "}";
o << "\n" << "}";
namespace re2c
{
-static void permutate_one (FILE * input, FILE * keys, const multipath_t & path);
-static arccount_t cover_one (FILE * input, FILE * keys, const multipath_t & prefix, const path_t & suffix);
+template <typename cunit_t, typename key_t>
+ static void permutate_one (FILE * input, FILE * keys, const multipath_t & path);
+template <typename cunit_t, typename key_t>
+ static arccount_t cover_one (FILE * input, FILE * keys, const multipath_t & prefix, const path_t & suffix);
/*
* note [estimating total size of paths in skeleton]
* abandoned and recursion returns immediately.
*
*/
-void Node::permutate (const multipath_t & prefix, FILE * input, FILE * keys)
+template <typename cunit_t, typename key_t>
+ void Node::permutate (const multipath_t & prefix, FILE * input, FILE * keys)
{
if (end ())
{
- permutate_one (input, keys, prefix);
+ permutate_one<cunit_t, key_t> (input, keys, prefix);
}
else if (loop < 2)
{
{
multipath_t new_prefix = prefix;
new_prefix.extend (i->first->rule, &i->second);
- i->first->permutate (new_prefix, input, keys);
+ i->first->permutate<cunit_t, key_t> (new_prefix, input, keys);
}
}
}
* abandoned and recursion returns immediately.
*
*/
-arccount_t Node::cover (const multipath_t & prefix, FILE * input, FILE * keys)
+template <typename cunit_t, typename key_t>
+ arccount_t Node::cover (const multipath_t & prefix, FILE * input, FILE * keys)
{
arccount_t size (0u);
if (suffix != NULL)
{
- size = cover_one (input, keys, prefix, *suffix);
+ size = cover_one<cunit_t, key_t> (input, keys, prefix, *suffix);
}
else if (end ())
{
{
multipath_t new_prefix = prefix;
new_prefix.extend (i->first->rule, &i->second);
- size = size + i->first->cover (new_prefix, input, keys);
+ size = size + i->first->cover<cunit_t, key_t> (new_prefix, input, keys);
if (size.overflow ())
{
return arccount_t::limit ();
return size;
}
-void Skeleton::generate_paths (FILE * input, FILE * keys)
+template <typename cunit_t, typename key_t>
+ void Skeleton::generate_paths_cunit_key (FILE * input, FILE * keys)
{
multipath_t prefix (nodes->rule);
if (nodes->sizeof_permutate (arccount_t (1u), arccount_t (0u)).overflow ())
{
- if (nodes->cover (prefix, input, keys).overflow ())
+ if (nodes->cover<cunit_t, key_t> (prefix, input, keys).overflow ())
{
warning
( NULL
}
else
{
- nodes->permutate (prefix, input, keys);
+ nodes->permutate<cunit_t, key_t> (prefix, input, keys);
+ }
+}
+
+template <typename cunit_t>
+ void Skeleton::generate_paths_cunit (FILE * input, FILE * keys)
+{
+ switch (sizeof_key)
+ {
+ case 4: generate_paths_cunit_key<cunit_t, uint32_t> (input, keys); break;
+ case 2: generate_paths_cunit_key<cunit_t, uint16_t> (input, keys); break;
+ case 1: generate_paths_cunit_key<cunit_t, uint8_t> (input, keys); break;
+ }
+}
+
+void Skeleton::generate_paths (FILE * input, FILE * keys)
+{
+ switch (encoding.szCodeUnit ())
+ {
+ case 4: generate_paths_cunit<uint32_t> (input, keys); break;
+ case 2: generate_paths_cunit<uint16_t> (input, keys); break;
+ case 1: generate_paths_cunit<uint8_t> (input, keys); break;
}
}
fclose (keys);
}
-static void keygen (FILE * f, size_t count, size_t len, size_t len_match, rule_rank_t match)
+template <typename key_t>
+ static void keygen (FILE * f, size_t count, size_t len, size_t len_match, rule_rank_t match)
{
- assert (sizeof (uint32_t) == sizeof (unsigned int));
-
const size_t keys_size = 3 * count;
- uint32_t * keys = new uint32_t [keys_size];
+ key_t * keys = new key_t [keys_size];
for (uint32_t i = 0; i < keys_size;)
{
- keys[i++] = static_cast<uint32_t> (len);
- keys[i++] = static_cast<uint32_t> (len_match);
- keys[i++] = match.uint32 ();
+ keys[i++] = static_cast<key_t> (len);
+ keys[i++] = static_cast<key_t> (len_match);
+ keys[i++] = static_cast<key_t> (match.uint32 ());
}
- fwrite (keys, sizeof (uint32_t), keys_size, f);
+ fwrite (keys, sizeof (key_t), keys_size, f);
delete [] keys;
}
-template <typename type_t>
-static void generic_permutate_one (FILE * input, FILE * keys, const multipath_t & path)
+template <typename cunit_t, typename key_t>
+ static void permutate_one (FILE * input, FILE * keys, const multipath_t & path)
{
const size_t len = path.len ();
// input
const size_t buffer_size = len * count;
- type_t * buffer = new type_t [buffer_size];
+ cunit_t * buffer = new cunit_t [buffer_size];
for (size_t i = 0, period = count; i < len; ++i)
{
const multiarc_t & arc = *path[i];
for (size_t j = 0; j < count; ++j)
{
const size_t k = (j / period) % width;
- buffer[j * len + i] = static_cast<type_t> (arc[k]);
+ buffer[j * len + i] = static_cast<cunit_t> (arc[k]);
}
}
- fwrite (buffer, sizeof (type_t), buffer_size, input);
+ fwrite (buffer, sizeof (cunit_t), buffer_size, input);
delete [] buffer;
// keys
- keygen (keys, count, len, path.len_matching (), path.match ());
-}
-
-static void permutate_one (FILE * input, FILE * keys, const multipath_t & path)
-{
- switch (encoding.szCodeUnit ())
- {
- case 4: generic_permutate_one<uint32_t> (input, keys, path); break;
- case 2: generic_permutate_one<uint16_t> (input, keys, path); break;
- case 1: generic_permutate_one<uint8_t> (input, keys, path); break;
- }
+ keygen<key_t> (keys, count, len, path.len_matching (), path.match ());
}
-template <typename type_t>
-static arccount_t generic_cover_one (FILE * input, FILE * keys, const multipath_t & prefix, const path_t & suffix)
+template <typename cunit_t, typename key_t>
+ static arccount_t cover_one (FILE * input, FILE * keys, const multipath_t & prefix, const path_t & suffix)
{
const size_t prefix_len = prefix.len ();
const size_t suffix_len = suffix.len ();
{
// input
const size_t buffer_size = size.uint32 ();
- type_t * buffer = new type_t [buffer_size];
+ cunit_t * buffer = new cunit_t [buffer_size];
for (size_t i = 0; i < prefix_len; ++i)
{
const std::vector<uint32_t> & arc = *prefix[i];
for (size_t j = 0; j < count; ++j)
{
const size_t k = j % width;
- buffer[j * len + i] = static_cast<type_t> (arc[k]);
+ buffer[j * len + i] = static_cast<cunit_t> (arc[k]);
}
}
for (size_t i = 0; i < suffix_len; ++i)
{
- const type_t c = static_cast<type_t> (suffix[i]);
+ const cunit_t c = static_cast<cunit_t> (suffix[i]);
const size_t k = prefix_len + i;
for (size_t j = 0; j < count; ++j)
{
buffer[j * len + k] = c;
}
}
- fwrite (buffer, sizeof (type_t), buffer_size, input);
+ fwrite (buffer, sizeof (cunit_t), buffer_size, input);
delete [] buffer;
// keys
const rule_rank_t match = none
? prefix.match ()
: suffix.match ();
- keygen (keys, count, len, len_match, match);
+ keygen<key_t> (keys, count, len, len_match, match);
}
return size;
}
-static arccount_t cover_one (FILE * input, FILE * keys, const multipath_t & prefix, const path_t & suffix)
-{
- switch (encoding.szCodeUnit ())
- {
- case 4: return generic_cover_one<uint32_t> (input, keys, prefix, suffix);
- case 2: return generic_cover_one<uint16_t> (input, keys, prefix, suffix);
- case 1: return generic_cover_one<uint8_t> (input, keys, prefix, suffix);
- default: return arccount_t (0u);
- }
-}
-
} // namespace re2c