protected bool Error(ref ParseStackEntry top, string str)
{
SYMBOL er = (SYMBOL)new error(this,top); // 4.4c
if (m_debug)
Console.WriteLine("Error encountered: "+str);
er.pos = top.m_value.pos;
ParserEntry pe;
if (m_symbols.symbolInfo[0]!=null && m_symbols.erh.counter<1000) // 4.4c
// first pop the stack until we find an item that can pass error
for (;top!=null && m_stack.Count>0; Pop(ref top,1,er))
{
if (m_debug)
Console.WriteLine("Error recovery uncovers state {0}",top.m_state);
if (er.Pass(m_symbols,top.m_state, out pe))
{
SYMBOL oldtop = top.m_value;
top.m_value = er;
pe.Pass(ref top); // pass the error symbol
// now discard tokens until we find one we can pass
while (top.m_value!=m_symbols.EOFSymbol && !top.m_value.Pass(m_symbols,top.m_state, out pe))
{
SYMBOL newtop;
if (pe!=null && pe.IsReduce())
{
newtop = null;
if (pe.m_action!=null)
newtop = pe.m_action.Action(this); // before we change the stack
m_ungot = top.m_value;
Pop(ref top,((ParserReduce)pe).m_depth,er);
newtop.pos = top.m_value.pos;
top.m_value = newtop;
}
else
{ // discard it
string cnm = top.m_value.yyname;
if (m_debug)
{
if (cnm=="TOKEN")
Console.WriteLine("Error recovery discards literal {0}",(string)((TOKEN)top.m_value).yytext);
else
Console.WriteLine("Error recovery discards token {0}",cnm);
}
top.m_value = NextSym();
}
}
if (m_debug)
Console.WriteLine("Recovery complete");
m_symbols.erh.counter++;
return true;
}
}
m_symbols.erh.Error(new CSToolsException(13,m_lexer,er.pos,"syntax error",str));
top.m_value = er;
return false;
}