bin_PROGRAMS = re2c
win_BINARIES = $(WINBUILDDIR)/re2c.exe
-re2c_SOURCES = code.cc dfa.cc main.cc parser.cc actions.cc scanner.re substr.cc range.cc \
+re2c_SOURCES = cases.cc code.cc dfa.cc main.cc parser.cc actions.cc scanner.re substr.cc range.cc \
translate.cc scanner.cc mbo_getopt.cc print.cc input.cc input_api.cc output.cc \
enc.cc utf8.cc utf8_range.cc utf8_regexp.cc utf16.cc utf16_range.cc utf16_regexp.cc range_suffix.cc \
- basics.h code.h code_names.h dfa.h enc.h indent.h input.h input_api.h free_list.h globals.h ins.h \
+ basics.h cases.h code.h code_names.h dfa.h enc.h indent.h input.h input_api.h free_list.h globals.h ins.h \
mbo_getopt.h parser.h print.h range.h range_suffix.h re.h \
scanner.h smart_ptr.h substr.h token.h output.h \
utf16.h utf16_range.h utf16_regexp.h utf8.h utf8_range.h utf8_regexp.h
--- /dev/null
+#include "cases.h"
+
+namespace re2c {
+
+Cases::Cases (const Span * span, uint span_size)
+ : def (span[span_size - 1].to)
+ , cases (new Case[span_size - 1])
+ , cases_size (0)
+{
+ for (uint i = 0, lb = 0; i < span_size - 1; ++ i)
+ {
+ if (span[i].to != def)
+ {
+ add (lb, span[i].ub, span[i].to);
+ }
+ lb = span[i].ub;
+ }
+}
+
+void Cases::add (uint lb, uint ub, State * to)
+{
+ for (uint i = 0; i < cases_size; ++i)
+ {
+ if (cases[i].to == to)
+ {
+ cases[i].ranges.push_back (std::make_pair (lb, ub));
+ return;
+ }
+ }
+ cases[cases_size].ranges.push_back (std::make_pair (lb, ub));
+ cases[cases_size].to = to;
+ ++cases_size;
+}
+
+uint Cases::size () const
+{
+ return cases_size;
+}
+
+State * Cases::default_case () const
+{
+ return def;
+}
+
+const Case & Cases::operator [] (uint i) const
+{
+ return cases[i];
+}
+
+Cases::~Cases ()
+{
+ delete [] cases;
+}
+
+} // namespace re2c
#include <iostream>
#include <sstream>
+#include "cases.h"
#include "code.h"
#include "globals.h"
#include "dfa.h"
}
}
-static bool genCases(OutputFile & o, uint ind, uint lb, Span *s, bool &newLine, uint mask)
+static bool genCases (OutputFile & o, uint ind, const std::vector<std::pair<uint, uint> > & ranges, uint mask)
{
bool used = false;
- if (!newLine)
- {
- o << "\n";
- }
- newLine = true;
- if (lb < s->ub)
+ for (uint i = 0; i < ranges.size (); ++i)
{
- for (;;)
+ for (uint b = ranges[i].first; b < ranges[i].second; ++b)
{
- if (!mask || lb > 0x00FF)
+ if (!mask || b > 0x00FF) // FIXME: delete this condition, check somewhere in unmap
{
o << indent(ind) << "case ";
- o.write_char_hex (lb);
+ o.write_char_hex (b);
o << ":";
if (dFlag && encoding.is(Enc::EBCDIC))
{
- const uint c = encoding.decodeUnsafe(lb);
+ const uint c = encoding.decodeUnsafe(b);
if (isprint(c))
o << " /* " << std::string(1, c) << " */";
}
- newLine = false;
used = true;
}
-
- if (++lb == s->ub)
+ bool last_case = i == ranges.size () - 1 && b == ranges[i].second - 1;
+ if (!last_case)
{
- break;
+ o << "\n";
}
-
- o << "\n";
- newLine = true;
}
}
void Go::genSwitch(OutputFile & o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
{
- bool newLine = true;
-
if ((mask ? wSpans : nSpans) <= 2)
{
genLinear(o, ind, from, next, readCh, mask);
}
else
{
- State *def = span[nSpans - 1].to;
- Span **sP = new Span * [nSpans - 1], **r, **s, **t;
-
- t = &sP[0];
-
- for (uint i = 0; i < nSpans; ++i)
- {
- if (span[i].to != def)
- {
- *(t++) = &span[i];
- }
- }
+ Cases cases (span, nSpans);
if (dFlag)
{
o << indent(ind) << "switch (" << mapCodeName["yych"] << ") {\n";
}
- while (t != &sP[0])
+ for (uint i = 0; i < cases.size (); ++i)
{
- bool used = false;
-
- r = s = &sP[0];
-
- const State *to = (*s)->to;
-
- if (*s == &span[0])
- {
- used |= genCases(o, ind, 0, *s, newLine, mask);
- }
- else
- {
- used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
- }
-
- while (++s < t)
- {
- if ((*s)->to == to)
- {
- used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
- }
- else
- {
- *(r++) = *s;
- }
- }
-
- if (used)
- {
- genGoTo(o, newLine ? ind+1 : 1, from, to, readCh);
- newLine = true;
- }
- t = r;
+ genCases (o, ind, cases[i].ranges, mask);
+ genGoTo(o, 1, from, cases[i].to, readCh);
}
o << indent(ind) << "default:";
- genGoTo(o, 1, from, def, readCh);
+ genGoTo(o, 1, from, cases.default_case (), readCh);
o << indent(ind) << "}\n";
-
- delete [] sP;
}
}