11#define QLALR_NO_DEBUG_NULLABLES
12#define QLALR_NO_DEBUG_LOOKBACKS
13#define QLALR_NO_DEBUG_DIRECT_READS
14#define QLALR_NO_DEBUG_READS
15#define QLALR_NO_DEBUG_INCLUDES
16#define QLALR_NO_DEBUG_LOOKAHEADS
18using namespace Qt::StringLiterals;
23 static QTextStream result(stderr, QTextStream::WriteOnly);
29 static QTextStream result(stdout, QTextStream::WriteOnly);
82 out << *r
.lhs <<
" ::=";
84 for (NameList::const_iterator name = r
.rhs.begin (); name != r
.rhs.end (); ++name)
94 for (NameSet::const_iterator n = ns.begin (); n != ns.end (); ++n)
121 out << *r->lhs <<
":";
122 for (NameList::iterator name = r->rhs.begin (); name != r->rhs.end (); ++name)
126 if (item.dot == name)
150 return {
kernel.insert(it, item),
true};
160 return {
closure.insert (it, item),
true};
175 table_name =
"parser_table"_L1;
179 spells.insert (tk_end,
"end of file"_L1);
186 Name name =
std::find (names.begin (), names.end (), id);
188 if (name == names.end ())
189 name = names.insert (names.end (), id);
199 for (NameList::iterator it = rule->rhs.begin (); it != rule->rhs.end (); ++it)
203 || undefined.find (name) != undefined.end ())
206 undefined.insert(name);
207 fprintf (stderr,
"*** Warning. Symbol `%s' is not defined\n", qPrintable (*name));
255 return std::distance (
states.begin (), state);
288 NameList::iterator nn =
std::find_if(rule->rhs.begin(), rule->rhs.end(),
NotNullable(this));
290 if (nn == rule->rhs.end ())
291 changed |=
nullables.insert (rule->lhs).second;
296 qerr() <<
"nullables = {" << nullables << Qt::endl;
307 return {
states.insert (it, state),
true};
315 { items.push_back (item); }
321 for (
auto &item : items)
322 st.insert(item->next());
330 if (! state->closure.empty ())
333 typedef QMap<Name, _Bucket> bucket_map_type;
335 bucket_map_type buckets;
336 QStack<ItemPointer> working_list;
338 for (
ItemPointer item = state->kernel.begin (); item != state->kernel.end (); ++item)
339 working_list.push (item);
341 state->closure = state->kernel;
343 while (! working_list.empty ())
348 if (item->isReduceItem ())
351 buckets [*item->dot].insert (item);
355 const auto range = std::as_const(_M_grammar->rule_map).equal_range(*item->dot);
356 for (
auto it = range.first; it != range.second; ++it)
361 ii.dot = rule->rhs.begin ();
366 working_list.push (r.first);
371 QList<StatePointer> todo;
373 for (bucket_map_type::iterator bucket = buckets.begin (); bucket != buckets.end (); ++bucket)
380 todo.push_back (target);
382 state->bundle.insert (bucket.key(), target);
385 while (! todo.empty ())
396 for (Bundle::iterator a = p->bundle.begin (); a != p->bundle.end (); ++a)
403 const auto range = std::as_const(_M_grammar->rule_map).equal_range(A);
404 for (
auto it = range.first; it != range.second; ++it)
409 for (NameList::iterator dot = rule->rhs.begin (); dot != rule->rhs.end (); ++dot)
410 q = q->bundle.value (*dot,
states.end ());
412 Q_ASSERT (q !=
states.end ());
416 for (; item != q->closure.end (); ++item)
418 if (item->rule == rule && item->dot == item->end_rhs ())
422 if (item == q->closure.end ())
425 Q_ASSERT (rule->rhs.begin () == rule->rhs.end ());
427 for (item = q->closure.begin (); item != q->closure.end (); ++item)
429 if (item->rule == rule && item->dot == item->end_rhs ())
434 Q_ASSERT (item != q->closure.end ());
436 lookbacks.insert (item, Lookback (p, A));
439 qerr() <<
"*** (" << id (q) <<
", " << *rule <<
") lookback (" << id (p) <<
", " << *A <<
")" << Qt::endl;
450 for (Bundle::iterator a = q->bundle.begin (); a != q->bundle.end (); ++a)
457 for (Bundle::iterator z = r->bundle.begin (); z != r->bundle.end (); ++z)
464 q->reads [a.key ()].insert (sym);
469 for (QMap<Name, NameSet>::iterator dr = q->reads.begin (); dr != q->reads.end (); ++dr)
470 qerr() <<
"*** DR(" << id (q) <<
", " << dr.key () <<
") = " << dr.value () << Qt::endl;
479 for (Bundle::iterator a = q->bundle.begin (); a != q->bundle.end (); ++a)
486 for (Bundle::iterator z = r->bundle.begin (); z != r->bundle.end (); ++z)
493 ReadsGraph::iterator source = ReadsGraph::get (Read (q, a.key ()));
494 ReadsGraph::iterator target = ReadsGraph::get (Read (r, sym));
496 source->insertEdge (target);
500 dump (qerr(), source);
502 dump (qerr(), target);
517 for (ReadsGraph::iterator node = ReadsGraph::begin_nodes (); node != ReadsGraph::end_nodes (); ++node)
525 for (ReadsGraph::iterator node = ReadsGraph::begin_nodes (); node != ReadsGraph::end_nodes (); ++node)
534 int N = node->dfn = ++_M_reads_dfn;
535 _M_reads_stack.push (node);
541 for (ReadsGraph::edge_iterator edge = node->begin (); edge != node->end (); ++edge)
543 ReadsGraph::iterator r = *edge;
547 node->dfn = qMin (N, r->dfn);
549 NameSet &dst = node->data.state->reads [node->data.nt];
550 NameSet &src = r->data.state->reads [r->data.nt];
551 dst.insert (src.begin (), src.end ());
556 ReadsGraph::iterator tos = _M_reads_stack.top ();
559 tos = _M_reads_stack.top ();
560 _M_reads_stack.pop ();
562 }
while (tos != node);
569 p->follows = p->reads;
575 for (IncludesGraph::iterator node = IncludesGraph::begin_nodes (); node != IncludesGraph::end_nodes (); ++node)
583 for (IncludesGraph::iterator node = IncludesGraph::begin_nodes (); node != IncludesGraph::end_nodes (); ++node)
591 for (Bundle::iterator a = pp->bundle.begin (); a != pp->bundle.end (); ++a)
593 Name name = a.key ();
598 const auto range = std::as_const(_M_grammar->rule_map).equal_range(name);
599 for (
auto it = range.first; it != range.second; ++it)
604 for (NameList::iterator A = rule->rhs.begin (); A != rule->rhs.end (); ++A)
606 NameList::iterator dot = A;
612 IncludesGraph::iterator target = IncludesGraph::get (Include (pp, name));
613 IncludesGraph::iterator source = IncludesGraph::get (Include (p, *A));
615 source->insertEdge (target);
618 qerr() <<
"*** (" << id (p) <<
", " << *A <<
") includes (" << id (pp) <<
", " << *name <<
")" << Qt::endl;
624 p = p->bundle.value (*A);
629 NameList::iterator first_not_nullable =
std::find_if(dot, rule->rhs.end(),
NotNullable(this));
630 if (first_not_nullable != rule->rhs.end ())
634 IncludesGraph::iterator target = IncludesGraph::get (Include (pp, name));
635 IncludesGraph::iterator source = IncludesGraph::get (Include (p, *A));
637 source->insertEdge (target);
640 qerr() <<
"*** (" << id (p) <<
", " << *A <<
") includes (" << id (pp) <<
", " << *name <<
")" << Qt::endl;
653 int N = node->dfn = ++_M_includes_dfn;
654 _M_includes_stack.push (node);
660 for (IncludesGraph::edge_iterator edge = node->begin (); edge != node->end (); ++edge)
662 IncludesGraph::iterator r = *edge;
666 node->dfn = qMin (N, r->dfn);
669 qerr() <<
"*** Merge. follows";
671 qerr() <<
" += follows";
676 NameSet &dst = node->data.state->follows [node->data.nt];
677 NameSet &src = r->data.state->follows [r->data.nt];
679 dst.insert (src.begin (), src.end ());
684 IncludesGraph::iterator tos = _M_includes_stack.top ();
687 tos = _M_includes_stack.top ();
688 _M_includes_stack.pop ();
690 }
while (tos != node);
698 for (
ItemPointer item = p->closure.begin (); item != p->closure.end (); ++item)
700 const auto range = std::as_const(lookbacks).equal_range(item);
701 for (
auto it = range.first; it != range.second; ++it)
707 qerr() <<
"(" << id (p) <<
", " << *item->rule <<
") lookbacks ";
708 dump (qerr(), lookback);
709 qerr() <<
" with follows (" << id (q) <<
", " << lookback.nt <<
") = " << q->follows [lookback.nt] << Qt::endl;
712 lookaheads [item].insert (q->follows [lookback.nt].begin (), q->follows [lookback.nt].end ());
720 for (; k != p->kernel.end (); ++k, ++c)
721 lookaheads [k] = lookaheads [c];
732 for (
ItemPointer item = state->closure.begin (); item != state->closure.end (); ++item)
734 if (item->dot != item->end_rhs ())
737 int la =
static_cast<
int>(lookaheads.value(item).size());
738 if (def == state->closure.end () || la > size)
745 if (def != state->closure.end ())
747 Q_ASSERT (size >= 0);
748 state->defaultReduce = def->rule;
753void Automaton::dump (QTextStream &out, IncludeNode incl)
755 out <<
"(" << id (incl->data.state) <<
", " << incl->data.nt <<
")";
760 out <<
"(" << id (rd->data.state) <<
", " << rd->data.nt <<
")";
763void Automaton::dump (QTextStream &out,
const Lookback &lp)
765 out <<
"(" << id (lp.state) <<
", " << lp.nt <<
")";
ReadsGraph::iterator ReadNode
void buildDefaultReduceActions()
void visitReadNode(ReadNode node)
void buildIncludesDigraph()
std::pair< StatePointer, bool > internState(const State &state)
IncludesGraph::iterator IncludeNode
void buildIncludesAndFollows()
void visitIncludeNode(IncludeNode node)
void closure(StatePointer state)
Name intern(const char *id)
int expected_reduce_reduce
bool isNonTerminal(Name name) const
bool isTerminal(Name name) const
void buildExtendedGrammar()
Name intern(const QString &id)
int expected_shift_reduce
bool operator<(const Include &other) const
bool isReduceItem() const
bool operator<(const Lookback &other) const
bool operator<(const Read &other) const
QT_FORWARD_DECLARE_CLASS(QTextStream)
#define QLALR_NO_DEBUG_DIRECT_READS
#define QLALR_NO_DEBUG_READS
#define QLALR_NO_DEBUG_LOOKAHEADS
#define QLALR_NO_DEBUG_NULLABLES
#define QLALR_NO_DEBUG_INCLUDES
#define QLALR_NO_DEBUG_LOOKBACKS
ItemList::iterator ItemPointer
StateList::iterator StatePointer
std::list< QString >::iterator Name
QTextStream & operator<<(QTextStream &out, const Rule &r)
debug_infot::iterator RulePointer
QTextStream & operator<<(QTextStream &out, const Item &item)
bool operator<(Name a, Name b)
QDataStream & operator<<(QDataStream &stream, const QImage &image)
[0]
NotNullable(Automaton *aut)
bool operator()(Name name) const
std::pair< ItemPointer, bool > insertClosure(const Item &item)
std::pair< ItemPointer, bool > insert(const Item &item)
RulePointer defaultReduce
std::list< ItemPointer > items
State toState(Automaton *aut)
void insert(ItemPointer item)