Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
lalr.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:insignificant reason:build-tool
4
5#include "lalr.h"
6
7#include <limits.h>
8
9#include <algorithm>
10
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
17
18using namespace Qt::StringLiterals;
19
22{
23 static QTextStream result(stderr, QTextStream::WriteOnly);
24 return result;
25}
26
28{
29 static QTextStream result(stdout, QTextStream::WriteOnly);
30 return result;
31}
32QT_END_NAMESPACE
33
34namespace std {
35bool operator < (Name a, Name b)
36{
37 return *a < *b;
38}
39
41{
42 return &*a < &*b;
43}
44
46{
47 return &*a < &*b;
48}
49}
50
51bool Read::operator < (const Read &other) const
52{
53 if (state == other.state)
54 return nt < other.nt;
55
56 return state < other.state;
57}
58
59bool Include::operator < (const Include &other) const
60{
61 if (state == other.state)
62 return nt < other.nt;
63
64 return state < other.state;
65}
66
67bool Lookback::operator < (const Lookback &other) const
68{
69 if (state == other.state)
70 return nt < other.nt;
71
72 return state < other.state;
73}
74
75QTextStream &operator << (QTextStream &out, const Name &n)
76{
77 return out << *n;
78}
79
80QTextStream &operator << (QTextStream &out, const Rule &r)
81{
82 out << *r.lhs << " ::=";
83
84 for (NameList::const_iterator name = r.rhs.begin (); name != r.rhs.end (); ++name)
85 out << " " << **name;
86
87 return out;
88}
89
90QTextStream &operator << (QTextStream &out, const NameSet &ns)
91{
92 out << "{";
93
94 for (NameSet::const_iterator n = ns.begin (); n != ns.end (); ++n)
95 {
96 if (n != ns.begin ())
97 out << ", ";
98
99 out << *n;
100 }
101
102 return out << "}";
103}
104
105Item Item::next () const
106{
107 Q_ASSERT (! isReduceItem ());
108
109 Item n;
110 n.rule = rule;
111 n.dot = dot;
112 ++n.dot;
113
114 return n;
115}
116
117QTextStream &operator << (QTextStream &out, const Item &item)
118{
119 RulePointer r = item.rule;
120
121 out << *r->lhs << ":";
122 for (NameList::iterator name = r->rhs.begin (); name != r->rhs.end (); ++name)
123 {
124 out << " ";
125
126 if (item.dot == name)
127 out << ". ";
128
129 out << **name;
130 }
131
132 if (item.isReduceItem ())
133 out << " .";
134
135 return out;
136}
137
139 defaultReduce (g->rules.end ())
140{
141}
142
143std::pair<ItemPointer, bool> State::insert(const Item &item)
144{
145 ItemPointer it = std::find (kernel.begin (), kernel.end (), item);
146
147 if (it != kernel.end ())
148 return {it, false};
149
150 return {kernel.insert(it, item), true};
151}
152
153std::pair<ItemPointer, bool> State::insertClosure(const Item &item)
154{
155 ItemPointer it = std::find (closure.begin (), closure.end (), item);
156
157 if (it != closure.end ())
158 return {it, false};
159
160 return {closure.insert (it, item), true};
161}
162
163
164/////////////////////////////////////////////////////////////
165// Grammar
166/////////////////////////////////////////////////////////////
168 start (names.end ())
169{
172 current_prec = 0;
174
175 table_name = "parser_table"_L1;
176
177 tk_end = intern ("$end");
178 terminals.insert (tk_end);
179 spells.insert (tk_end, "end of file"_L1);
180
181 /*tk_error= terminals.insert (intern ("error"))*/;
182}
183
184Name Grammar::intern (const QString &id)
185{
186 Name name = std::find (names.begin (), names.end (), id);
187
188 if (name == names.end ())
189 name = names.insert (names.end (), id);
190
191 return name;
192}
193
195{
196 NameSet undefined;
197 for (RulePointer rule = rules.begin (); rule != rules.end (); ++rule)
198 {
199 for (NameList::iterator it = rule->rhs.begin (); it != rule->rhs.end (); ++it)
200 {
201 Name name = *it;
202 if (isTerminal (name) || declared_lhs.find (name) != declared_lhs.end ()
203 || undefined.find (name) != undefined.end ())
204 continue;
205
206 undefined.insert(name);
207 fprintf (stderr, "*** Warning. Symbol `%s' is not defined\n", qPrintable (*name));
208 }
209
210 rule_map.insert (rule->lhs, rule);
211 }
212}
213
215{
216 accept_symbol = intern ("$accept");
217 goal = rules.insert (rules.end (), Rule ());
218 goal->lhs = accept_symbol;
219 goal->rhs.push_back (start);
220 goal->rhs.push_back (tk_end);
221
223}
224
226{
229
231 _M_automaton (aut) {}
232
233 bool operator () (Name name) const
234 { return _M_automaton->nullables.find (name) == _M_automaton->nullables.end (); }
235};
236
238 _M_grammar (g),
239 start (states.end ())
240{
241}
242
244{
245 return 1 + std::distance (_M_grammar->rules.begin (), rule);
246}
247
248int Automaton::id (Name name)
249{
250 return std::distance (_M_grammar->names.begin (), name);
251}
252
254{
255 return std::distance (states.begin (), state);
256}
257
259{
260 Item item;
262 item.dot = _M_grammar->goal->rhs.begin ();
263
265 tmp.insert (item);
266 start = internState (tmp).first;
267
269
276}
277
279{
280 bool changed = true;
281
282 while (changed)
283 {
284 changed = false;
285
286 for (RulePointer rule = _M_grammar->rules.begin (); rule != _M_grammar->rules.end (); ++rule)
287 {
288 NameList::iterator nn = std::find_if(rule->rhs.begin(), rule->rhs.end(), NotNullable(this));
289
290 if (nn == rule->rhs.end ())
291 changed |= nullables.insert (rule->lhs).second;
292 }
293 }
294
296 qerr() << "nullables = {" << nullables << Qt::endl;
297#endif
298}
299
300std::pair<StatePointer, bool> Automaton::internState(const State &state)
301{
302 StatePointer it = std::find (states.begin (), states.end (), state);
303
304 if (it != states.end ())
305 return {it, false};
306
307 return {states.insert (it, state), true};
308}
309
311{
313
314 void insert (ItemPointer item)
315 { items.push_back (item); }
316
318 {
319 State st (aut->_M_grammar);
320
321 for (auto &item : items)
322 st.insert(item->next());
323
324 return st;
325 }
326};
327
329{
330 if (! state->closure.empty ()) // ### not true.
331 return;
332
333 typedef QMap<Name, _Bucket> bucket_map_type;
334
335 bucket_map_type buckets;
336 QStack<ItemPointer> working_list;
337
338 for (ItemPointer item = state->kernel.begin (); item != state->kernel.end (); ++item)
339 working_list.push (item);
340
341 state->closure = state->kernel;
342
343 while (! working_list.empty ())
344 {
345 ItemPointer item = working_list.top ();
346 working_list.pop ();
347
348 if (item->isReduceItem ())
349 continue;
350
351 buckets [*item->dot].insert (item);
352
353 if (_M_grammar->isNonTerminal (*item->dot))
354 {
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)
357 {
358 const RulePointer &rule = *it;
359 Item ii;
360 ii.rule = rule;
361 ii.dot = rule->rhs.begin ();
362
363 std::pair<ItemPointer, bool> r = state->insertClosure(ii);
364
365 if (r.second)
366 working_list.push (r.first);
367 }
368 }
369 }
370
371 QList<StatePointer> todo;
372
373 for (bucket_map_type::iterator bucket = buckets.begin (); bucket != buckets.end (); ++bucket)
374 {
375 std::pair<StatePointer, bool> r = internState(bucket->toState(this));
376
377 StatePointer target = r.first;
378
379 if (r.second)
380 todo.push_back (target);
381
382 state->bundle.insert (bucket.key(), target);
383 }
384
385 while (! todo.empty ())
386 {
387 closure (todo.front ());
388 todo.pop_front ();
389 }
390}
391
393{
394 for (StatePointer p = states.begin (); p != states.end (); ++p)
395 {
396 for (Bundle::iterator a = p->bundle.begin (); a != p->bundle.end (); ++a)
397 {
398 Name A = a.key ();
399
401 continue;
402
403 const auto range = std::as_const(_M_grammar->rule_map).equal_range(A);
404 for (auto it = range.first; it != range.second; ++it)
405 {
406 const RulePointer &rule = *it;
407 StatePointer q = p;
408
409 for (NameList::iterator dot = rule->rhs.begin (); dot != rule->rhs.end (); ++dot)
410 q = q->bundle.value (*dot, states.end ());
411
412 Q_ASSERT (q != states.end ());
413
414 ItemPointer item = q->closure.begin ();
415
416 for (; item != q->closure.end (); ++item)
417 {
418 if (item->rule == rule && item->dot == item->end_rhs ())
419 break;
420 }
421
422 if (item == q->closure.end ())
423 {
424 Q_ASSERT (q == p);
425 Q_ASSERT (rule->rhs.begin () == rule->rhs.end ());
426
427 for (item = q->closure.begin (); item != q->closure.end (); ++item)
428 {
429 if (item->rule == rule && item->dot == item->end_rhs ())
430 break;
431 }
432 }
433
434 Q_ASSERT (item != q->closure.end ());
435
436 lookbacks.insert (item, Lookback (p, A));
437
439 qerr() << "*** (" << id (q) << ", " << *rule << ") lookback (" << id (p) << ", " << *A << ")" << Qt::endl;
440#endif
441 }
442 }
443 }
444}
445
447{
448 for (StatePointer q = states.begin (); q != states.end (); ++q)
449 {
450 for (Bundle::iterator a = q->bundle.begin (); a != q->bundle.end (); ++a)
451 {
452 if (! _M_grammar->isNonTerminal (a.key ()))
453 continue;
454
455 StatePointer r = a.value ();
456
457 for (Bundle::iterator z = r->bundle.begin (); z != r->bundle.end (); ++z)
458 {
459 Name sym = z.key ();
460
461 if (! _M_grammar->isTerminal (sym))
462 continue;
463
464 q->reads [a.key ()].insert (sym);
465 }
466 }
467
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;
471#endif
472 }
473}
474
476{
477 for (StatePointer q = states.begin (); q != states.end (); ++q)
478 {
479 for (Bundle::iterator a = q->bundle.begin (); a != q->bundle.end (); ++a)
480 {
481 if (! _M_grammar->isNonTerminal (a.key ()))
482 continue;
483
484 StatePointer r = a.value ();
485
486 for (Bundle::iterator z = r->bundle.begin (); z != r->bundle.end (); ++z)
487 {
488 Name sym = z.key ();
489
490 if (! _M_grammar->isNonTerminal(sym) || nullables.find (sym) == nullables.end ())
491 continue;
492
493 ReadsGraph::iterator source = ReadsGraph::get (Read (q, a.key ()));
494 ReadsGraph::iterator target = ReadsGraph::get (Read (r, sym));
495
496 source->insertEdge (target);
497
499 qerr() << "*** ";
500 dump (qerr(), source);
501 qerr() << " reads ";
502 dump (qerr(), target);
503 qerr() << Qt::endl;
504#endif
505 }
506 }
507 }
508}
509
511{
514
515 _M_reads_dfn = 0;
516
517 for (ReadsGraph::iterator node = ReadsGraph::begin_nodes (); node != ReadsGraph::end_nodes (); ++node)
518 {
519 if (! node->root)
520 continue;
521
522 visitReadNode (node);
523 }
524
525 for (ReadsGraph::iterator node = ReadsGraph::begin_nodes (); node != ReadsGraph::end_nodes (); ++node)
526 visitReadNode (node);
527}
528
530{
531 if (node->dfn != 0)
532 return; // nothing to do
533
534 int N = node->dfn = ++_M_reads_dfn;
535 _M_reads_stack.push (node);
536
538 // qerr() << "*** Debug. visit node (" << id (node->data.state) << ", " << node->data.nt << ") N = " << N << Qt::endl;
539#endif
540
541 for (ReadsGraph::edge_iterator edge = node->begin (); edge != node->end (); ++edge)
542 {
543 ReadsGraph::iterator r = *edge;
544
546
547 node->dfn = qMin (N, r->dfn);
548
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 ());
552 }
553
554 if (node->dfn == N)
555 {
556 ReadsGraph::iterator tos = _M_reads_stack.top ();
557
558 do {
559 tos = _M_reads_stack.top ();
560 _M_reads_stack.pop ();
561 tos->dfn = INT_MAX;
562 } while (tos != node);
563 }
564}
565
567{
568 for (StatePointer p = states.begin (); p != states.end (); ++p)
569 p->follows = p->reads;
570
572
573 _M_includes_dfn = 0;
574
575 for (IncludesGraph::iterator node = IncludesGraph::begin_nodes (); node != IncludesGraph::end_nodes (); ++node)
576 {
577 if (! node->root)
578 continue;
579
581 }
582
583 for (IncludesGraph::iterator node = IncludesGraph::begin_nodes (); node != IncludesGraph::end_nodes (); ++node)
585}
586
588{
589 for (StatePointer pp = states.begin (); pp != states.end (); ++pp)
590 {
591 for (Bundle::iterator a = pp->bundle.begin (); a != pp->bundle.end (); ++a)
592 {
593 Name name = a.key ();
594
596 continue;
597
598 const auto range = std::as_const(_M_grammar->rule_map).equal_range(name);
599 for (auto it = range.first; it != range.second; ++it)
600 {
601 const RulePointer &rule = *it;
602 StatePointer p = pp;
603
604 for (NameList::iterator A = rule->rhs.begin (); A != rule->rhs.end (); ++A)
605 {
606 NameList::iterator dot = A;
607 ++dot;
608
609 if (_M_grammar->isNonTerminal (*A) && dot == rule->rhs.end ())
610 {
611 // found an include edge.
612 IncludesGraph::iterator target = IncludesGraph::get (Include (pp, name));
613 IncludesGraph::iterator source = IncludesGraph::get (Include (p, *A));
614
615 source->insertEdge (target);
616
618 qerr() << "*** (" << id (p) << ", " << *A << ") includes (" << id (pp) << ", " << *name << ")" << Qt::endl;
619#endif // QLALR_NO_DEBUG_INCLUDES
620
621 continue;
622 }
623
624 p = p->bundle.value (*A);
625
627 continue;
628
629 NameList::iterator first_not_nullable = std::find_if(dot, rule->rhs.end(), NotNullable(this));
630 if (first_not_nullable != rule->rhs.end ())
631 continue;
632
633 // found an include edge.
634 IncludesGraph::iterator target = IncludesGraph::get (Include (pp, name));
635 IncludesGraph::iterator source = IncludesGraph::get (Include (p, *A));
636
637 source->insertEdge (target);
638
640 qerr() << "*** (" << id (p) << ", " << *A << ") includes (" << id (pp) << ", " << *name << ")" << Qt::endl;
641#endif // QLALR_NO_DEBUG_INCLUDES
642 }
643 }
644 }
645 }
646}
647
649{
650 if (node->dfn != 0)
651 return; // nothing to do
652
653 int N = node->dfn = ++_M_includes_dfn;
654 _M_includes_stack.push (node);
655
657 // qerr() << "*** Debug. visit node (" << id (node->data.state) << ", " << node->data.nt << ") N = " << N << Qt::endl;
658#endif
659
660 for (IncludesGraph::edge_iterator edge = node->begin (); edge != node->end (); ++edge)
661 {
662 IncludesGraph::iterator r = *edge;
663
665
666 node->dfn = qMin (N, r->dfn);
667
669 qerr() << "*** Merge. follows";
670 dump (qerr(), node);
671 qerr() << " += follows";
672 dump (qerr(), r);
673 qerr() << Qt::endl;
674#endif
675
676 NameSet &dst = node->data.state->follows [node->data.nt];
677 NameSet &src = r->data.state->follows [r->data.nt];
678
679 dst.insert (src.begin (), src.end ());
680 }
681
682 if (node->dfn == N)
683 {
684 IncludesGraph::iterator tos = _M_includes_stack.top ();
685
686 do {
687 tos = _M_includes_stack.top ();
688 _M_includes_stack.pop ();
689 tos->dfn = INT_MAX;
690 } while (tos != node);
691 }
692}
693
695{
696 for (StatePointer p = states.begin (); p != states.end (); ++p)
697 {
698 for (ItemPointer item = p->closure.begin (); item != p->closure.end (); ++item)
699 {
700 const auto range = std::as_const(lookbacks).equal_range(item);
701 for (auto it = range.first; it != range.second; ++it)
702 {
703 const Lookback &lookback = *it;
704 StatePointer q = lookback.state;
705
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;
710#endif
711
712 lookaheads [item].insert (q->follows [lookback.nt].begin (), q->follows [lookback.nt].end ());
713 }
714 }
715
716 // propagate the lookahead in the kernel
717 ItemPointer k = p->kernel.begin ();
718 ItemPointer c = p->closure.begin ();
719
720 for (; k != p->kernel.end (); ++k, ++c)
721 lookaheads [k] = lookaheads [c];
722 }
723}
724
726{
727 for (StatePointer state = states.begin (); state != states.end (); ++state)
728 {
729 ItemPointer def = state->closure.end ();
730 int size = -1;
731
732 for (ItemPointer item = state->closure.begin (); item != state->closure.end (); ++item)
733 {
734 if (item->dot != item->end_rhs ())
735 continue;
736
737 int la = static_cast<int>(lookaheads.value(item).size());
738 if (def == state->closure.end () || la > size)
739 {
740 def = item;
741 size = la;
742 }
743 }
744
745 if (def != state->closure.end ())
746 {
747 Q_ASSERT (size >= 0);
748 state->defaultReduce = def->rule;
749 }
750 }
751}
752
753void Automaton::dump (QTextStream &out, IncludeNode incl)
754{
755 out << "(" << id (incl->data.state) << ", " << incl->data.nt << ")";
756}
757
758void Automaton::dump (QTextStream &out, ReadNode rd)
759{
760 out << "(" << id (rd->data.state) << ", " << rd->data.nt << ")";
761}
762
763void Automaton::dump (QTextStream &out, const Lookback &lp)
764{
765 out << "(" << id (lp.state) << ", " << lp.nt << ")";
766}
void buildReadsDigraph()
Definition lalr.cpp:475
Automaton(Grammar *g)
Definition lalr.cpp:237
int id(RulePointer rule)
Definition lalr.cpp:243
ReadsGraph::iterator ReadNode
Definition lalr.h:317
void buildDefaultReduceActions()
Definition lalr.cpp:725
void buildNullables()
Definition lalr.cpp:278
StatePointer start
Definition lalr.h:353
void build()
Definition lalr.cpp:258
void visitReadNode(ReadNode node)
Definition lalr.cpp:529
void buildReads()
Definition lalr.cpp:510
void buildIncludesDigraph()
Definition lalr.cpp:587
std::pair< StatePointer, bool > internState(const State &state)
Definition lalr.cpp:300
IncludesGraph::iterator IncludeNode
Definition lalr.h:320
NameSet nullables
Definition lalr.h:354
void buildIncludesAndFollows()
Definition lalr.cpp:566
Grammar * _M_grammar
Definition lalr.h:351
void buildLookaheads()
Definition lalr.cpp:694
void buildDirectReads()
Definition lalr.cpp:446
StateList states
Definition lalr.h:352
void buildLookbackSets()
Definition lalr.cpp:392
void visitIncludeNode(IncludeNode node)
Definition lalr.cpp:648
void closure(StatePointer state)
Definition lalr.cpp:328
@ NonAssoc
Definition lalr.h:252
Name intern(const char *id)
Definition lalr.h:220
int expected_reduce_reduce
Definition lalr.h:249
Name accept_symbol
Definition lalr.h:246
Name tk_end
Definition lalr.h:245
Assoc current_assoc
Definition lalr.h:263
NameSet terminals
Definition lalr.h:239
NameSet declared_lhs
Definition lalr.h:247
debug_infot rules
Definition lalr.h:242
Name start
Definition lalr.h:238
int current_prec
Definition lalr.h:264
bool isNonTerminal(Name name) const
Definition lalr.h:225
bool isTerminal(Name name) const
Definition lalr.h:222
void buildRuleMap()
Definition lalr.cpp:194
Grammar()
Definition lalr.cpp:167
RulePointer goal
Definition lalr.h:244
RuleMap rule_map
Definition lalr.h:243
void buildExtendedGrammar()
Definition lalr.cpp:214
Name intern(const QString &id)
Definition lalr.cpp:184
NameSet non_terminals
Definition lalr.h:240
int expected_shift_reduce
Definition lalr.h:248
bool operator<(const Include &other) const
Definition lalr.cpp:59
Name nt
Definition lalr.h:306
StatePointer state
Definition lalr.h:305
[0]
Definition lalr.h:84
bool isReduceItem() const
Definition lalr.h:98
Item next() const
Definition lalr.cpp:105
RulePointer rule
Definition lalr.h:104
StatePointer state
Definition lalr.h:79
bool operator<(const Lookback &other) const
Definition lalr.cpp:67
Name nt
Definition lalr.h:80
Definition lalr.h:268
bool operator<(const Read &other) const
Definition lalr.cpp:51
StatePointer state
Definition lalr.h:284
Name nt
Definition lalr.h:285
Definition lalr.h:49
NameList rhs
Definition lalr.h:60
Name lhs
Definition lalr.h:59
QT_FORWARD_DECLARE_CLASS(QTextStream)
#define QLALR_NO_DEBUG_DIRECT_READS
Definition lalr.cpp:13
#define QLALR_NO_DEBUG_READS
Definition lalr.cpp:14
#define QLALR_NO_DEBUG_LOOKAHEADS
Definition lalr.cpp:16
#define QLALR_NO_DEBUG_NULLABLES
Definition lalr.cpp:11
#define QLALR_NO_DEBUG_INCLUDES
Definition lalr.cpp:15
#define QLALR_NO_DEBUG_LOOKBACKS
Definition lalr.cpp:12
std::set< Name > NameSet
Definition lalr.h:30
ItemList::iterator ItemPointer
Definition lalr.h:34
StateList::iterator StatePointer
Definition lalr.h:43
QTextStream & qout()
Definition qev.cpp:12
std::list< QString >::iterator Name
Definition lalr.h:28
QTextStream & operator<<(QTextStream &out, const Rule &r)
Definition lalr.cpp:80
debug_infot::iterator RulePointer
Definition lalr.h:38
QTextStream & operator<<(QTextStream &out, const Item &item)
Definition lalr.cpp:117
bool operator<(Name a, Name b)
Definition lalr.cpp:35
QDataStream & operator<<(QDataStream &stream, const QImage &image)
[0]
Definition qimage.cpp:4012
NotNullable(Automaton *aut)
Definition lalr.cpp:230
bool operator()(Name name) const
Definition lalr.cpp:233
Name argument_type
Definition lalr.cpp:227
Automaton * _M_automaton
Definition lalr.cpp:228
std::pair< ItemPointer, bool > insertClosure(const Item &item)
Definition lalr.cpp:153
std::pair< ItemPointer, bool > insert(const Item &item)
Definition lalr.cpp:143
RulePointer defaultReduce
Definition lalr.h:128
State(Grammar *grammar)
Definition lalr.cpp:138
ItemList closure
Definition lalr.h:124
ItemList kernel
Definition lalr.h:123
std::list< ItemPointer > items
Definition lalr.cpp:312
State toState(Automaton *aut)
Definition lalr.cpp:317
void insert(ItemPointer item)
Definition lalr.cpp:314