1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
#include "srconflict.ih"
// called fm processshiftreduceconflict.cc
// A conflict was observed as item 'reducibleItemIdx' and
// 'shiftableItemIdx' have identical LA symbols
//
void SRConflict::handleSRconflict(Next::ConstIter const &next,
size_t reducibleItemIdx)
{
using Solution = Enum::Solution;
StateItem::Vector const &itemVector = d_itemVector;
Symbol const *precedence = itemVector[reducibleItemIdx].precedence();
bool forced = false;
Solution solution;
// the reducible item does not
if (precedence == 0) // have an explicit precedence
{
// solution = Solution::REDUCE; // force a reduction
solution = Solution::SHIFT; // force a shift
forced = true;
++s_nConflicts; // and a conflict
}
else // otherwise try to solve by
{ // precedence or association
solution = next->solveByPrecedence(precedence);
if (solution == Solution::UNDECIDED)
solution = next->solveByAssociation();
}
switch (solution) // perform SHIFT or REDUCE
{
case Solution::REDUCE:
d_rmShift.push_back(
RmShift(
next - d_nextVector.begin(),
forced)
);
return;
case Solution::UNDECIDED:
forced = true;
++s_nConflicts;
break;
default: // case SHIFT:
break;
}
if (d_lastItemIdx == reducibleItemIdx and d_lastNext == next->next())
{
if (forced)
--s_nConflicts;
return;
}
d_lastItemIdx = reducibleItemIdx;
d_lastNext = next->next();
d_rmReduction.push_back(
RmReduction{ reducibleItemIdx, next->next(), next->symbol(), forced }
);
}
|