{
std::string str;
- while (ind-- > 0)
+ while (!DFlag && ind-- > 0)
{
str += indString;
}
void genGoTo(std::ostream &o, uint ind, const State *from, const State *to, bool & readCh)
{
+ if (DFlag)
+ {
+ o << from->label << " -> " << to->label << "\n";
+ return;
+ }
+
if (readCh && from->label + 1 != to->label)
{
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMarker)
{
+ if (DFlag)
+ {
+ return;
+ }
+
uint fillIndex = next_fill_index;
if (fFlag)
void Match::emit(std::ostream &o, uint ind, bool &readCh, const std::string&) const
{
+ if (DFlag)
+ {
+ return;
+ }
+
if (state->link)
{
o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
void Save::emit(std::ostream &o, uint ind, bool &readCh, const std::string&) const
{
+ if (DFlag)
+ {
+ return;
+ }
+
if (bUsedYYAccept)
{
o << indent(ind) << mapCodeName["yyaccept"] << " = " << selector << ";\n";
if (mapRules.size() > 0)
{
bUsedYYMarker = true;
- o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYMARKER"] << ";\n";
+ if (!DFlag)
+ {
+ o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYMARKER"] << ";\n";
+ }
if (readCh) // shouldn't be necessary, but might become at some point
{
{
emitBinary(o, ind, 0, mapRules.size() - 1, readCh);
}
+ else if (DFlag)
+ {
+ for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
+ {
+ o << state->label << " -> " << it->second->label;
+ o << " [label=\"yyaccept=" << it->first << "\"]\n";
+ }
+ }
else
{
o << indent(ind) << "switch (" << mapCodeName["yyaccept"] << ") {\n";
void Rule::emit(std::ostream &o, uint ind, bool &, const std::string& condName) const
{
+ if (DFlag)
+ {
+ o << state->label << " [label=\"" << sourceFileInfo.fname << ":" << rule->code->line << "\"];\n";
+ return;
+ }
+
uint back = rule->ctx->fixedLength();
if (back != 0u)
genIf(o, ind, "!=", s[0].ub, readCh);
genGoTo(o, 0, from, bg, readCh);
}
- if (next->label != from->label + 1)
+ if (next->label != from->label + 1 || DFlag)
{
genGoTo(o, ind, from, next, readCh);
}
if (n == 1)
{
// if(bg != next){
- if (s[0].to->label != from->label + 1)
+ if (s[0].to->label != from->label + 1 || DFlag)
{
genGoTo(o, ind, from, s[0].to, readCh);
}
genIf(o, ind, ">=", s[0].ub, readCh);
genGoTo(o, 0, from, s[1].to, readCh);
}
- if (next->label != from->label + 1)
+ if (next->label != from->label + 1 || DFlag)
{
genGoTo(o, ind, from, next, readCh);
}
}
}
- if (next->label != from->label + 1)
+ if (next->label != from->label + 1 || DFlag)
{
genGoTo(o, ind, from, next, readCh);
}
doLinear(o, ind, span, nSpans, from, next, readCh, mask);
}
-bool genCases(std::ostream &o, uint ind, uint lb, Span *s, bool &newLine, uint mask)
+bool genCases(std::ostream &o, uint ind, uint lb, Span *s, bool &newLine, uint mask, const State *from, const State *to)
{
bool used = false;
{
if (!mask || lb > 0x00FF)
{
- o << indent(ind) << "case ";
- prtChOrHex(o, lb);
- o << ":";
+ if (DFlag)
+ {
+ o << from->label << " -> " << to->label;
+ o << " [label=";
+ prtChOrHex(o, lb);
+ o << "]";
+ }
+ else
+ {
+ o << indent(ind) << "case ";
+ prtChOrHex(o, lb);
+ o << ":";
+ }
newLine = false;
used = true;
}
}
}
- if (dFlag)
+ if (!DFlag)
{
- o << indent(ind) << mapCodeName["YYDEBUG"] << "(-1, " << mapCodeName["yych"] << ");\n";
- }
+ if (dFlag)
+ {
+ o << indent(ind) << mapCodeName["YYDEBUG"] << "(-1, " << mapCodeName["yych"] << ");\n";
+ }
- if (readCh)
- {
- o << indent(ind) << "switch ((" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")) {\n";
- readCh = false;
- }
- else
- {
- o << indent(ind) << "switch (" << mapCodeName["yych"] << ") {\n";
+ if (readCh)
+ {
+ o << indent(ind) << "switch ((" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")) {\n";
+ readCh = false;
+ }
+ else
+ {
+ o << indent(ind) << "switch (" << mapCodeName["yych"] << ") {\n";
+ }
}
while (t != &sP[0])
r = s = &sP[0];
+ const State *to = (*s)->to;
+
if (*s == &span[0])
{
- used |= genCases(o, ind, 0, *s, newLine, mask);
+ used |= genCases(o, ind, 0, *s, newLine, mask, from, to);
}
else
{
- used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
+ used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask, from, to);
}
- State *to = (*s)->to;
-
while (++s < t)
{
if ((*s)->to == to)
{
- used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
+ used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask, from, to);
}
else
{
}
}
- if (used)
+ if (used && !DFlag)
{
genGoTo(o, newLine ? ind+1 : 1, from, to, readCh);
newLine = true;
t = r;
}
- o << indent(ind) << "default:";
- genGoTo(o, 1, from, def, readCh);
- o << indent(ind) << "}\n";
+ if (DFlag)
+ {
+ o << "\n" << from->label << " -> " << def->label;
+ o << " [label=default]\n" ;
+ }
+ else
+ {
+ o << indent(ind) << "default:";
+ genGoTo(o, 1, from, def, readCh);
+ o << indent(ind) << "}\n";
+ }
delete [] sP;
}
if (bProlog)
{
o << "\n" << outputFileInfo;
- if ((!fFlag && bUsedYYAccept)
+
+ if (DFlag)
+ {
+ bPrologBrace = true;
+ o << "digraph re2c {\n";
+ }
+ else if ((!fFlag && bUsedYYAccept)
|| (!fFlag && bEmitYYCh)
|| (bFlag && !cFlag && BitMap::first)
|| (cFlag && !bWroteCondCheck && gFlag && !specMap->empty())
{
ind = 1;
}
-
- if (!fFlag)
+
+ if (!fFlag && !DFlag)
{
if (bEmitYYCh)
{
{
o << replaceParam(condDivider, condDividerParam, condName) << "\n";
}
- o << condPrefix << condName << ":\n";
+
+ if (DFlag)
+ {
+ o << condName << " -> " << (start_label+1) << "\n";
+ }
+ else
+ {
+ o << condPrefix << condName << ":\n";
+ }
}
if (cFlag && bFlag && BitMap::first)
{
}
genCondGotoSub(o, ind, vCondList, 0, vCondList.size() - 1);
}
+ else if (DFlag)
+ {
+ for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it)
+ {
+ o << "0 -> " << it->first << " [label=\"state=" << it->first << "\"]\n";
+ }
+ }
else
{
o << indent(ind) << "switch (" << genGetCondition() << ") {\n";
bool bFlag = false;
bool cFlag = false;
bool dFlag = false;
+bool DFlag = false;
bool eFlag = false;
bool fFlag = false;
bool FFlag = false;
mbo_opt_struct('b', 0, "bit-vectors"),
mbo_opt_struct('c', 0, "start-conditions"),
mbo_opt_struct('d', 0, "debug-output"),
+ mbo_opt_struct('D', 0, "emit-dot"),
mbo_opt_struct('e', 0, "ecb"),
mbo_opt_struct('f', 0, "storable-state"),
mbo_opt_struct('F', 0, "flex-syntax"),
mbo_opt_struct('u', 0, "unicode"),
mbo_opt_struct('v', 0, "version"),
mbo_opt_struct('V', 0, "vernum"),
- mbo_opt_struct('w', 0, "wide-chars"),
+ mbo_opt_struct('w', 0, "wide-chars"),
mbo_opt_struct('1', 0, "single-pass"),
mbo_opt_struct(10, 0, "no-generation-date"),
mbo_opt_struct(11, 0, "case-insensitive"),
static void usage()
{
- cerr << "usage: re2c [-bdefghisvVw1] [-o file] file\n"
+ cerr << "usage: re2c [-bcdDefFghisvVw1] [-o file] file\n"
"\n"
"-? -h --help Display this info.\n"
"\n"
" about the current position and in which state the\n"
" parser is.\n"
"\n"
+ "-D --emit-dot Emit a Graphviz dot view of the DFA graph\n"
+ "\n"
"-e --ecb Cross-compile from an ASCII platform to\n"
" an EBCDIC one.\n"
"\n"
dFlag = true;
break;
+ case 'D':
+ DFlag = true;
+ iFlag = true;
+ break;
+
case 'f':
fFlag = true;
break;