/***********************************************************************************************************************************
- * Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de All rights reserved. This program and the accompanying material are
- * made available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
+ * Copyright (c) 2002 www.phpeclipse.de All rights reserved. This program and the accompanying material are made available under the
+ * terms of the Common Public License v1.0 which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
- * Contributors: Klaus Hartlage - www.eclipseproject.de
+ * Contributors: www.phpeclipse.de
**********************************************************************************************************************************/
package net.sourceforge.phpdt.internal.compiler.parser;
import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
+import net.sourceforge.phpeclipse.internal.compiler.ast.AND_AND_Expression;
import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode;
import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression;
import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.ConditionalExpression;
+import net.sourceforge.phpeclipse.internal.compiler.ast.EqualExpression;
import net.sourceforge.phpeclipse.internal.compiler.ast.Expression;
import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
import net.sourceforge.phpeclipse.internal.compiler.ast.IfStatement;
import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference;
import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.OR_OR_Expression;
import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
import net.sourceforge.phpeclipse.internal.compiler.ast.Statement;
+import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteral;
+import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteralDQ;
+import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteralSQ;
import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
public class Parser //extends PHPParserSuperclass
implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation {
public void initializeScanner() {
this.scanner = new Scanner(false /* comment */, false /* whitespace */, this.options
.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */, false, false,
- this.options.taskTags/* taskTags */, this.options.taskPriorites/* taskPriorities */);
+ this.options.taskTags/* taskTags */,
+ this.options.taskPriorites/* taskPriorities */,
+ true/*isTaskCaseSensitive*/);
}
/**
throw new SyntaxError(1, 0, " ", error);
}
+ private void reportSyntaxError(String error) {
+ int problemStartPosition = scanner.getCurrentTokenStartPosition();
+ int problemEndPosition = scanner.getCurrentTokenEndPosition();
+ reportSyntaxError(error, problemStartPosition, problemEndPosition + 1);
+ }
+
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() {
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)) {
+ || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) {
return;
}
} while (true);
getNextToken();
functionDefinition(methodDecl);
return statement;
+ } else if (token == TokenNamedeclare) {
+ //T_DECLARE '(' declare_list ')' declare_statement
+ getNextToken();
+ if (token != TokenNameLPAREN) {
+ throwSyntaxError("'(' expected in 'declare' statement.");
+ }
+ getNextToken();
+ declare_list();
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected in 'declare' statement.");
+ }
+ getNextToken();
+ declare_statement();
+ return statement;
} else if (token == TokenNametry) {
getNextToken();
if (token != TokenNameLBRACE) {
return statement;
}
+ private void declare_statement() {
+ // statement
+ //| ':' inner_statement_list T_ENDDECLARE ';'
+ //;
+ if (token == TokenNameCOLON) {
+ getNextToken();
+ // TODO: implement inner_statement_list();
+ statementList();
+ if (token != TokenNameenddeclare) {
+ throwSyntaxError("'enddeclare' expected in 'declare' statement.");
+ }
+ getNextToken();
+ if (token != TokenNameSEMICOLON) {
+ throwSyntaxError("';' expected after 'enddeclare' keyword.");
+ }
+ getNextToken();
+ } else {
+ statement(TokenNameRPAREN);
+ }
+ }
+
+ private void declare_list() {
+ // T_STRING '=' static_scalar
+ //| declare_list ',' T_STRING '=' static_scalar
+ while (true) {
+ if (token != TokenNameIdentifier) {
+ throwSyntaxError("Identifier expected in 'declare' list.");
+ }
+ getNextToken();
+ if (token != TokenNameEQUAL) {
+ throwSyntaxError("'=' expected in 'declare' list.");
+ }
+ getNextToken();
+ static_scalar();
+ if (token != TokenNameCOMMA) {
+ break;
+ }
+ getNextToken();
+ }
+ }
+
private void additional_catches() {
while (token == TokenNamecatch) {
getNextToken();
throwSyntaxError("'{' expected in 'catch' statement.");
}
getNextToken();
- statementList();
+ if (token != TokenNameRBRACE) {
+ statementList();
+ }
if (token != TokenNameRBRACE) {
throwSyntaxError("'}' expected in 'catch' statement.");
}
}
} else { // TokenNamedefault
getNextToken();
- if (token == TokenNameCOLON) {
+ if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
getNextToken();
if (token == TokenNameRBRACE) {
// empty default case
}
private Expression expr_without_variable(boolean only_variable) {
+ int exprSourceStart = scanner.getCurrentTokenStartPosition();
+ int exprSourceEnd = scanner.getCurrentTokenEndPosition();
Expression expression = new Expression();
- expression.sourceStart = scanner.getCurrentTokenStartPosition();
+ expression.sourceStart = exprSourceStart;
// default, may be overwritten
- expression.sourceEnd = scanner.getCurrentTokenEndPosition();
+ expression.sourceEnd = exprSourceEnd;
// internal_functions_in_yacc
// | T_CLONE expr
// | T_PRINT expr
scanner.encapsedStringStack.push(new Character('\''));
getNextToken();
try {
+ exprSourceStart = scanner.getCurrentTokenStartPosition();
if (token == TokenNameEncapsedString1) {
+ expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
+ .getCurrentTokenEndPosition());
} else {
encaps_list();
if (token != TokenNameEncapsedString1) {
throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
+ } else {
+ expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
+ .getCurrentTokenEndPosition());
}
}
} finally {
scanner.encapsedStringStack.push(new Character('"'));
getNextToken();
try {
+ exprSourceStart = scanner.getCurrentTokenStartPosition();
if (token == TokenNameEncapsedString2) {
+ expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
+ .getCurrentTokenEndPosition());
} else {
encaps_list();
if (token != TokenNameEncapsedString2) {
throwSyntaxError("'\"' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
+ } else {
+ expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), exprSourceStart, scanner
+ .getCurrentTokenEndPosition());
}
}
} finally {
getNextToken();
}
break;
- case TokenNameIntegerLiteral:
- case TokenNameDoubleLiteral:
case TokenNameStringDoubleQuote:
+ expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition());
+ common_scalar();
+ break;
case TokenNameStringSingleQuote:
+ expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner
+ .getCurrentTokenEndPosition());
+ common_scalar();
+ break;
+ case TokenNameIntegerLiteral:
+ case TokenNameDoubleLiteral:
case TokenNameStringInterpolated:
case TokenNameFILE:
case TokenNameLINE:
if (token != TokenNameEQUAL) {
throwSyntaxError("'=' expected after 'list' keyword.");
}
- getNextToken();
- expr();
+ getNextToken();
+ expr();
} else {
throwSyntaxError("'(' expected after 'list' keyword.");
}
case TokenNameXOR_EQUAL:
case TokenNameRIGHT_SHIFT_EQUAL:
case TokenNameLEFT_SHIFT_EQUAL:
- getNextToken();
- expr();
+ getNextToken();
+ expr();
break;
case TokenNamePLUS_PLUS:
case TokenNameMINUS_MINUS:
while (true) {
switch (token) {
case TokenNameOR_OR:
+ getNextToken();
+ expression = new OR_OR_Expression(expression, expr(), token);
+ break;
case TokenNameAND_AND:
+ getNextToken();
+ expression = new AND_AND_Expression(expression, expr(), token);
+ break;
+ case TokenNameEQUAL_EQUAL:
+ getNextToken();
+ expression = new EqualExpression(expression, expr(), token);
+ break;
case TokenNameand:
case TokenNameor:
case TokenNamexor:
case TokenNameRIGHT_SHIFT:
case TokenNameEQUAL_EQUAL_EQUAL:
case TokenNameNOT_EQUAL_EQUAL:
- case TokenNameEQUAL_EQUAL:
case TokenNameNOT_EQUAL:
case TokenNameLESS:
case TokenNameLESS_EQUAL:
case TokenNameGREATER:
case TokenNameGREATER_EQUAL:
- getNextToken();
- expr();
+ getNextToken();
+ expression = new BinaryExpression(expression, expr(), token);
break;
// | expr T_INSTANCEOF class_name_reference
// | expr '?' expr ':' expr
case TokenNameinstanceof:
getNextToken();
class_name_reference();
+ // TODO use InstanceofExpression
+ expression = new Expression();
+ expression.sourceStart = exprSourceStart;
+ expression.sourceEnd = scanner.getCurrentTokenEndPosition();
break;
case TokenNameQUESTION:
- getNextToken();
- expr();
- if (token == TokenNameCOLON) {
- getNextToken();
- expr();
+ getNextToken();
+ Expression valueIfTrue = expr();
+ if (token != TokenNameCOLON) {
+ throwSyntaxError("':' expected in conditional expression.");
}
+ getNextToken();
+ Expression valueIfFalse = expr();
+
+ expression = new ConditionalExpression(expression, valueIfTrue, valueIfFalse);
break;
default:
return expression;
}
private void internal_functions_in_yacc() {
- int start = 0;
+ // int start = 0;
ImportReference impt = null;
switch (token) {
case TokenNameisset:
break;
case TokenNameinclude:
//T_INCLUDE expr
- start = scanner.getCurrentTokenStartPosition();
- getNextToken();
- expr();
-
- impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
- impt.declarationSourceEnd = impt.sourceEnd;
- impt.declarationEnd = impt.declarationSourceEnd;
- //endPosition is just before the ;
- impt.declarationSourceStart = start;
- includesList.add(impt);
+ checkFileName(token, impt);
break;
case TokenNameinclude_once:
// T_INCLUDE_ONCE expr
- start = scanner.getCurrentTokenStartPosition();
- getNextToken();
- expr();
- impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
- impt.declarationSourceEnd = impt.sourceEnd;
- impt.declarationEnd = impt.declarationSourceEnd;
- //endPosition is just before the ;
- impt.declarationSourceStart = start;
- includesList.add(impt);
+ checkFileName(token, impt);
break;
case TokenNameeval:
// T_EVAL '(' expr ')'
break;
case TokenNamerequire:
//T_REQUIRE expr
- start = scanner.getCurrentTokenStartPosition();
- getNextToken();
- expr();
- impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
- impt.declarationSourceEnd = impt.sourceEnd;
- impt.declarationEnd = impt.declarationSourceEnd;
- //endPosition is just before the ;
- impt.declarationSourceStart = start;
- includesList.add(impt);
+ checkFileName(token, impt);
break;
case TokenNamerequire_once:
// T_REQUIRE_ONCE expr
- start = scanner.getCurrentTokenStartPosition();
- getNextToken();
- expr();
- impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
- impt.declarationSourceEnd = impt.sourceEnd;
- impt.declarationEnd = impt.declarationSourceEnd;
- //endPosition is just before the ;
- impt.declarationSourceStart = start;
- includesList.add(impt);
+ checkFileName(token, impt);
break;
}
}
+ private void checkFileName(int includeToken, ImportReference impt) {
+ //<include-token> expr
+ int start = scanner.getCurrentTokenStartPosition();
+ boolean hasLPAREN = false;
+ getNextToken();
+ if (token == TokenNameLPAREN) {
+ hasLPAREN = true;
+ getNextToken();
+ }
+ Expression expression = expr();
+ if (hasLPAREN) {
+ if (token == TokenNameRPAREN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected for keyword '" + scanner.toStringAction(includeToken) + "'");
+ }
+ }
+ impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
+ impt.declarationSourceEnd = impt.sourceEnd;
+ impt.declarationEnd = impt.declarationSourceEnd;
+ //endPosition is just before the ;
+ impt.declarationSourceStart = start;
+ includesList.add(impt);
+
+ if (expression instanceof StringLiteral) {
+ StringLiteral literal = (StringLiteral) expression;
+ char[] includeName = literal.source();
+ if (includeName.length == 0) {
+ reportSyntaxError("Empty filename after keyword '" + scanner.toStringAction(includeToken) + "'", literal.sourceStart,
+ literal.sourceStart + 1);
+ }
+ String includeNameString = new String(includeName);
+ if (literal instanceof StringLiteralDQ) {
+ if (includeNameString.indexOf('$') >= 0) {
+ // assuming that the filename contains a variable => no filename check
+ return;
+ }
+ }
+ if (includeNameString.startsWith("http://")) {
+ // assuming external include location
+ return;
+ }
+ if (scanner.compilationUnit != null) {
+ IResource resource = scanner.compilationUnit.getResource();
+ // java.io.File f = new java.io.File(new String(compilationUnit.getFileName()));
+ // System.out.println(expression.toStringExpression());
+ // }
+ if (resource != null && resource instanceof IFile) {
+ // check the filename:
+ // System.out.println(new String(compilationUnit.getFileName())+" - "+ expression.toStringExpression());
+ IProject project = resource.getProject();
+ if (project != null) {
+ IPath path = PHPFileUtil.determineFilePath(includeNameString, resource, project);
+
+ if (path == null) {
+ // reportSyntaxError("File: " + expression.toStringExpression() + " doesn't exist in project: "
+ // + project.getLocation().toString(), literal.sourceStart, literal.sourceEnd);
+ String[] args = { expression.toStringExpression(), project.getLocation().toString() };
+ problemReporter.phpIncludeNotExistWarning(args, literal.sourceStart, literal.sourceEnd, referenceContext,
+ compilationUnit.compilationResult);
+ } else {
+ impt.setFile( PHPFileUtil.createFile(path, project) );
+ }
+ }
+ }
+ }
+ }
+ }
+
private void isset_variables() {
// variable
// | isset_variables ','