protected abstract RuntimeException syntaxError(Token token, String description);
- private static String describeAction(int action) {
+ private static String describeAction(boolean isGoto, int action) {
if(action == ERROR_ACTION)
return "ERROR";
if(action == ACCEPT_ACTION)
return "ACCEPT";
StringBuilder b = new StringBuilder();
- if((action & REDUCE_MASK) != 0) {
- action ^= REDUCE_MASK;
- b.append("REDUCE");
+ if(isGoto)
+ b.append("GOTO ");
+ else {
+ if((action & REDUCE_MASK) != 0) {
+ action ^= REDUCE_MASK;
+ b.append("REDUCE");
+ }
+ else
+ b.append("SHIFT");
}
- else
- b.append("SHIFT");
if((action & POP_MASK) != 0) {
action ^= POP_MASK;
b.append(" POP");
return b.toString();
}
+ private void printState(int state) {
+ System.out.print("state=" + state + ":");
+ for(int i=symbolStackLength-1,j=stateStackLength-1;i>=0;--i) {
+ Object s = symbolStack[i];
+ if(s instanceof Token)
+ System.out.print(" " + TERMINAL_NAMES[((Token)s).id]);
+ else if(s == null)
+ System.out.print(" null");
+ else
+ System.out.print(" " + s.getClass().getSimpleName());
+ while(j>=0 && symbolStackPositionStack[j]==i)
+ System.out.print(" (" + stateStack[j--] + ")");
+ }
+ System.out.println();
+ }
+
private Object parse(int state) {
while(true) {
Token token = nextToken();
int tokenId = token.id;
+ if(TRACE)
+ System.out.println("---> token " + TERMINAL_NAMES[tokenId] + " \"" + token.text + "\" <---");
while(true) {
+ if(TRACE)
+ printState(state);
short action = getAction(state, tokenId);
- if(TRACE) {
- System.out.println("state=" + state + ", tokenId=" + TERMINAL_NAMES[tokenId] +
- ", action=" + describeAction(action));
- System.out.print(" ");
- for(int i=symbolStackLength-1,j=stateStackLength-1;i>=0;--i) {
- Object s = symbolStack[i];
- if(s instanceof Token)
- System.out.print(" " + TERMINAL_NAMES[((Token)s).id]);
- else
- System.out.print(" " + s.getClass().getSimpleName());
- while(j>=0 && symbolStackPositionStack[j]==i)
- System.out.print(" (" + stateStack[j--] + ")");
- }
- System.out.println();
- }
+ if(TRACE)
+ System.out.println(" -> action=" + describeAction(false, action));
//System.out.println(STATE_DESCRIPTIONS[state]);
if((action & REDUCE_MASK) != 0) {
if(action == ACCEPT_ACTION)
return symbolStack[symbolStackLength-1];
if(action == ERROR_ACTION)
throw syntaxError(token, parseErrorDescription(state, token, tokenId));
- stateStackLength -= (action >>> 13)&3;
+ int popAmount = (action >>> 13)&3;
+ if(TRACE) {
+ if(popAmount > 0)
+ System.out.println(" POP " + popAmount);
+ }
+ stateStackLength -= popAmount;
action &= STATE_MASK;
int reductionBegin = symbolStackPositionStack[--stateStackLength];
symbolStack[symbolStackLength] = symbol;
state = stateStack[stateStackLength];
+ if(TRACE) {
+ ++symbolStackLength;
+ printState(state);
+ --symbolStackLength;
+ System.out.println(" nonterminal=" + NONTERMINAL_NAMES[PRODUCT_LHS[action]]);
+ }
action = getGoto(state, PRODUCT_LHS[action]);
+ if(TRACE)
+ System.out.println(" -> action=" + describeAction(true, action));
+
// Pop state
if((action & POP_MASK) != 0) {
--stateStackLength;
case 124:
return reduceApplyType();
case 125:
- return reduceDummy1();
+ return reduceDummy();
default:
throw new RuntimeException("Internal parser error.");
/**
* dummy ::= COMMENT EOL
*/
- protected abstract Object reduceDummy1();
+ protected abstract Object reduceDummy();
protected void postReduce(Object reduced) {
}