/********************************************************************** 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.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; public class Parser //extends PHPParserSuperclass implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation { //internal data for the automat protected final static int StackIncrement = 255; protected int stateStackTop; protected int[] stack = new int[StackIncrement]; public int firstToken; // handle for multiple parsing goals public int lastAct; //handle for multiple parsing goals protected RecoveredElement currentElement; public static boolean VERBOSE_RECOVERY = false; protected boolean diet = false; //tells the scanner to jump over some // parts of the code/expressions like // method bodies //scanner token public Scanner scanner; private ArrayList phpList; private int currentPHPString; private boolean phpEnd; // private static HashMap keywordMap = null; private String str; // current character // char ch; // current token int token; // row counter for syntax errors: //int rowCount; // column counter for syntax errors: //int columnCount; //int chIndx; // // // current identifier // String identifier; Long longNumber; Double doubleNumber; private String stringValue; /** Contains the current expression. */ // private StringBuffer expression; private boolean phpMode; protected int modifiers; protected int modifiersSourceStart; protected Parser() { this.currentPHPString = 0; // PHPParserSuperclass.fileToParse = fileToParse; this.phpList = null; this.str = ""; this.token = TokenNameEOF; // this.chIndx = 0; // this.rowCount = 1; // this.columnCount = 0; this.phpEnd = false; // getNextToken(); this.initializeScanner(); } public void setFileToParse(IFile fileToParse) { this.currentPHPString = 0; // PHPParserSuperclass.fileToParse = fileToParse; this.phpList = null; this.str = ""; this.token = TokenNameEOF; this.phpEnd = false; this.initializeScanner(); } /** * ClassDeclaration Constructor. * * @param s * @param sess * Description of Parameter * @see */ public Parser(IFile fileToParse) { // if (keywordMap == null) { // keywordMap = new HashMap(); // for (int i = 0; i < PHP_KEYWORS.length; i++) { // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i])); // } // } this.currentPHPString = 0; // PHPParserSuperclass.fileToParse = fileToParse; this.phpList = null; this.str = ""; this.token = TokenNameEOF; // this.chIndx = 0; // this.rowCount = 1; // this.columnCount = 0; this.phpEnd = false; // getNextToken(); this.initializeScanner(); } public void initializeScanner() { this.scanner = new Scanner(false, false, false, false); } /** * Create marker for the parse error */ // private void setMarker(String message, int charStart, int charEnd, int // errorLevel) { // setMarker(fileToParse, message, charStart, charEnd, errorLevel); // } /** * This method will throw the SyntaxError. It will add the good lines and * columns to the Error * * @param error * the error message * @throws SyntaxError * the error raised */ private void throwSyntaxError(String error) { int problemStartPosition = scanner.getCurrentTokenStartPosition(); int problemEndPosition = scanner.getCurrentTokenEndPosition(); throwSyntaxError(error, problemStartPosition, problemEndPosition); } /** * This method will throw the SyntaxError. It will add the good lines and * columns to the Error * * @param error * the error message * @throws SyntaxError * the error raised */ // private void throwSyntaxError(String error, int startRow) { // throw new SyntaxError(startRow, 0, " ", error); // } private void throwSyntaxError(String error, int problemStartPosition, int problemEndPosition) { problemReporter .phpParsingError(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext, compilationUnit.compilationResult); throw new SyntaxError(1, 0, " ", error); } private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) { problemReporter .phpParsingError(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext, compilationUnit.compilationResult); } /** * Method Declaration. * * @see */ // private void getChar() { // if (str.length() > chIndx) { // ch = str.charAt(chIndx++); // // return; // } // // chIndx = str.length() + 1; // ch = ' '; // // token = TokenNameEOF; // phpEnd = true; // } /** * gets the next token from input */ private void getNextToken() { try { token = scanner.getNextToken(); if (Scanner.DEBUG) { int currentEndPosition = scanner.getCurrentTokenEndPosition(); int currentStartPosition = scanner.getCurrentTokenStartPosition(); System.out .print(currentStartPosition + "," + currentEndPosition + ": "); System.out.println(scanner.toStringAction(token)); } } catch (InvalidInputException e) { token = TokenNameERROR; } return; } /** * Get a number. if it's a double the number will be stored in * doubleNumber and the token will have the value * {@link Parser#TokenNameDOUBLE_NUMBER}
* if it's a double the number will be stored in longNumber * and the token will have the value {@link Parser#TokenNameINT_NUMBER} */ // private void getNumber() { // StringBuffer inum = new StringBuffer(); // char dFlag = ' '; // int numFormat = 10; // // // save first digit // char firstCh = ch; // inum.append(ch); // // getChar(); // // determine number conversions: // if (firstCh == '0') { // switch (ch) { // case 'b' : // numFormat = 2; // getChar(); // break; // case 'B' : // numFormat = 2; // getChar(); // break; // case 'o' : // numFormat = 8; // getChar(); // break; // case 'O' : // numFormat = 8; // getChar(); // break; // case 'x' : // numFormat = 16; // getChar(); // break; // case 'X' : // numFormat = 16; // getChar(); // break; // } // } // // if (numFormat == 16) { // while ((ch >= '0' && ch <= '9') // || (ch >= 'a' && ch <= 'f') // || (ch >= 'A' && ch <= 'F')) { // inum.append(ch); // getChar(); // } // } else { // while ((ch >= '0' && ch <= '9') // || (ch == '.') // || (ch == 'E') // || (ch == 'e')) { // if ((ch == '.') || (ch == 'E') || (ch == 'e')) { // if (ch == '.' && dFlag != ' ') { // break; // } // if ((dFlag == 'E') || (dFlag == 'e')) { // break; // } // dFlag = ch; // inum.append(ch); // getChar(); // if ((ch == '-') || (ch == '+')) { // inum.append(ch); // getChar(); // } // } else { // inum.append(ch); // getChar(); // } // } // } // chIndx--; // // try { // if (dFlag != ' ') { // doubleNumber = new Double(inum.toString()); // token = TokenNameDoubleLiteral; // return; // } else { // longNumber = Long.valueOf(inum.toString(), numFormat); // token = TokenNameIntegerLiteral; // return; // } // // } catch (Throwable e) { // throwSyntaxError("Number format error: " + inum.toString()); // } // } // // /** // * Get a String. // * @param openChar the opening char ('\'', '"', '`') // * @param typeString the type of string {@link // #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING} // * @param errorMsg the error message in case of parse error in the string // */ // private void getString( // final char openChar, // final int typeString, // final String errorMsg) { // StringBuffer sBuffer = new StringBuffer(); // boolean openString = true; // int startRow = rowCount; // while (str.length() > chIndx) { // ch = str.charAt(chIndx++); // if (ch == '\\') { // sBuffer.append(ch); // if (str.length() > chIndx) { // ch = str.charAt(chIndx++); // sBuffer.append(ch); // } // } else if (ch == openChar) { // openString = false; // break; // } else if (ch == '\n') { // rowCount++; // columnCount = chIndx; // } else { // sBuffer.append(ch); // } // } // if (openString) { // if (typeString == TokenNameStringConstant) { // throwSyntaxError(errorMsg, startRow); // } else { // throwSyntaxError(errorMsg); // } // } // token = typeString; // stringValue = sBuffer.toString(); // } // public void htmlParserTester(String input) { // int lineNumber = 1; // int startLineNumber = 1; // int startIndex = 0; // char ch; // char ch2; // boolean phpMode = false; // boolean phpFound = false; // // phpList = new ArrayList(); // currentPHPString = 0; // // try { // int i = 0; // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '\n') { // lineNumber++; // } // if ((!phpMode) && ch == '<') { // ch2 = input.charAt(i++); // if (ch2 == '?') { // ch2 = input.charAt(i++); // if (Character.isWhitespace(ch2)) { // // php start // phpMode = true; // phpFound = true; // startIndex = i; // startLineNumber = lineNumber; // continue; // } else if (ch2 == 'p') { // ch2 = input.charAt(i++); // if (ch2 == 'h') { // ch2 = input.charAt(i++); // if (ch2 == 'p') { // phpMode = true; // phpFound = true; // startIndex = i; // startLineNumber = lineNumber; // continue; // } // i--; // } // i--; // } else if (ch2 == 'P') { // ch2 = input.charAt(i++); // if (ch2 == 'H') { // ch2 = input.charAt(i++); // if (ch2 == 'P') { // phpMode = true; // phpFound = true; // startIndex = i; // startLineNumber = lineNumber; // continue; // } // i--; // } // i--; // } // i--; // } // i--; // } // // if (phpMode) { // if (ch == '/' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '/') { // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '?' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '>') { // // php end // phpMode = false; // phpList.add( // new PHPString( // input.substring( // startIndex, // i - 2), // startLineNumber)); // continue; // } // i--; // } else if (ch == '\n') { // lineNumber++; // break; // } // } // continue; // } else if (ch2 == '*') { // // multi-line comment // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '\n') { // lineNumber++; // } else if (ch == '*' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '/') { // break; // } // i--; // } // } // continue; // } else { // i--; // } // } else if (ch == '#') { // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '?' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '>') { // // php end // phpMode = false; // phpList.add( // new PHPString( // input.substring(startIndex, i - 2), // startLineNumber)); // continue; // } // i--; // } else if (ch == '\n') { // lineNumber++; // break; // } // } // continue; // } else if (ch == '"') { // ch = ' '; // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '\n') { // lineNumber++; // } else if ( // ch == '\\' && i < input.length()) { // escape // i++; // } else if (ch == '"') { // break; // } // } // continue; // } else if (ch == '\'') { // ch = ' '; // while (i < input.length()) { // ch = input.charAt(i++); // if (ch == '\n') { // lineNumber++; // } else if ( // ch == '\\' && i < input.length()) { // escape // i++; // } else if (ch == '\'') { // break; // } // } // continue; // } // // if (ch == '?' && i < input.length()) { // ch2 = input.charAt(i++); // if (ch2 == '>') { // // php end // phpMode = false; // phpList.add( // new PHPString( // input.substring(startIndex, i - 2), // startLineNumber)); // continue; // } // i--; // } // } // } // // if (!phpFound) { // setMarker( // "No PHP source code found.", // lineNumber, // PHPParser.INFO); // } else { // if (phpMode) { // setMarker( // "Open PHP tag at end of file.", // lineNumber, // PHPParser.INFO); // phpList.add( // new PHPString( // input.substring(startIndex, i - 2), // startLineNumber)); // } // // for (int j=0;j"); // // } // phpParserTester(null, 1); // // PHPString temp; // // for(int j=0;j TokenNameKEYWORD) { // current.add(new PHPVarDeclaration(current, variableName, // // chIndx - ident.length, // scanner.getCurrentTokenStartPosition(), new String(ident))); // } else { // switch (token) { // case TokenNameVariable : // case TokenNamethis : // current.add(new PHPVarDeclaration(current, variableName, // // chIndx - // // ident.length, // scanner.getCurrentTokenStartPosition(), new String( // ident))); // break; // case TokenNameIdentifier : // current.add(new PHPVarDeclaration(current, variableName, // // chIndx - // // ident.length, // scanner.getCurrentTokenStartPosition(), new String( // ident))); // break; // case TokenNameDoubleLiteral : // current.add(new PHPVarDeclaration(current, variableName // + doubleNumber, // // chIndx - // // ident.length, // scanner.getCurrentTokenStartPosition(), new String( // ident))); // break; // case TokenNameIntegerLiteral : // current.add(new PHPVarDeclaration(current, variableName, // // chIndx - // // ident.length, // scanner.getCurrentTokenStartPosition(), new String( // ident))); // break; // case TokenNameStringInterpolated : // case TokenNameStringLiteral : // current.add(new PHPVarDeclaration(current, variableName, // // chIndx - // // ident.length, // scanner.getCurrentTokenStartPosition(), new String( // ident))); // break; // case TokenNameStringConstant : // current.add(new PHPVarDeclaration(current, variableName, // // chIndx - // // ident.length, // scanner.getCurrentTokenStartPosition(), new String( // ident))); // break; // default : // current.add(new PHPVarDeclaration(current, variableName, // // chIndx - // // ident.length // scanner.getCurrentTokenStartPosition())); // break; // } // } // } else { // ident = scanner.getCurrentIdentifierSource(); // current.add(new PHPVarDeclaration(current, variableName, // // chIndx - ident.length // scanner.getCurrentTokenStartPosition())); // } // } // } else if (token == TokenNamefunction) { // getNextToken(); // if (token == TokenNameAND) { // getNextToken(); // } // if (token == TokenNameIdentifier // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) { // ident = scanner.getCurrentIdentifierSource(); // outlineInfo.addVariable(new String(ident)); // temp = new PHPFunctionDeclaration(current, new String(ident), // // chIndx - ident.length // scanner.getCurrentTokenStartPosition()); // current.add(temp); // getNextToken(); // parseDeclarations(outlineInfo, temp, true); // } // } else if (token == TokenNameclass) { // getNextToken(); // if (token == TokenNameIdentifier // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) { // ident = scanner.getCurrentIdentifierSource(); // outlineInfo.addVariable(new String(ident)); // temp = new PHPClassDeclaration(current, new String(ident), // // chIndx - ident.len // scanner.getCurrentTokenStartPosition()); // current.add(temp); // // stack.push(temp); // getNextToken(); // //skip tokens for classname, extends and others until // // we have the opening '{' // while (token != TokenNameLBRACE && token != TokenNameEOF // && token != TokenNameERROR) { // getNextToken(); // } // parseDeclarations(outlineInfo, temp, true); // // stack.pop(); // } // } else if ((token == TokenNameLBRACE) // || (token == TokenNameDOLLAR_LBRACE)) { // getNextToken(); // counter++; // } else if (token == TokenNameRBRACE) { // getNextToken(); // --counter; // if (counter == 0 && goBack) { // return; // } // } else if (token == TokenNamerequire || token == TokenNamerequire_once // || token == TokenNameinclude || token == TokenNameinclude_once) { // ident = scanner.getCurrentTokenSource(); // getNextToken(); // int startPosition = scanner.getCurrentTokenStartPosition(); // expr(); // char[] expr = scanner.getCurrentTokenSource(startPosition); // outlineInfo.addVariable(new String(ident)); // current.add(new PHPReqIncDeclaration(current, new String(ident), // // chIndx - ident.length, // startPosition, new String(expr))); // getNextToken(); // } else { // getNextToken(); // } // } // } catch (SyntaxError sytaxErr) { // // try { // // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR); // // setMarker(sytaxErr.getMessage(), // // scanner.getCurrentTokenStartPosition(), // // scanner.getCurrentTokenEndPosition(), ERROR); // // } catch (CoreException e) { // // } // } // } private void statementList() { do { statement(TokenNameEOF); if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse) || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor) || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch) || (token == TokenNameEOF) || (token == TokenNameERROR)) { return; } } while (true); } private void functionBody(MethodDeclaration methodDecl) { // '{' [statement-list] '}' if (token == TokenNameLBRACE) { getNextToken(); } else { throwSyntaxError("'{' expected in compound-statement."); } if (token != TokenNameRBRACE) { statementList(); } if (token == TokenNameRBRACE) { methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); getNextToken(); } else { throwSyntaxError("'}' expected in compound-statement."); } } private void statement(int previousToken) { // if (token > TokenNameKEYWORD && token != TokenNamelist && token != // TokenNamenew) { // char[] ident = scanner.getCurrentIdentifierSource(); // String keyword = new String(ident); if (token == TokenNameAT) { getNextToken(); if (token != TokenNamerequire && token != TokenNamerequire_once && token != TokenNameinclude && token != TokenNameinclude_once && token != TokenNameIdentifier && token != TokenNameVariable && token != TokenNamethis && token != TokenNameStringInterpolated) { throwSyntaxError("identifier expected after '@'."); } } if (token == TokenNameinclude || token == TokenNameinclude_once) { getNextToken(); if (token == TokenNameLPAREN) { expr(); if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (previousToken != TokenNameAT && token != TokenNameStopPHP) { throwSyntaxError("';' expected after 'include' or 'include_once'."); } // getNextToken(); } } else { concatenationExpression(); } return; } else if (token == TokenNamerequire || token == TokenNamerequire_once) { getNextToken(); //constant(); if (token == TokenNameLPAREN) { expr(); if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (previousToken != TokenNameAT && token != TokenNameStopPHP) { throwSyntaxError("';' expected after 'require' or 'require_once'."); } // getNextToken(); } } else { concatenationExpression(); } return; } else if (token == TokenNameif) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'if' keyword."); } expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'if' condition."); } ifStatement(); return; } else if (token == TokenNameswitch) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'switch' keyword."); } expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'switch' condition."); } switchStatement(); return; } else if (token == TokenNamefor) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'for' keyword."); } if (token == TokenNameSEMICOLON) { getNextToken(); } else { expressionList(); if (token == TokenNameSEMICOLON) { getNextToken(); } else { throwSyntaxError("';' expected after 'for'."); } } if (token == TokenNameSEMICOLON) { getNextToken(); } else { expressionList(); if (token == TokenNameSEMICOLON) { getNextToken(); } else { throwSyntaxError("';' expected after 'for'."); } } if (token == TokenNameRPAREN) { getNextToken(); } else { expressionList(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'for'."); } } forStatement(); return; } else if (token == TokenNamewhile) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'while' keyword."); } expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'while' condition."); } whileStatement(); return; } else if (token == TokenNamedo) { getNextToken(); if (token == TokenNameLBRACE) { getNextToken(); } else { throwSyntaxError("'{' expected after 'do' keyword."); } if (token != TokenNameRBRACE) { statementList(); } if (token == TokenNameRBRACE) { getNextToken(); } else { throwSyntaxError("'}' expected after 'do' keyword."); } if (token == TokenNamewhile) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'while' keyword."); } expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'while' condition."); } } else { throwSyntaxError("'while' expected after 'do' keyword."); } if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (token != TokenNameStopPHP) { throwSyntaxError("';' expected after do-while statement."); } getNextToken(); } return; } else if (token == TokenNameforeach) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'foreach' keyword."); } expr(); if (token == TokenNameas) { getNextToken(); } else { throwSyntaxError("'as' expected after 'foreach' exxpression."); } variable(); if (token == TokenNameEQUAL_GREATER) { getNextToken(); variable(); } if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'foreach' expression."); } foreachStatement(); return; } else if (token == TokenNamecontinue || token == TokenNamebreak || token == TokenNamereturn) { getNextToken(); if (token != TokenNameSEMICOLON) { expr(); } if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (token != 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 == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'unset' statement."); } unset_variables(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'unset' statement."); } if (token == TokenNameSEMICOLON) { getNextToken(); } else { if (token != 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."); // } // 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(methodDecl); return; } else if (token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) { TypeDeclaration typeDecl = new TypeDeclaration( this.compilationUnit.compilationResult); typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); // default super class typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0); compilationUnit.types.add(typeDecl); try { pushOnAstStack(typeDecl); unticked_class_declaration_statement(typeDecl); // classBody(typeDecl); } finally { astPtr--; astLengthPtr--; } return; // } else { // throwSyntaxError("Unexpected keyword '" + keyword + "'"); } else if (token == TokenNameLBRACE) { getNextToken(); if (token != TokenNameRBRACE) { statementList(); } if (token == TokenNameRBRACE) { getNextToken(); return; } else { throwSyntaxError("'}' expected."); } } else { if (token != TokenNameSEMICOLON) { expr(); } if (token == TokenNameSEMICOLON) { getNextToken(); return; } else { if (token != TokenNameStopPHP && token != TokenNameEOF) { throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")"); } getNextToken(); } } } private void unset_variables() { // unset_variables: // unset_variable // | unset_variables ',' unset_variable // unset_variable: // variable while (true) { variable(); if (token != TokenNameCOMMA) { break; } getNextToken(); } } private final void initializeModifiers() { this.modifiers = 0; this.modifiersSourceStart = -1; } private final void checkAndSetModifiers(int flag) { this.modifiers |= flag; if (this.modifiersSourceStart < 0) this.modifiersSourceStart = this.scanner.startPosition; } private void unticked_class_declaration_statement(TypeDeclaration typeDecl) { initializeModifiers(); if (token == TokenNameinterface) { // interface_entry T_STRING // interface_extends_list // '{' class_statement_list '}' checkAndSetModifiers(AccInterface); getNextToken(); typeDecl.modifiers = this.modifiers; if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { typeDecl.sourceStart = scanner.getCurrentTokenStartPosition(); typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); typeDecl.name = scanner.getCurrentIdentifierSource(); if (token > TokenNameKEYWORD) { throwSyntaxError("Don't use a keyword for interface declaration [" + scanner.toStringAction(token) + "].", typeDecl.sourceStart, typeDecl.sourceEnd); } getNextToken(); interface_extends_list(); } else { typeDecl.sourceStart = scanner.getCurrentTokenStartPosition(); typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); typeDecl.name = new char[]{' '}; throwSyntaxError("Interface name expected after keyword 'interface'.", typeDecl.sourceStart, typeDecl.sourceEnd); return; } } else { // class_entry_type T_STRING extends_from // implements_list // '{' class_statement_list'}' class_entry_type(); typeDecl.modifiers = this.modifiers; //identifier //identifier 'extends' identifier if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { typeDecl.sourceStart = scanner.getCurrentTokenStartPosition(); typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); typeDecl.name = scanner.getCurrentIdentifierSource(); if (token > TokenNameKEYWORD) { throwSyntaxError("Don't use a keyword for class declaration [" + scanner.toStringAction(token) + "].", typeDecl.sourceStart, typeDecl.sourceEnd); } getNextToken(); // extends_from: // /* empty */ // | T_EXTENDS fully_qualified_class_name if (token == TokenNameextends) { getNextToken(); if (token == TokenNameIdentifier) { getNextToken(); } else { throwSyntaxError("Class name expected after keyword 'extends'.", scanner.getCurrentTokenStartPosition(), scanner .getCurrentTokenEndPosition()); } } implements_list(); } else { typeDecl.sourceStart = scanner.getCurrentTokenStartPosition(); typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); typeDecl.name = new char[]{' '}; throwSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd); return; } } // '{' class_statement_list '}' if (token == TokenNameLBRACE) { getNextToken(); if (token != TokenNameRBRACE) { class_statement_list(); } if (token == TokenNameRBRACE) { typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); getNextToken(); } else { throwSyntaxError("'}' expected at end of interface body."); } } else { throwSyntaxError("'{' expected at start of interface body."); } } private void class_entry_type() { // T_CLASS // | T_ABSTRACT T_CLASS // | T_FINAL T_CLASS if (token == TokenNameclass) { getNextToken(); } else if (token == TokenNameabstract) { checkAndSetModifiers(AccAbstract); getNextToken(); if (token != TokenNameclass) { throwSyntaxError("Keyword 'class' expected after keyword 'abstract'."); } getNextToken(); } else if (token == TokenNamefinal) { checkAndSetModifiers(AccFinal); getNextToken(); if (token != TokenNameclass) { throwSyntaxError("Keyword 'class' expected after keyword 'final'."); } getNextToken(); } else { throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected"); } } private void interface_extends_list() { // /* empty */ // | T_EXTENDS interface_list if (token == TokenNameextends) { getNextToken(); interface_list(); } } private void implements_list() { // /* empty */ // | T_IMPLEMENTS interface_list if (token == TokenNameimplements) { getNextToken(); interface_list(); } } private void interface_list() { // interface_list: // fully_qualified_class_name //| interface_list ',' fully_qualified_class_name do { if (token == TokenNameIdentifier) { getNextToken(); } else { throwSyntaxError("Interface name expected after keyword 'implements'."); } if (token != TokenNameCOMMA) { return; } getNextToken(); } while (true); } // private void classBody(TypeDeclaration typeDecl) { // //'{' [class-element-list] '}' // if (token == TokenNameLBRACE) { // getNextToken(); // if (token != TokenNameRBRACE) { // class_statement_list(); // } // if (token == TokenNameRBRACE) { // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); // getNextToken(); // } else { // throwSyntaxError("'}' expected at end of class body."); // } // } else { // throwSyntaxError("'{' expected at start of class body."); // } // } private void class_statement_list() { do { class_statement(); } while (token == 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); reportSyntaxError( "Keyword 'var' is deprecated. Please use 'public' 'private' or 'protected' modifier for field declarations.", scanner.getCurrentTokenStartPosition(), scanner .getCurrentTokenEndPosition()); getNextToken(); classProperty(); } else { boolean hasModifiers = member_modifiers(); if (token == TokenNamefunction) { if (!hasModifiers) { checkAndSetModifiers(AccPublic); } MethodDeclaration methodDecl = new MethodDeclaration( this.compilationUnit.compilationResult); methodDecl.declarationSourceStart = scanner .getCurrentTokenStartPosition(); methodDecl.modifiers = this.modifiers; getNextToken(); functionDefinition(methodDecl); } else { if (!hasModifiers) { throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations."); } classProperty(); } } // 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 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 classProperty() { //'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(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(MethodDeclaration methodDecl) { //identifier '(' [parameter-list] ')' if (token == TokenNameAND) { getNextToken(); } if (token == TokenNameIdentifier) { methodDecl.sourceStart = scanner.getCurrentTokenStartPosition(); methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); methodDecl.selector = scanner.getCurrentIdentifierSource(); getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected in function declaration."); } if (token != TokenNameRPAREN) { parameterList(); } if (token != TokenNameRPAREN) { throwSyntaxError("')' expected in function declaration."); } else { methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1; getNextToken(); } } else { if (token > TokenNameKEYWORD) { throwSyntaxError("Don't use keyword for function declaration [" + token + "]."); } throwSyntaxError("Function name expected after keyword 'function'."); } } // private void parameterList() { //parameter-declaration //parameter-list ',' parameter-declaration do { parameterDeclaration(); if (token != TokenNameCOMMA) { break; } getNextToken(); } while (true); } private void parameterDeclaration() { //variable //variable-reference if (token == TokenNameAND) { getNextToken(); if (isVariable()) { getNextToken(); } else { throwSyntaxError("Variable expected after reference operator '&'."); } } //variable '=' constant if (token == TokenNameVariable) { getNextToken(); if (token == TokenNameEQUAL) { getNextToken(); constant(); } return; } if (token == TokenNamethis) { throwSyntaxError("Reserved word '$this' not allowed in parameter declaration."); } } private void labeledStatementList() { if (token != TokenNamecase && token != TokenNamedefault) { throwSyntaxError("'case' or 'default' expected."); } do { if (token == TokenNamecase) { getNextToken(); expr(); //constant(); if (token == TokenNameCOLON || token == TokenNameSEMICOLON) { getNextToken(); if (token == TokenNamecase || token == TokenNamedefault) { // empty // case // statement // ? continue; } statementList(); } // else if (token == TokenNameSEMICOLON) { // setMarker( // "':' expected after 'case' keyword (Found token: " + // scanner.toStringAction(token) + ")", // scanner.getCurrentTokenStartPosition(), // scanner.getCurrentTokenEndPosition(), // INFO); // getNextToken(); // if (token == TokenNamecase) { // empty case statement ? // continue; // } // statementList(); // } else { throwSyntaxError("':' character after 'case' constant expected (Found token: " + scanner.toStringAction(token) + ")"); } } else { // TokenNamedefault getNextToken(); if (token == TokenNameCOLON) { getNextToken(); statementList(); } else { throwSyntaxError("':' character after 'default' expected."); } } } while (token == TokenNamecase || token == TokenNamedefault); } // public void labeledStatement() { // if (token == TokenNamecase) { // getNextToken(); // constant(); // if (token == TokenNameDDOT) { // getNextToken(); // statement(); // } else { // throwSyntaxError("':' character after 'case' constant expected."); // } // return; // } else if (token == TokenNamedefault) { // getNextToken(); // if (token == TokenNameDDOT) { // getNextToken(); // statement(); // } else { // throwSyntaxError("':' character after 'default' expected."); // } // return; // } // } // public void expressionStatement() { // } // private void inclusionStatement() { // } // public void compoundStatement() { // } // public void selectionStatement() { // } // // public void iterationStatement() { // } // // public void jumpStatement() { // } // // public void outputStatement() { // } // // public void scopeStatement() { // } // // public void flowStatement() { // } // // public void definitionStatement() { // } private void ifStatement() { // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';' if (token == TokenNameCOLON) { getNextToken(); if (token != TokenNameendif) { statementList(); switch (token) { case TokenNameelse : getNextToken(); if (token == TokenNameCOLON) { getNextToken(); if (token != TokenNameendif) { statementList(); } } else { if (token == TokenNameif) { //'else if' getNextToken(); elseifStatementList(); } else { throwSyntaxError("':' expected after 'else'."); } } break; case TokenNameelseif : getNextToken(); elseifStatementList(); break; } } if (token != TokenNameendif) { throwSyntaxError("'endif' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after if-statement."); } getNextToken(); } else { // statement [else-statement] statement(TokenNameEOF); if (token == TokenNameelseif) { getNextToken(); if (token == TokenNameLPAREN) { getNextToken(); } else { throwSyntaxError("'(' expected after 'elseif' keyword."); } expr(); if (token == TokenNameRPAREN) { getNextToken(); } else { throwSyntaxError("')' expected after 'elseif' condition."); } ifStatement(); } else if (token == TokenNameelse) { getNextToken(); statement(TokenNameEOF); } } } private void elseifStatementList() { do { elseifStatement(); switch (token) { case TokenNameelse : getNextToken(); if (token == TokenNameCOLON) { getNextToken(); if (token != TokenNameendif) { statementList(); } return; } else { if (token == TokenNameif) { //'else if' getNextToken(); } else { throwSyntaxError("':' expected after 'else'."); } } break; case TokenNameelseif : getNextToken(); break; default : return; } } while (true); } private void elseifStatement() { if (token == TokenNameLPAREN) { getNextToken(); expr(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected in else-if-statement."); } getNextToken(); if (token != TokenNameCOLON) { throwSyntaxError("':' expected in else-if-statement."); } getNextToken(); if (token != TokenNameendif) { statementList(); } } } private void switchStatement() { if (token == TokenNameCOLON) { // ':' [labeled-statement-list] 'endswitch' ';' getNextToken(); labeledStatementList(); if (token != TokenNameendswitch) { throwSyntaxError("'endswitch' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after switch-statement."); } getNextToken(); } else { // '{' [labeled-statement-list] '}' if (token != TokenNameLBRACE) { throwSyntaxError("'{' expected in switch statement."); } getNextToken(); if (token != TokenNameRBRACE) { labeledStatementList(); } if (token != TokenNameRBRACE) { throwSyntaxError("'}' expected in switch statement."); } getNextToken(); } } private void forStatement() { if (token == TokenNameCOLON) { getNextToken(); statementList(); if (token != TokenNameendfor) { throwSyntaxError("'endfor' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after for-statement."); } getNextToken(); } else { statement(TokenNameEOF); } } private void whileStatement() { // ':' statement-list 'endwhile' ';' if (token == TokenNameCOLON) { getNextToken(); statementList(); if (token != TokenNameendwhile) { throwSyntaxError("'endwhile' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after while-statement."); } getNextToken(); } else { statement(TokenNameEOF); } } private void foreachStatement() { if (token == TokenNameCOLON) { getNextToken(); statementList(); if (token != TokenNameendforeach) { throwSyntaxError("'endforeach' expected."); } getNextToken(); if (token != TokenNameSEMICOLON) { throwSyntaxError("';' expected after foreach-statement."); } getNextToken(); } else { statement(TokenNameEOF); } } // private void exitStatus() { // if (token == TokenNameLPAREN) { // getNextToken(); // } else { // throwSyntaxError("'(' expected in 'exit-status'."); // } // if (token != TokenNameRPAREN) { // expression(); // } // if (token == TokenNameRPAREN) { // getNextToken(); // } else { // throwSyntaxError("')' expected after 'exit-status'."); // } // } private void expressionList() { do { expr(); if (token == TokenNameCOMMA) { getNextToken(); } else { break; } } while (true); } private void expr() { //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_without_variable() { // String ident; char[] ident; boolean castFlag = false; boolean arrayFlag = false; switch (token) { case TokenNameisset : case TokenNameempty : case TokenNameeval : case TokenNameinclude : case TokenNameinclude_once : case TokenNamerequire : case TokenNamerequire_once : internal_functions_in_yacc(); break; case TokenNamenew : getNextToken(); expr(); 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; if (PHP_TYPES[i].equals("array")) { arrayFlag = true; } break; } } } if (castFlag) { getNextToken(); if (arrayFlag && token == TokenNameLPAREN) { getNextToken(); if (token == TokenNameRPAREN) { getNextToken(); } else { expr(); if (token != TokenNameRPAREN) { throwSyntaxError(") expected after 'array('."); } } } if (token != TokenNameRPAREN) { throwSyntaxError(") expected after cast-type '" + str + "'."); } getNextToken(); expr(); break; } else { expr(); } if (token != TokenNameRPAREN) { throwSyntaxError(") expected in postfix-expression."); } getNextToken(); break; case TokenNameDoubleLiteral : getNextToken(); break; case TokenNameIntegerLiteral : getNextToken(); break; case TokenNameDOLLAR_LBRACE : getNextToken(); expr(); if (token != TokenNameRBRACE) { throwSyntaxError("'}' expected after indirect variable token '${'."); } getNextToken(); break; case TokenNameVariable : case TokenNamethis : ident = scanner.getCurrentIdentifierSource(); getNextToken(); if (token == TokenNameLBRACE) { getNextToken(); expr(); 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(); expr(); break; case TokenNameexit : getNextToken(); exit_expr(); 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(); expr(); 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(); expr(); 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(); expr(); 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() { 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(TokenNameAT); } else { expr_without_variable(); // 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 : expr_without_variable(); } } private void castExpression() { // if (token == TokenNameARGOPEN) { // getNextToken(); // typeName(); // if (token != TokenNameARGCLOSE) { // throwSyntaxError(") expected after cast-expression."); // } // getNextToken(); // } unaryExpression(); } private void assignExpression() { 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() { do { assignExpression(); if (token != TokenNameMULTIPLY && token != TokenNameDIVIDE && token != TokenNameREMAINDER) { return; } getNextToken(); } while (true); } private void concatenationExpression() { do { multiplicativeExpression(); if (token != TokenNameDOT) { return; } getNextToken(); } while (true); } private void additiveExpression() { do { concatenationExpression(); if (token != TokenNamePLUS && token != TokenNameMINUS) { return; } getNextToken(); } while (true); } private void shiftExpression() { do { additiveExpression(); if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) { return; } getNextToken(); } while (true); } private void relationalExpression() { do { shiftExpression(); if (token != TokenNameLESS && token != TokenNameGREATER && token != TokenNameLESS_EQUAL && token != TokenNameGREATER_EQUAL) { return; } getNextToken(); } while (true); } private void identicalExpression() { do { relationalExpression(); if (token != TokenNameEQUAL_EQUAL_EQUAL && token != TokenNameNOT_EQUAL_EQUAL) { return; } getNextToken(); } while (true); } private void equalityExpression() { do { identicalExpression(); if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) { return; } getNextToken(); } while (true); } private void ternaryExpression() { equalityExpression(); if (token == TokenNameQUESTION) { getNextToken(); expr(); if (token == TokenNameCOLON) { getNextToken(); expr(); } else { throwSyntaxError("':' expected in ternary operator '? :'."); } } } private void andExpression() { do { ternaryExpression(); if (token != TokenNameAND) { return; } getNextToken(); } while (true); } private void exclusiveorExpression() { do { andExpression(); if (token != TokenNameXOR) { return; } getNextToken(); } while (true); } private void inclusiveorExpression() { do { exclusiveorExpression(); if (token != TokenNameOR) { return; } getNextToken(); } while (true); } private void booleanandExpression() { do { inclusiveorExpression(); if (token != TokenNameAND_AND) { return; } getNextToken(); } while (true); } private void booleanorExpression() { do { booleanandExpression(); if (token != TokenNameOR_OR) { return; } getNextToken(); } while (true); } private void logicalandExpression() { do { booleanorExpression(); if (token != TokenNameAND) { return; } getNextToken(); } while (true); } private void logicalexclusiveorExpression() { do { logicalandExpression(); if (token != TokenNameXOR) { return; } getNextToken(); } while (true); } private void logicalinclusiveorExpression() { 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() { do { variable(); if (token == TokenNameCOMMA) { getNextToken(); } else { break; } } while (true); } private void variable() { 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(); constant(); } } else { throwSyntaxError("$-variable expected in variable-list."); } } } private void exit_expr() { // /* empty */ // | '(' ')' // | '(' expr ')' if (token != TokenNameLPAREN) { return; } getNextToken(); if (token == TokenNameRPAREN) { getNextToken(); return; } expr(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected after keyword 'exit'"); } getNextToken(); } private void internal_functions_in_yacc() { switch (token) { case TokenNameisset : // T_ISSET '(' isset_variables ')' getNextToken(); if (token != TokenNameLPAREN) { throwSyntaxError("'(' expected after keyword 'isset'"); } getNextToken(); isset_variables(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected after keyword 'isset'"); } getNextToken(); break; case TokenNameempty : // T_EMPTY '(' variable ')' getNextToken(); if (token != TokenNameLPAREN) { throwSyntaxError("'(' expected after keyword 'empty'"); } getNextToken(); variable(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected after keyword 'empty'"); } getNextToken(); break; case TokenNameinclude : //T_INCLUDE expr getNextToken(); expr(); break; case TokenNameinclude_once : // T_INCLUDE_ONCE expr getNextToken(); expr(); break; case TokenNameeval : // T_EVAL '(' expr ')' getNextToken(); if (token != TokenNameLPAREN) { throwSyntaxError("'(' expected after keyword 'eval'"); } getNextToken(); expr(); if (token != TokenNameRPAREN) { throwSyntaxError("')' expected after keyword 'eval'"); } getNextToken(); break; case TokenNamerequire : //T_REQUIRE expr getNextToken(); expr(); break; case TokenNamerequire_once : // T_REQUIRE_ONCE expr getNextToken(); expr(); break; } } private void isset_variables() { // variable // | isset_variables ',' if (token == TokenNameRPAREN) { throwSyntaxError("Variable expected after keyword 'isset'"); } while (true) { variable(); if (token == TokenNameCOMMA) { getNextToken(); } else { break; } } } /** * It will look for a value (after a '=' for example) @ */ private void constant() { // 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."); } } 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; } } }