/**********************************************************************
Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de
All rights reserved. This program and the accompanying material
are made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v10.html
Contributors:
Klaus Hartlage - www.eclipseproject.de
**********************************************************************/
package net.sourceforge.phpdt.internal.compiler.parser;
import java.util.ArrayList;
import net.sourceforge.phpdt.core.compiler.CharOperation;
import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
import net.sourceforge.phpdt.core.compiler.InvalidInputException;
import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode;
import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
import org.eclipse.core.resources.IFile;
public class Parser //extends PHPParserSuperclass
implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation {
//internal data for the automat
protected final static int StackIncrement = 255;
protected int stateStackTop;
protected int[] stack = new int[StackIncrement];
public int firstToken; // handle for multiple parsing goals
public int lastAct; //handle for multiple parsing goals
protected RecoveredElement currentElement;
public static boolean VERBOSE_RECOVERY = false;
protected boolean diet = false; //tells the scanner to jump over some
// parts of the code/expressions like
// method bodies
//scanner token
public Scanner scanner;
private ArrayList phpList;
private int currentPHPString;
private boolean phpEnd;
// private static HashMap keywordMap = null;
private String str;
// current character
// char ch;
// current token
int token;
// row counter for syntax errors:
//int rowCount;
// column counter for syntax errors:
//int columnCount;
//int chIndx;
//
// // current identifier
// String identifier;
Long longNumber;
Double doubleNumber;
private String stringValue;
/** Contains the current expression. */
// private StringBuffer expression;
//private boolean phpMode;
protected int modifiers;
protected int modifiersSourceStart;
protected Parser() {
this.currentPHPString = 0;
// PHPParserSuperclass.fileToParse = fileToParse;
this.phpList = null;
this.str = "";
this.token = TokenNameEOF;
// this.chIndx = 0;
// this.rowCount = 1;
// this.columnCount = 0;
this.phpEnd = false;
// getNextToken();
this.initializeScanner();
}
public void setFileToParse(IFile fileToParse) {
this.currentPHPString = 0;
// PHPParserSuperclass.fileToParse = fileToParse;
this.phpList = null;
this.str = "";
this.token = TokenNameEOF;
this.phpEnd = false;
this.initializeScanner();
}
/**
* ClassDeclaration Constructor.
*
* @param s
* @param sess
* Description of Parameter
* @see
*/
public Parser(IFile fileToParse) {
// if (keywordMap == null) {
// keywordMap = new HashMap();
// for (int i = 0; i < PHP_KEYWORS.length; i++) {
// keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
// }
// }
this.currentPHPString = 0;
// PHPParserSuperclass.fileToParse = fileToParse;
this.phpList = null;
this.str = "";
this.token = TokenNameEOF;
// this.chIndx = 0;
// this.rowCount = 1;
// this.columnCount = 0;
this.phpEnd = false;
// getNextToken();
this.initializeScanner();
}
public void initializeScanner() {
this.scanner = new Scanner(false, false, false, false);
}
/**
* Create marker for the parse error
*/
// private void setMarker(String message, int charStart, int charEnd, int
// errorLevel) {
// setMarker(fileToParse, message, charStart, charEnd, errorLevel);
// }
/**
* This method will throw the SyntaxError. It will add the good lines and
* columns to the Error
*
* @param error
* the error message
* @throws SyntaxError
* the error raised
*/
private void throwSyntaxError(String error) {
int problemStartPosition = scanner.getCurrentTokenStartPosition();
int problemEndPosition = scanner.getCurrentTokenEndPosition();
throwSyntaxError(error, problemStartPosition, problemEndPosition);
}
/**
* This method will throw the SyntaxError. It will add the good lines and
* columns to the Error
*
* @param error
* the error message
* @throws SyntaxError
* the error raised
*/
// private void throwSyntaxError(String error, int startRow) {
// throw new SyntaxError(startRow, 0, " ", error);
// }
private void throwSyntaxError(String error, int problemStartPosition,
int problemEndPosition) {
problemReporter
.phpParsingError(new String[]{error}, problemStartPosition,
problemEndPosition, referenceContext,
compilationUnit.compilationResult);
throw new SyntaxError(1, 0, " ", error);
}
private void reportSyntaxError(String error, int problemStartPosition,
int problemEndPosition) {
problemReporter
.phpParsingError(new String[]{error}, problemStartPosition,
problemEndPosition, referenceContext,
compilationUnit.compilationResult);
}
private void reportSyntaxWarning(String error, int problemStartPosition,
int problemEndPosition) {
problemReporter.phpParsingWarning(new String[]{error},
problemStartPosition, problemEndPosition, referenceContext,
compilationUnit.compilationResult);
}
/**
* Method Declaration.
*
* @see
*/
// private void getChar() {
// if (str.length() > chIndx) {
// ch = str.charAt(chIndx++);
//
// return;
// }
//
// chIndx = str.length() + 1;
// ch = ' ';
// // token = TokenNameEOF;
// phpEnd = true;
// }
/**
* gets the next token from input
*/
private void getNextToken() {
try {
token = scanner.getNextToken();
if (Scanner.DEBUG) {
int currentEndPosition = scanner.getCurrentTokenEndPosition();
int currentStartPosition = scanner.getCurrentTokenStartPosition();
System.out
.print(currentStartPosition + "," + currentEndPosition + ": ");
System.out.println(scanner.toStringAction(token));
}
} catch (InvalidInputException e) {
token = TokenNameERROR;
}
return;
}
/**
* Get a number. if it's a double
the number will be stored in
* doubleNumber
and the token will have the value
* {@link Parser#TokenNameDOUBLE_NUMBER}
* if it's a double
the number will be stored in longNumber
* and the token will have the value {@link Parser#TokenNameINT_NUMBER}
*/
// private void getNumber() {
// StringBuffer inum = new StringBuffer();
// char dFlag = ' ';
// int numFormat = 10;
//
// // save first digit
// char firstCh = ch;
// inum.append(ch);
//
// getChar();
// // determine number conversions:
// if (firstCh == '0') {
// switch (ch) {
// case 'b' :
// numFormat = 2;
// getChar();
// break;
// case 'B' :
// numFormat = 2;
// getChar();
// break;
// case 'o' :
// numFormat = 8;
// getChar();
// break;
// case 'O' :
// numFormat = 8;
// getChar();
// break;
// case 'x' :
// numFormat = 16;
// getChar();
// break;
// case 'X' :
// numFormat = 16;
// getChar();
// break;
// }
// }
//
// if (numFormat == 16) {
// while ((ch >= '0' && ch <= '9')
// || (ch >= 'a' && ch <= 'f')
// || (ch >= 'A' && ch <= 'F')) {
// inum.append(ch);
// getChar();
// }
// } else {
// while ((ch >= '0' && ch <= '9')
// || (ch == '.')
// || (ch == 'E')
// || (ch == 'e')) {
// if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
// if (ch == '.' && dFlag != ' ') {
// break;
// }
// if ((dFlag == 'E') || (dFlag == 'e')) {
// break;
// }
// dFlag = ch;
// inum.append(ch);
// getChar();
// if ((ch == '-') || (ch == '+')) {
// inum.append(ch);
// getChar();
// }
// } else {
// inum.append(ch);
// getChar();
// }
// }
// }
// chIndx--;
//
// try {
// if (dFlag != ' ') {
// doubleNumber = new Double(inum.toString());
// token = TokenNameDoubleLiteral;
// return;
// } else {
// longNumber = Long.valueOf(inum.toString(), numFormat);
// token = TokenNameIntegerLiteral;
// return;
// }
//
// } catch (Throwable e) {
// throwSyntaxError("Number format error: " + inum.toString());
// }
// }
//
// /**
// * Get a String.
// * @param openChar the opening char ('\'', '"', '`')
// * @param typeString the type of string {@link
// #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
// * @param errorMsg the error message in case of parse error in the string
// */
// private void getString(
// final char openChar,
// final int typeString,
// final String errorMsg) {
// StringBuffer sBuffer = new StringBuffer();
// boolean openString = true;
// int startRow = rowCount;
// while (str.length() > chIndx) {
// ch = str.charAt(chIndx++);
// if (ch == '\\') {
// sBuffer.append(ch);
// if (str.length() > chIndx) {
// ch = str.charAt(chIndx++);
// sBuffer.append(ch);
// }
// } else if (ch == openChar) {
// openString = false;
// break;
// } else if (ch == '\n') {
// rowCount++;
// columnCount = chIndx;
// } else {
// sBuffer.append(ch);
// }
// }
// if (openString) {
// if (typeString == TokenNameStringConstant) {
// throwSyntaxError(errorMsg, startRow);
// } else {
// throwSyntaxError(errorMsg);
// }
// }
// token = typeString;
// stringValue = sBuffer.toString();
// }
// public void htmlParserTester(String input) {
// int lineNumber = 1;
// int startLineNumber = 1;
// int startIndex = 0;
// char ch;
// char ch2;
// boolean phpMode = false;
// boolean phpFound = false;
//
// phpList = new ArrayList();
// currentPHPString = 0;
//
// try {
// int i = 0;
// while (i < input.length()) {
// ch = input.charAt(i++);
// if (ch == '\n') {
// lineNumber++;
// }
// if ((!phpMode) && ch == '<') {
// ch2 = input.charAt(i++);
// if (ch2 == '?') {
// ch2 = input.charAt(i++);
// if (Character.isWhitespace(ch2)) {
// // php start
// phpMode = true;
// phpFound = true;
// startIndex = i;
// startLineNumber = lineNumber;
// continue;
// } else if (ch2 == 'p') {
// ch2 = input.charAt(i++);
// if (ch2 == 'h') {
// ch2 = input.charAt(i++);
// if (ch2 == 'p') {
// phpMode = true;
// phpFound = true;
// startIndex = i;
// startLineNumber = lineNumber;
// continue;
// }
// i--;
// }
// i--;
// } else if (ch2 == 'P') {
// ch2 = input.charAt(i++);
// if (ch2 == 'H') {
// ch2 = input.charAt(i++);
// if (ch2 == 'P') {
// phpMode = true;
// phpFound = true;
// startIndex = i;
// startLineNumber = lineNumber;
// continue;
// }
// i--;
// }
// i--;
// }
// i--;
// }
// i--;
// }
//
// if (phpMode) {
// if (ch == '/' && i < input.length()) {
// ch2 = input.charAt(i++);
// if (ch2 == '/') {
// while (i < input.length()) {
// ch = input.charAt(i++);
// if (ch == '?' && i < input.length()) {
// ch2 = input.charAt(i++);
// if (ch2 == '>') {
// // php end
// phpMode = false;
// phpList.add(
// new PHPString(
// input.substring(
// startIndex,
// i - 2),
// startLineNumber));
// continue;
// }
// i--;
// } else if (ch == '\n') {
// lineNumber++;
// break;
// }
// }
// continue;
// } else if (ch2 == '*') {
// // multi-line comment
// while (i < input.length()) {
// ch = input.charAt(i++);
// if (ch == '\n') {
// lineNumber++;
// } else if (ch == '*' && i < input.length()) {
// ch2 = input.charAt(i++);
// if (ch2 == '/') {
// break;
// }
// i--;
// }
// }
// continue;
// } else {
// i--;
// }
// } else if (ch == '#') {
// while (i < input.length()) {
// ch = input.charAt(i++);
// if (ch == '?' && i < input.length()) {
// ch2 = input.charAt(i++);
// if (ch2 == '>') {
// // php end
// phpMode = false;
// phpList.add(
// new PHPString(
// input.substring(startIndex, i - 2),
// startLineNumber));
// continue;
// }
// i--;
// } else if (ch == '\n') {
// lineNumber++;
// break;
// }
// }
// continue;
// } else if (ch == '"') {
// ch = ' ';
// while (i < input.length()) {
// ch = input.charAt(i++);
// if (ch == '\n') {
// lineNumber++;
// } else if (
// ch == '\\' && i < input.length()) { // escape
// i++;
// } else if (ch == '"') {
// break;
// }
// }
// continue;
// } else if (ch == '\'') {
// ch = ' ';
// while (i < input.length()) {
// ch = input.charAt(i++);
// if (ch == '\n') {
// lineNumber++;
// } else if (
// ch == '\\' && i < input.length()) { // escape
// i++;
// } else if (ch == '\'') {
// break;
// }
// }
// continue;
// }
//
// if (ch == '?' && i < input.length()) {
// ch2 = input.charAt(i++);
// if (ch2 == '>') {
// // php end
// phpMode = false;
// phpList.add(
// new PHPString(
// input.substring(startIndex, i - 2),
// startLineNumber));
// continue;
// }
// i--;
// }
// }
// }
//
// if (!phpFound) {
// setMarker(
// "No PHP source code found.",
// lineNumber,
// PHPParser.INFO);
// } else {
// if (phpMode) {
// setMarker(
// "Open PHP tag at end of file.",
// lineNumber,
// PHPParser.INFO);
// phpList.add(
// new PHPString(
// input.substring(startIndex, i - 2),
// startLineNumber));
// }
// // for (int j=0;j");
// // }
// phpParserTester(null, 1);
// // PHPString temp;
// // for(int j=0;j TokenNameKEYWORD) {
// current.add(new PHPVarDeclaration(current, variableName,
// // chIndx - ident.length,
// scanner.getCurrentTokenStartPosition(), new String(ident)));
// } else {
// switch (token) {
// case TokenNameVariable :
// case TokenNamethis :
// current.add(new PHPVarDeclaration(current, variableName,
// // chIndx -
// // ident.length,
// scanner.getCurrentTokenStartPosition(), new String(
// ident)));
// break;
// case TokenNameIdentifier :
// current.add(new PHPVarDeclaration(current, variableName,
// // chIndx -
// // ident.length,
// scanner.getCurrentTokenStartPosition(), new String(
// ident)));
// break;
// case TokenNameDoubleLiteral :
// current.add(new PHPVarDeclaration(current, variableName
// + doubleNumber,
// // chIndx -
// // ident.length,
// scanner.getCurrentTokenStartPosition(), new String(
// ident)));
// break;
// case TokenNameIntegerLiteral :
// current.add(new PHPVarDeclaration(current, variableName,
// // chIndx -
// // ident.length,
// scanner.getCurrentTokenStartPosition(), new String(
// ident)));
// break;
// case TokenNameStringInterpolated :
// case TokenNameStringLiteral :
// current.add(new PHPVarDeclaration(current, variableName,
// // chIndx -
// // ident.length,
// scanner.getCurrentTokenStartPosition(), new String(
// ident)));
// break;
// case TokenNameStringConstant :
// current.add(new PHPVarDeclaration(current, variableName,
// // chIndx -
// // ident.length,
// scanner.getCurrentTokenStartPosition(), new String(
// ident)));
// break;
// default :
// current.add(new PHPVarDeclaration(current, variableName,
// // chIndx -
// // ident.length
// scanner.getCurrentTokenStartPosition()));
// break;
// }
// }
// } else {
// ident = scanner.getCurrentIdentifierSource();
// current.add(new PHPVarDeclaration(current, variableName,
// // chIndx - ident.length
// scanner.getCurrentTokenStartPosition()));
// }
// }
// } else if (token == TokenNamefunction) {
// getNextToken();
// if (token == TokenNameAND) {
// getNextToken();
// }
// if (token == TokenNameIdentifier
// && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
// ident = scanner.getCurrentIdentifierSource();
// outlineInfo.addVariable(new String(ident));
// temp = new PHPFunctionDeclaration(current, new String(ident),
// // chIndx - ident.length
// scanner.getCurrentTokenStartPosition());
// current.add(temp);
// getNextToken();
// parseDeclarations(outlineInfo, temp, true);
// }
// } else if (token == TokenNameclass) {
// getNextToken();
// if (token == TokenNameIdentifier
// && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
// ident = scanner.getCurrentIdentifierSource();
// outlineInfo.addVariable(new String(ident));
// temp = new PHPClassDeclaration(current, new String(ident),
// // chIndx - ident.len
// scanner.getCurrentTokenStartPosition());
// current.add(temp);
// // stack.push(temp);
// getNextToken();
// //skip tokens for classname, extends and others until
// // we have the opening '{'
// while (token != TokenNameLBRACE && token != TokenNameEOF
// && token != TokenNameERROR) {
// getNextToken();
// }
// parseDeclarations(outlineInfo, temp, true);
// // stack.pop();
// }
// } else if ((token == TokenNameLBRACE)
// || (token == TokenNameDOLLAR_LBRACE)) {
// getNextToken();
// counter++;
// } else if (token == TokenNameRBRACE) {
// getNextToken();
// --counter;
// if (counter == 0 && goBack) {
// return;
// }
// } else if (token == TokenNamerequire || token == TokenNamerequire_once
// || token == TokenNameinclude || token == TokenNameinclude_once) {
// ident = scanner.getCurrentTokenSource();
// getNextToken();
// int startPosition = scanner.getCurrentTokenStartPosition();
// expr();
// char[] expr = scanner.getCurrentTokenSource(startPosition);
// outlineInfo.addVariable(new String(ident));
// current.add(new PHPReqIncDeclaration(current, new String(ident),
// // chIndx - ident.length,
// startPosition, new String(expr)));
// getNextToken();
// } else {
// getNextToken();
// }
// }
// } catch (SyntaxError sytaxErr) {
// // try {
// // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
// // setMarker(sytaxErr.getMessage(),
// // scanner.getCurrentTokenStartPosition(),
// // scanner.getCurrentTokenEndPosition(), ERROR);
// // } catch (CoreException e) {
// // }
// }
// }
private void statementList() {
do {
statement(TokenNameEOF);
if ((token == TokenNameRBRACE) || (token == TokenNamecase)
|| (token == TokenNamedefault) || (token == TokenNameelse)
|| (token == TokenNameelseif) || (token == TokenNameendif)
|| (token == TokenNameendfor) || (token == TokenNameendforeach)
|| (token == TokenNameendwhile) || (token == TokenNameendswitch)
|| (token == TokenNameEOF) || (token == TokenNameERROR)) {
return;
}
} while (true);
}
private void functionBody(MethodDeclaration methodDecl) {
// '{' [statement-list] '}'
if (token == TokenNameLBRACE) {
getNextToken();
} else {
throwSyntaxError("'{' expected in compound-statement.");
}
if (token != TokenNameRBRACE) {
statementList();
}
if (token == TokenNameRBRACE) {
methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
getNextToken();
} else {
throwSyntaxError("'}' expected in compound-statement.");
}
}
private void statement(int previousToken) {
// if (token > TokenNameKEYWORD && token != TokenNamelist && token !=
// TokenNamenew) {
// char[] ident = scanner.getCurrentIdentifierSource();
// String keyword = new String(ident);
// if (token == TokenNameAT) {
// getNextToken();
// if (token != TokenNamerequire && token != TokenNamerequire_once
// && token != TokenNameinclude && token != TokenNameinclude_once
// && token != TokenNameIdentifier && token != TokenNameVariable
// && token != TokenNameStringInterpolated) {
// throwSyntaxError("identifier expected after '@'.");
// }
// }
// if (token == TokenNameinclude || token == TokenNameinclude_once) {
// getNextToken();
// if (token == TokenNameLPAREN) {
// expr();
// if (token == TokenNameSEMICOLON) {
// getNextToken();
// } else {
// if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
// throwSyntaxError("';' expected after 'include' or 'include_once'.");
// }
// // getNextToken();
// }
// } else {
// concatenationExpression();
// }
// return;
// } else if (token == TokenNamerequire || token == TokenNamerequire_once)
// {
// getNextToken();
// //constant();
// if (token == TokenNameLPAREN) {
// expr();
// if (token == TokenNameSEMICOLON) {
// getNextToken();
// } else {
// if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
// throwSyntaxError("';' expected after 'require' or 'require_once'.");
// }
// // getNextToken();
// }
// } else {
// concatenationExpression();
// }
// return;
// } else
if (token == TokenNameif) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("'(' expected after 'if' keyword.");
}
expr();
if (token == TokenNameRPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'if' condition.");
}
ifStatement();
return;
} else if (token == TokenNameswitch) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("'(' expected after 'switch' keyword.");
}
expr();
if (token == TokenNameRPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'switch' condition.");
}
switchStatement();
return;
} else if (token == TokenNamefor) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("'(' expected after 'for' keyword.");
}
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
expressionList();
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
throwSyntaxError("';' expected after 'for'.");
}
}
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
expressionList();
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
throwSyntaxError("';' expected after 'for'.");
}
}
if (token == TokenNameRPAREN) {
getNextToken();
} else {
expressionList();
if (token == TokenNameRPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'for'.");
}
}
forStatement();
return;
} else if (token == TokenNamewhile) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("'(' expected after 'while' keyword.");
}
expr();
if (token == TokenNameRPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'while' condition.");
}
whileStatement();
return;
} else if (token == TokenNamedo) {
getNextToken();
if (token == TokenNameLBRACE) {
getNextToken();
} else {
throwSyntaxError("'{' expected after 'do' keyword.");
}
if (token != TokenNameRBRACE) {
statementList();
}
if (token == TokenNameRBRACE) {
getNextToken();
} else {
throwSyntaxError("'}' expected after 'do' keyword.");
}
if (token == TokenNamewhile) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("'(' expected after 'while' keyword.");
}
expr();
if (token == TokenNameRPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'while' condition.");
}
} else {
throwSyntaxError("'while' expected after 'do' keyword.");
}
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
if (token != TokenNameINLINE_HTML) {
throwSyntaxError("';' expected after do-while statement.");
}
getNextToken();
}
return;
} else if (token == TokenNameforeach) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("'(' expected after 'foreach' keyword.");
}
expr();
if (token == TokenNameas) {
getNextToken();
} else {
throwSyntaxError("'as' expected after 'foreach' exxpression.");
}
// variable();
foreach_variable();
foreach_optional_arg();
if (token == TokenNameEQUAL_GREATER) {
getNextToken();
variable();
}
if (token == TokenNameRPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'foreach' expression.");
}
foreachStatement();
return;
} else if (token == TokenNamecontinue || token == TokenNamebreak
|| token == TokenNamereturn) {
getNextToken();
if (token != TokenNameSEMICOLON) {
expr();
}
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
if (token != TokenNameINLINE_HTML) {
throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
}
getNextToken();
}
return;
} else if (token == TokenNameecho) {
getNextToken();
expressionList();
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
if (token != TokenNameINLINE_HTML) {
throwSyntaxError("';' expected after 'echo' statement.");
}
getNextToken();
}
return;
} else if (token == TokenNameINLINE_HTML) {
getNextToken();
return;
// } else if (token == TokenNameprint) {
// getNextToken();
// expression();
// if (token == TokenNameSEMICOLON) {
// getNextToken();
// } else {
// if (token != TokenNameStopPHP) {
// throwSyntaxError("';' expected after 'print' statement.");
// }
// getNextToken();
// }
// return;
} else if (token == TokenNameglobal) {
getNextToken();
global_var_list();
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
if (token != TokenNameINLINE_HTML) {
throwSyntaxError("';' expected after 'global' statement.");
}
getNextToken();
}
return;
} else if (token == TokenNamestatic) {
getNextToken();
static_var_list();
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
if (token != TokenNameINLINE_HTML) {
throwSyntaxError("';' expected after 'static' statement.");
}
getNextToken();
}
return;
} else if (token == TokenNameunset) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("'(' expected after 'unset' statement.");
}
unset_variables();
if (token == TokenNameRPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'unset' statement.");
}
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
if (token != TokenNameINLINE_HTML) {
throwSyntaxError("';' expected after 'unset' statement.");
}
getNextToken();
}
return;
} else if (token == TokenNamefunction) {
MethodDeclaration methodDecl = new MethodDeclaration(
this.compilationUnit.compilationResult);
methodDecl.declarationSourceStart = scanner
.getCurrentTokenStartPosition();
getNextToken();
functionDefinition(methodDecl);
return;
} else if (token == TokenNametry) {
getNextToken();
if (token != TokenNameLBRACE) {
throwSyntaxError("'{' expected in 'try' statement.");
}
getNextToken();
statementList();
if (token != TokenNameRBRACE) {
throwSyntaxError("'}' expected in 'try' statement.");
}
getNextToken();
return;
} else if (token == TokenNamecatch) {
getNextToken();
if (token != TokenNameLPAREN) {
throwSyntaxError("'(' expected in 'catch' statement.");
}
getNextToken();
fully_qualified_class_name();
if (token != TokenNameVariable) {
throwSyntaxError("Variable expected in 'catch' statement.");
}
getNextToken();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected in 'catch' statement.");
}
getNextToken();
if (token != TokenNameLBRACE) {
throwSyntaxError("'{' expected in 'catch' statement.");
}
getNextToken();
statementList();
if (token != TokenNameRBRACE) {
throwSyntaxError("'}' expected in 'catch' statement.");
}
getNextToken();
additional_catches();
return;
} else if (token == TokenNamethrow) {
getNextToken();
expr();
if (token == TokenNameSEMICOLON) {
getNextToken();
} else {
throwSyntaxError("';' expected after 'throw' exxpression.");
}
return;
} else if (token == TokenNamefinal || token == TokenNameabstract
|| token == TokenNameclass || token == TokenNameinterface) {
TypeDeclaration typeDecl = new TypeDeclaration(
this.compilationUnit.compilationResult);
typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
// default super class
typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
compilationUnit.types.add(typeDecl);
try {
pushOnAstStack(typeDecl);
unticked_class_declaration_statement(typeDecl);
// classBody(typeDecl);
} finally {
astPtr--;
astLengthPtr--;
}
return;
// } else {
// throwSyntaxError("Unexpected keyword '" + keyword + "'");
} else if (token == TokenNameLBRACE) {
getNextToken();
if (token != TokenNameRBRACE) {
statementList();
}
if (token == TokenNameRBRACE) {
getNextToken();
return;
} else {
throwSyntaxError("'}' expected.");
}
} else {
if (token != TokenNameSEMICOLON) {
expr();
}
if (token == TokenNameSEMICOLON) {
getNextToken();
return;
} else {
if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
throwSyntaxError("';' expected after expression (Found token: "
+ scanner.toStringAction(token) + ")");
}
getNextToken();
}
}
}
private void additional_catches() {
while (token == TokenNamecatch) {
getNextToken();
if (token != TokenNameLPAREN) {
throwSyntaxError("'(' expected in 'catch' statement.");
}
getNextToken();
fully_qualified_class_name();
if (token != TokenNameVariable) {
throwSyntaxError("Variable expected in 'catch' statement.");
}
getNextToken();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected in 'catch' statement.");
}
getNextToken();
if (token != TokenNameLBRACE) {
throwSyntaxError("'{' expected in 'catch' statement.");
}
getNextToken();
statementList();
if (token != TokenNameRBRACE) {
throwSyntaxError("'}' expected in 'catch' statement.");
}
getNextToken();
}
}
private void foreach_variable() {
// w_variable
//| '&' w_variable
if (token == TokenNameAND) {
getNextToken();
}
w_variable();
}
private void foreach_optional_arg() {
// /* empty */
//| T_DOUBLE_ARROW foreach_variable
if (token == TokenNameEQUAL_GREATER) {
getNextToken();
foreach_variable();
}
}
private void global_var_list() {
// global_var_list:
// global_var_list ',' global_var
//| global_var
while (true) {
global_var();
if (token != TokenNameCOMMA) {
break;
}
getNextToken();
}
}
private void global_var() {
//global_var:
// T_VARIABLE
//| '$' r_variable
//| '$' '{' expr '}'
if (token == TokenNameVariable) {
getNextToken();
} else if (token == TokenNameDOLLAR) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
expr();
if (token != TokenNameLPAREN) {
throwSyntaxError("')' expected in global variable.");
}
getNextToken();
} else {
r_variable();
}
}
}
private void static_var_list() {
//static_var_list:
// static_var_list ',' T_VARIABLE
//| static_var_list ',' T_VARIABLE '=' static_scalar
//| T_VARIABLE
//| T_VARIABLE '=' static_scalar
while (true) {
if (token == TokenNameVariable) {
getNextToken();
if (token == TokenNameEQUAL) {
getNextToken();
static_scalar();
}
if (token != TokenNameCOMMA) {
break;
}
getNextToken();
} else {
break;
}
}
}
private void unset_variables() {
// unset_variables:
// unset_variable
// | unset_variables ',' unset_variable
// unset_variable:
// variable
while (true) {
variable();
if (token != TokenNameCOMMA) {
break;
}
getNextToken();
}
}
private final void initializeModifiers() {
this.modifiers = 0;
this.modifiersSourceStart = -1;
}
private final void checkAndSetModifiers(int flag) {
this.modifiers |= flag;
if (this.modifiersSourceStart < 0)
this.modifiersSourceStart = this.scanner.startPosition;
}
private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
initializeModifiers();
if (token == TokenNameinterface) {
// interface_entry T_STRING
// interface_extends_list
// '{' class_statement_list '}'
checkAndSetModifiers(AccInterface);
getNextToken();
typeDecl.modifiers = this.modifiers;
if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
typeDecl.name = scanner.getCurrentIdentifierSource();
if (token > TokenNameKEYWORD) {
throwSyntaxError("Don't use a keyword for interface declaration ["
+ scanner.toStringAction(token) + "].", typeDecl.sourceStart,
typeDecl.sourceEnd);
}
getNextToken();
interface_extends_list();
} else {
typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
typeDecl.name = new char[]{' '};
throwSyntaxError("Interface name expected after keyword 'interface'.",
typeDecl.sourceStart, typeDecl.sourceEnd);
return;
}
} else {
// class_entry_type T_STRING extends_from
// implements_list
// '{' class_statement_list'}'
class_entry_type();
typeDecl.modifiers = this.modifiers;
//identifier
//identifier 'extends' identifier
if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
typeDecl.name = scanner.getCurrentIdentifierSource();
if (token > TokenNameKEYWORD) {
throwSyntaxError("Don't use a keyword for class declaration ["
+ scanner.toStringAction(token) + "].", typeDecl.sourceStart,
typeDecl.sourceEnd);
}
getNextToken();
// extends_from:
// /* empty */
// | T_EXTENDS fully_qualified_class_name
if (token == TokenNameextends) {
getNextToken();
if (token == TokenNameIdentifier) {
getNextToken();
} else {
throwSyntaxError("Class name expected after keyword 'extends'.",
scanner.getCurrentTokenStartPosition(), scanner
.getCurrentTokenEndPosition());
}
}
implements_list();
} else {
typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
typeDecl.name = new char[]{' '};
throwSyntaxError("Class name expected after keyword 'class'.",
typeDecl.sourceStart, typeDecl.sourceEnd);
return;
}
}
// '{' class_statement_list '}'
if (token == TokenNameLBRACE) {
getNextToken();
if (token != TokenNameRBRACE) {
class_statement_list();
}
if (token == TokenNameRBRACE) {
typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
getNextToken();
} else {
throwSyntaxError("'}' expected at end of class body.");
}
} else {
throwSyntaxError("'{' expected at start of class body.");
}
}
private void class_entry_type() {
// T_CLASS
// | T_ABSTRACT T_CLASS
// | T_FINAL T_CLASS
if (token == TokenNameclass) {
getNextToken();
} else if (token == TokenNameabstract) {
checkAndSetModifiers(AccAbstract);
getNextToken();
if (token != TokenNameclass) {
throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
}
getNextToken();
} else if (token == TokenNamefinal) {
checkAndSetModifiers(AccFinal);
getNextToken();
if (token != TokenNameclass) {
throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
}
getNextToken();
} else {
throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
}
}
private void interface_extends_list() {
// /* empty */
// | T_EXTENDS interface_list
if (token == TokenNameextends) {
getNextToken();
interface_list();
}
}
private void implements_list() {
// /* empty */
// | T_IMPLEMENTS interface_list
if (token == TokenNameimplements) {
getNextToken();
interface_list();
}
}
private void interface_list() {
// interface_list:
// fully_qualified_class_name
//| interface_list ',' fully_qualified_class_name
do {
if (token == TokenNameIdentifier) {
getNextToken();
} else {
throwSyntaxError("Interface name expected after keyword 'implements'.");
}
if (token != TokenNameCOMMA) {
return;
}
getNextToken();
} while (true);
}
// private void classBody(TypeDeclaration typeDecl) {
// //'{' [class-element-list] '}'
// if (token == TokenNameLBRACE) {
// getNextToken();
// if (token != TokenNameRBRACE) {
// class_statement_list();
// }
// if (token == TokenNameRBRACE) {
// typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
// getNextToken();
// } else {
// throwSyntaxError("'}' expected at end of class body.");
// }
// } else {
// throwSyntaxError("'{' expected at start of class body.");
// }
// }
private void class_statement_list() {
do {
class_statement();
} while (token == TokenNamepublic || token == TokenNameprotected
|| token == TokenNameprivate || token == TokenNamestatic
|| token == TokenNameabstract || token == TokenNamefinal
|| token == TokenNamefunction || token == TokenNamevar
|| token == TokenNameconst);
}
private void class_statement() {
// class_statement:
// variable_modifiers class_variable_declaration ';'
// | class_constant_declaration ';'
// | method_modifiers T_FUNCTION is_reference T_STRING
// '(' parameter_list ')' method_body
initializeModifiers();
if (token == TokenNamevar) {
checkAndSetModifiers(AccPublic);
problemReporter.phpVarDeprecatedWarning(scanner
.getCurrentTokenStartPosition(),
scanner.getCurrentTokenEndPosition(), referenceContext,
compilationUnit.compilationResult);
getNextToken();
class_variable_declaration();
} else if (token == TokenNameconst) {
class_constant_declaration();
if (token != TokenNameSEMICOLON) {
throwSyntaxError("';' expected after class const declaration.");
}
getNextToken();
} else {
boolean hasModifiers = member_modifiers();
if (token == TokenNamefunction) {
if (!hasModifiers) {
checkAndSetModifiers(AccPublic);
}
MethodDeclaration methodDecl = new MethodDeclaration(
this.compilationUnit.compilationResult);
methodDecl.declarationSourceStart = scanner
.getCurrentTokenStartPosition();
methodDecl.modifiers = this.modifiers;
getNextToken();
functionDefinition(methodDecl);
} else {
if (!hasModifiers) {
throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
}
class_variable_declaration();
}
}
// if (token == TokenNamefunction) {
// MethodDeclaration methodDecl = new MethodDeclaration(
// this.compilationUnit.compilationResult);
// methodDecl.declarationSourceStart = scanner
// .getCurrentTokenStartPosition();
// getNextToken();
// functionDefinition(methodDecl);
// } else if (token == TokenNamevar) {
// getNextToken();
// classProperty();
// } else {
// throwSyntaxError("'function' or 'var' expected.");
// }
}
private void class_constant_declaration() {
// class_constant_declaration ',' T_STRING '=' static_scalar
// | T_CONST T_STRING '=' static_scalar
if (token != TokenNameconst) {
throwSyntaxError("'const' keyword expected in class declaration.");
} else {
getNextToken();
}
while (true) {
if (token != TokenNameIdentifier) {
throwSyntaxError("Identifier expected in class const declaration.");
}
getNextToken();
if (token != TokenNameEQUAL) {
throwSyntaxError("'=' expected in class const declaration.");
}
getNextToken();
static_scalar();
if (token != TokenNameCOMMA) {
break; // while(true)-loop
}
getNextToken();
}
}
// private void variable_modifiers() {
// // variable_modifiers:
// // non_empty_member_modifiers
// //| T_VAR
// initializeModifiers();
// if (token == TokenNamevar) {
// checkAndSetModifiers(AccPublic);
// reportSyntaxError(
// "Keyword 'var' is deprecated. Please use 'public' 'private' or 'protected'
// modifier for field declarations.",
// scanner.getCurrentTokenStartPosition(), scanner
// .getCurrentTokenEndPosition());
// getNextToken();
// } else {
// if (!member_modifiers()) {
// throwSyntaxError("'public' 'private' or 'protected' modifier expected for
// field declarations.");
// }
// }
// }
// private void method_modifiers() {
// //method_modifiers:
// // /* empty */
// //| non_empty_member_modifiers
// initializeModifiers();
// if (!member_modifiers()) {
// checkAndSetModifiers(AccPublic);
// }
// }
private boolean member_modifiers() {
// T_PUBLIC
//| T_PROTECTED
//| T_PRIVATE
//| T_STATIC
//| T_ABSTRACT
//| T_FINAL
boolean foundToken = false;
while (true) {
if (token == TokenNamepublic) {
checkAndSetModifiers(AccPublic);
getNextToken();
foundToken = true;
} else if (token == TokenNameprotected) {
checkAndSetModifiers(AccProtected);
getNextToken();
foundToken = true;
} else if (token == TokenNameprivate) {
checkAndSetModifiers(AccPrivate);
getNextToken();
foundToken = true;
} else if (token == TokenNamestatic) {
checkAndSetModifiers(AccStatic);
getNextToken();
foundToken = true;
} else if (token == TokenNameabstract) {
checkAndSetModifiers(AccAbstract);
getNextToken();
foundToken = true;
} else if (token == TokenNamefinal) {
checkAndSetModifiers(AccFinal);
getNextToken();
foundToken = true;
} else {
break;
}
}
return foundToken;
}
private void class_variable_declaration() {
// class_variable_declaration:
// class_variable_declaration ',' T_VARIABLE
// | class_variable_declaration ',' T_VARIABLE '=' static_scalar
// | T_VARIABLE
// | T_VARIABLE '=' static_scalar
do {
if (token == TokenNameVariable) {
getNextToken();
if (token == TokenNameEQUAL) {
getNextToken();
static_scalar();
}
} else {
// if (token == TokenNamethis) {
// throwSyntaxError("'$this' not allowed after keyword 'public'
// 'protected' 'private' 'var'.");
// }
throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
}
if (token != TokenNameCOMMA) {
break;
}
getNextToken();
} while (true);
if (token != TokenNameSEMICOLON) {
throwSyntaxError("';' expected after field declaration.");
}
getNextToken();
}
private void functionDefinition(MethodDeclaration methodDecl) {
boolean isAbstract = false;
if (astPtr == 0) {
compilationUnit.types.add(methodDecl);
} else {
AstNode node = astStack[astPtr];
if (node instanceof TypeDeclaration) {
TypeDeclaration typeDecl = ((TypeDeclaration) node);
if (typeDecl.methods == null) {
typeDecl.methods = new AbstractMethodDeclaration[]{methodDecl};
} else {
AbstractMethodDeclaration[] newMethods;
System
.arraycopy(
typeDecl.methods,
0,
newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1],
1, typeDecl.methods.length);
newMethods[0] = methodDecl;
typeDecl.methods = newMethods;
}
if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
isAbstract = true;
} else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
isAbstract = true;
}
}
}
functionDeclarator(methodDecl);
if (token == TokenNameSEMICOLON) {
if (!isAbstract) {
throwSyntaxError("Body declaration expected for method: "
+ new String(methodDecl.selector));
}
getNextToken();
return;
}
functionBody(methodDecl);
}
private void functionDeclarator(MethodDeclaration methodDecl) {
//identifier '(' [parameter-list] ')'
if (token == TokenNameAND) {
getNextToken();
}
if (token == TokenNameIdentifier) {
methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
methodDecl.selector = scanner.getCurrentIdentifierSource();
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("'(' expected in function declaration.");
}
if (token != TokenNameRPAREN) {
parameter_list();
}
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected in function declaration.");
} else {
methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
getNextToken();
}
} else {
if (token > TokenNameKEYWORD) {
throwSyntaxError("Don't use keyword for function declaration [" + token
+ "].");
}
throwSyntaxError("Function name expected after keyword 'function'.");
}
}
//
private void parameter_list() {
// non_empty_parameter_list
// | /* empty */
non_empty_parameter_list(true);
}
private void non_empty_parameter_list(boolean empty_allowed) {
// optional_class_type T_VARIABLE
// | optional_class_type '&' T_VARIABLE
// | optional_class_type '&' T_VARIABLE '=' static_scalar
// | optional_class_type T_VARIABLE '=' static_scalar
// | non_empty_parameter_list ',' optional_class_type T_VARIABLE
// | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
// | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
// static_scalar
// | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
// static_scalar
if (token == TokenNameIdentifier || token == TokenNameVariable
|| token == TokenNameAND) {
while (true) {
if (token == TokenNameIdentifier) {
getNextToken();
}
if (token == TokenNameAND) {
getNextToken();
}
if (token == TokenNameVariable) {
getNextToken();
if (token == TokenNameEQUAL) {
getNextToken();
static_scalar();
}
} else {
throwSyntaxError("Variable expected in parameter list.");
}
if (token != TokenNameCOMMA) {
break;
}
getNextToken();
}
return;
}
if (!empty_allowed) {
throwSyntaxError("Identifier expected in parameter list.");
}
}
private void optional_class_type() {
// /* empty */
//| T_STRING
}
private void parameterDeclaration() {
//variable
//variable-reference
if (token == TokenNameAND) {
getNextToken();
if (isVariable()) {
getNextToken();
} else {
throwSyntaxError("Variable expected after reference operator '&'.");
}
}
//variable '=' constant
if (token == TokenNameVariable) {
getNextToken();
if (token == TokenNameEQUAL) {
getNextToken();
static_scalar();
}
return;
}
// if (token == TokenNamethis) {
// throwSyntaxError("Reserved word '$this' not allowed in parameter
// declaration.");
// }
}
private void labeledStatementList() {
if (token != TokenNamecase && token != TokenNamedefault) {
throwSyntaxError("'case' or 'default' expected.");
}
do {
if (token == TokenNamecase) {
getNextToken();
expr(); //constant();
if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
getNextToken();
if (token == TokenNamecase || token == TokenNamedefault) { // empty
// case
// statement
// ?
continue;
}
statementList();
}
// else if (token == TokenNameSEMICOLON) {
// setMarker(
// "':' expected after 'case' keyword (Found token: " +
// scanner.toStringAction(token) + ")",
// scanner.getCurrentTokenStartPosition(),
// scanner.getCurrentTokenEndPosition(),
// INFO);
// getNextToken();
// if (token == TokenNamecase) { // empty case statement ?
// continue;
// }
// statementList();
// }
else {
throwSyntaxError("':' character after 'case' constant expected (Found token: "
+ scanner.toStringAction(token) + ")");
}
} else { // TokenNamedefault
getNextToken();
if (token == TokenNameCOLON) {
getNextToken();
statementList();
} else {
throwSyntaxError("':' character after 'default' expected.");
}
}
} while (token == TokenNamecase || token == TokenNamedefault);
}
// public void labeledStatement() {
// if (token == TokenNamecase) {
// getNextToken();
// constant();
// if (token == TokenNameDDOT) {
// getNextToken();
// statement();
// } else {
// throwSyntaxError("':' character after 'case' constant expected.");
// }
// return;
// } else if (token == TokenNamedefault) {
// getNextToken();
// if (token == TokenNameDDOT) {
// getNextToken();
// statement();
// } else {
// throwSyntaxError("':' character after 'default' expected.");
// }
// return;
// }
// }
// public void expressionStatement() {
// }
// private void inclusionStatement() {
// }
// public void compoundStatement() {
// }
// public void selectionStatement() {
// }
//
// public void iterationStatement() {
// }
//
// public void jumpStatement() {
// }
//
// public void outputStatement() {
// }
//
// public void scopeStatement() {
// }
//
// public void flowStatement() {
// }
//
// public void definitionStatement() {
// }
private void ifStatement() {
// ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
if (token == TokenNameCOLON) {
getNextToken();
if (token != TokenNameendif) {
statementList();
switch (token) {
case TokenNameelse :
getNextToken();
if (token == TokenNameCOLON) {
getNextToken();
if (token != TokenNameendif) {
statementList();
}
} else {
if (token == TokenNameif) { //'else if'
getNextToken();
elseifStatementList();
} else {
throwSyntaxError("':' expected after 'else'.");
}
}
break;
case TokenNameelseif :
getNextToken();
elseifStatementList();
break;
}
}
if (token != TokenNameendif) {
throwSyntaxError("'endif' expected.");
}
getNextToken();
if (token != TokenNameSEMICOLON) {
throwSyntaxError("';' expected after if-statement.");
}
getNextToken();
} else {
// statement [else-statement]
statement(TokenNameEOF);
if (token == TokenNameelseif) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
} else {
throwSyntaxError("'(' expected after 'elseif' keyword.");
}
expr();
if (token == TokenNameRPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'elseif' condition.");
}
ifStatement();
} else if (token == TokenNameelse) {
getNextToken();
statement(TokenNameEOF);
}
}
}
private void elseifStatementList() {
do {
elseifStatement();
switch (token) {
case TokenNameelse :
getNextToken();
if (token == TokenNameCOLON) {
getNextToken();
if (token != TokenNameendif) {
statementList();
}
return;
} else {
if (token == TokenNameif) { //'else if'
getNextToken();
} else {
throwSyntaxError("':' expected after 'else'.");
}
}
break;
case TokenNameelseif :
getNextToken();
break;
default :
return;
}
} while (true);
}
private void elseifStatement() {
if (token == TokenNameLPAREN) {
getNextToken();
expr();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected in else-if-statement.");
}
getNextToken();
if (token != TokenNameCOLON) {
throwSyntaxError("':' expected in else-if-statement.");
}
getNextToken();
if (token != TokenNameendif) {
statementList();
}
}
}
private void switchStatement() {
if (token == TokenNameCOLON) {
// ':' [labeled-statement-list] 'endswitch' ';'
getNextToken();
labeledStatementList();
if (token != TokenNameendswitch) {
throwSyntaxError("'endswitch' expected.");
}
getNextToken();
if (token != TokenNameSEMICOLON) {
throwSyntaxError("';' expected after switch-statement.");
}
getNextToken();
} else {
// '{' [labeled-statement-list] '}'
if (token != TokenNameLBRACE) {
throwSyntaxError("'{' expected in switch statement.");
}
getNextToken();
if (token != TokenNameRBRACE) {
labeledStatementList();
}
if (token != TokenNameRBRACE) {
throwSyntaxError("'}' expected in switch statement.");
}
getNextToken();
}
}
private void forStatement() {
if (token == TokenNameCOLON) {
getNextToken();
statementList();
if (token != TokenNameendfor) {
throwSyntaxError("'endfor' expected.");
}
getNextToken();
if (token != TokenNameSEMICOLON) {
throwSyntaxError("';' expected after for-statement.");
}
getNextToken();
} else {
statement(TokenNameEOF);
}
}
private void whileStatement() {
// ':' statement-list 'endwhile' ';'
if (token == TokenNameCOLON) {
getNextToken();
statementList();
if (token != TokenNameendwhile) {
throwSyntaxError("'endwhile' expected.");
}
getNextToken();
if (token != TokenNameSEMICOLON) {
throwSyntaxError("';' expected after while-statement.");
}
getNextToken();
} else {
statement(TokenNameEOF);
}
}
private void foreachStatement() {
if (token == TokenNameCOLON) {
getNextToken();
statementList();
if (token != TokenNameendforeach) {
throwSyntaxError("'endforeach' expected.");
}
getNextToken();
if (token != TokenNameSEMICOLON) {
throwSyntaxError("';' expected after foreach-statement.");
}
getNextToken();
} else {
statement(TokenNameEOF);
}
}
// private void exitStatus() {
// if (token == TokenNameLPAREN) {
// getNextToken();
// } else {
// throwSyntaxError("'(' expected in 'exit-status'.");
// }
// if (token != TokenNameRPAREN) {
// expression();
// }
// if (token == TokenNameRPAREN) {
// getNextToken();
// } else {
// throwSyntaxError("')' expected after 'exit-status'.");
// }
// }
private void expressionList() {
do {
expr();
if (token == TokenNameCOMMA) {
getNextToken();
} else {
break;
}
} while (true);
}
private void expr() {
// r_variable
// | expr_without_variable
// if (token!=TokenNameEOF) {
if (Scanner.TRACE) {
System.out.println("TRACE: expr()");
}
expr_without_variable(true);
// }
}
private void expr_without_variable(boolean only_variable) {
// internal_functions_in_yacc
// | T_CLONE expr
// | T_PRINT expr
// | '(' expr ')'
// | '@' expr
// | '+' expr
// | '-' expr
// | '!' expr
// | '~' expr
// | T_INC rw_variable
// | T_DEC rw_variable
// | T_INT_CAST expr
// | T_DOUBLE_CAST expr
// | T_STRING_CAST expr
// | T_ARRAY_CAST expr
// | T_OBJECT_CAST expr
// | T_BOOL_CAST expr
// | T_UNSET_CAST expr
// | T_EXIT exit_expr
// | scalar
// | T_ARRAY '(' array_pair_list ')'
// | '`' encaps_list '`'
// | T_LIST '(' assignment_list ')' '=' expr
// | T_NEW class_name_reference ctor_arguments
// | variable '=' expr
// | variable '=' '&' variable
// | variable '=' '&' T_NEW class_name_reference ctor_arguments
// | variable T_PLUS_EQUAL expr
// | variable T_MINUS_EQUAL expr
// | variable T_MUL_EQUAL expr
// | variable T_DIV_EQUAL expr
// | variable T_CONCAT_EQUAL expr
// | variable T_MOD_EQUAL expr
// | variable T_AND_EQUAL expr
// | variable T_OR_EQUAL expr
// | variable T_XOR_EQUAL expr
// | variable T_SL_EQUAL expr
// | variable T_SR_EQUAL expr
// | rw_variable T_INC
// | rw_variable T_DEC
// | expr T_BOOLEAN_OR expr
// | expr T_BOOLEAN_AND expr
// | expr T_LOGICAL_OR expr
// | expr T_LOGICAL_AND expr
// | expr T_LOGICAL_XOR expr
// | expr '|' expr
// | expr '&' expr
// | expr '^' expr
// | expr '.' expr
// | expr '+' expr
// | expr '-' expr
// | expr '*' expr
// | expr '/' expr
// | expr '%' expr
// | expr T_SL expr
// | expr T_SR expr
// | expr T_IS_IDENTICAL expr
// | expr T_IS_NOT_IDENTICAL expr
// | expr T_IS_EQUAL expr
// | expr T_IS_NOT_EQUAL expr
// | expr '<' expr
// | expr T_IS_SMALLER_OR_EQUAL expr
// | expr '>' expr
// | expr T_IS_GREATER_OR_EQUAL expr
// | expr T_INSTANCEOF class_name_reference
// | expr '?' expr ':' expr
if (Scanner.TRACE) {
System.out.println("TRACE: expr_without_variable() PART 1");
}
switch (token) {
case TokenNameisset :
case TokenNameempty :
case TokenNameeval :
case TokenNameinclude :
case TokenNameinclude_once :
case TokenNamerequire :
case TokenNamerequire_once :
internal_functions_in_yacc();
break;
// | '(' expr ')'
case TokenNameLPAREN :
getNextToken();
expr();
if (token == TokenNameRPAREN) {
getNextToken();
} else {
throwSyntaxError("')' expected in expression.");
}
break;
// | T_CLONE expr
// | T_PRINT expr
// | '@' expr
// | '+' expr
// | '-' expr
// | '!' expr
// | '~' expr
// | T_INT_CAST expr
// | T_DOUBLE_CAST expr
// | T_STRING_CAST expr
// | T_ARRAY_CAST expr
// | T_OBJECT_CAST expr
// | T_BOOL_CAST expr
// | T_UNSET_CAST expr
case TokenNameclone :
case TokenNameprint :
case TokenNameAT :
case TokenNamePLUS :
case TokenNameMINUS :
case TokenNameNOT :
case TokenNameTWIDDLE :
case TokenNameintCAST :
case TokenNamedoubleCAST :
case TokenNamestringCAST :
case TokenNamearrayCAST :
case TokenNameobjectCAST :
case TokenNameboolCAST :
case TokenNameunsetCAST :
getNextToken();
expr();
break;
case TokenNameexit :
getNextToken();
exit_expr();
break;
// scalar:
// T_STRING
//| T_STRING_VARNAME
//| class_constant
//| '"' encaps_list '"'
//| '\'' encaps_list '\''
//| T_START_HEREDOC encaps_list T_END_HEREDOC
// | '`' encaps_list '`'
// | common_scalar
case TokenNameIntegerLiteral :
case TokenNameDoubleLiteral :
case TokenNameStringLiteral :
case TokenNameStringConstant :
case TokenNameStringInterpolated :
case TokenNameFILE :
case TokenNameLINE :
case TokenNameCLASS_C :
case TokenNameMETHOD_C :
case TokenNameFUNC_C :
common_scalar();
break;
case TokenNameHEREDOC :
getNextToken();
break;
case TokenNamearray :
// T_ARRAY '(' array_pair_list ')'
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
if (token == TokenNameRPAREN) {
getNextToken();
break;
}
array_pair_list();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected after keyword 'array'"
+ "(Found token: " + scanner.toStringAction(token) + ")");
}
getNextToken();
} else {
throwSyntaxError("'(' expected after keyword 'array'"
+ "(Found token: " + scanner.toStringAction(token) + ")");
}
break;
case TokenNamelist :
// | T_LIST '(' assignment_list ')' '=' expr
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
assignment_list();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected after 'list' keyword.");
}
getNextToken();
if (token != TokenNameEQUAL) {
throwSyntaxError("'=' expected after 'list' keyword.");
}
getNextToken();
expr();
} else {
throwSyntaxError("'(' expected after 'list' keyword.");
}
break;
case TokenNamenew :
// | T_NEW class_name_reference ctor_arguments
getNextToken();
class_name_reference();
ctor_arguments();
break;
// | T_INC rw_variable
// | T_DEC rw_variable
case TokenNamePLUS_PLUS :
case TokenNameMINUS_MINUS :
getNextToken();
rw_variable();
break;
// | variable '=' expr
// | variable '=' '&' variable
// | variable '=' '&' T_NEW class_name_reference ctor_arguments
// | variable T_PLUS_EQUAL expr
// | variable T_MINUS_EQUAL expr
// | variable T_MUL_EQUAL expr
// | variable T_DIV_EQUAL expr
// | variable T_CONCAT_EQUAL expr
// | variable T_MOD_EQUAL expr
// | variable T_AND_EQUAL expr
// | variable T_OR_EQUAL expr
// | variable T_XOR_EQUAL expr
// | variable T_SL_EQUAL expr
// | variable T_SR_EQUAL expr
// | rw_variable T_INC
// | rw_variable T_DEC
case TokenNameIdentifier :
case TokenNameVariable :
case TokenNameDOLLAR :
variable();
switch (token) {
case TokenNameEQUAL :
getNextToken();
if (token == TokenNameAND) {
getNextToken();
if (token == TokenNamenew) {
getNextToken();
throwSyntaxError("not yet implemented (= & new)");
// class_name_reference();
// ctor_arguments();
} else {
variable();
}
} else {
expr();
}
break;
case TokenNamePLUS_EQUAL :
case TokenNameMINUS_EQUAL :
case TokenNameMULTIPLY_EQUAL :
case TokenNameDIVIDE_EQUAL :
case TokenNameDOT_EQUAL :
case TokenNameREMAINDER_EQUAL :
case TokenNameAND_EQUAL :
case TokenNameOR_EQUAL :
case TokenNameXOR_EQUAL :
case TokenNameRIGHT_SHIFT_EQUAL :
case TokenNameLEFT_SHIFT_EQUAL :
getNextToken();
expr();
break;
case TokenNamePLUS_PLUS :
case TokenNameMINUS_MINUS :
getNextToken();
break;
default :
if (!only_variable) {
throwSyntaxError("Variable expression not allowed (found token '"
+ scanner.toStringAction(token) + "').");
}
}
break;
default :
if (token != TokenNameINLINE_HTML) {
throwSyntaxError("Error in expression (found token '"
+ scanner.toStringAction(token) + "').");
}
return;
}
if (Scanner.TRACE) {
System.out.println("TRACE: expr_without_variable() PART 2");
}
// | expr T_BOOLEAN_OR expr
// | expr T_BOOLEAN_AND expr
// | expr T_LOGICAL_OR expr
// | expr T_LOGICAL_AND expr
// | expr T_LOGICAL_XOR expr
// | expr '|' expr
// | expr '&' expr
// | expr '^' expr
// | expr '.' expr
// | expr '+' expr
// | expr '-' expr
// | expr '*' expr
// | expr '/' expr
// | expr '%' expr
// | expr T_SL expr
// | expr T_SR expr
// | expr T_IS_IDENTICAL expr
// | expr T_IS_NOT_IDENTICAL expr
// | expr T_IS_EQUAL expr
// | expr T_IS_NOT_EQUAL expr
// | expr '<' expr
// | expr T_IS_SMALLER_OR_EQUAL expr
// | expr '>' expr
// | expr T_IS_GREATER_OR_EQUAL expr
while (true) {
switch (token) {
case TokenNameOR_OR :
case TokenNameAND_AND :
case TokenNameand :
case TokenNameor :
case TokenNamexor :
case TokenNameAND :
case TokenNameOR :
case TokenNameXOR :
case TokenNameDOT :
case TokenNamePLUS :
case TokenNameMINUS :
case TokenNameMULTIPLY :
case TokenNameDIVIDE :
case TokenNameREMAINDER :
case TokenNameLEFT_SHIFT :
case TokenNameRIGHT_SHIFT :
case TokenNameEQUAL_EQUAL_EQUAL :
case TokenNameNOT_EQUAL_EQUAL :
case TokenNameEQUAL_EQUAL :
case TokenNameNOT_EQUAL :
case TokenNameLESS :
case TokenNameLESS_EQUAL :
case TokenNameGREATER :
case TokenNameGREATER_EQUAL :
getNextToken();
expr();
break;
// | expr T_INSTANCEOF class_name_reference
// | expr '?' expr ':' expr
case TokenNameinstanceof :
getNextToken();
class_name_reference();
break;
case TokenNameQUESTION :
getNextToken();
expr();
if (token == TokenNameCOLON) {
getNextToken();
expr();
}
break;
default :
return;
}
}
}
private void class_name_reference() {
// class_name_reference:
// T_STRING
//| dynamic_class_name_reference
if (Scanner.TRACE) {
System.out.println("TRACE: class_name_reference()");
}
if (token == TokenNameIdentifier) {
getNextToken();
} else {
dynamic_class_name_reference();
}
}
private void dynamic_class_name_reference() {
//dynamic_class_name_reference:
// base_variable T_OBJECT_OPERATOR object_property
// dynamic_class_name_variable_properties
//| base_variable
if (Scanner.TRACE) {
System.out.println("TRACE: dynamic_class_name_reference()");
}
base_variable();
if (token == TokenNameMINUS_GREATER) {
getNextToken();
object_property();
dynamic_class_name_variable_properties();
}
}
private void dynamic_class_name_variable_properties() {
// dynamic_class_name_variable_properties:
// dynamic_class_name_variable_properties
// dynamic_class_name_variable_property
// | /* empty */
if (Scanner.TRACE) {
System.out.println("TRACE: dynamic_class_name_variable_properties()");
}
while (token == TokenNameMINUS_GREATER) {
dynamic_class_name_variable_property();
}
}
private void dynamic_class_name_variable_property() {
// dynamic_class_name_variable_property:
// T_OBJECT_OPERATOR object_property
if (Scanner.TRACE) {
System.out.println("TRACE: dynamic_class_name_variable_property()");
}
if (token == TokenNameMINUS_GREATER) {
getNextToken();
object_property();
}
}
private void ctor_arguments() {
// ctor_arguments:
// /* empty */
//| '(' function_call_parameter_list ')'
if (token == TokenNameLPAREN) {
getNextToken();
if (token == TokenNameRPAREN) {
getNextToken();
return;
}
non_empty_function_call_parameter_list();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected in ctor_arguments.");
}
getNextToken();
}
}
private void assignment_list() {
// assignment_list:
// assignment_list ',' assignment_list_element
//| assignment_list_element
while (true) {
assignment_list_element();
if (token != TokenNameCOMMA) {
break;
}
getNextToken();
}
}
private void assignment_list_element() {
//assignment_list_element:
// variable
//| T_LIST '(' assignment_list ')'
//| /* empty */
if (token == TokenNameVariable || token == TokenNameDOLLAR) {
variable();
} else {
if (token == TokenNamelist) {
getNextToken();
if (token == TokenNameLPAREN) {
getNextToken();
assignment_list();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected after 'list' keyword.");
}
getNextToken();
} else {
throwSyntaxError("'(' expected after 'list' keyword.");
}
}
}
}
private void array_pair_list() {
// array_pair_list:
// /* empty */
//| non_empty_array_pair_list possible_comma
non_empty_array_pair_list();
if (token == TokenNameCOMMA) {
getNextToken();
}
}
private void non_empty_array_pair_list() {
//non_empty_array_pair_list:
// non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
//| non_empty_array_pair_list ',' expr
//| expr T_DOUBLE_ARROW expr
//| expr
//| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
//| non_empty_array_pair_list ',' '&' w_variable
//| expr T_DOUBLE_ARROW '&' w_variable
//| '&' w_variable
while (true) {
expr();
if (token == TokenNameAND) {
getNextToken();
variable();
return;
} else if (token == TokenNameEQUAL_GREATER) {
getNextToken();
if (token == TokenNameAND) {
getNextToken();
variable();
} else {
expr();
}
}
if (token != TokenNameCOMMA) {
return;
}
getNextToken();
if (token == TokenNameRPAREN) {
return;
}
}
}
// private void variableList() {
// do {
// variable();
// if (token == TokenNameCOMMA) {
// getNextToken();
// } else {
// break;
// }
// } while (true);
// }
private void variable_without_objects() {
// variable_without_objects:
// reference_variable
// | simple_indirect_reference reference_variable
if (Scanner.TRACE) {
System.out.println("TRACE: variable_without_objects()");
}
while (token == TokenNameDOLLAR) {
getNextToken();
}
reference_variable();
}
private void function_call() {
// function_call:
// T_STRING '(' function_call_parameter_list ')'
//| class_constant '(' function_call_parameter_list ')'
//| static_member '(' function_call_parameter_list ')'
//| variable_without_objects '(' function_call_parameter_list ')'
if (Scanner.TRACE) {
System.out.println("TRACE: function_call()");
}
if (token == TokenNameIdentifier) {
getNextToken();
switch (token) {
case TokenNamePAAMAYIM_NEKUDOTAYIM :
// static member:
getNextToken();
if (token == TokenNameIdentifier) {
// class _constant
getNextToken();
} else {
// static member:
variable_without_objects();
}
break;
}
} else {
variable_without_objects();
}
if (token != TokenNameLPAREN) {
// TODO is this ok ?
return;
// throwSyntaxError("'(' expected in function call.");
}
getNextToken();
if (token == TokenNameRPAREN) {
getNextToken();
return;
}
non_empty_function_call_parameter_list();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected in function call.");
}
getNextToken();
}
// private void function_call_parameter_list() {
// function_call_parameter_list:
// non_empty_function_call_parameter_list { $$ = $1; }
// | /* empty */
// }
private void non_empty_function_call_parameter_list() {
//non_empty_function_call_parameter_list:
// expr_without_variable
// | variable
// | '&' w_variable
// | non_empty_function_call_parameter_list ',' expr_without_variable
// | non_empty_function_call_parameter_list ',' variable
// | non_empty_function_call_parameter_list ',' '&' w_variable
if (Scanner.TRACE) {
System.out.println("TRACE: non_empty_function_call_parameter_list()");
}
while (true) {
if (token == TokenNameAND) {
getNextToken();
w_variable();
} else {
// if (token == TokenNameIdentifier || token == TokenNameVariable
// || token == TokenNameDOLLAR) {
// variable();
// } else {
expr_without_variable(true);
// }
}
if (token != TokenNameCOMMA) {
break;
}
getNextToken();
}
}
private void fully_qualified_class_name() {
if (token == TokenNameIdentifier) {
getNextToken();
} else {
throwSyntaxError("Class name expected.");
}
}
private void static_member() {
// static_member:
// fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
// variable_without_objects
if (Scanner.TRACE) {
System.out.println("TRACE: static_member()");
}
fully_qualified_class_name();
if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
throwSyntaxError("'::' expected after class name (static_member).");
}
getNextToken();
variable_without_objects();
}
private void base_variable_with_function_calls() {
// base_variable_with_function_calls:
// base_variable
//| function_call
boolean functionCall = false;
if (Scanner.TRACE) {
System.out.println("TRACE: base_variable_with_function_calls()");
}
if (token == TokenNameIdentifier) {
functionCall = true;
} else if (token == TokenNameVariable) {
int tempToken = token;
int tempPosition = scanner.currentPosition;
getNextToken();
if (token == TokenNameLPAREN) {
functionCall = true;
}
token = tempToken;
scanner.currentPosition = tempPosition;
scanner.phpMode = true;
}
if (functionCall) {
function_call();
} else {
base_variable();
}
}
private void base_variable() {
// base_variable:
// reference_variable
// | simple_indirect_reference reference_variable
// | static_member
if (Scanner.TRACE) {
System.out.println("TRACE: base_variable()");
}
if (token == TokenNameIdentifier) {
static_member();
} else {
while (token == TokenNameDOLLAR) {
getNextToken();
}
reference_variable();
}
}
// private void simple_indirect_reference() {
// // simple_indirect_reference:
// // '$'
// //| simple_indirect_reference '$'
// }
private void reference_variable() {
// reference_variable:
// reference_variable '[' dim_offset ']'
// | reference_variable '{' expr '}'
// | compound_variable
if (Scanner.TRACE) {
System.out.println("TRACE: reference_variable()");
}
compound_variable();
while (true) {
if (token == TokenNameLBRACE) {
getNextToken();
expr();
if (token != TokenNameRBRACE) {
throwSyntaxError("'}' expected in reference variable.");
}
getNextToken();
} else if (token == TokenNameLBRACKET) {
getNextToken();
if (token != TokenNameRBRACKET) {
expr();
// dim_offset();
if (token != TokenNameRBRACKET) {
throwSyntaxError("']' expected in reference variable.");
}
}
getNextToken();
} else {
break;
}
}
}
private void compound_variable() {
// compound_variable:
// T_VARIABLE
// | '$' '{' expr '}'
if (Scanner.TRACE) {
System.out.println("TRACE: compound_variable()");
}
if (token == TokenNameVariable) {
getNextToken();
} else {
// because of simple_indirect_reference
while (token == TokenNameDOLLAR) {
getNextToken();
}
if (token != TokenNameLBRACE) {
throwSyntaxError("'{' expected after compound variable token '$'.");
}
getNextToken();
expr();
if (token != TokenNameRBRACE) {
throwSyntaxError("'}' expected after compound variable token '$'.");
}
getNextToken();
}
}
// private void dim_offset() {
// // dim_offset:
// // /* empty */
// // | expr
// expr();
// }
private void object_property() {
// object_property:
// object_dim_list
//| variable_without_objects
if (Scanner.TRACE) {
System.out.println("TRACE: object_property()");
}
if (token == TokenNameVariable || token == TokenNameDOLLAR) {
variable_without_objects();
} else {
object_dim_list();
}
}
private void object_dim_list() {
//object_dim_list:
// object_dim_list '[' dim_offset ']'
//| object_dim_list '{' expr '}'
//| variable_name
if (Scanner.TRACE) {
System.out.println("TRACE: object_dim_list()");
}
variable_name();
while (true) {
if (token == TokenNameLBRACE) {
getNextToken();
expr();
if (token != TokenNameRBRACE) {
throwSyntaxError("'}' expected in object_dim_list.");
}
getNextToken();
} else if (token == TokenNameLBRACKET) {
getNextToken();
if (token == TokenNameRBRACKET) {
getNextToken();
continue;
}
expr();
if (token != TokenNameRBRACKET) {
throwSyntaxError("']' expected in object_dim_list.");
}
getNextToken();
} else {
break;
}
}
}
private void variable_name() {
//variable_name:
// T_STRING
//| '{' expr '}'
if (Scanner.TRACE) {
System.out.println("TRACE: variable_name()");
}
if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
if (token > TokenNameKEYWORD) {
// TODO show a warning "Keyword used as variable" ?
}
getNextToken();
} else {
if (token != TokenNameLBRACE) {
throwSyntaxError("'{' expected in variable name.");
}
getNextToken();
expr();
if (token != TokenNameRBRACE) {
throwSyntaxError("'}' expected in variable name.");
}
}
}
private void r_variable() {
variable();
}
private void w_variable() {
variable();
}
private void rw_variable() {
variable();
}
private void variable() {
// variable:
// base_variable_with_function_calls T_OBJECT_OPERATOR
// object_property method_or_not variable_properties
// | base_variable_with_function_calls
base_variable_with_function_calls();
if (token == TokenNameMINUS_GREATER) {
getNextToken();
object_property();
method_or_not();
variable_properties();
}
// if (token == TokenNameDOLLAR_LBRACE) {
// getNextToken();
// expr();
// ;
// if (token != TokenNameRBRACE) {
// throwSyntaxError("'}' expected after indirect variable token '${'.");
// }
// getNextToken();
// } else {
// if (token == TokenNameVariable) {
// getNextToken();
// if (token == TokenNameLBRACKET) {
// getNextToken();
// expr();
// if (token != TokenNameRBRACKET) {
// throwSyntaxError("']' expected in variable-list.");
// }
// getNextToken();
// } else if (token == TokenNameEQUAL) {
// getNextToken();
// static_scalar();
// }
// } else {
// throwSyntaxError("$-variable expected in variable-list.");
// }
// }
}
private void variable_properties() {
// variable_properties:
// variable_properties variable_property
// | /* empty */
while (token == TokenNameMINUS_GREATER) {
variable_property();
}
}
private void variable_property() {
// variable_property:
// T_OBJECT_OPERATOR object_property method_or_not
if (Scanner.TRACE) {
System.out.println("TRACE: variable_property()");
}
if (token == TokenNameMINUS_GREATER) {
getNextToken();
object_property();
method_or_not();
} else {
throwSyntaxError("'->' expected in variable_property.");
}
}
private void method_or_not() {
// method_or_not:
// '(' function_call_parameter_list ')'
// | /* empty */
if (Scanner.TRACE) {
System.out.println("TRACE: method_or_not()");
}
if (token == TokenNameLPAREN) {
getNextToken();
if (token == TokenNameRPAREN) {
getNextToken();
return;
}
non_empty_function_call_parameter_list();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected in method_or_not.");
}
getNextToken();
}
}
private void exit_expr() {
// /* empty */
// | '(' ')'
// | '(' expr ')'
if (token != TokenNameLPAREN) {
return;
}
getNextToken();
if (token == TokenNameRPAREN) {
getNextToken();
return;
}
expr();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected after keyword 'exit'");
}
getNextToken();
}
private void internal_functions_in_yacc() {
switch (token) {
case TokenNameisset :
// T_ISSET '(' isset_variables ')'
getNextToken();
if (token != TokenNameLPAREN) {
throwSyntaxError("'(' expected after keyword 'isset'");
}
getNextToken();
isset_variables();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected after keyword 'isset'");
}
getNextToken();
break;
case TokenNameempty :
// T_EMPTY '(' variable ')'
getNextToken();
if (token != TokenNameLPAREN) {
throwSyntaxError("'(' expected after keyword 'empty'");
}
getNextToken();
variable();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected after keyword 'empty'");
}
getNextToken();
break;
case TokenNameinclude :
//T_INCLUDE expr
getNextToken();
expr();
break;
case TokenNameinclude_once :
// T_INCLUDE_ONCE expr
getNextToken();
expr();
break;
case TokenNameeval :
// T_EVAL '(' expr ')'
getNextToken();
if (token != TokenNameLPAREN) {
throwSyntaxError("'(' expected after keyword 'eval'");
}
getNextToken();
expr();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected after keyword 'eval'");
}
getNextToken();
break;
case TokenNamerequire :
//T_REQUIRE expr
getNextToken();
expr();
break;
case TokenNamerequire_once :
// T_REQUIRE_ONCE expr
getNextToken();
expr();
break;
}
}
private void isset_variables() {
// variable
// | isset_variables ','
if (token == TokenNameRPAREN) {
throwSyntaxError("Variable expected after keyword 'isset'");
}
while (true) {
variable();
if (token == TokenNameCOMMA) {
getNextToken();
} else {
break;
}
}
}
private boolean common_scalar() {
// common_scalar:
// T_LNUMBER
// | T_DNUMBER
// | T_CONSTANT_ENCAPSED_STRING
// | T_LINE
// | T_FILE
// | T_CLASS_C
// | T_METHOD_C
// | T_FUNC_C
switch (token) {
case TokenNameIntegerLiteral :
getNextToken();
return true;
case TokenNameDoubleLiteral :
getNextToken();
return true;
case TokenNameStringLiteral :
getNextToken();
return true;
case TokenNameStringConstant :
getNextToken();
return true;
case TokenNameStringInterpolated :
getNextToken();
return true;
case TokenNameFILE :
getNextToken();
return true;
case TokenNameLINE :
getNextToken();
return true;
case TokenNameCLASS_C :
getNextToken();
return true;
case TokenNameMETHOD_C :
getNextToken();
return true;
case TokenNameFUNC_C :
getNextToken();
return true;
}
return false;
}
private void scalar() {
// scalar:
// T_STRING
//| T_STRING_VARNAME
//| class_constant
//| common_scalar
//| '"' encaps_list '"'
//| '\'' encaps_list '\''
//| T_START_HEREDOC encaps_list T_END_HEREDOC
throwSyntaxError("Not yet implemented (scalar).");
}
private void static_scalar() {
// static_scalar: /* compile-time evaluated scalars */
// common_scalar
// | T_STRING
// | '+' static_scalar
// | '-' static_scalar
// | T_ARRAY '(' static_array_pair_list ')'
// | static_class_constant
if (common_scalar()) {
return;
}
switch (token) {
case TokenNameIdentifier :
getNextToken();
// static_class_constant:
// T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
getNextToken();
if (token == TokenNameIdentifier) {
getNextToken();
} else {
throwSyntaxError("Identifier expected after '::' operator.");
}
}
break;
case TokenNamePLUS :
getNextToken();
static_scalar();
break;
case TokenNameMINUS :
getNextToken();
static_scalar();
break;
case TokenNamearray :
getNextToken();
if (token != TokenNameLPAREN) {
throwSyntaxError("'(' expected after keyword 'array'");
}
getNextToken();
if (token == TokenNameRPAREN) {
getNextToken();
break;
}
non_empty_static_array_pair_list();
if (token != TokenNameRPAREN) {
throwSyntaxError("')' expected after keyword 'array'");
}
getNextToken();
break;
// case TokenNamenull :
// getNextToken();
// break;
// case TokenNamefalse :
// getNextToken();
// break;
// case TokenNametrue :
// getNextToken();
// break;
default :
throwSyntaxError("Static scalar/constant expected.");
}
}
private void non_empty_static_array_pair_list() {
// non_empty_static_array_pair_list:
// non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
// static_scalar
//| non_empty_static_array_pair_list ',' static_scalar
//| static_scalar T_DOUBLE_ARROW static_scalar
//| static_scalar
while (true) {
static_scalar();
if (token == TokenNameEQUAL_GREATER) {
getNextToken();
static_scalar();
}
if (token != TokenNameCOMMA) {
break;
}
getNextToken();
if (token == TokenNameRPAREN) {
break;
}
}
}
public void reportSyntaxError() { //int act, int currentKind, int
// stateStackTop) {
/* remember current scanner position */
int startPos = scanner.startPosition;
int currentPos = scanner.currentPosition;
// String[] expectings;
// String tokenName = name[symbol_index[currentKind]];
//fetch all "accurate" possible terminals that could recover the error
// int start, end = start = asi(stack[stateStackTop]);
// while (asr[end] != 0)
// end++;
// int length = end - start;
// expectings = new String[length];
// if (length != 0) {
// char[] indexes = new char[length];
// System.arraycopy(asr, start, indexes, 0, length);
// for (int i = 0; i < length; i++) {
// expectings[i] = name[symbol_index[indexes[i]]];
// }
// }
//if the pb is an EOF, try to tell the user that they are some
// if (tokenName.equals(UNEXPECTED_EOF)) {
// if (!this.checkAndReportBracketAnomalies(problemReporter())) {
// char[] tokenSource;
// try {
// tokenSource = this.scanner.getCurrentTokenSource();
// } catch (Exception e) {
// tokenSource = new char[] {};
// }
// problemReporter().parseError(
// this.scanner.startPosition,
// this.scanner.currentPosition - 1,
// tokenSource,
// tokenName,
// expectings);
// }
// } else { //the next test is HEAVILY grammar DEPENDENT.
// if ((length == 14)
// && (expectings[0] == "=") //$NON-NLS-1$
// && (expectings[1] == "*=") //$NON-NLS-1$
// && (expressionPtr > -1)) {
// switch(currentKind) {
// case TokenNameSEMICOLON:
// case TokenNamePLUS:
// case TokenNameMINUS:
// case TokenNameDIVIDE:
// case TokenNameREMAINDER:
// case TokenNameMULTIPLY:
// case TokenNameLEFT_SHIFT:
// case TokenNameRIGHT_SHIFT:
//// case TokenNameUNSIGNED_RIGHT_SHIFT:
// case TokenNameLESS:
// case TokenNameGREATER:
// case TokenNameLESS_EQUAL:
// case TokenNameGREATER_EQUAL:
// case TokenNameEQUAL_EQUAL:
// case TokenNameNOT_EQUAL:
// case TokenNameXOR:
// case TokenNameAND:
// case TokenNameOR:
// case TokenNameOR_OR:
// case TokenNameAND_AND:
// // the ; is not the expected token ==> it ends a statement when an
// expression is not ended
// problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
// break;
// case TokenNameRBRACE :
// problemReporter().missingSemiColon(expressionStack[expressionPtr]);
// break;
// default:
// char[] tokenSource;
// try {
// tokenSource = this.scanner.getCurrentTokenSource();
// } catch (Exception e) {
// tokenSource = new char[] {};
// }
// problemReporter().parseError(
// this.scanner.startPosition,
// this.scanner.currentPosition - 1,
// tokenSource,
// tokenName,
// expectings);
// this.checkAndReportBracketAnomalies(problemReporter());
// }
// } else {
char[] tokenSource;
try {
tokenSource = this.scanner.getCurrentTokenSource();
} catch (Exception e) {
tokenSource = new char[]{};
}
// problemReporter().parseError(
// this.scanner.startPosition,
// this.scanner.currentPosition - 1,
// tokenSource,
// tokenName,
// expectings);
this.checkAndReportBracketAnomalies(problemReporter());
// }
// }
/* reset scanner where it was */
scanner.startPosition = startPos;
scanner.currentPosition = currentPos;
}
public static final int RoundBracket = 0;
public static final int SquareBracket = 1;
public static final int CurlyBracket = 2;
public static final int BracketKinds = 3;
protected int[] nestedMethod; //the ptr is nestedType
protected int nestedType, dimensions;
//ast stack
final static int AstStackIncrement = 100;
protected int astPtr;
protected AstNode[] astStack = new AstNode[AstStackIncrement];
protected int astLengthPtr;
protected int[] astLengthStack;
AstNode[] noAstNodes = new AstNode[AstStackIncrement];
public CompilationUnitDeclaration compilationUnit; /*
* the result from parse()
*/
protected ReferenceContext referenceContext;
protected ProblemReporter problemReporter;
// protected CompilationResult compilationResult;
/**
* Returns this parser's problem reporter initialized with its reference
* context. Also it is assumed that a problem is going to be reported, so
* initializes the compilation result's line positions.
*/
public ProblemReporter problemReporter() {
if (scanner.recordLineSeparator) {
compilationUnit.compilationResult.lineSeparatorPositions = scanner
.getLineEnds();
}
problemReporter.referenceContext = referenceContext;
return problemReporter;
}
/*
* Reconsider the entire source looking for inconsistencies in {} () []
*/
public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
scanner.wasAcr = false;
boolean anomaliesDetected = false;
try {
char[] source = scanner.source;
int[] leftCount = {0, 0, 0};
int[] rightCount = {0, 0, 0};
int[] depths = {0, 0, 0};
int[][] leftPositions = new int[][]{new int[10], new int[10], new int[10]};
int[][] leftDepths = new int[][]{new int[10], new int[10], new int[10]};
int[][] rightPositions = new int[][]{new int[10], new int[10],
new int[10]};
int[][] rightDepths = new int[][]{new int[10], new int[10], new int[10]};
scanner.currentPosition = scanner.initialPosition; //starting
// point
// (first-zero-based
// char)
while (scanner.currentPosition < scanner.eofPosition) { //loop for
// jumping
// over
// comments
try {
// ---------Consume white space and handles
// startPosition---------
boolean isWhiteSpace;
do {
scanner.startPosition = scanner.currentPosition;
// if (((scanner.currentCharacter =
// source[scanner.currentPosition++]) == '\\') &&
// (source[scanner.currentPosition] == 'u')) {
// isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
// } else {
if (scanner.recordLineSeparator
&& ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
// only record line positions we have not
// recorded yet
scanner.pushLineSeparator();
}
}
isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
// }
} while (isWhiteSpace
&& (scanner.currentPosition < scanner.eofPosition));
// -------consume token until } is found---------
switch (scanner.currentCharacter) {
case '{' :
{
int index = leftCount[CurlyBracket]++;
if (index == leftPositions[CurlyBracket].length) {
System.arraycopy(leftPositions[CurlyBracket], 0,
(leftPositions[CurlyBracket] = new int[index * 2]), 0,
index);
System
.arraycopy(leftDepths[CurlyBracket], 0,
(leftDepths[CurlyBracket] = new int[index * 2]), 0,
index);
}
leftPositions[CurlyBracket][index] = scanner.startPosition;
leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
}
break;
case '}' :
{
int index = rightCount[CurlyBracket]++;
if (index == rightPositions[CurlyBracket].length) {
System.arraycopy(rightPositions[CurlyBracket], 0,
(rightPositions[CurlyBracket] = new int[index * 2]), 0,
index);
System.arraycopy(rightDepths[CurlyBracket], 0,
(rightDepths[CurlyBracket] = new int[index * 2]), 0,
index);
}
rightPositions[CurlyBracket][index] = scanner.startPosition;
rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
}
break;
case '(' :
{
int index = leftCount[RoundBracket]++;
if (index == leftPositions[RoundBracket].length) {
System.arraycopy(leftPositions[RoundBracket], 0,
(leftPositions[RoundBracket] = new int[index * 2]), 0,
index);
System
.arraycopy(leftDepths[RoundBracket], 0,
(leftDepths[RoundBracket] = new int[index * 2]), 0,
index);
}
leftPositions[RoundBracket][index] = scanner.startPosition;
leftDepths[RoundBracket][index] = depths[RoundBracket]++;
}
break;
case ')' :
{
int index = rightCount[RoundBracket]++;
if (index == rightPositions[RoundBracket].length) {
System.arraycopy(rightPositions[RoundBracket], 0,
(rightPositions[RoundBracket] = new int[index * 2]), 0,
index);
System.arraycopy(rightDepths[RoundBracket], 0,
(rightDepths[RoundBracket] = new int[index * 2]), 0,
index);
}
rightPositions[RoundBracket][index] = scanner.startPosition;
rightDepths[RoundBracket][index] = --depths[RoundBracket];
}
break;
case '[' :
{
int index = leftCount[SquareBracket]++;
if (index == leftPositions[SquareBracket].length) {
System.arraycopy(leftPositions[SquareBracket], 0,
(leftPositions[SquareBracket] = new int[index * 2]), 0,
index);
System.arraycopy(leftDepths[SquareBracket], 0,
(leftDepths[SquareBracket] = new int[index * 2]), 0,
index);
}
leftPositions[SquareBracket][index] = scanner.startPosition;
leftDepths[SquareBracket][index] = depths[SquareBracket]++;
}
break;
case ']' :
{
int index = rightCount[SquareBracket]++;
if (index == rightPositions[SquareBracket].length) {
System.arraycopy(rightPositions[SquareBracket], 0,
(rightPositions[SquareBracket] = new int[index * 2]), 0,
index);
System.arraycopy(rightDepths[SquareBracket], 0,
(rightDepths[SquareBracket] = new int[index * 2]), 0,
index);
}
rightPositions[SquareBracket][index] = scanner.startPosition;
rightDepths[SquareBracket][index] = --depths[SquareBracket];
}
break;
case '\'' :
{
if (scanner.getNextChar('\\')) {
scanner.scanEscapeCharacter();
} else { // consume next character
scanner.unicodeAsBackSlash = false;
// if (((scanner.currentCharacter =
// source[scanner.currentPosition++]) ==
// '\\') &&
// (source[scanner.currentPosition] ==
// 'u')) {
// scanner.getNextUnicodeChar();
// } else {
if (scanner.withoutUnicodePtr != 0) {
scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
}
// }
}
scanner.getNextChar('\'');
break;
}
case '"' :
// consume next character
scanner.unicodeAsBackSlash = false;
// if (((scanner.currentCharacter =
// source[scanner.currentPosition++]) == '\\') &&
// (source[scanner.currentPosition] == 'u')) {
// scanner.getNextUnicodeChar();
// } else {
if (scanner.withoutUnicodePtr != 0) {
scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
}
// }
while (scanner.currentCharacter != '"') {
if (scanner.currentCharacter == '\r') {
if (source[scanner.currentPosition] == '\n')
scanner.currentPosition++;
break; // the string cannot go further that
// the line
}
if (scanner.currentCharacter == '\n') {
break; // the string cannot go further that
// the line
}
if (scanner.currentCharacter == '\\') {
scanner.scanEscapeCharacter();
}
// consume next character
scanner.unicodeAsBackSlash = false;
// if (((scanner.currentCharacter =
// source[scanner.currentPosition++]) == '\\')
// && (source[scanner.currentPosition] == 'u'))
// {
// scanner.getNextUnicodeChar();
// } else {
if (scanner.withoutUnicodePtr != 0) {
scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
}
// }
}
break;
case '/' :
{
int test;
if ((test = scanner.getNextChar('/', '*')) == 0) { //line
// comment
//get the next char
if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
&& (source[scanner.currentPosition] == 'u')) {
//-------------unicode traitement
// ------------
int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
scanner.currentPosition++;
while (source[scanner.currentPosition] == 'u') {
scanner.currentPosition++;
}
if ((c1 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c1 < 0
|| (c2 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c2 < 0
|| (c3 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c3 < 0
|| (c4 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c4 < 0) { //error don't
// care of the
// value
scanner.currentCharacter = 'A';
} //something different from \n and \r
else {
scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
}
}
while (scanner.currentCharacter != '\r'
&& scanner.currentCharacter != '\n') {
//get the next char
scanner.startPosition = scanner.currentPosition;
if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
&& (source[scanner.currentPosition] == 'u')) {
//-------------unicode traitement
// ------------
int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
scanner.currentPosition++;
while (source[scanner.currentPosition] == 'u') {
scanner.currentPosition++;
}
if ((c1 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c1 < 0
|| (c2 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c2 < 0
|| (c3 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c3 < 0
|| (c4 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c4 < 0) { //error don't
// care of the
// value
scanner.currentCharacter = 'A';
} //something different from \n
// and \r
else {
scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
}
}
}
if (scanner.recordLineSeparator
&& ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
// only record line positions we
// have not recorded yet
scanner.pushLineSeparator();
if (this.scanner.taskTags != null) {
this.scanner.checkTaskTag(this.scanner
.getCurrentTokenStartPosition(), this.scanner
.getCurrentTokenEndPosition());
}
}
}
break;
}
if (test > 0) { //traditional and annotation
// comment
boolean star = false;
// consume next character
scanner.unicodeAsBackSlash = false;
// if (((scanner.currentCharacter =
// source[scanner.currentPosition++]) ==
// '\\') &&
// (source[scanner.currentPosition] ==
// 'u')) {
// scanner.getNextUnicodeChar();
// } else {
if (scanner.withoutUnicodePtr != 0) {
scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
}
// }
if (scanner.currentCharacter == '*') {
star = true;
}
//get the next char
if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
&& (source[scanner.currentPosition] == 'u')) {
//-------------unicode traitement
// ------------
int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
scanner.currentPosition++;
while (source[scanner.currentPosition] == 'u') {
scanner.currentPosition++;
}
if ((c1 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c1 < 0
|| (c2 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c2 < 0
|| (c3 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c3 < 0
|| (c4 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c4 < 0) { //error don't
// care of the
// value
scanner.currentCharacter = 'A';
} //something different from * and /
else {
scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
}
}
//loop until end of comment */
while ((scanner.currentCharacter != '/') || (!star)) {
star = scanner.currentCharacter == '*';
//get next char
if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
&& (source[scanner.currentPosition] == 'u')) {
//-------------unicode traitement
// ------------
int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
scanner.currentPosition++;
while (source[scanner.currentPosition] == 'u') {
scanner.currentPosition++;
}
if ((c1 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c1 < 0
|| (c2 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c2 < 0
|| (c3 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c3 < 0
|| (c4 = Character
.getNumericValue(source[scanner.currentPosition++])) > 15
|| c4 < 0) { //error don't
// care of the
// value
scanner.currentCharacter = 'A';
} //something different from * and
// /
else {
scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
}
}
}
if (this.scanner.taskTags != null) {
this.scanner.checkTaskTag(this.scanner
.getCurrentTokenStartPosition(), this.scanner
.getCurrentTokenEndPosition());
}
break;
}
break;
}
default :
if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
scanner.scanIdentifierOrKeyword(false);
break;
}
if (Character.isDigit(scanner.currentCharacter)) {
scanner.scanNumber(false);
break;
}
}
//-----------------end switch while
// try--------------------
} catch (IndexOutOfBoundsException e) {
break; // read until EOF
} catch (InvalidInputException e) {
return false; // no clue
}
}
if (scanner.recordLineSeparator) {
// compilationUnit.compilationResult.lineSeparatorPositions =
// scanner.getLineEnds();
}
// check placement anomalies against other kinds of brackets
for (int kind = 0; kind < BracketKinds; kind++) {
for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
int start = leftPositions[kind][leftIndex]; // deepest
// first
// find matching closing bracket
int depth = leftDepths[kind][leftIndex];
int end = -1;
for (int i = 0; i < rightCount[kind]; i++) {
int pos = rightPositions[kind][i];
// want matching bracket further in source with same
// depth
if ((pos > start) && (depth == rightDepths[kind][i])) {
end = pos;
break;
}
}
if (end < 0) { // did not find a good closing match
problemReporter.unmatchedBracket(start, referenceContext,
compilationUnit.compilationResult);
return true;
}
// check if even number of opening/closing other brackets
// in between this pair of brackets
int balance = 0;
for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) {
for (int i = 0; i < leftCount[otherKind]; i++) {
int pos = leftPositions[otherKind][i];
if ((pos > start) && (pos < end))
balance++;
}
for (int i = 0; i < rightCount[otherKind]; i++) {
int pos = rightPositions[otherKind][i];
if ((pos > start) && (pos < end))
balance--;
}
if (balance != 0) {
problemReporter.unmatchedBracket(start, referenceContext,
compilationUnit.compilationResult); //bracket
// anomaly
return true;
}
}
}
// too many opening brackets ?
for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
anomaliesDetected = true;
problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind]
- i - 1], referenceContext, compilationUnit.compilationResult);
}
// too many closing brackets ?
for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
anomaliesDetected = true;
problemReporter.unmatchedBracket(rightPositions[kind][i],
referenceContext, compilationUnit.compilationResult);
}
if (anomaliesDetected)
return true;
}
return anomaliesDetected;
} catch (ArrayStoreException e) { // jdk1.2.2 jit bug
return anomaliesDetected;
} catch (NullPointerException e) { // jdk1.2.2 jit bug
return anomaliesDetected;
}
}
protected void pushOnAstLengthStack(int pos) {
try {
astLengthStack[++astLengthPtr] = pos;
} catch (IndexOutOfBoundsException e) {
int oldStackLength = astLengthStack.length;
int[] oldPos = astLengthStack;
astLengthStack = new int[oldStackLength + StackIncrement];
System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
astLengthStack[astLengthPtr] = pos;
}
}
protected void pushOnAstStack(AstNode node) {
/*
* add a new obj on top of the ast stack
*/
try {
astStack[++astPtr] = node;
} catch (IndexOutOfBoundsException e) {
int oldStackLength = astStack.length;
AstNode[] oldStack = astStack;
astStack = new AstNode[oldStackLength + AstStackIncrement];
System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
astPtr = oldStackLength;
astStack[astPtr] = node;
}
try {
astLengthStack[++astLengthPtr] = 1;
} catch (IndexOutOfBoundsException e) {
int oldStackLength = astLengthStack.length;
int[] oldPos = astLengthStack;
astLengthStack = new int[oldStackLength + AstStackIncrement];
System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
astLengthStack[astLengthPtr] = 1;
}
}
}