namespace re2c {
+typedef std::vector<std::string> code_lines_t;
+
void emit_action(OutputFile &o, uint32_t ind, bool &readCh,
const DFA &dfa, const State *s, const std::set<label_t> &used_labels);
-void gen_goto(OutputFile &o, uint32_t ind, bool &readCh,
+void gen_goto_plain(OutputFile &o, uint32_t ind, bool &readCh,
const State *to, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
void gen_goto_case(OutputFile &o, uint32_t ind, bool &readCh,
const State *to, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
void gen_goto_if(OutputFile &o, uint32_t ind, bool &readCh,
const State *to, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
-void gen_settags(OutputFile &o, uint32_t ind, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
+void gen_settags(code_lines_t &code, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
std::string vartag_name(const std::string *name, size_t rule);
std::string vartag_expr(const std::string *name, size_t rule);
std::string vartag_name_fallback(const Tag &tag);
#include "src/parse/code.h"
#include "src/parse/loc.h"
#include "src/util/strrreplace.h"
+#include "src/util/to_string.h"
namespace re2c
{
static void genYYFill(OutputFile &o, size_t need);
static void genSetCondition(OutputFile &o, uint32_t ind, const std::string &cond);
static void genSetState(OutputFile &o, uint32_t ind, uint32_t fillIndex);
+static void gen_goto(code_lines_t &code, bool &readCh, const State *to, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
void emit_action(OutputFile &o, uint32_t ind, bool &readCh,
const DFA &dfa, const State *s, const std::set<label_t> &used_labels)
o.wind(--ind).ws("}\n");
} else {
const accept_t &acc = *s->action.info.accepts;
- gen_goto(o, ind, readCh, acc[l].first, dfa, acc[l].second, true);
+ gen_goto_plain(o, ind, readCh, acc[l].first, dfa, acc[l].second, true);
}
}
// only one possible 'yyaccept' value: unconditional jump
if (nacc == 1) {
- gen_goto(o, ind, readCh, acc[0].first, dfa, acc[0].second, true);
+ gen_goto_plain(o, ind, readCh, acc[0].first, dfa, acc[0].second, true);
return;
}
const State *to, const DFA &dfa, const tagcmd_t &tags,
bool restore_fallback)
{
- const bool multiline = readCh || !tags.empty();
+ code_lines_t code;
+ gen_goto(code, readCh, to, dfa, tags, restore_fallback);
+ const size_t lines = code.size();
- if (multiline) {
- o.ws("\n");
- gen_goto(o, ind + 1, readCh, to, dfa, tags, restore_fallback);
+ if (lines == 1) {
+ o.wind(1).wstring(code[0]);
} else {
- gen_goto(o, 1, readCh, to, dfa, tags, restore_fallback);
+ o.ws("\n");
+ for (size_t i = 0; i < lines; ++i) {
+ o.wind(ind + 1).wstring(code[i]);
+ }
}
}
const State *to, const DFA &dfa, const tagcmd_t &tags,
bool restore_fallback)
{
- const int32_t linecount = (readCh && to != NULL)
- + !tags.empty()
- + (to != NULL);
+ code_lines_t code;
+ gen_goto(code, readCh, to, dfa, tags, restore_fallback);
+ const size_t lines = code.size();
- if (linecount > 1) {
+ if (lines == 1) {
+ o.wstring(code[0]);
+ } else {
o.ws("{\n");
- gen_goto(o, ind + 1, readCh, to, dfa, tags, restore_fallback);
+ for (size_t i = 0; i < lines; ++i) {
+ o.wind(ind + 1).wstring(code[i]);
+ }
o.wind(ind).ws("}\n");
- } else {
- gen_goto(o, 0, readCh, to, dfa, tags, restore_fallback);
}
}
-void gen_goto(OutputFile &o, uint32_t ind, bool &readCh,
+void gen_goto_plain(OutputFile &o, uint32_t ind, bool &readCh,
const State *to, const DFA &dfa, const tagcmd_t &tags,
bool restore_fallback)
+{
+ code_lines_t code;
+ gen_goto(code, readCh, to, dfa, tags, restore_fallback);
+ const size_t lines = code.size();
+
+ for (size_t i = 0; i < lines; ++i) {
+ o.wind(ind).wstring(code[i]);
+ }
+}
+
+void gen_goto(code_lines_t &code, bool &readCh, const State *to,
+ const DFA &dfa, const tagcmd_t &tags, bool restore_fallback)
{
if (to == NULL) {
readCh = false;
}
if (readCh) {
- o.wstring(opts->input_api.stmt_peek(ind));
+ code.push_back(opts->input_api.stmt_peek(0));
readCh = false;
}
- gen_settags(o, ind, dfa, tags, restore_fallback);
+ gen_settags(code, dfa, tags, restore_fallback);
if (to) {
- o.wind(ind).ws("goto ").wstring(opts->labelPrefix)
- .wlabel(to->label).ws(";\n");
+ code.push_back("goto " + opts->labelPrefix
+ + to_string(to->label) + ";\n");
}
}
-void gen_settags(OutputFile &o, uint32_t ind, const DFA &dfa,
+void gen_settags(code_lines_t &code, const DFA &dfa,
const tagcmd_t &cmd, bool restore_fallback)
{
if (cmd.empty()) return;
if (!dfa.basetag) {
assert(cmd.copy == ZERO_TAGS);
- o.wstring(opts->input_api.stmt_backupctx(ind));
+ code.push_back(opts->input_api.stmt_backupctx(0));
return;
}
x = vartag_expr(tag.name, tag.rule),
y = vartag_expr_fallback(tag);
if (restore_fallback) std::swap(x, y);
- o.wind(ind).wstring(y).ws(" = ").wstring(x).ws(";\n");
+ code.push_back(y + " = " + x + ";\n");
}
}
if (cmd.set != ZERO_TAGS) {
- o.wstring(opts->input_api.stmt_dist(ind, dfa.tagpool[cmd.set], tags));
+ code.push_back(opts->input_api.stmt_dist(0,
+ dfa.tagpool[cmd.set], tags));
}
}
output_if(o, ind, readCh, cond->compare, cond->value);
gen_goto_if(o, ind, readCh, b.to, dfa, b.tags, false);
} else {
- gen_goto(o, ind, readCh, b.to, dfa, b.tags, false);
+ gen_goto_plain(o, ind, readCh, b.to, dfa, b.tags, false);
}
}
}
o.wu32(bitmap->m);
}
o.ws(") {\n");
- gen_goto(o, ind + 1, readCh, bitmap_state, dfa, tagcmd_t(), false);
+ gen_goto_plain(o, ind + 1, readCh, bitmap_state, dfa, tagcmd_t(), false);
o.wind(ind).ws("}\n");
if (lgo != NULL)
{
void Go::emit (OutputFile & o, uint32_t ind, const DFA &dfa, bool & readCh)
{
- gen_settags(o, ind, dfa, tags, false);
+ code_lines_t code;
+ gen_settags(code, dfa, tags, NULL);
+ for (size_t i = 0; i < code.size(); ++i) {
+ o.wind(ind).wstring(code[i]);
+ }
+
switch (type) {
case EMPTY:
break;