org.aspectj.org.eclipse.jdt.internal.compiler.parser.CommitRollbackParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
Tools from the AspectJ project
/*******************************************************************************
* Copyright (c) 2013 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.compiler.parser;
import org.aspectj.org.eclipse.jdt.core.compiler.InvalidInputException;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Statement;
public abstract class CommitRollbackParser implements TerminalTokens, ParserBasicInformation {
// resumeOnSyntaxError codes:
protected static final int HALT = 0; // halt and throw up hands.
protected static final int RESTART = 1; // stacks adjusted, alternate goal from check point.
protected static final int RESUME = 2; // stacks untouched, just continue from where left off.
public Scanner scanner;
public int currentToken;
public CommitRollbackParser snapShot;
private static final int[] RECOVERY_TOKENS = new int [] { TokenNameSEMICOLON, TokenNameRPAREN,};
protected CommitRollbackParser createSnapShotParser() {
return new Parser();
}
protected void commit() {
if (this.snapShot == null) {
this.snapShot = createSnapShotParser();
}
this.snapShot.copyState(this);
}
public void copyState(CommitRollbackParser commitRollbackParser) {
// Subclasses should implement.
}
protected int getNextToken() {
try {
return this.scanner.getNextToken();
} catch (InvalidInputException e) {
return TokenNameEOF;
}
}
protected void shouldStackAssistNode() {
// Not relevant here.
}
// We get here on real syntax error or syntax error triggered by fake EOF at completion site, never due to triggered recovery.
protected int fallBackToSpringForward(Statement unused) {
int nextToken;
boolean atCompletionSite = false;
int automatonState = automatonState();
// If triggered fake EOF at completion site, see if the real next token would have passed muster.
if (this.currentToken == TokenNameEOF) {
if (this.scanner.eofPosition < this.scanner.source.length) {
atCompletionSite = true;
this.scanner.eofPosition = this.scanner.source.length;
nextToken = getNextToken();
if (automatonWillShift(nextToken, automatonState)) {
this.currentToken = nextToken;
return RESUME;
}
} else {
nextToken = TokenNameEOF;
}
} else {
nextToken = this.currentToken;
}
if (nextToken == TokenNameEOF)
return HALT; // don't know how to proceed.
this.scanner.ungetToken(nextToken); // spit out what has been bitten more than we can chew.
// OK, next token is no good to resume "in place", attempt some local repair. FIXME: need to make sure we don't get stuck keep reducing empty statements !!
for (int i = 0, length = RECOVERY_TOKENS.length; i < length; i++) {
if (automatonWillShift(RECOVERY_TOKENS[i], automatonState)) {
this.currentToken = RECOVERY_TOKENS[i];
return RESUME;
}
}
// OK, no in place resumption, no local repair, fast forward to next statement.
if (this.snapShot == null)
return RESTART;
this.copyState(this.snapShot);
if (atCompletionSite) {
this.currentToken = TokenNameSEMICOLON;
shouldStackAssistNode();
return RESUME;
}
this.currentToken = this.scanner.fastForward(unused);
return RESUME;
}
public abstract int automatonState();
public abstract boolean automatonWillShift(int nextToken, int lastAction);
}