blob: 7de57ff56644f3e5a940f175fd8a7c46bee04923 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 University of Illinois at Urbana-Champaign and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* UIUC - Initial API and implementation
*******************************************************************************/
package org.eclipse.photran.internal.core.parser;
import org.eclipse.photran.internal.core.lexer.*; import org.eclipse.photran.internal.core.analysis.binding.ScopingNode; import org.eclipse.photran.internal.core.SyntaxException; import java.io.IOException;
import java.util.AbstractList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.zip.Inflater;
import org.eclipse.photran.internal.core.parser.Parser.Nonterminal;
import org.eclipse.photran.internal.core.parser.Parser.Production;
@SuppressWarnings("all")
final class ContainsStmtParsingTables extends ParsingTables
{
private static ContainsStmtParsingTables instance = null;
public static ContainsStmtParsingTables getInstance()
{
if (instance == null)
instance = new ContainsStmtParsingTables();
return instance;
}
@Override
public int getActionCode(int state, org.eclipse.photran.internal.core.lexer.Token lookahead)
{
return ActionTable.getActionCode(state, lookahead);
}
@Override
public int getActionCode(int state, int lookaheadTokenIndex)
{
return ActionTable.get(state, lookaheadTokenIndex);
}
@Override
public int getGoTo(int state, Nonterminal nonterminal)
{
return GoToTable.getGoTo(state, nonterminal);
}
@Override
public int getRecoveryCode(int state, org.eclipse.photran.internal.core.lexer.Token lookahead)
{
return RecoveryTable.getRecoveryCode(state, lookahead);
}
/**
* The ACTION table.
* <p>
* The ACTION table maps a state and an input symbol to one of four
* actions: shift, reduce, accept, or error.
*/
protected static final class ActionTable
{
/**
* Returns the action the parser should take if it is in the given state
* and has the given symbol as its lookahead.
* <p>
* The result value should be interpreted as follows:
* <ul>
* <li> If <code>result & ACTION_MASK == SHIFT_ACTION</code>,
* shift the terminal and go to state number
* <code>result & VALUE_MASK</code>.
* <li> If <code>result & ACTION_MASK == REDUCE_ACTION</code>,
* reduce by production number <code>result & VALUE_MASK</code>.
* <li> If <code>result & ACTION_MASK == ACCEPT_ACTION</code>,
* parsing has completed successfully.
* <li> Otherwise, a syntax error has been found.
* </ul>
*
* @return a code for the action to take (see above)
*/
protected static int getActionCode(int state, org.eclipse.photran.internal.core.lexer.Token lookahead)
{
assert 0 <= state && state < Parser.NUM_STATES;
assert lookahead != null;
Integer index = Parser.terminalIndices.get(lookahead.getTerminal());
if (index == null)
return 0;
else
return get(state, index);
}
protected static final int[] rowmap = { 0, 1, 2, 3, 0, 0, 0, 1 };
protected static final int[] columnmap = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public static int get(int row, int col)
{
if (isErrorEntry(row, col))
return 0;
else if (columnmap[col] % 2 == 0)
return lookupValue(rowmap[row], columnmap[col]/2) >>> 16;
else
return lookupValue(rowmap[row], columnmap[col]/2) & 0xFFFF;
}
protected static boolean isErrorEntry(int row, int col)
{
final int INT_BITS = 32;
int sigmapRow = row;
int sigmapCol = col / INT_BITS;
int bitNumberFromLeft = col % INT_BITS;
int sigmapMask = 0x1 << (INT_BITS - bitNumberFromLeft - 1);
return (lookupSigmap(sigmapRow, sigmapCol) & sigmapMask) == 0;
}
protected static int[][] sigmap = null;
protected static void sigmapInit()
{
try
{
final int rows = 8;
final int cols = 8;
final int compressedBytes = 29;
final int uncompressedBytes = 257;
byte[] decoded = new byte[compressedBytes];
base64Decode(decoded,
"eNoTYMAALMgcAQb8gFJ5wooUGCgG+MwHAE5ZAIU=");
byte[] buffer = new byte[uncompressedBytes];
Inflater inflater = new Inflater();
inflater.setInput(decoded, 0, compressedBytes);
inflater.inflate(buffer);
inflater.end();
sigmap = new int[rows][cols];
for (int index = 0; index < uncompressedBytes-1; index += 4)
{
int byte1 = 0x000000FF & (int)buffer[index + 0];
int byte2 = 0x000000FF & (int)buffer[index + 1];
int byte3 = 0x000000FF & (int)buffer[index + 2];
int byte4 = 0x000000FF & (int)buffer[index + 3];
int element = index / 4;
int row = element / cols;
int col = element % cols;
sigmap[row][col] = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
}
}
catch (Exception e)
{
throw new Error(e);
}
}
protected static int lookupSigmap(int row, int col)
{
return sigmap[row][col];
}
protected static int[][] value = null;
protected static void valueInit()
{
try
{
final int rows = 4;
final int cols = 2;
final int compressedBytes = 32;
final int uncompressedBytes = 33;
byte[] decoded = new byte[compressedBytes];
base64Decode(decoded,
"eNpz/dfAfoChgdHhBgOD6yMg/s8ABg2sEJoBAKdwBxQ=");
byte[] buffer = new byte[uncompressedBytes];
Inflater inflater = new Inflater();
inflater.setInput(decoded, 0, compressedBytes);
inflater.inflate(buffer);
inflater.end();
value = new int[rows][cols];
for (int index = 0; index < uncompressedBytes-1; index += 4)
{
int byte1 = 0x000000FF & (int)buffer[index + 0];
int byte2 = 0x000000FF & (int)buffer[index + 1];
int byte3 = 0x000000FF & (int)buffer[index + 2];
int byte4 = 0x000000FF & (int)buffer[index + 3];
int element = index / 4;
int row = element / cols;
int col = element % cols;
value[row][col] = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
}
}
catch (Exception e)
{
throw new Error(e);
}
}
protected static int lookupValue(int row, int col)
{
return value[row][col];
}
static
{
sigmapInit();
valueInit();
}
}
/**
* The GOTO table.
* <p>
* The GOTO table maps a state and a nonterminal to a new state.
* It is used when the parser reduces. Suppose, for example, the parser
* is reducing by the production <code>A ::= B C D</code>. Then it
* will pop three symbols from the <code>stateStack</code> and three symbols
* from the <code>valueStack</code>. It will look at the value now on top
* of the state stack (call it <i>n</i>), and look up the entry for
* <i>n</i> and <code>A</code> in the GOTO table to determine what state
* it should transition to.
*/
protected static final class GoToTable
{
/**
* Returns the state the parser should transition to if the given
* state is on top of the <code>stateStack</code> after popping
* symbols corresponding to the right-hand side of the given production.
*
* @return the state to transition to (0 <= result < Parser.NUM_STATES)
*/
protected static int getGoTo(int state, Nonterminal nonterminal)
{
assert 0 <= state && state < Parser.NUM_STATES;
assert nonterminal != null;
return get(state, nonterminal.getIndex());
}
protected static final int[] rowmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
protected static final int[] columnmap = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 };
public static int get(int row, int col)
{
if (isErrorEntry(row, col))
return -1;
else if (columnmap[col] % 2 == 0)
return lookupValue(rowmap[row], columnmap[col]/2) >>> 16;
else
return lookupValue(rowmap[row], columnmap[col]/2) & 0xFFFF;
}
protected static boolean isErrorEntry(int row, int col)
{
final int INT_BITS = 32;
int sigmapRow = row;
int sigmapCol = col / INT_BITS;
int bitNumberFromLeft = col % INT_BITS;
int sigmapMask = 0x1 << (INT_BITS - bitNumberFromLeft - 1);
return (lookupSigmap(sigmapRow, sigmapCol) & sigmapMask) == 0;
}
protected static int[][] sigmap = null;
protected static void sigmapInit()
{
try
{
final int rows = 8;
final int cols = 16;
final int compressedBytes = 24;
final int uncompressedBytes = 513;
byte[] decoded = new byte[compressedBytes];
base64Decode(decoded,
"eNpjYEABHEhsFgZCQIFhFAx1AABRqQAt");
byte[] buffer = new byte[uncompressedBytes];
Inflater inflater = new Inflater();
inflater.setInput(decoded, 0, compressedBytes);
inflater.inflate(buffer);
inflater.end();
sigmap = new int[rows][cols];
for (int index = 0; index < uncompressedBytes-1; index += 4)
{
int byte1 = 0x000000FF & (int)buffer[index + 0];
int byte2 = 0x000000FF & (int)buffer[index + 1];
int byte3 = 0x000000FF & (int)buffer[index + 2];
int byte4 = 0x000000FF & (int)buffer[index + 3];
int element = index / 4;
int row = element / cols;
int col = element % cols;
sigmap[row][col] = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
}
}
catch (Exception e)
{
throw new Error(e);
}
}
protected static int lookupSigmap(int row, int col)
{
return sigmap[row][col];
}
protected static int[][] value = null;
protected static void valueInit()
{
try
{
final int rows = 1;
final int cols = 2;
final int compressedBytes = 13;
final int uncompressedBytes = 9;
byte[] decoded = new byte[compressedBytes];
base64Decode(decoded,
"eNpjYGFgYmD+/58BAA==");
byte[] buffer = new byte[uncompressedBytes];
Inflater inflater = new Inflater();
inflater.setInput(decoded, 0, compressedBytes);
inflater.inflate(buffer);
inflater.end();
value = new int[rows][cols];
for (int index = 0; index < uncompressedBytes-1; index += 4)
{
int byte1 = 0x000000FF & (int)buffer[index + 0];
int byte2 = 0x000000FF & (int)buffer[index + 1];
int byte3 = 0x000000FF & (int)buffer[index + 2];
int byte4 = 0x000000FF & (int)buffer[index + 3];
int element = index / 4;
int row = element / cols;
int col = element % cols;
value[row][col] = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
}
}
catch (Exception e)
{
throw new Error(e);
}
}
protected static int lookupValue(int row, int col)
{
return value[row][col];
}
static
{
sigmapInit();
valueInit();
}
}
/**
* The error recovery table.
* <p>
* See {@link #attemptToRecoverFromSyntaxError()} for a description of the
* error recovery algorithm.
* <p>
* This table takes the state on top of the stack and the current lookahead
* symbol and returns what action should be taken. The result value should
* be interpreted as follows:
* <ul>
* <li> If <code>result & ACTION_MASK == DISCARD_STATE_ACTION</code>,
* pop a symbol from the parser stacks; a &quot;known&quot; sequence
* of symbols has not been found.
* <li> If <code>result & ACTION_MASK == DISCARD_TERMINAL_ACTION</code>,
* a &quot;known&quot; sequence of symbols has been found, and we
* are looking for the error lookahead symbol. Shift the terminal.
* <li> If <code>result & ACTION_MASK == RECOVER_ACTION</code>, we have
* matched the error recovery production
* <code>Production.values[result & VALUE_MASK]</code>, so reduce
* by that production (including the lookahead symbol), and then
* continue with normal parsing.
* </ul>
* If it is not possible to recover from a syntax error, either the state
* stack will be emptied or the end of input will be reached before a
* RECOVER_ACTION is found.
*
* @return a code for the action to take (see above)
*/
protected static final class RecoveryTable
{
protected static int getRecoveryCode(int state, org.eclipse.photran.internal.core.lexer.Token lookahead)
{
assert 0 <= state && state < Parser.NUM_STATES;
assert lookahead != null;
Integer index = Parser.terminalIndices.get(lookahead.getTerminal());
if (index == null)
return 0;
else
return get(state, index);
}
protected static final int[] rowmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
protected static final int[] columnmap = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public static int get(int row, int col)
{
if (isErrorEntry(row, col))
return 0;
else if (columnmap[col] % 2 == 0)
return lookupValue(rowmap[row], columnmap[col]/2) >>> 16;
else
return lookupValue(rowmap[row], columnmap[col]/2) & 0xFFFF;
}
protected static boolean isErrorEntry(int row, int col)
{
final int INT_BITS = 32;
int sigmapRow = row;
int sigmapCol = col / INT_BITS;
int bitNumberFromLeft = col % INT_BITS;
int sigmapMask = 0x1 << (INT_BITS - bitNumberFromLeft - 1);
return (lookupSigmap(sigmapRow, sigmapCol) & sigmapMask) == 0;
}
protected static int[][] sigmap = null;
protected static void sigmapInit()
{
try
{
final int rows = 8;
final int cols = 8;
final int compressedBytes = 12;
final int uncompressedBytes = 257;
byte[] decoded = new byte[compressedBytes];
base64Decode(decoded,
"eNpjYBjhAAABAQAB");
byte[] buffer = new byte[uncompressedBytes];
Inflater inflater = new Inflater();
inflater.setInput(decoded, 0, compressedBytes);
inflater.inflate(buffer);
inflater.end();
sigmap = new int[rows][cols];
for (int index = 0; index < uncompressedBytes-1; index += 4)
{
int byte1 = 0x000000FF & (int)buffer[index + 0];
int byte2 = 0x000000FF & (int)buffer[index + 1];
int byte3 = 0x000000FF & (int)buffer[index + 2];
int byte4 = 0x000000FF & (int)buffer[index + 3];
int element = index / 4;
int row = element / cols;
int col = element % cols;
sigmap[row][col] = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
}
}
catch (Exception e)
{
throw new Error(e);
}
}
protected static int lookupSigmap(int row, int col)
{
return sigmap[row][col];
}
protected static int[][] value = null;
protected static void valueInit()
{
try
{
final int rows = 1;
final int cols = 1;
final int compressedBytes = 7;
final int uncompressedBytes = 5;
byte[] decoded = new byte[compressedBytes];
base64Decode(decoded,
"eNpjYAACAA==");
byte[] buffer = new byte[uncompressedBytes];
Inflater inflater = new Inflater();
inflater.setInput(decoded, 0, compressedBytes);
inflater.inflate(buffer);
inflater.end();
value = new int[rows][cols];
for (int index = 0; index < uncompressedBytes-1; index += 4)
{
int byte1 = 0x000000FF & (int)buffer[index + 0];
int byte2 = 0x000000FF & (int)buffer[index + 1];
int byte3 = 0x000000FF & (int)buffer[index + 2];
int byte4 = 0x000000FF & (int)buffer[index + 3];
int element = index / 4;
int row = element / cols;
int col = element % cols;
value[row][col] = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
}
}
catch (Exception e)
{
throw new Error(e);
}
}
protected static int lookupValue(int row, int col)
{
return value[row][col];
}
static
{
sigmapInit();
valueInit();
}
}
}