31 return "bux::TID_EOF";
33 return "<@> aka bux::ROOT_NID";
36 return std::format(
"bux::TOKENGEN_LB+{}", token -
TOKENGEN_LB);
38 std::string out = std::format(
"0x{:x}", token);
39 if (isascii(
int(token)))
48 m_ErrState(std::numeric_limits<
T_StateID>::max()),
57 info.
m_attr.assign(unownedAttr,
true);
63 add(token, info, unreadStack);
71 onError(info,
"Already accepted");
78 if (m_ShiftCountdown && !--m_ShiftCountdown)
81 std::function<void()> t;
82 t.swap(m_OnPostShift);
90 std::function<void()> t;
91 t.swap(m_OnPostShift);
96 onError(info,
"Reduction error on acception");
104 if (m_ErrState == std::numeric_limits<T_StateID>::max())
106 m_ErrState = currentState();
108 m_ErrPos = info.
m_pos;
111 if (recover(token, info, unreadStack))
114 info.
m_attr.assign(0,
false);
120 auto out = std::format(
"Syntax error on state={} token={}", m_ErrState,
m_Policy.
printToken(m_ErrToken));
121 if (
auto *attr =info.
m_attr.get())
122 out.append(
" of attr type ").append(
HRTN(*attr));
124 out +=
" with null attr";
126 if (m_CurStack.
empty())
127 out +=
"\nEmpty stack";
130 out += std::format(
"\nStack[{}] Dump:", m_CurStack.
size()-1);
132 for (
const auto &i: m_CurStack)
137 out += std::format(
"\n({},{})\t{}\ts={}\tt={}",
146 panicRollback(unreadStack);
147 m_ErrState = std::numeric_limits<T_StateID>::max();
155 if (reduceOn(prodId, info.
m_pos))
157 m_ErrState = std::numeric_limits<T_StateID>::max();
160 onError(info,
"Reduction error on production "+std::to_string(prodId));
162 onError(info,
"Unknown action id "+std::to_string(actionid));
166 if (!unreadStack.empty())
168 token = unreadStack.top().m_TokenID;
169 info = unreadStack.top();
177 if (m_CurStack.empty())
180 return m_CurStack.top().m_StateID;
188void C_Parser::panicRollback(C_StateStackLR1 &unreadStack)
191 for (finalSize = 0; finalSize < m_CurStack.size(); ++finalSize)
197 while (!unreadStack.empty())
199 m_CurStack.push(unreadStack.top());
202 while (m_CurStack.size() > finalSize)
204 C_StateLR1 &top = m_CurStack.top();
206 unreadStack.push(top);
212bool C_Parser::recover(
T_LexID token,
C_LexInfo &info, C_StateStackLR1 &unreadStack)
215 for (
auto i = m_CurStack.size(); i; --i, isLast =
false)
223 if (!isLast && info.m_pos == m_CurStack[i].m_pos)
227 for (
size_t j = i; j; --j, isLast =
false)
229 if (m_CurStack[j-1].m_pos < (isLast?info.m_pos:m_CurStack[j].m_pos))
235 auto &t = unreadStack.push();
238 while (m_CurStack.size() > i)
240 unreadStack.push(m_CurStack.top());
243 info.m_pos = unreadStack.top().m_pos;
250bool C_Parser::reduceOn(
size_t id,
const C_SourcePos &pos)
252 I_ParserPolicy::C_ReduceInfo ri;
254 if (m_CurStack.size() >= ri.m_PopLength)
256 const auto base = m_CurStack.end() - ri.m_PopLength;
260 [=,
this,size=ri.m_PopLength](
size_t n)->C_LexInfo& {
262 onError(pos,
"Production["+std::to_string(id)+
"] out of range "+std::to_string(n)+
'/'+std::to_string(size));
268 li.m_pos = base->m_pos;
269 m_CurStack.pop(ri.m_PopLength);
274 shift(ri.m_ResultID, li);
282 m_ShiftCountdown = shifts;
283 m_OnPostShift = calledOnce;
288 const auto ret = m_CurSrc;
295 const auto state = currentState();
296 auto &t = m_CurStack.push();