void DotGraph::operator () (Automaton *aut) { Grammar *g = aut->_M_grammar; out << "digraph {" << endl << endl; out << "subgraph Includes {" << endl; for (Automaton::IncludesGraph::iterator incl = Automaton::IncludesGraph::begin_nodes (); incl != Automaton::IncludesGraph::end_nodes (); ++incl) { for (Automaton::IncludesGraph::edge_iterator edge = incl->begin (); edge != incl->end (); ++edge) { out << "\t\"(" << aut->id (incl->data.state) << ", " << incl->data.nt << ")\""; out << "\t->\t"; out << "\"(" << aut->id ((*edge)->data.state) << ", " << (*edge)->data.nt << ")\"\t"; out << "[label=\"" << incl->data.state->follows [incl->data.nt] << "\"]"; out << endl; } } out << "}" << endl << endl; out << "subgraph LRA {" << endl; //out << "node [shape=record];" << endl << endl; for (StatePointer q = aut->states.begin (); q != aut->states.end (); ++q) { int state = aut->id (q); out << "\t" << state << "\t[shape=record,label=\"{"; out << "<0> State " << state; int index = 1; for (ItemPointer item = q->kernel.begin (); item != q->kernel.end (); ++item) out << "| <" << index++ << "> " << *item; out << "}\"]" << endl; for (Bundle::iterator a = q->bundle.begin (); a != q->bundle.end (); ++a) { const char *clr = g->isTerminal (a.key ()) ? "blue" : "red"; out << "\t" << state << "\t->\t" << aut->id (*a) << "\t[color=\"" << clr << "\",label=\"" << a.key () << "\"]" << endl; } out << endl; } out << "}" << endl; out << endl << endl << "}" << endl; }
void CppGenerator::operator () () { // action table... state_count = aut.states.size (); terminal_count = grammar.terminals.size (); non_terminal_count = grammar.non_terminals.size (); #define ACTION(i, j) table [(i) * terminal_count + (j)] #define GOTO(i, j) pgoto [(i) * non_terminal_count + (j)] int *table = new int [state_count * terminal_count]; ::memset (table, 0, state_count * terminal_count * sizeof (int)); int *pgoto = new int [state_count * non_terminal_count]; ::memset (pgoto, 0, state_count * non_terminal_count * sizeof (int)); accept_state = -1; int shift_reduce_conflict_count = 0; int reduce_reduce_conflict_count = 0; for (StatePointer state = aut.states.begin (); state != aut.states.end (); ++state) { int q = aut.id (state); for (Bundle::iterator a = state->bundle.begin (); a != state->bundle.end (); ++a) { int symbol = aut.id (a.key ()); int r = aut.id (a.value ()); Q_ASSERT (r < state_count); if (grammar.isNonTerminal (a.key ())) { Q_ASSERT (symbol >= terminal_count && symbol < grammar.names.size ()); GOTO (q, symbol - terminal_count) = r; } else ACTION (q, symbol) = r; } for (ItemPointer item = state->closure.begin (); item != state->closure.end (); ++item) { if (item->dot != item->end_rhs ()) continue; int r = aut.id (item->rule); NameSet lookaheads = aut.lookaheads.value (item); if (item->rule == grammar.goal) accept_state = q; foreach (Name s, lookaheads) { int &u = ACTION (q, aut.id (s)); if (u == 0) u = - r; else if (u < 0) { if (verbose) qout << "*** Warning. Found a reduce/reduce conflict in state " << q << " on token ``" << s << "'' between rule " << r << " and " << -u << endl; ++reduce_reduce_conflict_count; u = qMax (u, -r); if (verbose) qout << "\tresolved using rule " << -u << endl; } else if (u > 0) { if (item->rule->prec != grammar.names.end() && grammar.token_info.contains (s)) { Grammar::TokenInfo info_r = grammar.token_info.value (item->rule->prec); Grammar::TokenInfo info_s = grammar.token_info.value (s); if (info_r.prec > info_s.prec) u = -r; else if (info_r.prec == info_s.prec) { switch (info_r.assoc) { case Grammar::Left: u = -r; break; case Grammar::Right: // shift... nothing to do break; case Grammar::NonAssoc: u = 0; break; } // switch } } else { ++shift_reduce_conflict_count; if (verbose) qout << "*** Warning. Found a shift/reduce conflict in state " << q << " on token ``" << s << "'' with rule " << r << endl; } } } } }
void ParseTable::operator () (Automaton *aut) { Grammar *g = aut->_M_grammar; int rindex = 1; for (RulePointer rule = g->rules.begin (); rule != g->rules.end (); ++rule) out << rindex++ << ")\t" << *rule << endl; out << endl << endl; int index = 0; for (StatePointer state = aut->states.begin (); state != aut->states.end (); ++state) { out << "state " << index++ << endl << endl; for (ItemPointer item = state->kernel.begin (); item != state->kernel.end (); ++item) { out << " * " << *item; if (item->dot == item->end_rhs ()) out << " " << aut->lookaheads [item]; out << endl; } bool first = true; for (Bundle::iterator arrow = state->bundle.begin (); arrow != state->bundle.end (); ++arrow) { if (! g->isTerminal (arrow.key ())) continue; if (first) out << endl; first = false; out << " " << *arrow.key () << " shift, and go to state " << std::distance (aut->states.begin (), *arrow) << endl; } first = true; for (ItemPointer item = state->closure.begin (); item != state->closure.end (); ++item) { if (item->dot != item->end_rhs () || item->rule == state->defaultReduce) continue; if (first) out << endl; first = false; foreach (Name la, aut->lookaheads.value (item)) out << " " << *la << " reduce using rule " << aut->id (item->rule) << " (" << *item->rule->lhs << ")" << endl; } first = true; for (Bundle::iterator arrow = state->bundle.begin (); arrow != state->bundle.end (); ++arrow) { if (! g->isNonTerminal (arrow.key ())) continue; if (first) out << endl; first = false; out << " " << *arrow.key () << " go to state " << std::distance (aut->states.begin (), *arrow) << endl; } if (state->defaultReduce != g->rules.end ()) { out << endl << " $default reduce using rule " << aut->id (state->defaultReduce) << " (" << *state->defaultReduce->lhs << ")" << endl; } out << endl; } }