/********************************************************************** 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 **********************************************************************/ package net.sourceforge.phpdt.internal.compiler.parser; import java.util.ArrayList; import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; import net.sourceforge.phpdt.core.compiler.InvalidInputException; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.phpeditor.PHPString; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.preference.IPreferenceStore; import test.PHPParserSuperclass; public class Parser extends PHPParserSuperclass implements ITerminalSymbols { //scanner token public Scanner scanner; private ArrayList phpList; private int currentPHPString; private boolean phpEnd; // private static HashMap keywordMap = null; private String str; // current character // char ch; // current token int token; // row counter for syntax errors: //int rowCount; // column counter for syntax errors: //int columnCount; //int chIndx; // // // current identifier // String identifier; Long longNumber; Double doubleNumber; private String stringValue; /** Contains the current expression. */ // private StringBuffer expression; private boolean phpMode; // 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() { } public void setFileToParse(IFile fileToParse) { this.currentPHPString = 0; this.fileToParse = fileToParse; this.phpList = null; this.str = ""; this.token = TokenNameEOF; this.phpEnd = false; this.initializeScanner(); } /** * ClassDeclaration Constructor. * *@param s *@param sess Description of Parameter *@see */ public Parser(IFile fileToParse) { // if (keywordMap == null) { // keywordMap = new HashMap(); // for (int i = 0; i < PHP_KEYWORS.length; i++) { // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i])); // } // } this.currentPHPString = 0; this.fileToParse = fileToParse; this.phpList = null; this.str = ""; this.token = TokenNameEOF; // this.chIndx = 0; // this.rowCount = 1; // this.columnCount = 0; this.phpEnd = false; // getNextToken(); this.initializeScanner(); } public void initializeScanner() { this.scanner = new Scanner(false, false, false, false); } /** * Create marker for the parse error */ private void setMarker(String message, int charStart, int charEnd, int errorLevel) throws CoreException { setMarker(fileToParse, message, charStart, charEnd, errorLevel); } /** * This method will throw the SyntaxError. * It will add the good lines and columns to the Error * @param error the error message * @throws SyntaxError the error raised */ private void throwSyntaxError(String error) { // 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); } /** * 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); } /** * Method Declaration. * *@see */ // private void getChar() { // if (str.length() > chIndx) { // ch = str.charAt(chIndx++); // // return; // } // // chIndx = str.length() + 1; // ch = ' '; // // token = TokenNameEOF; // phpEnd = true; // } /** * gets the next token from input */ private void getNextToken() throws CoreException { try { token = scanner.getNextToken(); if (Scanner.DEBUG) { int currentEndPosition = scanner.getCurrentTokenEndPosition(); int currentStartPosition = scanner.getCurrentTokenStartPosition(); System.out.print(currentStartPosition + "," + currentEndPosition + ": "); System.out.println(scanner.toStringAction(token)); } } catch (InvalidInputException e) { token = TokenNameERROR; } return; } /** * Get a number. * if it's a double the number will be stored in doubleNumber and the token will have the * value {@link Parser#TokenNameDOUBLE_NUMBER}
* if it's a double the number will be stored in longNumber and the token will have the * value {@link Parser#TokenNameINT_NUMBER} */ // private void getNumber() { // StringBuffer inum = new StringBuffer(); // char dFlag = ' '; // int numFormat = 10; // // // save first digit // char firstCh = ch; // inum.append(ch); // // getChar(); // // determine number conversions: // if (firstCh == '0') { // switch (ch) { // case 'b' : // numFormat = 2; // getChar(); // break; // case 'B' : // numFormat = 2; // getChar(); // break; // case 'o' : // numFormat = 8; // getChar(); // break; // case 'O' : // numFormat = 8; // getChar(); // break; // case 'x' : // numFormat = 16; // getChar(); // break; // case 'X' : // numFormat = 16; // getChar(); // break; // } // } // // if (numFormat == 16) { // while ((ch >= '0' && ch <= '9') // || (ch >= 'a' && ch <= 'f') // || (ch >= 'A' && ch <= 'F')) { // inum.append(ch); // getChar(); // } // } else { // while ((ch >= '0' && ch <= '9') // || (ch == '.') // || (ch == 'E') // || (ch == 'e')) { // if ((ch == '.') || (ch == 'E') || (ch == 'e')) { // if (ch == '.' && dFlag != ' ') { // break; // } // if ((dFlag == 'E') || (dFlag == 'e')) { // break; // } // dFlag = ch; // inum.append(ch); // getChar(); // if ((ch == '-') || (ch == '+')) { // inum.append(ch); // getChar(); // } // } else { // inum.append(ch); // getChar(); // } // } // } // chIndx--; // // try { // if (dFlag != ' ') { // doubleNumber = new Double(inum.toString()); // token = TokenNameDoubleLiteral; // return; // } else { // longNumber = Long.valueOf(inum.toString(), numFormat); // token = TokenNameIntegerLiteral; // return; // } // // } catch (Throwable e) { // throwSyntaxError("Number format error: " + inum.toString()); // } // } // // /** // * Get a String. // * @param openChar the opening char ('\'', '"', '`') // * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING} // * @param errorMsg the error message in case of parse error in the string // */ // private void getString( // final char openChar, // final int typeString, // final String errorMsg) { // StringBuffer sBuffer = new StringBuffer(); // boolean openString = true; // int startRow = rowCount; // while (str.length() > chIndx) { // ch = str.charAt(chIndx++); // if (ch == '\\') { // sBuffer.append(ch); // if (str.length() > chIndx) { // ch = str.charAt(chIndx++); // sBuffer.append(ch); // } // } else if (ch == openChar) { // openString = false; // break; // } else if (ch == '\n') { // rowCount++; // columnCount = chIndx; // } else { // sBuffer.append(ch); // } // } // if (openString) { // if (typeString == TokenNameStringConstant) { // throwSyntaxError(errorMsg, startRow); // } else { // throwSyntaxError(errorMsg); // } // } // token = typeString; // stringValue = sBuffer.toString(); // } // public void htmlParserTester(String input) { // int lineNumber = 1; // int startLineNumber = 1; // int startIndex = 0; // char ch; // char ch2; // boolean phpMode = false; // boolean phpFound = false; // // phpList = new ArrayList(); // currentPHPString = 0; // // try { // int i = 0; // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '\n') { // lineNumber++; // } // if ((!phpMode) && ch == '<') { // ch2 = input.charAt(i++); // if (ch2 == '?') { // ch2 = input.charAt(i++); // if (Character.isWhitespace(ch2)) { // // php start // phpMode = true; // phpFound = true; // startIndex = i; // startLineNumber = lineNumber; // continue; // } else if (ch2 == 'p') { // ch2 = input.charAt(i++); // if (ch2 == 'h') { // ch2 = input.charAt(i++); // if (ch2 == 'p') { // phpMode = true; // phpFound = true; // startIndex = i; // startLineNumber = lineNumber; // continue; // } // i--; // } // i--; // } else if (ch2 == 'P') { // ch2 = input.charAt(i++); // if (ch2 == 'H') { // ch2 = input.charAt(i++); // if (ch2 == 'P') { // phpMode = true; // phpFound = true; // startIndex = i; // startLineNumber = lineNumber; // continue; // } // i--; // } // i--; // } // i--; // } // i--; // } // // if (phpMode) { // if (ch == '/' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '/') { // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '?' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '>') { // // php end // phpMode = false; // phpList.add( // new PHPString( // input.substring( // startIndex, // i - 2), // startLineNumber)); // continue; // } // i--; // } else if (ch == '\n') { // lineNumber++; // break; // } // } // continue; // } else if (ch2 == '*') { // // multi-line comment // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '\n') { // lineNumber++; // } else if (ch == '*' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '/') { // break; // } // i--; // } // } // continue; // } else { // i--; // } // } else if (ch == '#') { // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '?' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '>') { // // php end // phpMode = false; // phpList.add( // new PHPString( // input.substring(startIndex, i - 2), // startLineNumber)); // continue; // } // i--; // } else if (ch == '\n') { // lineNumber++; // break; // } // } // continue; // } else if (ch == '"') { // ch = ' '; // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '\n') { // lineNumber++; // } else if ( // ch == '\\' && i < input.length()) { // escape // i++; // } else if (ch == '"') { // break; // } // } // continue; // } else if (ch == '\'') { // ch = ' '; // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '\n') { // lineNumber++; // } else if ( // ch == '\\' && i < input.length()) { // escape // i++; // } else if (ch == '\'') { // break; // } // } // continue; // } // // if (ch == '?' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '>') { // // php end // phpMode = false; // phpList.add( // new PHPString( // input.substring(startIndex, i - 2), // startLineNumber)); // continue; // } // i--; // } // } // } // // if (!phpFound) { // setMarker( // "No PHP source code found.", // lineNumber, // PHPParser.INFO); // } else { // if (phpMode) { // setMarker( // "Open PHP tag at end of file.", // lineNumber, // PHPParser.INFO); // phpList.add( // new PHPString( // input.substring(startIndex, i - 2), // startLineNumber)); // } // // for (int j=0;j"); // // } // phpParserTester(null, 1); // // PHPString temp; // // for(int j=0;j TokenNameKEYWORD) { current.add(new PHPVarDeclaration(current, variableName, // chIndx - ident.length, scanner.getCurrentTokenStartPosition(), new String(ident))); } else { switch (token) { case TokenNameVariable : case TokenNamethis : current.add(new PHPVarDeclaration(current, variableName, // chIndx - ident.length, scanner.getCurrentTokenStartPosition(), new String(ident))); break; case TokenNameIdentifier : current.add(new PHPVarDeclaration(current, variableName, // chIndx - ident.length, scanner.getCurrentTokenStartPosition(), new String(ident))); break; case TokenNameDoubleLiteral : current.add(new PHPVarDeclaration(current, variableName + doubleNumber, // chIndx - ident.length, scanner.getCurrentTokenStartPosition(), new String(ident))); break; case TokenNameIntegerLiteral : current.add(new PHPVarDeclaration(current, variableName, // chIndx - ident.length, scanner.getCurrentTokenStartPosition(), new String(ident))); break; case TokenNameStringInterpolated : case TokenNameStringLiteral : current.add(new PHPVarDeclaration(current, variableName, // chIndx - ident.length, scanner.getCurrentTokenStartPosition(), new String(ident))); break; case TokenNameStringConstant : current.add(new PHPVarDeclaration(current, variableName, // chIndx - ident.length, scanner.getCurrentTokenStartPosition(), new String(ident))); break; default : current.add(new PHPVarDeclaration(current, variableName, // chIndx - ident.length scanner.getCurrentTokenStartPosition())); break; } } } else { ident = scanner.getCurrentIdentifierSource(); current.add(new PHPVarDeclaration(current, variableName, // chIndx - ident.length scanner.getCurrentTokenStartPosition())); } } } else if (token == TokenNamefunction) { getNextToken(); if (token == TokenNameAND) { getNextToken(); } if (token == TokenNameIdentifier && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) { ident = scanner.getCurrentIdentifierSource(); outlineInfo.addVariable(new String(ident)); temp = new PHPFunctionDeclaration(current, new String(ident), // chIndx - ident.length scanner.getCurrentTokenStartPosition()); current.add(temp); getNextToken(); parseDeclarations(outlineInfo, temp, true); } } else if (token == TokenNameclass) { getNextToken(); if (token == TokenNameIdentifier && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) { ident = scanner.getCurrentIdentifierSource(); outlineInfo.addVariable(new String(ident)); temp = new PHPClassDeclaration(current, new String(ident), // chIndx - ident.len scanner.getCurrentTokenStartPosition()); current.add(temp); // stack.push(temp); getNextToken(); //skip tokens for classname, extends and others until we have the opening '{' while (token != TokenNameLBRACE && token != TokenNameEOF && token != TokenNameERROR) { getNextToken(); } parseDeclarations(outlineInfo, temp, true); // stack.pop(); } } else if ((token == TokenNameLBRACE) || (token == TokenNameDOLLAR_LBRACE)) { getNextToken(); counter++; } else if (token == TokenNameRBRACE) { getNextToken(); --counter; if (counter == 0 && goBack) { return; } } else if ( token == TokenNamerequire || token == TokenNamerequire_once || token == TokenNameinclude || token == TokenNameinclude_once) { ident = scanner.getCurrentTokenSource(); getNextToken(); int startPosition = scanner.getCurrentTokenStartPosition(); 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) { } } } private void statementList() throws CoreException { do { statement(); 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 { // '{' [statement-list] '}' if (token == TokenNameLBRACE) { getNextToken(); } else { throwSyntaxError("'{' expected in compound-statement."); } if (token != TokenNameRBRACE) { statementList(); } if (token == TokenNameRBRACE) { getNextToken(); } else { throwSyntaxError("'}' expected in compound-statement."); } } private void statement() throws CoreException { // 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) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'if' keyword."); } expression(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'if' condition."); } ifStatement(); return; } else if (token == TokenNameswitch) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'switch' keyword."); } expression(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'switch' condition."); } switchStatement(); return; } else if (token == TokenNamefor) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'for' keyword."); } if (token == TokenNameSEMICOLON) { getNextToken(); } else { expressionList(); if (token == TokenNameSEMICOLON) { getNextToken(); } else { throwSyntaxError("';' expected after 'for'."); } } if (token == TokenNameSEMICOLON) { getNextToken(); } else { expressionList(); if (token == TokenNameSEMICOLON) { getNextToken(); } else { throwSyntaxError("';' expected after 'for'."); } } if (token == TokenNameRPAREN) { getNextToken(); } else { expressionList(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'for'."); } } forStatement(); return; } else if (token == TokenNamewhile) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'while' keyword."); } expression(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'while' condition."); } whileStatement(); return; } else if (token == TokenNamedo) { getNextToken(); if (token == TokenNameLBRACE) { getNextToken(); } else { throwSyntaxError("'{' expected after 'do' keyword."); } if (token != TokenNameRBRACE) { statementList(); } if (token == TokenNameRBRACE) { getNextToken(); } else { throwSyntaxError("'}' expected after 'do' keyword."); } if (token == TokenNamewhile) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'while' keyword."); } expression(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'while' condition."); } } else { throwSyntaxError("'while' expected after 'do' keyword."); } if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (token != TokenNameStopPHP) { throwSyntaxError("';' expected after do-while statement."); } getNextToken(); } return; } else if (token == TokenNameforeach) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'foreach' keyword."); } expression(); if (token == TokenNameas) { getNextToken(); } else { throwSyntaxError("'as' expected after 'foreach' exxpression."); } variable(); if (token == TokenNameEQUAL_GREATER) { getNextToken(); variable(); } if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'foreach' expression."); } foreachStatement(); return; } else if (token == TokenNamecontinue || token == TokenNamebreak || token == TokenNamereturn) { getNextToken(); if (token != TokenNameSEMICOLON) { expression(); } if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (token != TokenNameStopPHP) { throwSyntaxError("';' expected after 'continue', 'break' or 'return'."); } getNextToken(); } return; } else if (token == TokenNameecho) { getNextToken(); expressionList(); if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (token != TokenNameStopPHP) { throwSyntaxError("';' expected after 'echo' statement."); } getNextToken(); } return; // } else if (token == TokenNameprint) { // getNextToken(); // expression(); // if (token == TokenNameSEMICOLON) { // getNextToken(); // } else { // if (token != TokenNameStopPHP) { // throwSyntaxError("';' expected after 'print' statement."); // } // getNextToken(); // } // return; } else if (token == TokenNameglobal || token == TokenNamestatic) { getNextToken(); variableList(); if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (token != TokenNameStopPHP) { throwSyntaxError("';' expected after 'global' or 'static' 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) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'define' keyword."); } expression(); if (token == TokenNameCOMMA) { getNextToken(); } else { throwSyntaxError("',' expected after first 'define' constant."); } expression(); if (token == TokenNameCOMMA) { getNextToken(); expression(); } 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) { getNextToken(); functionDefinition(); return; } else if (token == TokenNameclass) { getNextToken(); classDeclarator(); classBody(); return; // } else { // throwSyntaxError("Unexpected keyword '" + keyword + "'"); } else if (token == TokenNameLBRACE) { // compoundStatement getNextToken(); if (token != TokenNameRBRACE) { statementList(); } if (token == TokenNameRBRACE) { getNextToken(); return; } else { throwSyntaxError("'}' expected."); } } else { if (token != TokenNameSEMICOLON) { expression(); } if (token == TokenNameSEMICOLON) { getNextToken(); return; } else { if (token != TokenNameStopPHP && token != TokenNameEOF) { throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")"); } getNextToken(); } } } private void classDeclarator() throws CoreException { //identifier //identifier 'extends' identifier if (token == TokenNameIdentifier) { getNextToken(); if (token == TokenNameextends) { getNextToken(); if (token == TokenNameIdentifier) { getNextToken(); } else { throwSyntaxError("ClassDeclaration name expected after keyword 'extends'."); } } } else { if (token > TokenNameKEYWORD) { throwSyntaxError("Don't use keyword for class declaration [" + token + "]."); } throwSyntaxError("ClassDeclaration name expected after keyword 'class'."); } } private void classBody() throws CoreException { //'{' [class-element-list] '}' if (token == TokenNameLBRACE) { getNextToken(); if (token != TokenNameRBRACE) { classElementList(); } if (token == TokenNameRBRACE) { getNextToken(); } else { throwSyntaxError("'}' expected at end of class body."); } } else { throwSyntaxError("'{' expected at start of class body."); } } private void classElementList() throws CoreException { do { classElement(); } while (token == TokenNamefunction || token == TokenNamevar); } private void classElement() throws CoreException { //class-property //function-definition if (token == TokenNamefunction) { getNextToken(); functionDefinition(); } else if (token == TokenNamevar) { getNextToken(); classProperty(); } else { throwSyntaxError("'function' or 'var' expected."); } } private void classProperty() throws CoreException { //'var' variable ';' //'var' variable '=' constant ';' do { if (token == TokenNameVariable) { getNextToken(); if (token == TokenNameEQUAL) { getNextToken(); constant(); } } else { if (token == TokenNamethis) { throwSyntaxError("Reserved word '$this' not allowed after keyword 'var'."); } throwSyntaxError("Variable expected after keyword 'var'."); } if (token != TokenNameCOMMA) { break; } getNextToken(); } while (true); if (token == TokenNameSEMICOLON) { getNextToken(); } else { throwSyntaxError("';' expected after variable declaration."); } } private void functionDefinition() throws CoreException { functionDeclarator(); compoundStatement(); } private void functionDeclarator() throws CoreException { //identifier '(' [parameter-list] ')' if (token == TokenNameAND) { getNextToken(); } if (token == TokenNameIdentifier) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected in function declaration."); } if (token != TokenNameRPAREN) { parameterList(); } if (token != TokenNameRPAREN) { throwSyntaxError("')' expected in function declaration."); } else { getNextToken(); } } else { if (token > TokenNameKEYWORD) { throwSyntaxError("Don't use keyword for function declaration [" + token + "]."); } throwSyntaxError("Function name expected after keyword 'function'."); } } // private void parameterList() throws CoreException { //parameter-declaration //parameter-list ',' parameter-declaration do { parameterDeclaration(); if (token != TokenNameCOMMA) { break; } getNextToken(); } while (true); } private void parameterDeclaration() throws CoreException { //variable //variable-reference if (token == TokenNameAND) { getNextToken(); if (isVariable()) { getNextToken(); } else { throwSyntaxError("Variable expected after reference operator '&'."); } } //variable '=' constant if (token == TokenNameVariable) { getNextToken(); if (token == TokenNameEQUAL) { getNextToken(); constant(); } return; } if (token == TokenNamethis) { throwSyntaxError("Reserved word '$this' not allowed in parameter declaration."); } } private void labeledStatementList() throws CoreException { if (token != TokenNamecase && token != TokenNamedefault) { throwSyntaxError("'case' or 'default' expected."); } do { if (token == TokenNamecase) { getNextToken(); expression(); //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); getNextToken(); if (token == TokenNamecase) { // empty case statement ? continue; } statementList(); } else { throwSyntaxError("':' character after 'case' constant expected (Found token: " + scanner.toStringAction(token) + ")"); } } else { // TokenNamedefault getNextToken(); if (token == TokenNameCOLON) { getNextToken(); statementList(); } else { throwSyntaxError("':' character after 'default' expected."); } } } while (token == TokenNamecase || token == TokenNamedefault); } // public void labeledStatement() { // if (token == TokenNamecase) { // getNextToken(); // constant(); // if (token == TokenNameDDOT) { // getNextToken(); // statement(); // } else { // throwSyntaxError("':' character after 'case' constant expected."); // } // return; // } else if (token == TokenNamedefault) { // getNextToken(); // if (token == TokenNameDDOT) { // getNextToken(); // statement(); // } else { // throwSyntaxError("':' character after 'default' expected."); // } // return; // } // } // public void expressionStatement() { // } // private void inclusionStatement() { // } // public void compoundStatement() { // } // public void selectionStatement() { // } // // public void iterationStatement() { // } // // public void jumpStatement() { // } // // public void outputStatement() { // } // // public void scopeStatement() { // } // // public void flowStatement() { // } // // public void definitionStatement() { // } private void ifStatement() throws CoreException { // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';' if (token == TokenNameCOLON) { getNextToken(); if (token != TokenNameendif) { statementList(); switch (token) { case TokenNameelse : getNextToken(); if (token == TokenNameCOLON) { getNextToken(); if (token != TokenNameendif) { statementList(); } } else { if (token == TokenNameif) { //'else if' getNextToken(); elseifStatementList(); } else { throwSyntaxError("':' expected after 'else'."); } } break; case TokenNameelseif : getNextToken(); elseifStatementList(); break; } } if (token != TokenNameendif) { throwSyntaxError("'endif' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after if-statement."); } getNextToken(); } else { // statement [else-statement] statement(); if (token == TokenNameelseif) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'elseif' keyword."); } expression(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'elseif' condition."); } ifStatement(); } else if (token == TokenNameelse) { getNextToken(); statement(); } } } private void elseifStatementList() throws CoreException { do { elseifStatement(); switch (token) { case TokenNameelse : getNextToken(); if (token == TokenNameCOLON) { getNextToken(); if (token != TokenNameendif) { statementList(); } return; } else { if (token == TokenNameif) { //'else if' getNextToken(); } else { throwSyntaxError("':' expected after 'else'."); } } break; case TokenNameelseif : getNextToken(); break; default : return; } } while (true); } private void elseifStatement() throws CoreException { if (token == TokenNameLPAREN) { getNextToken(); expression(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected in else-if-statement."); } getNextToken(); if (token != TokenNameCOLON) { throwSyntaxError("':' expected in else-if-statement."); } getNextToken(); if (token != TokenNameendif) { statementList(); } } } private void switchStatement() throws CoreException { if (token == TokenNameCOLON) { // ':' [labeled-statement-list] 'endswitch' ';' getNextToken(); labeledStatementList(); if (token != TokenNameendswitch) { throwSyntaxError("'endswitch' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after switch-statement."); } getNextToken(); } else { // '{' [labeled-statement-list] '}' if (token != TokenNameLBRACE) { throwSyntaxError("'{' expected in switch statement."); } getNextToken(); if (token != TokenNameRBRACE) { labeledStatementList(); } if (token != TokenNameRBRACE) { throwSyntaxError("'}' expected in switch statement."); } getNextToken(); } } private void forStatement() throws CoreException { if (token == TokenNameCOLON) { getNextToken(); statementList(); if (token != TokenNameendfor) { throwSyntaxError("'endfor' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after for-statement."); } getNextToken(); } else { statement(); } } private void whileStatement() throws CoreException { // ':' statement-list 'endwhile' ';' if (token == TokenNameCOLON) { getNextToken(); statementList(); if (token != TokenNameendwhile) { throwSyntaxError("'endwhile' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after while-statement."); } getNextToken(); } else { statement(); } } private void foreachStatement() throws CoreException { if (token == TokenNameCOLON) { getNextToken(); statementList(); if (token != TokenNameendforeach) { throwSyntaxError("'endforeach' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after foreach-statement."); } getNextToken(); } else { statement(); } } 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 { do { expression(); if (token == TokenNameCOMMA) { getNextToken(); } else { break; } } 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 postfixExpression() throws CoreException { // String ident; char[] ident; boolean castFlag = false; switch (token) { case TokenNamenew : getNextToken(); expression(); break; case TokenNamenull : getNextToken(); break; case TokenNamefalse : getNextToken(); break; case TokenNametrue : getNextToken(); break; case TokenNameStringConstant : getNextToken(); break; case TokenNameHEREDOC : case TokenNameStringInterpolated : case TokenNameStringLiteral : getNextToken(); break; case TokenNameLPAREN : 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 + "'."); } 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 : case TokenNamethis : 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(); if (token != TokenNameRPAREN) { expressionList(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected after variable '" + new String(ident) + "' in postfix-expression."); } } getNextToken(); } break; case TokenNameIdentifier : ident = scanner.getCurrentIdentifierSource(); getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); if (token != TokenNameRPAREN) { expressionList(); if (token != TokenNameRPAREN) { throwSyntaxError( "')' expected after identifier '" + new String(ident) + "' in postfix-expression." + "(Found token: " + scanner.toStringAction(token) + ")"); } } getNextToken(); } break; case TokenNameprint : getNextToken(); expression(); // if (token == TokenNameSEMICOLON) { // getNextToken(); // } else { // if (token != TokenNameStopPHP) { // throwSyntaxError("';' expected after 'print' statement."); // } // getNextToken(); // } break; case TokenNamelist : getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); if (token == TokenNameCOMMA) { getNextToken(); } expressionList(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected after 'list' keyword."); } getNextToken(); // if (token == TokenNameSET) { // getNextToken(); // logicalinclusiveorExpression(); // } } else { throwSyntaxError("'(' expected after 'list' keyword."); } 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; } boolean while_flag = true; do { switch (token) { case TokenNameLBRACKET : getNextToken(); expression(); if (token != TokenNameRBRACKET) { throwSyntaxError("] expected in postfix-expression."); } getNextToken(); 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(); } else if (token == TokenNameLPAREN) { getNextToken(); expressionList(); if (token != TokenNameRPAREN) { throwSyntaxError(") expected after '->'."); } getNextToken(); } else if (token == TokenNameLBRACE) { getNextToken(); expression(); if (token != TokenNameRBRACE) { throwSyntaxError("} expected after '->'."); } getNextToken(); } } break; case TokenNamePLUS_PLUS : getNextToken(); break; case TokenNameMINUS_MINUS : getNextToken(); break; default : while_flag = false; } } 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(); if (token == TokenNameinclude || token == TokenNameinclude_once || token == TokenNamerequire || token == TokenNamerequire_once) { statement(); } else { postfixExpression(); // 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 castExpression() throws CoreException { // if (token == TokenNameARGOPEN) { // getNextToken(); // typeName(); // if (token != TokenNameARGCLOSE) { // throwSyntaxError(") expected after cast-expression."); // } // getNextToken(); // } unaryExpression(); } 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) { // <<= getNextToken(); logicalinclusiveorExpression(); } else if (token == TokenNameRIGHT_SHIFT_EQUAL) { // >>= getNextToken(); logicalinclusiveorExpression(); } else if (token == TokenNameTWIDDLE_EQUAL) { // ~= getNextToken(); logicalinclusiveorExpression(); } } private void multiplicativeExpression() throws CoreException { do { assignExpression(); if (token != TokenNameMULTIPLY && token != TokenNameDIVIDE && token != TokenNameREMAINDER) { return; } getNextToken(); } while (true); } private void concatenationExpression() throws CoreException { do { multiplicativeExpression(); if (token != TokenNameDOT) { return; } getNextToken(); } while (true); } private void additiveExpression() throws CoreException { do { concatenationExpression(); if (token != TokenNamePLUS && token != TokenNameMINUS) { return; } getNextToken(); } while (true); } private void shiftExpression() throws CoreException { do { additiveExpression(); if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) { return; } getNextToken(); } while (true); } private void relationalExpression() throws CoreException { do { shiftExpression(); if (token != TokenNameLESS && token != TokenNameGREATER && token != TokenNameLESS_EQUAL && token != TokenNameGREATER_EQUAL) { return; } getNextToken(); } while (true); } private void identicalExpression() throws CoreException { do { relationalExpression(); if (token != TokenNameEQUAL_EQUAL_EQUAL && token != TokenNameNOT_EQUAL_EQUAL) { return; } getNextToken(); } while (true); } private void equalityExpression() throws CoreException { do { identicalExpression(); if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) { return; } getNextToken(); } while (true); } private void ternaryExpression() throws CoreException { equalityExpression(); if (token == TokenNameQUESTION) { getNextToken(); expression(); if (token == TokenNameCOLON) { getNextToken(); expression(); } else { throwSyntaxError("':' expected in ternary operator '? :'."); } } } private void andExpression() throws CoreException { do { ternaryExpression(); if (token != TokenNameAND) { return; } getNextToken(); } while (true); } private void exclusiveorExpression() throws CoreException { do { andExpression(); if (token != TokenNameXOR) { return; } getNextToken(); } while (true); } private void inclusiveorExpression() throws CoreException { do { exclusiveorExpression(); if (token != TokenNameOR) { return; } getNextToken(); } while (true); } private void booleanandExpression() throws CoreException { do { inclusiveorExpression(); if (token != TokenNameAND_AND) { return; } getNextToken(); } while (true); } private void booleanorExpression() throws CoreException { do { booleanandExpression(); if (token != TokenNameOR_OR) { return; } getNextToken(); } while (true); } private void logicalandExpression() throws CoreException { do { booleanorExpression(); if (token != TokenNameAND) { return; } getNextToken(); } while (true); } private void logicalexclusiveorExpression() throws CoreException { do { logicalandExpression(); if (token != TokenNameXOR) { return; } getNextToken(); } while (true); } private void logicalinclusiveorExpression() throws CoreException { do { logicalexclusiveorExpression(); if (token != TokenNameOR) { return; } getNextToken(); } while (true); } // public void assignmentExpression() { // if (token == TokenNameVARIABLE) { // getNextToken(); // if (token == TokenNameSET) { // getNextToken(); // logicalinclusiveorExpression(); // } // } else { // logicalinclusiveorExpression(); // } // } private void variableList() throws CoreException { do { variable(); if (token == TokenNameCOMMA) { getNextToken(); } else { break; } } while (true); } private void variable() throws CoreException { if (token == TokenNameDOLLAR_LBRACE) { getNextToken(); expression(); ; if (token != TokenNameRBRACE) { throwSyntaxError("'}' expected after indirect variable token '${'."); } getNextToken(); } else { if (token == TokenNameVariable) { 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."); } } } /** * It will look for a value (after a '=' for example) * @throws CoreException */ private void constant() throws CoreException { // String ident; switch (token) { case TokenNamePLUS : getNextToken(); switch (token) { case TokenNameDoubleLiteral : getNextToken(); break; case TokenNameIntegerLiteral : getNextToken(); break; default : throwSyntaxError("Constant expected after '+' presign."); } break; case TokenNameMINUS : getNextToken(); switch (token) { case TokenNameDoubleLiteral : getNextToken(); break; case TokenNameIntegerLiteral : getNextToken(); break; default : throwSyntaxError("Constant expected after '-' presign."); } break; case TokenNamenull : getNextToken(); break; case TokenNamefalse : getNextToken(); break; case TokenNametrue : getNextToken(); break; case TokenNameIdentifier : // ident = identifier; char[] ident = scanner.getCurrentIdentifierSource(); getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); if (token != TokenNameRPAREN) { expressionList(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected after identifier '" + new String(ident) + "' in postfix-expression."); } } getNextToken(); } break; case TokenNameStringLiteral : getNextToken(); break; case TokenNameStringConstant : getNextToken(); break; case TokenNameStringInterpolated : getNextToken(); break; case TokenNameDoubleLiteral : getNextToken(); break; case TokenNameIntegerLiteral : getNextToken(); break; default : throwSyntaxError("Constant expected."); } } }