long time = System.currentTimeMillis();
int state = 0; // Current state
int i, j, oldstate;
IntegerList stack = new IntegerList();
stack.push(0); // First state is zero
Stack treestack = new Stack();
int tokenindex = -1; // Index of the token from the input
while (true)
{
state = stack.peek();
/* ============================= Reading token ================================ */
if (tokenindex < 0)
{
do
{
scanner.readNextToken(state);
tokenindex = scanner.getTokenIndex();
//System.out.println("tokenindex="+tokenindex+" ignorable="+scanner.isIgnorable());
if (scanner.isIgnorable())
{
TokenContainer tokencontainer = new TokenContainer();
tokencontainer.tokenindex = tokenindex;
tokencontainer.textstart = scanner.getTextStart();
tokencontainer.textlength = scanner.getTextLength();
tokencontainer.ignorable = true;
treestack.push(tokencontainer);
}
} while ((tokenindex>=0) && (scanner.isIgnorable()));
if (tokenindex < 0)
{
if (_logger!=null)
_logger.debug("State " + state + " no token could get recognized");
Vector acceptedsymbols = new Vector();
for (tokenindex = 0; tokenindex < table.getTerminalSymbolCount(); tokenindex++)
if (!table.isErrorAction(state, tokenindex))
acceptedsymbols.addElement(table.getTerminalSymbol(tokenindex));
String[] symbols = new String[acceptedsymbols.size()];
for (i = 0; i < acceptedsymbols.size(); i++)
symbols[i] = (String) acceptedsymbols.elementAt(i);
throw new ParserException("Token was not recognized",
scanner.getLineNumber(),
scanner.getColumnNumber(), symbols);
}
}
switch (table.getAction(state, tokenindex))
{
/* ================================== Error =================================== */
case ParserTable.ERROR :
if (_logger!=null)
_logger.debug("State " + state + " error token \"" +
Decoder.decode(new String(text, scanner.getTextStart(), scanner.getTextLength())) +
"\"("+table.getTerminalSymbol(tokenindex)+")");
Vector acceptedsymbols = new Vector();
for (tokenindex = 0; tokenindex < table.getTerminalSymbolCount(); tokenindex++)
if (!table.isErrorAction(state, tokenindex))
acceptedsymbols.addElement(table.getTerminalSymbol(tokenindex));
String[] symbols = new String[acceptedsymbols.size()];
for (i = 0; i < acceptedsymbols.size(); i++)
symbols[i] = (String) acceptedsymbols.elementAt(i);
throw new ParserException("Token was not recognized",
scanner.getLineNumber(),
scanner.getColumnNumber(), symbols);
/* ==================================== Shift =================================== */
case ParserTable.SHIFT :
if (_logger!=null)
_logger.debug("State " + state + " shift token \"" +
Decoder.decode(new String(text, scanner.getTextStart(), scanner.getTextLength())) +
"\"("+table.getTerminalSymbol(tokenindex)+")");
TokenContainer tokencontainer = new TokenContainer();
tokencontainer.tokenindex = tokenindex;
tokencontainer.textstart = scanner.getTextStart();
tokencontainer.textlength = scanner.getTextLength();
treestack.push(tokencontainer);
stack.push(table.getActionArgument(state, tokenindex));
tokenindex = -1;
break;
/* ============================ Reduce & Accept =================================== */
case ParserTable.REDUCE :
case ParserTable.ACCEPT :
if (_logger!=null)
_logger.debug("State " + state + " reduce by " +
table.getNonTerminalSymbol(table.getProductionSymbol(
table.getActionArgument(state, tokenindex))) +
" (" + (table.getActionArgument(state, tokenindex)) + ")");
ProductionContainer newcontainer = new ProductionContainer();
newcontainer.productionindex = table.getActionArgument(state, tokenindex);
for (i = 0; i < table.getProductionLength(table.getActionArgument(state, tokenindex)); i++)
{
if (treestack.peek() instanceof ProductionContainer)
{
stack.pop();
ProductionContainer container = (ProductionContainer) treestack.pop();
switch (table.getProductionReduceType(container.productionindex))
{
case ParserTable.APPEND : // APPEND
if (table.getProductionSymbol(newcontainer.productionindex)==
table.getProductionSymbol(container.productionindex))
newcontainer.insertChilds(container);
else
newcontainer.insert(container);
break;
case ParserTable.RESOLVE : // RESOLVE
newcontainer.insertChilds(container);
break;
case ParserTable.NORMAL : // NORMAL
newcontainer.insert(container);
break;
case ParserTable.NEGLECT : // NEGLECT
break;
}
}
else
{
TokenContainer container = (TokenContainer) treestack.pop();
newcontainer.insert(container);
if (container.ignorable)
i--;
else
stack.pop();
}
}
oldstate = stack.peek();
treestack.push(newcontainer);
//stack.push(table.getTransition(oldstate, table.getProductionSymbol(table.getActionArgument(state,
// tokenindex))));
/* ================================== Accept =================================== */
if ((table.isAcceptAction(state, tokenindex)) && (stack.getSize() == 1))
{
if (_logger!=null)
_logger.debug("State " + state + " accept & reduce production " +
table.getActionArgument(state, tokenindex));
stack.pop();
DocumentContainer documentcontainer = new DocumentContainer(table, text,
(ProductionContainer)treestack.pop());
if (_logger!=null)
_logger.debug("Parsing time " + (System.currentTimeMillis() - time) + " ms");
return documentcontainer;
}
else
stack.push(table.getTransition(oldstate, table.getProductionSymbol(
table.getActionArgument(state, tokenindex))));
}
}
}