Skip to content

Commit 3cd6b6d

Browse files
author
Simon Yu
committed
GUI: support LALR item sets display during automaton building
1 parent adf983e commit 3cd6b6d

File tree

1 file changed

+66
-22
lines changed

1 file changed

+66
-22
lines changed

src/parser/LALRParser.h

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,25 @@ class LALRParser : public LRParser {
5858
std::map<StateID, Constraint> transit(std::vector<State> const &lr0States,
5959
ActionID actionID,
6060
LALRClosure const &lalrClosure) {
61-
std::map<StateID, Constraint> res;
61+
std::map<StateID, Constraint> result;
6262

6363
for (auto const &[lr0StateID, constraint] : lalrClosure) {
6464
auto const &lr0State = lr0States[lr0StateID];
6565
auto const &trans = *lr0State.transitions;
6666
auto range = trans.rangeOf(actionID);
6767
for (auto it = range.first; it != range.second; ++it) {
68-
auto iter = res.find(it->destination);
69-
if (iter == res.end()) {
70-
res.emplace(it->destination, constraint);
68+
auto iter = result.find(it->destination);
69+
if (iter == result.end()) {
70+
result.emplace(it->destination, constraint);
7171
} else {
7272
// Must merge
7373
iter->second |= constraint;
7474
}
7575
}
7676
}
7777

78-
makeClosure(lr0States, res);
79-
return res;
78+
makeClosure(lr0States, result);
79+
return result;
8080
}
8181

8282
// Real constraint resolving method.
@@ -148,7 +148,7 @@ class LALRParser : public LRParser {
148148
startClosure.emplace(s0, *startState.constraint);
149149
makeClosure(lr0States, startClosure);
150150

151-
step::addState(s0, "");
151+
step::addState(s0, std::string{kernelLabelMap.back().front()} + ", $");
152152
step::setStart(s0);
153153
step::show("Add start state.");
154154
util::Formatter f;
@@ -162,21 +162,25 @@ class LALRParser : public LRParser {
162162
// Try different actions
163163
auto nAction = static_cast<int>(M.actions.size());
164164
for (int i = 0; i < nAction; ++i) {
165-
if (i == epsilonID)
165+
if (i == epsilonID) {
166166
continue;
167+
}
168+
167169
auto actionID = static_cast<ActionID>(i);
168170
auto newClosure =
169171
transit(lr0States, actionID, closureIter->first);
170172

171173
// Cannot accept this action
172-
if (newClosure.empty())
174+
if (newClosure.empty()) {
173175
continue;
174-
176+
}
177+
175178
auto iter = closureIndexMap.find(newClosure);
176179
if (iter == closureIndexMap.end()) {
177180
// Add new closure
178181
auto closureID =
179182
static_cast<StateID>(closureIndexMap.size());
183+
std::string stateInfo = this->dumpLALRClosure(newClosure);
180184
queue.push(closureIndexMap
181185
.emplace(std::move(newClosure), closureID)
182186
.first);
@@ -185,13 +189,13 @@ class LALRParser : public LRParser {
185189
M.addTransition(StateID{closureIter->second}, closureID,
186190
actionID);
187191

188-
step::addState(closureID, "");
192+
step::addState(closureID, stateInfo);
189193
step::addEdge(closureIter->second, closureID,
190194
M.actions[actionID]);
191-
auto sv = f.formatView("Trans(s%d, %s) = s%d",
192-
closureIter->second,
193-
M.actions[actionID], closureID);
194-
step::show(sv);
195+
auto message = f.formatView("Trans(s%d, %s) = s%d",
196+
closureIter->second,
197+
M.actions[actionID], closureID);
198+
step::show(message);
195199
} else {
196200
// Merge closures.
197201
// Now number of elements in two maps should be the same.
@@ -207,16 +211,16 @@ class LALRParser : public LRParser {
207211
M.addTransition(StateID{closureIter->second},
208212
StateID{iter->second}, actionID);
209213
// The merged state should be checked again
210-
if (flag)
214+
if (flag) {
211215
queue.push(iter);
216+
}
212217

213-
// step::updateState(iter->second, M.dumpClosureString(
214-
// StateID{iter->second}));
215218
step::addEdge(closureIter->second, iter->second, M.actions[actionID]);
216-
auto sv = f.formatView("Trans(s%d, %s) = s%d",
217-
closureIter->second,
218-
M.actions[actionID], iter->second);
219-
step::show(sv);
219+
step::updateState(iter->second, this->dumpLALRClosure(newClosure));
220+
auto message = f.formatView(
221+
"Trans(s%d, %s) = s%d", closureIter->second,
222+
M.actions[actionID], iter->second);
223+
step::show(message);
220224
}
221225
}
222226
}
@@ -285,6 +289,46 @@ class LALRParser : public LRParser {
285289
int rhsIndex) override {
286290
return allTermConstraint;
287291
}
292+
293+
private:
294+
std::string dumpLALRClosure(const LALRClosure &closure) const {
295+
std::string result;
296+
auto const &states = this->nfa.getAllStates();
297+
auto EOI = this->nfa.endOfInputAction;
298+
auto const &actions = this->nfa.getAllActions();
299+
bool finalFlag = false;
300+
bool newLineFlag = false;
301+
302+
for (auto &[index, constraint] : closure) {
303+
if (newLineFlag) {
304+
result += "\n";
305+
}
306+
307+
auto const &state = states[index];
308+
309+
result += escape_ascii(
310+
kernelLabelMap[state.productionID][state.rhsIndex]);
311+
312+
if (!finalFlag && constraint.contains(EOI) &&
313+
(state.rhsIndex + 1 ==
314+
kernelLabelMap[state.productionID].size())) {
315+
finalFlag = true;
316+
}
317+
318+
result += ", ";
319+
bool slash = false;
320+
for (auto actionID : constraint) {
321+
if (slash) {
322+
result += "/";
323+
}
324+
result += escape_ascii(actions[actionID]);
325+
slash = true;
326+
}
327+
328+
newLineFlag = true;
329+
}
330+
return result;
331+
}
288332
};
289333
} // namespace gram
290334

0 commit comments

Comments
 (0)