X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java index 11b48d9..2a0e2c1 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java @@ -1,150 +1,86 @@ /********************************************************************** -Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de -All rights reserved. This program and the accompanying materials -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 -**********************************************************************/ + 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 java.util.Hashtable; - -import net.sourceforge.phpdt.core.compiler.*; -import net.sourceforge.phpeclipse.PHPeclipsePlugin; +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 net.sourceforge.phpeclipse.phpeditor.PHPString; - import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.ui.texteditor.MarkerUtilities; -import test.PHPParserSuperclass; - -public class Parser extends PHPParserSuperclass implements ITerminalSymbols { - +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 IFile fileToParse; 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; - - // final static int TokenNameEOF = 0; - // final static int TokenNameERROR = 1; - // final static int TokenNameHTML = 2; - // - // final static int TokenNameREMAINDER = 30; - // final static int TokenNameNOT = 31; - // final static int TokenNameDOT = 32; - // final static int TokenNameXOR = 33; - // final static int TokenNameDIVIDE = 34; - // final static int TokenNameMULTIPLY = 35; - // final static int TokenNameMINUS = 36; - // final static int TokenNamePLUS = 37; - // final static int TokenNameEQUAL_EQUAL = 38; - // final static int TokenNameNOT_EQUAL = 39; - // final static int TokenNameGREATER = 40; - // final static int TokenNameGREATER_EQUAL = 41; - // final static int TokenNameLESS = 42; - // final static int TokenNameLESS_EQUAL = 43; - // final static int TokenNameAND_AND = 44; - // final static int TokenNameOR_OR = 45; - // // final static int TokenNameHASH = 46; - // final static int TokenNameCOLON = 47; - // final static int TokenNameDOT_EQUAL = 48; - // - // final static int TokenNameEQUAL = 49; - // final static int TokenNameMINUS_GREATER = 50; // -> - // final static int TokenNameFOREACH = 51; - // final static int TokenNameAND = 52; - // //final static int TokenNameDOLLARLISTOPEN = 53; - // final static int TokenNameTWIDDLE = 54; - // final static int TokenNameTWIDDLE_EQUAL = 55; - // final static int TokenNameREMAINDER_EQUAL = 56; - // final static int TokenNameXOR_EQUAL = 57; - // final static int TokenNameRIGHT_SHIFT_EQUAL = 58; - // final static int TokenNameLEFT_SHIFT_EQUAL = 59; - // final static int TokenNameAND_EQUAL = 60; - // final static int TokenNameOR_EQUAL = 61; - // final static int TokenNameQUESTION = 62; - // final static int TokenNameCOLON_COLON = 63; - // final static int TokenNameAT = 63; - // // final static int TokenNameHEREDOC = 64; - // - // final static int TokenNameDOLLAROPEN = 127; - // final static int TokenNameLPAREN = 128; - // final static int TokenNameRPAREN = 129; - // final static int TokenNameLBRACE = 130; - // final static int TokenNameRBRACE = 131; - // final static int TokenNameLBRACKET = 132; - // final static int TokenNameRBRACKET = 133; - // final static int TokenNameCOMMA = 134; - // - // final static int TokenNameStringLiteral = 136; - // final static int TokenNameIdentifier = 138; - // // final static int TokenNameDIGIT = 139; - // final static int TokenNameSEMICOLON = 140; - // // final static int TokenNameSLOT = 141; - // // final static int TokenNameSLOTSEQUENCE = 142; - // final static int TokenNameMINUS_MINUS = 144; - // final static int TokenNamePLUS_PLUS = 145; - // final static int TokenNamePLUS_EQUAL = 146; - // final static int TokenNameDIVIDE_EQUAL = 147; - // final static int TokenNameMINUS_EQUAL = 148; - // final static int TokenNameMULTIPLY_EQUAL = 149; - // final static int TokenNameVariable = 150; - // final static int TokenNameIntegerLiteral = 151; - // final static int TokenNameDoubleLiteral = 152; - // final static int TokenNameStringInterpolated = 153; - // final static int TokenNameStringConstant = 154; - // - // final static int TokenNameLEFT_SHIFT = 155; - // final static int TokenNameRIGHT_SHIFT = 156; - // final static int TokenNameEQUAL_EQUAL_EQUAL = 157; - // final static int TokenNameNOT_EQUAL_EQUAL = 158; - // final static int TokenNameOR = 159; - // final static int TokenNameAT = 153; // @ - - public Parser() { + //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; - this.fileToParse = fileToParse; + // PHPParserSuperclass.fileToParse = fileToParse; this.phpList = null; this.str = ""; this.token = TokenNameEOF; @@ -152,11 +88,12 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { this.initializeScanner(); } /** - * Class Constructor. - * - *@param s - *@param sess Description of Parameter - *@see + * ClassDeclaration Constructor. + * + * @param s + * @param sess + * Description of Parameter + * @see */ public Parser(IFile fileToParse) { // if (keywordMap == null) { @@ -166,7 +103,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // } // } this.currentPHPString = 0; - this.fileToParse = fileToParse; + // PHPParserSuperclass.fileToParse = fileToParse; this.phpList = null; this.str = ""; this.token = TokenNameEOF; @@ -175,67 +112,69 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // 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) - throws CoreException { - setMarker(fileToParse, message, charStart, charEnd, errorLevel); - } - + // 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 + * 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) { - - // if (str.length() < chIndx) { - // chIndx--; - // } - // // read until end-of-line - // int eol = chIndx; - // while (str.length() > eol) { - // ch = str.charAt(eol++); - // if (ch == '\n') { - // eol--; - // break; - // } - // } - // throw new SyntaxError( - // rowCount, - // chIndx - columnCount + 1, - // str.substring(columnCount, eol), - // error); - throw new SyntaxError(1, 1, "", 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 + * 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 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 + * Method Declaration. + * + * @see */ // private void getChar() { // if (str.length() > chIndx) { @@ -246,646 +185,33 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // // chIndx = str.length() + 1; // ch = ' '; - // // token = TokenNameEOF; + // // token = TokenNameEOF; // phpEnd = true; // } - /** * gets the next token from input */ - private void getNextToken() throws CoreException { + 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 + .print(currentStartPosition + "," + currentEndPosition + ": "); System.out.println(scanner.toStringAction(token)); } } catch (InvalidInputException e) { token = TokenNameERROR; } return; - - // boolean phpFound = false; - // char ch2; - // - // phpEnd = false; - // try { - // if (!phpMode) { - // - // while (str.length() > chIndx) { - // token = TokenNameERROR; - // ch = str.charAt(chIndx++); - // - // if (ch == '\n') { - // rowCount++; - // } - // if (ch == '<') { - // ch2 = str.charAt(chIndx++); - // if (ch2 == '?') { - // ch2 = str.charAt(chIndx++); - // if (Character.isWhitespace(ch2)) { - // // php start - // phpMode = true; - // phpFound = true; - // break; - // } else if (ch2 == 'p' || ch2 == 'P') { - // ch2 = str.charAt(chIndx++); - // if (ch2 == 'h' || ch2 == 'H') { - // ch2 = str.charAt(chIndx++); - // if (ch2 == 'p' || ch2 == 'P') { - // phpMode = true; - // phpFound = true; - // break; - // } - // chIndx--; - // } - // chIndx--; - // } - // chIndx--; - // } - // chIndx--; - // } - // } - // - // } - // - // if (phpMode) { - // while (str.length() > chIndx) { - // ch = str.charAt(chIndx++); - // token = TokenNameERROR; - // if (ch == '\n') { - // rowCount++; - // columnCount = chIndx; - // continue; // while loop - // } - // if (str.length() == chIndx) { - // phpEnd = true; - // } - // if (!Character.isWhitespace(ch)) { - // if (ch == '$') { - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '{') { - // chIndx++; - // token = TokenNameDOLLAROPEN; - // return; - // } - // } - // getIdentifier(); - // return; - // } - // if ((ch >= 'a' && ch <= 'z') - // || (ch >= 'A' && ch <= 'Z') - // || (ch == '_') - // || (ch == '$')) { - // getIdentifier(); - // return; - // } - // if (ch >= '0' && ch <= '9') { - // getNumber(); - // return; - // } - // if (ch == '/') { - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '/') { - // ch = '/'; - // chIndx++; - // // read comment until end of line: - // while ((str.length() > chIndx) - // && (ch != '\n')) { - // ch = str.charAt(chIndx++); - // if (ch == '?') { - // ch2 = str.charAt(chIndx); - // if (ch2 == '>') { - // chIndx++; - // token = TokenNameHTML; - // // php end - // phpMode = false; - // phpEnd = true; - // return; - // } - // } - // } - // rowCount++; - // continue; - // - // } else if (str.charAt(chIndx) == '*') { - // chIndx++; - // // multi line comment: - // while (str.length() > chIndx) { - // if (str.charAt(chIndx) == '*' - // && (str.length() > (chIndx + 1)) - // && str.charAt(chIndx + 1) == '/') { - // chIndx += 2; - // break; - // } - // ch = str.charAt(chIndx++); - // if (ch == '\n') { - // rowCount++; - // columnCount = chIndx; - // } - // } - // continue; - // } - // } - // } else if (ch == '#') { - // // read comment until end of line: - // while ((str.length() > chIndx) && (ch != '\n')) { - // ch = str.charAt(chIndx++); - // if (ch == '?') { - // ch2 = str.charAt(chIndx); - // if (ch2 == '>') { - // chIndx++; - // token = TokenNameHTML; - // // php end - // phpMode = false; - // phpEnd = true; - // return; - // } - // } - // } - // rowCount++; - // continue; - // - // } else if (ch == '"') { - // getString( - // '"', - // TokenNameStringInterpolated, - // "Open string character '\"' at end of file."); - // return; - // } else if (ch == '\'') { - // getString( - // '\'', - // TokenNameStringConstant, - // "Open string character \"'\" at end of file."); - // return; - // } else if (ch == '`') { - // getString( - // '`', - // TokenNameStringConstant, - // "Open string character \"`\" at end of file."); - // setMarker( - // "Other string delimiters prefered (found \"`\").", - // rowCount, - // PHPParser.INFO); - // return; - // } - // - // switch (ch) { - // - // case '(' : - // token = TokenNameLPAREN; - // - // break; - // case ')' : - // token = TokenNameRPAREN; - // - // break; - // case '{' : - // token = TokenNameLBRACE; - // - // break; - // case '}' : - // token = TokenNameRBRACE; - // - // break; - // case '[' : - // token = TokenNameLBRACKET; - // - // break; - // case ']' : - // token = TokenNameRBRACKET; - // - // break; - // case ',' : - // token = TokenNameCOMMA; - // - // break; - // case '?' : - // token = TokenNameQUESTION; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '>') { - // chIndx++; - // token = TokenNameHTML; - // // php end - // phpMode = false; - // phpEnd = true; - // break; - // } - // } - // - // break; - // case '@' : - // token = TokenNameAT; - // break; - // case '~' : - // token = TokenNameTWIDDLE; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameTWIDDLE_EQUAL; - // - // break; - // } - // } - // break; - // case '.' : - // token = TokenNameDOT; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameDOT_EQUAL; - // - // break; - // } - // } - // - // break; - // case '"' : - // token = TokenNameStringLiteral; - // - // break; - // case '%' : - // token = TokenNameREMAINDER; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameREMAINDER_EQUAL; - // - // break; - // } - // } - // break; - // case ';' : - // token = TokenNameSEMICOLON; - // - // break; - // case '^' : - // token = TokenNameXOR; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameXOR_EQUAL; - // - // break; - // } - // } - // break; - // case '/' : - // token = TokenNameDIVIDE; - // - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameDIVIDE_EQUAL; - // - // break; - // } - // } - // - // break; - // case '*' : - // token = TokenNameMULTIPLY; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '*') { - // chIndx++; - // token = TokenNameXOR; - // - // break; - // } - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameMULTIPLY_EQUAL; - // - // break; - // } - // } - // - // break; - // case '+' : - // token = TokenNamePLUS; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '+') { - // chIndx++; - // token = TokenNamePLUS_PLUS; - // - // break; - // } - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNamePLUS_EQUAL; - // - // break; - // } - // } - // break; - // case '-' : - // token = TokenNameMINUS; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '-') { - // chIndx++; - // token = TokenNameMINUS_MINUS; - // - // break; - // } - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameMINUS_EQUAL; - // - // break; - // } - // if (str.charAt(chIndx) == '>') { - // chIndx++; - // token = TokenNameMINUS_GREATER; - // - // break; - // } - // } - // - // break; - // case '=' : - // token = TokenNameEQUAL; - // - // if (str.length() > chIndx) { - // ch = str.charAt(chIndx); - // - // if (ch == '=') { - // chIndx++; - // token = TokenNameEQUAL_EQUAL; - // if (str.length() > chIndx) { - // ch = str.charAt(chIndx); - // - // if (ch == '=') { - // chIndx++; - // token = - // TokenNameEQUAL_EQUAL_EQUAL; - // } - // } - // break; - // } - // if (ch == '>') { - // chIndx++; - // token = TokenNameEQUAL_GREATER; - // - // break; - // } - // } - // - // break; - // case '!' : - // token = TokenNameNOT; - // - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameNOT_EQUAL; - // if (str.length() > chIndx) { - // ch = str.charAt(chIndx); - // - // if (ch == '=') { - // chIndx++; - // token = - // TokenNameNOT_EQUAL_EQUAL; - // } - // } - // break; - // } - // } - // - // break; - // case '>' : - // token = TokenNameGREATER; - // - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameGREATER_EQUAL; - // break; - // } - // if (str.charAt(chIndx) == '>') { - // chIndx++; - // token = TokenNameRIGHT_SHIFT; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = - // TokenNameRIGHT_SHIFT_EQUAL; - // break; - // } - // } - // break; - // } - // } - // - // break; - // case '<' : - // token = TokenNameLESS; - // - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameLESS_EQUAL; - // - // break; - // } - // if (str.charAt(chIndx) == '<') { - // chIndx++; - // token = TokenNameLEFT_SHIFT; - // if (str.charAt(chIndx) == '<') { - // // heredoc - // int startRow = rowCount; - // if (str.length() > chIndx) { - // - // ch = str.charAt(++chIndx); - // if ((ch >= 'a' && ch <= 'z') - // || (ch >= 'A' && ch <= 'Z') - // || (ch == '_')) { - // chIndx++; - // getIdentifier(); - // token = - // TokenNameStringConstant; - // while (str.length() - // > chIndx) { - // ch = - // str.charAt( - // chIndx++); - // if (ch == '\n') { - // if (str.length() - // >= chIndx - // + identifier - // .length()) { - // if (str - // .substring( - // chIndx, - // chIndx - // + identifier - // .length()) - // .equals(identifier)) { - // chIndx - // += identifier - // .length(); - // return; - // } - // } - // } - // } - // } - // } - // throwSyntaxError( - // "Open heredoc syntax after operator '<<<'.", - // startRow); - // } else if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameLEFT_SHIFT_EQUAL; - // break; - // } - // break; - // } - // } - // - // break; - // - // case '|' : - // token = TokenNameOR; - // - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '|') { - // chIndx++; - // token = TokenNameOR_OR; - // break; - // } - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameOR_EQUAL; - // break; - // } - // } - // - // break; - // case '&' : - // token = TokenNameAND; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == '&') { - // chIndx++; - // token = TokenNameAND_AND; - // break; - // } - // if (str.charAt(chIndx) == '=') { - // chIndx++; - // token = TokenNameAND_EQUAL; - // break; - // } - // break; - // } - // - // break; - // case ':' : - // token = TokenNameCOLON; - // if (str.length() > chIndx) { - // if (str.charAt(chIndx) == ':') { - // chIndx++; - // token = TokenNameCOLON_COLON; - // } - // } - // break; - // // case '#' : - // // token = TokenNameHASH; - // // - // // break; - // // case '@' : - // // token = TokenNameAT; - // // - // // break; - // default : - // throwSyntaxError( - // "unexpected character: '" + ch + "'"); - // } - // - // if (token == TokenNameERROR) { - // throwSyntaxError("token not found"); - // } - // - // return; - // } - // } - // } - // } catch (StringIndexOutOfBoundsException e) { - // // catched from charAt - // } - // - // chIndx = str.length() + 1; - // ch = ' '; - // token = TokenNameEOF; - // phpEnd = true; - // //PHPString temp; - // // if (phpList != null) { - // // if (currentPHPString < phpList.size()) { - // // token = TokenNameUNDEFINED; - // // temp = (PHPString) phpList.get(currentPHPString++); - // // this.str = temp.getPHPString(); - // // this.token = TokenNameEOF; - // // this.chIndx = 0; - // // this.rowCount = temp.getLineNumber(); - // // this.columnCount = 0; - // // getNextToken(); - // // phpEnd = true; - // // } else { - // // token = TokenNameUNDEFINED; - // // return; - // // } - // // } } - - // /** - // * Get an identifier. - // */ - // private void getIdentifier() { - // // StringBuffer ident = new StringBuffer(); - // int startPosition = chIndx - 1; - // // ident.append(ch); - // if (ch == '$') { - // getChar(); - // // attention recursive call: - // getIdentifier(); - // token = TokenNameVariable; - // return; - // } else { - // token = TokenNameIdentifier; - // } - // - // getChar(); - // - // //this will read the buffer until the next character is a forbidden character for identifier - // while ((ch >= 'a' && ch <= 'z') - // || (ch >= 'A' && ch <= 'Z') - // || (ch >= '0' && ch <= '9') - // || (ch == '_')) { - // // ident.append(ch); - // getChar(); - // } - // int endPosition = chIndx--; - // int length = (--endPosition) - startPosition; - // - // identifier = str.substring(startPosition, endPosition); - // // System.out.println(identifier); - // - // // determine if this identitfer is a keyword - // // @todo improve this in future version - // Integer i = (Integer) keywordMap.get(identifier.toLowerCase()); - // if (i != null) { - // token = i.intValue(); - // } - // } - /** - * 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} + * 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(); @@ -980,7 +306,8 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // /** // * Get a String. // * @param openChar the opening char ('\'', '"', '`') - // * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING} + // * @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( @@ -1018,7 +345,6 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // token = typeString; // stringValue = sBuffer.toString(); // } - // public void htmlParserTester(String input) { // int lineNumber = 1; // int startLineNumber = 1; @@ -1210,119 +536,133 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // input.substring(startIndex, i - 2), // startLineNumber)); // } - // // for (int j=0;j"); - // // } + // // 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 : - 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) { - 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(); - expression(); - 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 (CoreException e) { - } catch (SyntaxError sytaxErr) { - try { - // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR); - setMarker( - sytaxErr.getMessage(), - scanner.getCurrentTokenStartPosition(), - scanner.getCurrentTokenEndPosition(), - ERROR); - } catch (CoreException e) { - } - } + // public PHPOutlineInfo parseInfo(Object parent, String s) { + // PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent); + // // Stack stack = new Stack(); + // // stack.push(outlineInfo.getDeclarations()); + // this.str = s; + // this.token = TokenNameEOF; + // // this.chIndx = 0; + // // this.rowCount = 1; + // // this.columnCount = 0; + // this.phpEnd = false; + // this.phpMode = false; + // scanner.setSource(s.toCharArray()); + // scanner.setPHPMode(false); + // + // getNextToken(); + // parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false); + // + // return outlineInfo; + // } + private boolean isVariable() { + return token == TokenNameVariable; // || token == TokenNamethis; } - - private void statementList() throws CoreException { + // private void parseDeclarations(PHPOutlineInfo outlineInfo, + // OutlineableWithChildren current, boolean goBack) { + // char[] ident; + // // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek(); + // PHPSegmentWithChildren temp; + // int counter = 0; + // IPreferenceStore store = + // PHPeclipsePlugin.getDefault().getPreferenceStore(); + // try { + // while (token != TokenNameEOF && token != TokenNameERROR) { + // if (token == TokenNameVariable) { + // ident = scanner.getCurrentIdentifierSource(); + // outlineInfo.addVariable(new String(ident)); + // getNextToken(); + // } else if (token == TokenNamevar) { + // getNextToken(); + // if (token == TokenNameVariable + // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) { + // ident = scanner.getCurrentIdentifierSource(); + // //substring(1) added because PHPVarDeclaration doesn't + // // need the $ anymore + // String variableName = new String(ident).substring(1); + // outlineInfo.addVariable(variableName); + // getNextToken(); + // if (token != TokenNameSEMICOLON) { + // getNextToken(); + // ident = scanner.getCurrentTokenSource(); + // if (token > 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(); - if ((token == TokenNameRBRACE) - || (token == TokenNamecase) - || (token == TokenNamedefault) - || (token == TokenNameelseif) - || (token == TokenNameendif) - || (token == TokenNameendfor) - || (token == TokenNameendforeach) - || (token == TokenNameendwhile) - || (token == TokenNameendswitch) - || (token == TokenNameEOF) - || (token == TokenNameERROR)) { + 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 compoundStatement() throws CoreException { + private void functionBody(MethodDeclaration methodDecl) { // '{' [statement-list] '}' if (token == TokenNameLBRACE) { getNextToken(); @@ -1612,49 +938,69 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { statementList(); } if (token == TokenNameRBRACE) { + methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); getNextToken(); } else { throwSyntaxError("'}' expected in compound-statement."); } } - - private void statement() throws CoreException { - // if (token > TokenNameKEYWORD && token != TokenNamelist && token != TokenNamenew) { + private void statement(int previousToken) { + // if (token > TokenNameKEYWORD && token != TokenNamelist && token != + // TokenNamenew) { // char[] ident = scanner.getCurrentIdentifierSource(); // String keyword = new String(ident); - if (token == TokenNameinclude || token == TokenNameinclude_once) { - getNextToken(); - expression(); - if (token == TokenNameSEMICOLON) { - getNextToken(); - } else { - if (token != TokenNameStopPHP) { - throwSyntaxError("';' character after 'include' or 'include_once' expected."); - } - getNextToken(); - } - return; - } else if (token == TokenNamerequire || token == TokenNamerequire_once) { - getNextToken(); - //constant(); - expression(); - if (token == TokenNameSEMICOLON) { - getNextToken(); - } else { - if (token != TokenNameStopPHP) { - throwSyntaxError("';' character after 'require' or 'require_once' expected."); - } - getNextToken(); - } - return; - } else if (token == TokenNameif) { + // 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."); } - expression(); + expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { @@ -1662,7 +1008,6 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } ifStatement(); return; - } else if (token == TokenNameswitch) { getNextToken(); if (token == TokenNameLPAREN) { @@ -1670,7 +1015,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } else { throwSyntaxError("'(' expected after 'switch' keyword."); } - expression(); + expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { @@ -1724,7 +1069,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } else { throwSyntaxError("'(' expected after 'while' keyword."); } - expression(); + expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { @@ -1754,7 +1099,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } else { throwSyntaxError("'(' expected after 'while' keyword."); } - expression(); + expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { @@ -1779,7 +1124,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } else { throwSyntaxError("'(' expected after 'foreach' keyword."); } - expression(); + expr(); if (token == TokenNameas) { getNextToken(); } else { @@ -1797,14 +1142,11 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } foreachStatement(); return; - - } else if ( - token == TokenNamecontinue - || token == TokenNamebreak + } else if (token == TokenNamecontinue || token == TokenNamebreak || token == TokenNamereturn) { getNextToken(); if (token != TokenNameSEMICOLON) { - expression(); + expr(); } if (token == TokenNameSEMICOLON) { getNextToken(); @@ -1815,7 +1157,6 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { getNextToken(); } return; - } else if (token == TokenNameecho) { getNextToken(); expressionList(); @@ -1840,103 +1181,127 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // getNextToken(); // } // return; - - } else if (token == TokenNameglobal || token == TokenNamestatic) { + } else if (token == TokenNameglobal) { getNextToken(); - variableList(); + global_var_list(); if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (token != TokenNameStopPHP) { - throwSyntaxError("';' expected after 'global' or 'static' statement."); + throwSyntaxError("';' expected after 'global' statement."); } getNextToken(); } return; - - // } else if (token == TokenNameunset) { - // getNextToken(); - // if (token == TokenNameARGOPEN) { - // getNextToken(); - // } else { - // throwSyntaxError("'(' expected after 'unset' keyword."); - // } - // variableList(); - // if (token == TokenNameARGCLOSE) { - // getNextToken(); - // } else { - // throwSyntaxError("')' expected after 'unset' statement."); - // } - // if (token == TokenNameSEMICOLON) { - // getNextToken(); - // } else { - // if (token != TokenNameStopPHP) { - // throwSyntaxError("';' expected after 'unset' statement."); - // } - // getNextToken(); - // } - // return; - - // } else if (token == TokenNameexit || token == TokenNamedie) { - // getNextToken(); - // if (token != TokenNameSEMICOLON) { - // exitStatus(); - // } - // if (token == TokenNameSEMICOLON) { - // getNextToken(); - // } else { - // if (token != TokenNameStopPHP) { - // throwSyntaxError("';' expected after 'exit' or 'die' statement."); - // } - // getNextToken(); - // } - // return; - - } else if (token == TokenNamedefine) { + } else if (token == TokenNamestatic) { getNextToken(); - if (token == TokenNameLPAREN) { + static_var_list(); + if (token == TokenNameSEMICOLON) { getNextToken(); } else { - throwSyntaxError("'(' expected after 'define' keyword."); - } - expression(); - if (token == TokenNameCOMMA) { + if (token != TokenNameStopPHP) { + throwSyntaxError("';' expected after 'static' statement."); + } getNextToken(); - } else { - throwSyntaxError("',' expected after first 'define' constant."); } - expression(); - if (token == TokenNameCOMMA) { + return; + }else if (token == TokenNameunset) { + getNextToken(); + if (token == TokenNameLPAREN) { getNextToken(); - expression(); + } else { + throwSyntaxError("'(' expected after 'unset' statement."); } + unset_variables(); if (token == TokenNameRPAREN) { getNextToken(); } else { - throwSyntaxError("')' expected after 'define' statement."); + throwSyntaxError("')' expected after 'unset' statement."); } if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (token != TokenNameStopPHP) { - throwSyntaxError("';' expected after 'define' statement."); + throwSyntaxError("';' expected after 'unset' statement."); } getNextToken(); } return; + // } else if (token == TokenNameexit || token == TokenNamedie) { + // getNextToken(); + // if (token != TokenNameSEMICOLON) { + // exitStatus(); + // } + // if (token == TokenNameSEMICOLON) { + // getNextToken(); + // } else { + // if (token != TokenNameStopPHP) { + // throwSyntaxError("';' expected after 'exit' or 'die' + // statement."); + // } + // getNextToken(); + // } + // return; + // } else if (token == TokenNamedefine) { + // getNextToken(); + // if (token == TokenNameLPAREN) { + // getNextToken(); + // } else { + // throwSyntaxError("'(' expected after 'define' keyword."); + // } + // expr(); + // if (token == TokenNameCOMMA) { + // getNextToken(); + // } else { + // throwSyntaxError("',' expected after first 'define' constant."); + // } + // expr(); + // if (token == TokenNameCOMMA) { + // getNextToken(); + // expr(); + // } + // if (token == TokenNameRPAREN) { + // getNextToken(); + // } else { + // throwSyntaxError("')' expected after 'define' statement."); + // } + // if (token == TokenNameSEMICOLON) { + // getNextToken(); + // } else { + // if (token != TokenNameStopPHP) { + // throwSyntaxError("';' expected after 'define' statement."); + // } + // getNextToken(); + // } + // return; } else if (token == TokenNamefunction) { + MethodDeclaration methodDecl = new MethodDeclaration( + this.compilationUnit.compilationResult); + methodDecl.declarationSourceStart = scanner + .getCurrentTokenStartPosition(); getNextToken(); - functionDefinition(); + functionDefinition(methodDecl); return; - } else if (token == TokenNameclass) { - getNextToken(); - classDeclarator(); - classBody(); + } 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) { - // compoundStatement getNextToken(); if (token != TokenNameRBRACE) { statementList(); @@ -1949,53 +1314,175 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } } else { if (token != TokenNameSEMICOLON) { - expression(); + expr(); } if (token == TokenNameSEMICOLON) { getNextToken(); return; } else { if (token != TokenNameStopPHP && token != TokenNameEOF) { - throwSyntaxError( - "';' expected after expression (Found token: " - + scanner.toStringAction(token) - + ")"); + throwSyntaxError("';' expected after expression (Found token: " + + scanner.toStringAction(token) + ")"); } getNextToken(); } } } - - private void classDeclarator() throws CoreException { - //identifier - //identifier 'extends' identifier - if (token == TokenNameIdentifier) { + private void global_var_list() { + // global_var_list: + // global_var_list ',' global_var + //| global_var + while (true) { + global_var(); + if (token != TokenNameCOMMA) { + break; + } getNextToken(); - if (token == TokenNameextends) { + } + } + 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(); - if (token == TokenNameIdentifier) { + } 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(); - } else { - throwSyntaxError("Class name expected after keyword 'extends'."); + static_scalar(); } + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + } else { + break; } - } else { - if (token > TokenNameKEYWORD) { - throwSyntaxError( - "Don't use keyword for class declaration [" + token + "]."); + } + } + private void unset_variables() { + // unset_variables: + // unset_variable + // | unset_variables ',' unset_variable + // unset_variable: + // variable + while (true) { + variable(); + if (token != TokenNameCOMMA) { + break; } - throwSyntaxError("Class name expected after keyword 'class'."); + getNextToken(); } } - - private void classBody() throws CoreException { - //'{' [class-element-list] '}' + 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) { - classElementList(); + class_statement_list(); } if (token == TokenNameRBRACE) { + typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); getNextToken(); } else { throwSyntaxError("'}' expected at end of class body."); @@ -2004,63 +1491,268 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { throwSyntaxError("'{' expected at start of class body."); } } - - private void classElementList() throws CoreException { - do { - classElement(); - } while (token == TokenNamefunction || token == TokenNamevar); + 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 classElement() throws CoreException { - //class-property - //function-definition - if (token == TokenNamefunction) { + private void interface_extends_list() { + // /* empty */ + // | T_EXTENDS interface_list + if (token == TokenNameextends) { getNextToken(); - functionDefinition(); - } else if (token == TokenNamevar) { + interface_list(); + } + } + private void implements_list() { + // /* empty */ + // | T_IMPLEMENTS interface_list + if (token == TokenNameimplements) { getNextToken(); - classProperty(); + 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); + } + 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 { - throwSyntaxError("'function' or 'var' expected."); + 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 classProperty() throws CoreException { - //'var' variable ';' - //'var' variable '=' constant ';' + // 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(); - constant(); + static_scalar(); } } else { - throwSyntaxError("Variable expected after keyword 'var'."); + // 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) { - getNextToken(); - } else { - throwSyntaxError("';' expected after variable declaration."); + if (token != TokenNameSEMICOLON) { + throwSyntaxError("';' expected after field declaration."); } + getNextToken(); } - - private void functionDefinition() throws CoreException { - functionDeclarator(); - compoundStatement(); + private void functionDefinition(MethodDeclaration methodDecl) { + 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; + } + } + } + functionDeclarator(methodDecl); + functionBody(methodDecl); } - - private void functionDeclarator() throws CoreException { + 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(); @@ -2073,18 +1765,19 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { 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("Don't use keyword for function declaration [" + token + + "]."); } throwSyntaxError("Function name expected after keyword 'function'."); } } // - private void parameterList() throws CoreException { + private void parameterList() { //parameter-declaration //parameter-list ',' parameter-declaration do { @@ -2095,13 +1788,12 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { getNextToken(); } while (true); } - - private void parameterDeclaration() throws CoreException { + private void parameterDeclaration() { //variable //variable-reference if (token == TokenNameAND) { getNextToken(); - if (token == TokenNameVariable) { + if (isVariable()) { getNextToken(); } else { throwSyntaxError("Variable expected after reference operator '&'."); @@ -2112,51 +1804,49 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { getNextToken(); if (token == TokenNameEQUAL) { getNextToken(); - constant(); + static_scalar(); } return; } + // if (token == TokenNamethis) { + // throwSyntaxError("Reserved word '$this' not allowed in parameter + // declaration."); + // } } - - private void labeledStatementList() throws CoreException { + private void labeledStatementList() { if (token != TokenNamecase && token != TokenNamedefault) { throwSyntaxError("'case' or 'default' expected."); } do { if (token == TokenNamecase) { getNextToken(); - constant(); - if (token == TokenNameCOLON) { - 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) - // + ")", - // rowCount, - // PHPParser.INFO); - setMarker( - "':' expected after 'case' keyword (Found token: " - + scanner.toStringAction(token) - + ")", - scanner.getCurrentTokenStartPosition(), - scanner.getCurrentTokenEndPosition(), - INFO); + expr(); //constant(); + if (token == TokenNameCOLON || token == TokenNameSEMICOLON) { getNextToken(); - if (token == TokenNamecase) { // empty case statement ? + if (token == TokenNamecase || token == TokenNamedefault) { // empty + // case + // statement + // ? continue; } statementList(); - } else { - throwSyntaxError( - "':' character after 'case' constant expected (Found token: " - + scanner.toStringAction(token) - + ")"); + } + // 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(); @@ -2169,7 +1859,6 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } } while (token == TokenNamecase || token == TokenNamedefault); } - // public void labeledStatement() { // if (token == TokenNamecase) { // getNextToken(); @@ -2192,16 +1881,12 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // return; // } // } - // public void expressionStatement() { // } - // private void inclusionStatement() { // } - // public void compoundStatement() { // } - // public void selectionStatement() { // } // @@ -2222,33 +1907,35 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { // // public void definitionStatement() { // } - - private void ifStatement() throws CoreException { + private void ifStatement() { // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';' if (token == TokenNameCOLON) { getNextToken(); - statementList(); - switch (token) { - case TokenNameelse : - getNextToken(); - if (token == TokenNameCOLON) { + if (token != TokenNameendif) { + statementList(); + switch (token) { + case TokenNameelse : getNextToken(); - statementList(); - } else { - if (token == TokenNameif) { //'else if' + if (token == TokenNameCOLON) { getNextToken(); - elseifStatementList(); + if (token != TokenNameendif) { + statementList(); + } } else { - throwSyntaxError("':' expected after 'else'."); + if (token == TokenNameif) { //'else if' + getNextToken(); + elseifStatementList(); + } else { + throwSyntaxError("':' expected after 'else'."); + } } - } - break; - case TokenNameelseif : - getNextToken(); - elseifStatementList(); - break; + break; + case TokenNameelseif : + getNextToken(); + elseifStatementList(); + break; + } } - if (token != TokenNameendif) { throwSyntaxError("'endif' expected."); } @@ -2259,7 +1946,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { getNextToken(); } else { // statement [else-statement] - statement(); + statement(TokenNameEOF); if (token == TokenNameelseif) { getNextToken(); if (token == TokenNameLPAREN) { @@ -2267,7 +1954,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } else { throwSyntaxError("'(' expected after 'elseif' keyword."); } - expression(); + expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { @@ -2276,12 +1963,11 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { ifStatement(); } else if (token == TokenNameelse) { getNextToken(); - statement(); + statement(TokenNameEOF); } } } - - private void elseifStatementList() throws CoreException { + private void elseifStatementList() { do { elseifStatement(); switch (token) { @@ -2289,7 +1975,9 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { getNextToken(); if (token == TokenNameCOLON) { getNextToken(); - statementList(); + if (token != TokenNameendif) { + statementList(); + } return; } else { if (token == TokenNameif) { //'else if' @@ -2307,12 +1995,11 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } } while (true); } - - private void elseifStatement() throws CoreException { + private void elseifStatement() { if (token == TokenNameLPAREN) { getNextToken(); - expression(); - if (token != TokenNameLPAREN) { + expr(); + if (token != TokenNameRPAREN) { throwSyntaxError("')' expected in else-if-statement."); } getNextToken(); @@ -2320,11 +2007,12 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { throwSyntaxError("':' expected in else-if-statement."); } getNextToken(); - statementList(); + if (token != TokenNameendif) { + statementList(); + } } } - - private void switchStatement() throws CoreException { + private void switchStatement() { if (token == TokenNameCOLON) { // ':' [labeled-statement-list] 'endswitch' ';' getNextToken(); @@ -2350,11 +2038,9 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { throwSyntaxError("'}' expected in switch statement."); } getNextToken(); - } } - - private void forStatement() throws CoreException { + private void forStatement() { if (token == TokenNameCOLON) { getNextToken(); statementList(); @@ -2367,11 +2053,10 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } getNextToken(); } else { - statement(); + statement(TokenNameEOF); } } - - private void whileStatement() throws CoreException { + private void whileStatement() { // ':' statement-list 'endwhile' ';' if (token == TokenNameCOLON) { getNextToken(); @@ -2385,11 +2070,10 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } getNextToken(); } else { - statement(); + statement(TokenNameEOF); } } - - private void foreachStatement() throws CoreException { + private void foreachStatement() { if (token == TokenNameCOLON) { getNextToken(); statementList(); @@ -2402,29 +2086,27 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } getNextToken(); } else { - statement(); + statement(TokenNameEOF); } } - - private void exitStatus() throws CoreException { - 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() throws CoreException { + // 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 { - expression(); + expr(); if (token == TokenNameCOMMA) { getNextToken(); } else { @@ -2432,751 +2114,1768 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols { } } while (true); } - - private void expression() throws CoreException { - //todo: find a better way to get the expression - // expression = new StringBuffer(); - // for (int i = chIndx; i < str.length(); i++) { - // if (str.charAt(i) == ';') { - // break; - // } - // expression.append(str.charAt(i)); - // } - - // if (token == TokenNameSTRING_CONSTANT || token == TokenNameINTERPOLATED_STRING) { - // getNextToken(); - // } else { - logicalinclusiveorExpression(); - // while (token != TokenNameSEMICOLON) { - // getNextToken(); - // // } + 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 postfixExpression() throws CoreException { - // String ident; - char[] ident; - boolean castFlag = false; + 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 TokenNamenew : - getNextToken(); - expression(); + case TokenNameisset : + case TokenNameempty : + case TokenNameeval : + case TokenNameinclude : + case TokenNameinclude_once : + case TokenNamerequire : + case TokenNamerequire_once : + internal_functions_in_yacc(); break; - case TokenNamenull : + // | '(' expr ')' + case TokenNameLPAREN : getNextToken(); + expr(); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected in expression."); + } break; - case TokenNamefalse : - getNextToken(); + // | 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 TokenNametrue : + 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 : - getNextToken(); + case TokenNameStringInterpolated : + case TokenNameFILE : + case TokenNameLINE : + case TokenNameCLASS_C : + case TokenNameMETHOD_C : + case TokenNameFUNC_C : + common_scalar(); break; case TokenNameHEREDOC : - case TokenNameStringInterpolated : - case TokenNameStringLiteral : getNextToken(); break; - case TokenNameLPAREN : + case TokenNamearray : + // T_ARRAY '(' array_pair_list ')' getNextToken(); - if (token == TokenNameIdentifier) { - // check if identifier is a type: - // ident = identifier; - ident = scanner.getCurrentIdentifierSource(); - String str = new String(ident).toLowerCase(); - for (int i = 0; i < PHP_TYPES.length; i++) { - if (PHP_TYPES[i].equals(str)) { - castFlag = true; - break; - } - } - if (castFlag) { - getNextToken(); - if (token != TokenNameRPAREN) { - throwSyntaxError(") expected after cast-type '" + str + "'."); - } + if (token == TokenNameLPAREN) { + getNextToken(); + if (token == TokenNameRPAREN) { getNextToken(); - expression(); break; } - } - if (!castFlag) { - expression(); - } - if (token != TokenNameRPAREN) { - throwSyntaxError(") expected in postfix-expression."); - } - getNextToken(); - break; - case TokenNameDoubleLiteral : - getNextToken(); - break; - case TokenNameIntegerLiteral : - getNextToken(); - break; - case TokenNameDOLLAR_LBRACE : - getNextToken(); - expression(); - if (token != TokenNameRBRACE) { - throwSyntaxError("'}' expected after indirect variable token '${'."); - } - getNextToken(); - break; - case TokenNameVariable : - ident = scanner.getCurrentIdentifierSource(); - getNextToken(); - if (token == TokenNameLBRACE) { - getNextToken(); - expression(); - if (token != TokenNameRBRACE) { - throwSyntaxError( - "'}' expected after variable '" - + new String(ident) - + "' in variable-expression."); - } - getNextToken(); - } else if (token == TokenNameLPAREN) { - getNextToken(); + array_pair_list(); if (token != TokenNameRPAREN) { - expressionList(); - if (token != TokenNameRPAREN) { - throwSyntaxError( - "')' expected after variable '" - + new String(ident) - + "' in postfix-expression."); - } + throwSyntaxError("')' expected after keyword 'array'" + + "(Found token: " + scanner.toStringAction(token) + ")"); } getNextToken(); + } else { + throwSyntaxError("'(' expected after keyword 'array'" + + "(Found token: " + scanner.toStringAction(token) + ")"); } break; - case TokenNameIdentifier : - ident = scanner.getCurrentIdentifierSource(); + case TokenNamelist : + // | T_LIST '(' assignment_list ')' '=' expr getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); + assignment_list(); if (token != TokenNameRPAREN) { - expressionList(); - if (token != TokenNameRPAREN) { - throwSyntaxError( - "')' expected after identifier '" - + new String(ident) - + "' in postfix-expression." - + "(Found token: " - + scanner.toStringAction(token) - + ")"); - } + throwSyntaxError("')' expected after 'list' keyword."); + } + getNextToken(); + if (token != TokenNameEQUAL) { + throwSyntaxError("'=' expected after 'list' keyword."); } getNextToken(); + expr(); + } else { + throwSyntaxError("'(' expected after 'list' keyword."); } break; - case TokenNameprint : + case TokenNamenew : + // | T_NEW class_name_reference ctor_arguments getNextToken(); - expression(); - // if (token == TokenNameSEMICOLON) { - // getNextToken(); - // } else { - // if (token != TokenNameStopPHP) { - // throwSyntaxError("';' expected after 'print' statement."); - // } - // getNextToken(); - // } + class_name_reference(); + ctor_arguments(); break; - case TokenNamelist : + // | T_INC rw_variable + // | T_DEC rw_variable + case TokenNamePLUS_PLUS : + case TokenNameMINUS_MINUS : getNextToken(); - if (token == TokenNameLPAREN) { - getNextToken(); - if (token == TokenNameCOMMA) { + 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(); - } - expressionList(); - if (token != TokenNameRPAREN) { - throwSyntaxError("')' expected after 'list' keyword."); - } - getNextToken(); - // if (token == TokenNameSET) { - // getNextToken(); - // logicalinclusiveorExpression(); - // } - } else { - throwSyntaxError("'(' expected after 'list' keyword."); + 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; - // case TokenNameexit : - // getNextToken(); - // if (token != TokenNameSEMICOLON) { - // exitStatus(); - // } - // if (token == TokenNameSEMICOLON) { - // getNextToken(); - // } else { - // if (token != TokenNameStopPHP) { - // throwSyntaxError("';' expected after 'exit' expression."); - // } - // getNextToken(); - // } - // break; - // case TokenNamedie : - // getNextToken(); - // if (token != TokenNameSEMICOLON) { - // exitStatus(); - // } - // if (token == TokenNameSEMICOLON) { - // getNextToken(); - // } else { - // if (token != TokenNameStopPHP) { - // throwSyntaxError("';' expected after 'die' expression."); - // } - // } - // break; - - // case TokenNamearray : - // getNextToken(); - // if (token == TokenNameARGOPEN) { - // getNextToken(); - // if (token == TokenNameCOMMA) { - // getNextToken(); - // } - // expressionList(); - // if (token != TokenNameARGCLOSE) { - // throwSyntaxError("')' expected after 'list' keyword."); - // } - // getNextToken(); - // if (token == TokenNameSET) { - // getNextToken(); - // logicalinclusiveorExpression(); - // } - // } else { - // throwSyntaxError("'(' expected after 'list' keyword."); - // } - // break; + default : + if (token != TokenNameStopPHP) { + throwSyntaxError("Error in expression (found token '" + + scanner.toStringAction(token) + "')."); + } + return; } - boolean while_flag = true; - do { + 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 TokenNameLBRACKET : - getNextToken(); - expression(); - if (token != TokenNameRBRACKET) { - throwSyntaxError("] expected in postfix-expression."); - } + 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; - case TokenNameCOLON_COLON : // :: - case TokenNameMINUS_GREATER : // -> - getNextToken(); - if (token > TokenNameKEYWORD) { - ident = scanner.getCurrentIdentifierSource(); - // setMarker( - // "Avoid using keyword '" - // + new String(ident) - // + "' as variable name.", - // rowCount, - // PHPParser.INFO); - setMarker( - "Avoid using keyword '" - + new String(ident) - + "' as variable name.", - scanner.getCurrentTokenStartPosition(), - scanner.getCurrentTokenEndPosition(), - INFO); - } - switch (token) { - case TokenNameVariable : - ident = scanner.getCurrentIdentifierSource(); - getNextToken(); - // if (token == TokenNameARGOPEN) { - // getNextToken(); - // expressionList(); - // if (token != TokenNameARGCLOSE) { - // throwSyntaxError(") expected after variable '" + ident + "'."); - // } - // getNextToken(); - // } - break; - case TokenNameIdentifier : - //ident = scanner.getCurrentIdentifierSource(); - getNextToken(); - break; - case TokenNameLBRACE : - getNextToken(); - expression(); - if (token != TokenNameRBRACE) { - throwSyntaxError("} expected in postfix-expression."); - } - getNextToken(); - break; - default : - throwSyntaxError("Syntax error after '->' token."); - } while ( - token == TokenNameLBRACKET - || token == TokenNameLPAREN - || token == TokenNameLBRACE) { - if (token == TokenNameLBRACKET) { - getNextToken(); - expressionList(); - if (token != TokenNameRBRACKET) { - throwSyntaxError("] expected after '->'."); - } - getNextToken(); - } - if (token == TokenNameLPAREN) { - getNextToken(); - expressionList(); - if (token != TokenNameRPAREN) { - throwSyntaxError(") expected after '->'."); - } - getNextToken(); - } - if (token == TokenNameLBRACE) { - getNextToken(); - expression(); - if (token != TokenNameRBRACE) { - throwSyntaxError("} expected after '->'."); - } - getNextToken(); - } - } - break; - case TokenNamePLUS_PLUS : + // | expr T_INSTANCEOF class_name_reference + // | expr '?' expr ':' expr + case TokenNameinstanceof : getNextToken(); + throwSyntaxError("not yet implemented (class_name_reference)"); + // class_name_reference(); break; - case TokenNameMINUS_MINUS : + case TokenNameQUESTION : getNextToken(); + expr(); + if (token == TokenNameCOLON) { + getNextToken(); + expr(); + } break; default : - while_flag = false; + return; } - } - while (while_flag); } - - private void unaryExpression() throws CoreException { - switch (token) { - case TokenNamePLUS_PLUS : - getNextToken(); - unaryExpression(); - break; - case TokenNameMINUS_MINUS : - getNextToken(); - unaryExpression(); - break; - // '@' '&' '*' '+' '-' '~' '!' - case TokenNameAT : - getNextToken(); - castExpression(); - break; - case TokenNameAND : - getNextToken(); - castExpression(); - break; - case TokenNameMULTIPLY : - getNextToken(); - castExpression(); - break; - case TokenNamePLUS : - getNextToken(); - castExpression(); - break; - case TokenNameMINUS : - getNextToken(); - castExpression(); - break; - case TokenNameTWIDDLE : - getNextToken(); - castExpression(); - break; - case TokenNameNOT : - getNextToken(); - castExpression(); - break; - default : - postfixExpression(); + private void class_name_reference() { + // class_name_reference: + // T_STRING + //| dynamic_class_name_reference + if (Scanner.TRACE) { + System.out.println("TRACE: class_name_reference()"); } - } - - private void castExpression() throws CoreException { - // if (token == TokenNameARGOPEN) { - // getNextToken(); - // typeName(); - // if (token != TokenNameARGCLOSE) { - // throwSyntaxError(") expected after cast-expression."); - // } - // getNextToken(); - // } - unaryExpression(); - } - - // private void typeName() throws CoreException { - // //'string' 'unset' 'array' 'object' - // //'bool' 'boolean' - // //'real' 'double' 'float' - // //'int' 'integer' - // String identifier = ""; - // if (token == TokenNameIdentifier) { - // char[] ident = scanner.getCurrentIdentifierSource(); - // identifier = new String(ident); - // String str = identifier.toLowerCase(); - // getNextToken(); - // for (int i = 0; i < PHP_TYPES.length; i++) { - // if (PHP_TYPES[i].equals(str)) { - // return; - // } - // } - // } - // throwSyntaxError( - // "Expected type cast '( )'; Got '" + identifier + "'."); - // } - - private void assignExpression() throws CoreException { - castExpression(); - if (token == TokenNameEQUAL) { // = - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameDOT_EQUAL) { // .= - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameEQUAL_GREATER) { // => - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNamePLUS_EQUAL) { // += - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameMINUS_EQUAL) { // -= - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameMULTIPLY_EQUAL) { // *= - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameDIVIDE_EQUAL) { // *= - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameREMAINDER_EQUAL) { // %= - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameAND_EQUAL) { // &= - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameOR_EQUAL) { // |= - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameXOR_EQUAL) { // ^= - getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameLEFT_SHIFT_EQUAL) { // <<= + if (token == TokenNameIdentifier) { getNextToken(); - logicalinclusiveorExpression(); - } else if (token == TokenNameRIGHT_SHIFT_EQUAL) { // >>= + } 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(); - logicalinclusiveorExpression(); - } else if (token == TokenNameTWIDDLE_EQUAL) { // ~= + 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(); - logicalinclusiveorExpression(); + object_property(); } } - - private void multiplicativeExpression() throws CoreException { - do { - assignExpression(); - if (token != TokenNameMULTIPLY - && token != TokenNameDIVIDE - && token != TokenNameREMAINDER) { + 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(); - } while (true); + } } - - private void concatenationExpression() throws CoreException { - do { - multiplicativeExpression(); - if (token != TokenNameDOT) { - return; + private void assignment_list() { + // assignment_list: + // assignment_list ',' assignment_list_element + //| assignment_list_element + while (true) { + assignment_list_element(); + if (token != TokenNameCOMMA) { + break; } getNextToken(); - } while (true); + } } - - private void additiveExpression() throws CoreException { - do { - concatenationExpression(); - if (token != TokenNamePLUS && token != TokenNameMINUS) { - return; + 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(); - } while (true); + } } - - private void shiftExpression() throws CoreException { - do { - additiveExpression(); - if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) { + 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(); + } } - getNextToken(); - } while (true); - } - - private void relationalExpression() throws CoreException { - do { - shiftExpression(); - if (token != TokenNameLESS - && token != TokenNameGREATER - && token != TokenNameLESS_EQUAL - && token != TokenNameGREATER_EQUAL) { + if (token != TokenNameCOMMA) { return; } getNextToken(); - } while (true); - } - - private void identicalExpression() throws CoreException { - do { - relationalExpression(); - if (token != TokenNameEQUAL_EQUAL_EQUAL - && token != TokenNameNOT_EQUAL_EQUAL) { + 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(); - } while (true); + } + reference_variable(); } - - private void equalityExpression() throws CoreException { - do { - identicalExpression(); - if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) { - return; + 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(); - } while (true); + return; + } + non_empty_function_call_parameter_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected in function call."); + } + getNextToken(); } - - private void ternaryExpression() throws CoreException { - equalityExpression(); - if (token == TokenNameQUESTION) { - getNextToken(); - expression(); - if (token == TokenNameCOLON) { + // 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(); - expression(); + w_variable(); } else { - throwSyntaxError("':' expected in ternary operator '? :'."); +// if (token == TokenNameIdentifier || token == TokenNameVariable +// || token == TokenNameDOLLAR) { +// variable(); +// } else { + expr_without_variable(true); +// } } - } - } - - private void andExpression() throws CoreException { - do { - ternaryExpression(); - if (token != TokenNameAND) { - return; + if (token != TokenNameCOMMA) { + break; } getNextToken(); - } while (true); + } } - - private void exclusiveorExpression() throws CoreException { - do { - andExpression(); - if (token != TokenNameXOR) { - return; - } + private void fully_qualified_class_name() { + if (token == TokenNameIdentifier) { getNextToken(); - } while (true); + } else { + throwSyntaxError("Class name expected."); + } } - - private void inclusiveorExpression() throws CoreException { - do { - exclusiveorExpression(); - if (token != TokenNameOR) { - return; - } - getNextToken(); - } while (true); + 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 booleanandExpression() throws CoreException { - do { - inclusiveorExpression(); - if (token != TokenNameAND_AND) { - return; - } + 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(); - } while (true); + if (token == TokenNameLPAREN) { + functionCall = true; + } + token = tempToken; + scanner.currentPosition = tempPosition; + scanner.phpMode = true; + } + if (functionCall) { + function_call(); + } else { + base_variable(); + } } - - private void booleanorExpression() throws CoreException { - do { - booleanandExpression(); - if (token != TokenNameOR_OR) { - return; + 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(); } - getNextToken(); - } while (true); + reference_variable(); + } } - - private void logicalandExpression() throws CoreException { - do { - booleanorExpression(); - if (token != TokenNameAND) { - return; + // 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; } - getNextToken(); - } while (true); + } } - - private void logicalexclusiveorExpression() throws CoreException { - do { - logicalandExpression(); - if (token != TokenNameXOR) { - return; + 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(); - } while (true); - } - - private void logicalinclusiveorExpression() throws CoreException { - do { - logicalexclusiveorExpression(); - if (token != TokenNameOR) { - return; + expr(); + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected after compound variable token '$'."); } getNextToken(); - } while (true); + } } - - // public void assignmentExpression() { - // if (token == TokenNameVARIABLE) { - // getNextToken(); - // if (token == TokenNameSET) { - // getNextToken(); - // logicalinclusiveorExpression(); - // } - // } else { - // logicalinclusiveorExpression(); - // } + // private void dim_offset() { + // // dim_offset: + // // /* empty */ + // // | expr + // expr(); // } - - private void variableList() throws CoreException { - do { - variable(); - if (token == TokenNameCOMMA) { + 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; } - } while (true); + } } - - private void variable() throws CoreException { - if (token == TokenNameDOLLAR_LBRACE) { + private void variable_name() { + //variable_name: + // T_STRING + //| '{' expr '}' + if (Scanner.TRACE) { + System.out.println("TRACE: variable_name()"); + } + if (token == TokenNameIdentifier) { + getNextToken(); + } else { + if (token != TokenNameLBRACE) { + throwSyntaxError("'{' expected in variable name."); + } getNextToken(); - expression(); - ; + expr(); if (token != TokenNameRBRACE) { - throwSyntaxError("'}' expected after indirect variable token '${'."); + 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 { - if (token == TokenNameVariable) { + 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(); - if (token == TokenNameLBRACKET) { - getNextToken(); - expression(); - if (token != TokenNameRBRACKET) { - throwSyntaxError("']' expected in variable-list."); - } - getNextToken(); - } else if (token == TokenNameEQUAL) { - getNextToken(); - constant(); - } - } else { - throwSyntaxError("$-variable expected in variable-list."); + return; } + non_empty_function_call_parameter_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected in method_or_not."); + } + getNextToken(); } } - - /** - * It will look for a value (after a '=' for example) - * @throws CoreException - */ - private void constant() throws CoreException { - // String ident; + 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 TokenNamePLUS : + case TokenNameisset : + // T_ISSET '(' isset_variables ')' getNextToken(); - switch (token) { - case TokenNameDoubleLiteral : - getNextToken(); - break; - case TokenNameIntegerLiteral : - getNextToken(); - break; - default : - throwSyntaxError("Constant expected after '+' presign."); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected after keyword 'isset'"); } + getNextToken(); + isset_variables(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after keyword 'isset'"); + } + getNextToken(); break; - case TokenNameMINUS : + case TokenNameempty : + // T_EMPTY '(' variable ')' getNextToken(); - switch (token) { - case TokenNameDoubleLiteral : - getNextToken(); - break; - case TokenNameIntegerLiteral : - getNextToken(); - break; - default : - throwSyntaxError("Constant expected after '-' presign."); + 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 TokenNamenull : + case TokenNameinclude_once : + // T_INCLUDE_ONCE expr getNextToken(); + expr(); break; - case TokenNamefalse : + 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 TokenNametrue : + 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 : - // ident = identifier; - char[] ident = scanner.getCurrentIdentifierSource(); getNextToken(); - if (token == TokenNameLPAREN) { + // static_class_constant: + // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING + if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) { getNextToken(); - if (token != TokenNameRPAREN) { - expressionList(); - if (token != TokenNameRPAREN) { - throwSyntaxError( - "')' expected after identifier '" - + new String(ident) - + "' in postfix-expression."); - } + if (token == TokenNameIdentifier) { + getNextToken(); + } else { + throwSyntaxError("Identifier expected after '::' operator."); } - getNextToken(); } break; - case TokenNameStringLiteral : + case TokenNamePLUS : getNextToken(); + static_scalar(); break; - case TokenNameStringConstant : + case TokenNameMINUS : getNextToken(); + static_scalar(); break; - case TokenNameStringInterpolated : + case TokenNamearray : getNextToken(); - break; - case TokenNameDoubleLiteral : + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected after keyword 'array'"); + } getNextToken(); - break; - case TokenNameIntegerLiteral : + 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("Constant expected."); + 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; } } - } \ No newline at end of file