+/**********************************************************************
+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.phpeclipse.phpeditor;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
import net.sourceforge.phpeclipse.phpeditor.php.PHPKeywords;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.texteditor.MarkerUtilities;
-/**********************************************************************
-Copyright (c) 2000, 2002 IBM Corp. and others.
-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:
- IBM Corporation - Initial implementation
- Klaus Hartlage - www.eclipseproject.de
-**********************************************************************/
-
public class PHPParser extends PHPKeywords {
+ // strings for external parser call
+ private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
+ private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
public static final int ERROR = 2;
public static final int WARNING = 1;
final static int TT_LSHIFTASSIGN = 59;
final static int TT_ANDASSIGN = 60;
final static int TT_QUESTIONMARK = 61;
+ final static int TT_DDOT2 = 62;
+ final static int TT_AT = 63;
+ // final static int TT_HEREDOC = 64;
+ final static int TT_DOLLAROPEN = 127;
final static int TT_ARGOPEN = 128;
final static int TT_ARGCLOSE = 129;
final static int TT_LISTOPEN = 130;
/**
* Create marker for the parse error
*/
- protected void setMarker(String message, int lineNumber, int errorLevel) throws CoreException {
+ private void setMarker(String message, int lineNumber, int errorLevel) throws CoreException {
setMarker(fileToParse, message, lineNumber, errorLevel);
}
throw new SyntaxError(rowCount, chIndx - columnCount + 1, str.substring(columnCount, eol), error);
}
+ private void throwSyntaxError(String error, int startRow) {
+
+ throw new SyntaxError(startRow, 0, " ", error);
+ }
+
/**
* Method Declaration.
*
*@see
*/
- void getChar() {
+ private void getChar() {
if (str.length() > chIndx) {
ch = str.charAt(chIndx++);
/**
* gets the next token from input
*/
- void getNextToken() {
+ private void getNextToken() throws CoreException {
phpEnd = false;
while (str.length() > chIndx) {
phpEnd = true;
}
if (!Character.isWhitespace(ch)) {
- if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') || (ch == '$') || (ch == '@')) {
+ if (ch == '$') {
+ if (str.length() > chIndx) {
+ if (str.charAt(chIndx) == '{') {
+ chIndx++;
+ token = TT_DOLLAROPEN;
+ return;
+ }
+ }
+ getIdentifier();
+ return;
+ }
+ if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') || (ch == '$')) {
getIdentifier();
return;
}
} else if (ch == '\'') {
// read string until end
boolean openString = true;
+ int startRow = rowCount;
while (str.length() > chIndx) {
ch = str.charAt(chIndx++);
if (ch == '\\') {
}
}
if (openString) {
- throwSyntaxError("Open string character \"'\" at end of file.");
+ throwSyntaxError("Open string character \"'\" at end of file.", startRow);
}
token = TT_STRING_CONSTANT;
return;
+ } else if (ch == '`') {
+ // read string until end
+ boolean openString = true;
+ int startRow = rowCount;
+ while (str.length() > chIndx) {
+ ch = str.charAt(chIndx++);
+ if (ch == '\\') {
+ if (str.length() > chIndx) {
+ ch = str.charAt(chIndx++);
+ }
+ } else if (ch == '`') {
+ openString = false;
+ break;
+ } else if (ch == '\n') {
+ rowCount++;
+ columnCount = chIndx;
+ }
+ }
+ if (openString) {
+ throwSyntaxError("Open string character \"`\" at end of file.", startRow);
+ }
+ setMarker("Other string delimiters prefered (found \"`\").", rowCount, PHPParser.INFO);
+ token = TT_STRING_CONSTANT;
+ return;
}
switch (ch) {
case '?' :
token = TT_QUESTIONMARK;
break;
+ case '@' :
+ token = TT_AT;
+ break;
case '~' :
token = TT_TILDE;
if (str.length() > chIndx) {
if (str.charAt(chIndx) == '<') {
chIndx++;
token = TT_LSHIFT;
- if (str.length() > chIndx) {
- if (str.charAt(chIndx) == '=') {
- chIndx++;
- token = TT_LSHIFTASSIGN;
- break;
+ if (str.charAt(chIndx) == '<') {
+ // heredoc
+ int startRow = rowCount;
+ if (str.length() > chIndx) {
+
+ ch = str.charAt(++chIndx);
+ if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_')) {
+ chIndx++;
+ getIdentifier();
+ token = TT_STRING_CONSTANT;
+ while (str.length() > chIndx) {
+ ch = str.charAt(chIndx++);
+ if (ch == '\n') {
+ if (str.length() >= chIndx + identifier.length()) {
+ if (str.substring(chIndx, chIndx + identifier.length()).equals(identifier)) {
+ chIndx += identifier.length();
+ return;
+ }
+ }
+ }
+ }
+ }
}
+ throwSyntaxError("Open heredoc syntax after operator '<<<'.", startRow);
+ } else if (str.charAt(chIndx) == '=') {
+ chIndx++;
+ token = TT_LSHIFTASSIGN;
+ break;
}
break;
}
break;
case ':' :
token = TT_DDOT;
-
+ if (str.length() > chIndx) {
+ if (str.charAt(chIndx) == ':') {
+ chIndx++;
+ token = TT_DDOT2;
+ }
+ }
break;
case '#' :
token = TT_HASH;
}
}
- void getIdentifier() {
+ private void getIdentifier() {
StringBuffer ident = new StringBuffer();
ident.append(ch);
}
}
- void getNumber() {
+ private void getNumber() {
StringBuffer inum = new StringBuffer();
char dFlag = ' ';
int numFormat = 10;
}
public void htmlParse(String input) {
- boolean lineCommentMode = false;
- boolean multiLineCommentMode = false;
- boolean stringMode = false;
-
- StringBuffer buf = new StringBuffer();
int lineNumber = 1;
int startLineNumber = 1;
int startIndex = 0;
}
if (phpMode) {
- buf.append(ch);
- if (lineCommentMode && (ch == '\n')) {
- lineCommentMode = false;
- // read until end of line
- } else if ((!stringMode) && (ch == '#')) {
- // read until end of line
- lineCommentMode = true;
- continue;
- } else if ((!stringMode) && (!multiLineCommentMode) && (ch == '/')) {
+ if (ch == '/' && i < input.length()) {
ch2 = input.charAt(i++);
if (ch2 == '/') {
- lineCommentMode = true;
+ 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 == '*') {
- multiLineCommentMode = true;
- continue;
- } else {
- i--;
- }
- } else if (ch == '*' && multiLineCommentMode) {
- ch2 = input.charAt(i++);
- if (ch2 == '/') {
- multiLineCommentMode = false;
+ // 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 == '\\' && stringMode) {
- ch2 = input.charAt(i++);
- if (ch2 == '"') {
- 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;
+ }
}
- } else if ((!lineCommentMode) && (!multiLineCommentMode) && (ch == '"')) {
- if (stringMode) {
- stringMode = false;
- } else {
- stringMode = true;
+ 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 (lineCommentMode || multiLineCommentMode || stringMode) {
+ } 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 == '?') {
+ if (ch == '?' && i < input.length()) {
ch2 = input.charAt(i++);
if (ch2 == '>') {
// php end
}
i--;
}
- } else {
}
}
+
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<phpList.size();j++) {
// String temp = ((PHPString)phpList.get(j)).getPHPString();
// int startIndx = temp.length()-10;
}
}
- public void statementList() throws CoreException {
+ private void statementList() throws CoreException {
do {
statement();
if ((token == TT_LISTCLOSE)
} while (true);
}
- public void compoundStatement() throws CoreException {
+ private void compoundStatement() throws CoreException {
// '{' [statement-list] '}'
if (token == TT_LISTOPEN) {
getNextToken();
}
}
- public void statement() throws CoreException {
- if (token > TT_KEYWORD && token != TT_list) {
- String keyword = identifier;
- if (token == TT_include || token == TT_include_once) {
+ private void statement() throws CoreException {
+ // if (token > TT_KEYWORD && token != TT_list && token != TT_new) {
+ String keyword = identifier;
+ if (token == TT_include || token == TT_include_once) {
+ getNextToken();
+ expression();
+ if (token == TT_SEMICOLON) {
getNextToken();
- expression();
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- if (!phpEnd) {
- throwSyntaxError("';' character after 'include' or 'include_once' expected.");
- }
+ } else {
+ if (!phpEnd) {
+ throwSyntaxError("';' character after 'include' or 'include_once' expected.");
}
- return;
- } else if (token == TT_require || token == TT_require_once) {
+ }
+ return;
+ } else if (token == TT_require || token == TT_require_once) {
+ getNextToken();
+ //constant();
+ expression();
+ if (token == TT_SEMICOLON) {
getNextToken();
- //constant();
- expression();
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- if (!phpEnd) {
- throwSyntaxError("';' character after 'require' or 'require_once' expected.");
- }
+ } else {
+ if (!phpEnd) {
+ throwSyntaxError("';' character after 'require' or 'require_once' expected.");
}
- return;
- } else if (token == TT_if) {
+ }
+ return;
+ } else if (token == TT_if) {
+ getNextToken();
+ if (token == TT_ARGOPEN) {
getNextToken();
- if (token == TT_ARGOPEN) {
- getNextToken();
- } else {
- throwSyntaxError("'(' expected after 'if' keyword.");
- }
- expression();
- if (token == TT_ARGCLOSE) {
- getNextToken();
- } else {
- throwSyntaxError("')' expected after 'if' condition.");
- }
- ifStatement();
- return;
+ } else {
+ throwSyntaxError("'(' expected after 'if' keyword.");
+ }
+ expression();
+ if (token == TT_ARGCLOSE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'if' condition.");
+ }
+ ifStatement();
+ return;
- } else if (token == TT_switch) {
+ } else if (token == TT_switch) {
+ getNextToken();
+ if (token == TT_ARGOPEN) {
getNextToken();
- if (token == TT_ARGOPEN) {
- getNextToken();
- } else {
- throwSyntaxError("'(' expected after 'switch' keyword.");
- }
- expression();
- if (token == TT_ARGCLOSE) {
- getNextToken();
- } else {
- throwSyntaxError("')' expected after 'switch' condition.");
- }
- switchStatement();
- return;
- } else if (token == TT_for) {
+ } else {
+ throwSyntaxError("'(' expected after 'switch' keyword.");
+ }
+ expression();
+ if (token == TT_ARGCLOSE) {
getNextToken();
- if (token == TT_ARGOPEN) {
- getNextToken();
- } else {
- throwSyntaxError("'(' expected after 'for' keyword.");
- }
+ } else {
+ throwSyntaxError("')' expected after 'switch' condition.");
+ }
+ switchStatement();
+ return;
+ } else if (token == TT_for) {
+ getNextToken();
+ if (token == TT_ARGOPEN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'for' keyword.");
+ }
+ if (token == TT_SEMICOLON) {
+ getNextToken();
+ } else {
+ expressionList();
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- expression();
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- throwSyntaxError("';' character after 'for' expected.");
- }
+ throwSyntaxError("';' expected after 'for'.");
}
+ }
+ if (token == TT_SEMICOLON) {
+ getNextToken();
+ } else {
+ expressionList();
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- expression();
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- throwSyntaxError("';' character after 'for' expected.");
- }
+ throwSyntaxError("';' expected after 'for'.");
}
+ }
+ if (token == TT_ARGCLOSE) {
+ getNextToken();
+ } else {
+ expressionList();
if (token == TT_ARGCLOSE) {
getNextToken();
} else {
- expression();
- if (token == TT_ARGCLOSE) {
- getNextToken();
- } else {
- throwSyntaxError("')' expected after 'for' condition.");
- }
+ throwSyntaxError("')' expected after 'for'.");
}
- forStatement();
- return;
- } else if (token == TT_while) {
+ }
+ forStatement();
+ return;
+ } else if (token == TT_while) {
+ getNextToken();
+ if (token == TT_ARGOPEN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'while' keyword.");
+ }
+ expression();
+ if (token == TT_ARGCLOSE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'while' condition.");
+ }
+ whileStatement();
+ return;
+ } else if (token == TT_do) {
+ getNextToken();
+ if (token == TT_LISTOPEN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'{' expected after 'do' keyword.");
+ }
+ if (token != TT_LISTCLOSE) {
+ statementList();
+ }
+ if (token == TT_LISTCLOSE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'}' expected after 'do' keyword.");
+ }
+ if (token == TT_while) {
getNextToken();
if (token == TT_ARGOPEN) {
getNextToken();
} else {
throwSyntaxError("')' expected after 'while' condition.");
}
- whileStatement();
- return;
- } else if (token == TT_do) {
+ } else {
+ throwSyntaxError("'while' expected after 'do' keyword.");
+ }
+ if (token == TT_SEMICOLON) {
getNextToken();
- if (token == TT_LISTOPEN) {
- getNextToken();
- } else {
- throwSyntaxError("'{' expected after 'do' keyword.");
- }
- if (token != TT_LISTCLOSE) {
- statementList();
- }
- if (token == TT_LISTCLOSE) {
- getNextToken();
- } else {
- throwSyntaxError("'}' expected after 'do' keyword.");
- }
- if (token == TT_while) {
- getNextToken();
- if (token == TT_ARGOPEN) {
- getNextToken();
- } else {
- throwSyntaxError("'(' expected after 'while' keyword.");
- }
- expression();
- if (token == TT_ARGCLOSE) {
- getNextToken();
- } else {
- throwSyntaxError("')' expected after 'while' condition.");
- }
- } else {
- throwSyntaxError("'while' expected after 'do' keyword.");
- }
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- if (!phpEnd) {
- throwSyntaxError("';' expected after do-while statement.");
- }
+ } else {
+ if (!phpEnd) {
+ throwSyntaxError("';' expected after do-while statement.");
}
- return;
- } else if (token == TT_foreach) {
+ }
+ return;
+ } else if (token == TT_foreach) {
+ getNextToken();
+ if (token == TT_ARGOPEN) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'(' expected after 'foreach' keyword.");
+ }
+ expression();
+ if (token == TT_as) {
+ getNextToken();
+ } else {
+ throwSyntaxError("'as' expected after 'foreach' exxpression.");
+ }
+ variable();
+ if (token == TT_FOREACH) {
getNextToken();
- if (token == TT_ARGOPEN) {
- getNextToken();
- } else {
- throwSyntaxError("'(' expected after 'foreach' keyword.");
- }
- expression();
- if (token == TT_as) {
- getNextToken();
- } else {
- throwSyntaxError("'as' expected after 'foreach' exxpression.");
- }
variable();
- if (token == TT_FOREACH) {
- getNextToken();
- variable();
- }
- if (token == TT_ARGCLOSE) {
- getNextToken();
- } else {
- throwSyntaxError("')' expected after 'foreach' expression.");
- }
- foreachStatement();
- return;
+ }
+ if (token == TT_ARGCLOSE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("')' expected after 'foreach' expression.");
+ }
+ foreachStatement();
+ return;
- } else if (token == TT_continue || token == TT_break || token == TT_return) {
+ } else if (token == TT_continue || token == TT_break || token == TT_return) {
+ getNextToken();
+ if (token != TT_SEMICOLON) {
+ expression();
+ }
+ if (token == TT_SEMICOLON) {
getNextToken();
- if (token != TT_SEMICOLON) {
- expression();
- }
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- if (!phpEnd) {
- throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
- }
+ } else {
+ if (!phpEnd) {
+ throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
}
- return;
+ }
+ return;
- } else if (token == TT_echo) {
+ } else if (token == TT_echo) {
+ getNextToken();
+ expressionList();
+ if (token == TT_SEMICOLON) {
getNextToken();
- expressionList();
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- if (!phpEnd) {
- throwSyntaxError("';' expected after 'echo' statement.");
- }
+ } else {
+ if (!phpEnd) {
+ throwSyntaxError("';' expected after 'echo' statement.");
}
- return;
- } else if (token == TT_print) {
+ }
+ return;
+ // } else if (token == TT_print) {
+ // getNextToken();
+ // expression();
+ // if (token == TT_SEMICOLON) {
+ // getNextToken();
+ // } else {
+ // if (!phpEnd) {
+ // throwSyntaxError("';' expected after 'print' statement.");
+ // }
+ // }
+ // return;
+
+ } else if (token == TT_global || token == TT_static) {
+ getNextToken();
+ variableList();
+ if (token == TT_SEMICOLON) {
getNextToken();
- expression();
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- if (!phpEnd) {
- throwSyntaxError("';' expected after 'print' statement.");
- }
+ } else {
+ if (!phpEnd) {
+ throwSyntaxError("';' expected after 'global' or 'static' statement.");
}
- return;
+ }
+ return;
- } else if (token == TT_global || token == TT_static) {
+ // } else if (token == TT_unset) {
+ // getNextToken();
+ // if (token == TT_ARGOPEN) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("'(' expected after 'unset' keyword.");
+ // }
+ // variableList();
+ // if (token == TT_ARGCLOSE) {
+ // getNextToken();
+ // } else {
+ // throwSyntaxError("')' expected after 'unset' statement.");
+ // }
+ // if (token == TT_SEMICOLON) {
+ // getNextToken();
+ // } else {
+ // if (!phpEnd) {
+ // throwSyntaxError("';' expected after 'unset' statement.");
+ // }
+ // }
+ // return;
+
+ // } else if (token == TT_exit || token == TT_die) {
+ // getNextToken();
+ // if (token != TT_SEMICOLON) {
+ // exitStatus();
+ // }
+ // if (token == TT_SEMICOLON) {
+ // getNextToken();
+ // } else {
+ // if (!phpEnd) {
+ // throwSyntaxError("';' expected after 'exit' or 'die' statement.");
+ // }
+ // }
+ // return;
+
+ } else if (token == TT_define) {
+ getNextToken();
+ if (token == TT_ARGOPEN) {
getNextToken();
- variableList();
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- if (!phpEnd) {
- throwSyntaxError("';' expected after 'global' or 'static' statement.");
- }
- }
- return;
-
- } else if (token == TT_unset) {
+ } else {
+ throwSyntaxError("'(' expected after 'define' keyword.");
+ }
+ expression();
+ if (token == TT_COMMA) {
getNextToken();
- if (token == TT_ARGOPEN) {
- getNextToken();
- } else {
- throwSyntaxError("'(' expected after 'unset' keyword.");
- }
- variableList();
- if (token == TT_ARGCLOSE) {
- getNextToken();
- } else {
- throwSyntaxError("')' expected after 'unset' statement.");
- }
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- if (!phpEnd) {
- throwSyntaxError("';' expected after 'unset' statement.");
- }
- }
- return;
-
- // } else if (token == TT_exit || token == TT_die) {
- // getNextToken();
- // if (token != TT_SEMICOLON) {
- // exitStatus();
- // }
- // if (token == TT_SEMICOLON) {
- // getNextToken();
- // } else {
- // if (!phpEnd) {
- // throwSyntaxError("';' expected after 'exit' or 'die' statement.");
- // }
- // }
- // return;
-
- } else if (token == TT_define) {
+ } else {
+ throwSyntaxError("',' expected after first 'define' constant.");
+ }
+ expression();
+ if (token == TT_COMMA) {
getNextToken();
- if (token == TT_ARGOPEN) {
- getNextToken();
- } else {
- throwSyntaxError("'(' expected after 'define' keyword.");
- }
- constant();
- if (token == TT_COMMA) {
- getNextToken();
- } else {
- throwSyntaxError("',' expected after first 'define' constant.");
- }
- constant();
- if (token == TT_ARGCLOSE) {
- getNextToken();
- } else {
- throwSyntaxError("')' expected after 'define' statement.");
- }
- if (token == TT_SEMICOLON) {
- getNextToken();
- } else {
- if (!phpEnd) {
- throwSyntaxError("';' expected after 'define' statement.");
- }
- }
- return;
- } else if (token == TT_function) {
+ expression();
+ }
+ if (token == TT_ARGCLOSE) {
getNextToken();
- functionDefinition();
- return;
- } else if (token == TT_class) {
+ } else {
+ throwSyntaxError("')' expected after 'define' statement.");
+ }
+ if (token == TT_SEMICOLON) {
getNextToken();
- classDeclarator();
- classBody();
- return;
} else {
- throwSyntaxError("Unexpected keyword '" + keyword + "'");
+ if (!phpEnd) {
+ throwSyntaxError("';' expected after 'define' statement.");
+ }
}
-
+ return;
+ } else if (token == TT_function) {
+ getNextToken();
+ functionDefinition();
+ return;
+ } else if (token == TT_class) {
+ getNextToken();
+ classDeclarator();
+ classBody();
+ return;
+ // } else {
+ // throwSyntaxError("Unexpected keyword '" + keyword + "'");
} else if (token == TT_LISTOPEN) {
// compoundStatement
getNextToken();
}
}
}
-
}
- public void classDeclarator() {
+ private void classDeclarator() throws CoreException {
//identifier
//identifier 'extends' identifier
if (token == TT_IDENTIFIER) {
}
}
- public void classBody() throws CoreException {
+ private void classBody() throws CoreException {
//'{' [class-element-list] '}'
if (token == TT_LISTOPEN) {
getNextToken();
}
}
- public void classElementList() throws CoreException {
+ private void classElementList() throws CoreException {
do {
classElement();
} while (token == TT_function || token == TT_var);
}
- public void classElement() throws CoreException {
+ private void classElement() throws CoreException {
//class-property
//function-definition
if (token == TT_function) {
}
}
- public void classProperty() {
+ private void classProperty() throws CoreException {
//'var' variable ';'
//'var' variable '=' constant ';'
- if (token == TT_VARIABLE) {
- getNextToken();
- if (token == TT_ASSIGN) {
+ do {
+ if (token == TT_VARIABLE) {
getNextToken();
- constant();
- if (token == TT_SEMICOLON) {
+ if (token == TT_ASSIGN) {
getNextToken();
- } else {
- throwSyntaxError("';' expected after variable declaration.");
+ constant();
}
- } else if (token == TT_SEMICOLON) {
- getNextToken();
} else {
- throwSyntaxError("';' or '=' expected after variable declaration.");
+ throwSyntaxError("Variable expected after keyword 'var'.");
+ }
+ if (token != TT_COMMA) {
+ break;
}
+ getNextToken();
+ } while (true);
+ if (token == TT_SEMICOLON) {
+ getNextToken();
} else {
- throwSyntaxError("Variable expected after keyword 'var'.");
+ throwSyntaxError("';' expected after variable declaration.");
}
}
- public void functionDefinition() throws CoreException {
+ private void functionDefinition() throws CoreException {
functionDeclarator();
compoundStatement();
}
- public void functionDeclarator() {
+ private void functionDeclarator() throws CoreException {
//identifier '(' [parameter-list] ')'
+ if (token == TT_AMPERSAND) {
+ getNextToken();
+ }
if (token == TT_IDENTIFIER) {
getNextToken();
if (token == TT_ARGOPEN) {
}
}
//
- public void parameterList() {
+ private void parameterList() throws CoreException {
//parameter-declaration
//parameter-list ',' parameter-declaration
do {
} while (true);
}
- public void parameterDeclaration() {
+ private void parameterDeclaration() throws CoreException {
//variable
//variable-reference
+ if (token == TT_AMPERSAND) {
+ getNextToken();
+ if (token == TT_VARIABLE) {
+ getNextToken();
+ } else {
+ throwSyntaxError("Variable expected after reference operator '&'.");
+ }
+ }
//variable '=' constant
if (token == TT_VARIABLE) {
getNextToken();
}
}
- public void labeledStatementList() throws CoreException {
+ private void labeledStatementList() throws CoreException {
if (token != TT_case && token != TT_default) {
throwSyntaxError("'case' or 'default' expected.");
}
constant();
if (token == TT_DDOT) {
getNextToken();
+ if (token == TT_case || token == TT_default) { // empty case statement ?
+ continue;
+ }
statementList();
} else if (token == TT_SEMICOLON) {
setMarker("':' expected after 'case' keyword found ';'.", rowCount, PHPParser.INFO);
getNextToken();
+ if (token == TT_case) { // empty case statement ?
+ continue;
+ }
statementList();
} else {
throwSyntaxError("':' character after 'case' constant expected.");
// }
// }
- public void expressionStatement() {
- }
+ // public void expressionStatement() {
+ // }
- public void inclusionStatement() {
- }
+ // private void inclusionStatement() {
+ // }
// public void compoundStatement() {
// }
// public void definitionStatement() {
// }
- public void ifStatement() throws CoreException {
+ private void ifStatement() throws CoreException {
// ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
if (token == TT_DDOT) {
getNextToken();
}
}
}
- public void elseifStatementList() throws CoreException {
+
+ private void elseifStatementList() throws CoreException {
do {
elseifStatement();
switch (token) {
} while (true);
}
- public void elseifStatement() throws CoreException {
+ private void elseifStatement() throws CoreException {
if (token == TT_ARGOPEN) {
getNextToken();
expression();
}
}
- public void switchStatement() throws CoreException {
+ private void switchStatement() throws CoreException {
if (token == TT_DDOT) {
// ':' [labeled-statement-list] 'endswitch' ';'
getNextToken();
}
}
- public void forStatement() throws CoreException {
+ private void forStatement() throws CoreException {
if (token == TT_DDOT) {
getNextToken();
statementList();
}
}
- public void whileStatement() throws CoreException {
+ private void whileStatement() throws CoreException {
// ':' statement-list 'endwhile' ';'
if (token == TT_DDOT) {
getNextToken();
}
}
- public void foreachStatement() throws CoreException {
+ private void foreachStatement() throws CoreException {
if (token == TT_DDOT) {
getNextToken();
statementList();
}
}
- public void exitStatus() {
+ private void exitStatus() throws CoreException {
if (token == TT_ARGOPEN) {
getNextToken();
} else {
}
}
- public void expressionList() {
+ private void expressionList() throws CoreException {
do {
expression();
if (token == TT_COMMA) {
} while (true);
}
- public void expression() {
+ private void expression() throws CoreException {
// if (token == TT_STRING_CONSTANT || token == TT_INTERPOLATED_STRING) {
// getNextToken();
// } else {
// }
}
- public void postfixExpression() {
+ private void postfixExpression() throws CoreException {
String ident;
boolean castFlag = false;
switch (token) {
case TT_INT_NUMBER :
getNextToken();
break;
+ case TT_DOLLAROPEN :
+ getNextToken();
+ expression();
+ if (token != TT_LISTCLOSE) {
+ throwSyntaxError("'}' expected after indirect variable token '${'.");
+ }
+ getNextToken();
+ break;
case TT_VARIABLE :
ident = identifier;
getNextToken();
throwSyntaxError("'}' expected after variable '" + ident + "' in variable-expression.");
}
getNextToken();
+ } else if (token == TT_ARGOPEN) {
+ getNextToken();
+ if (token != TT_ARGCLOSE) {
+ expressionList();
+ if (token != TT_ARGCLOSE) {
+ throwSyntaxError("')' expected after variable '" + ident + "' in postfix-expression.");
+ }
+ }
+ getNextToken();
}
break;
case TT_IDENTIFIER :
getNextToken();
}
break;
+ case TT_print :
+ getNextToken();
+ expression();
+ // if (token == TT_SEMICOLON) {
+ // getNextToken();
+ // } else {
+ // if (!phpEnd) {
+ // throwSyntaxError("';' expected after 'print' statement.");
+ // }
+ // }
+ break;
case TT_list :
getNextToken();
if (token == TT_ARGOPEN) {
}
getNextToken();
break;
+ case TT_DDOT2 : // ::
case TT_REF : // ->
getNextToken();
- switch (token) {
- case TT_VARIABLE :
- ident = identifier;
+ if (token > TT_KEYWORD) {
+ ident = identifier;
+ setMarker("Avoid using keyword '" + ident + "' as variable name.", rowCount, PHPParser.INFO);
+ getNextToken();
+ if (token == TT_ARGOPEN) {
getNextToken();
- // if (token == TT_ARGOPEN) {
- // getNextToken();
- // expressionList();
- // if (token != TT_ARGCLOSE) {
- // throwSyntaxError(") expected after variable '" + ident + "'.");
- // }
- // getNextToken();
- // }
- break;
- case TT_IDENTIFIER :
- ident = identifier;
+ expressionList();
+ if (token != TT_ARGCLOSE) {
+ throwSyntaxError(") expected after identifier '" + ident + "'.");
+ }
getNextToken();
- if (token == TT_ARGOPEN) {
+ }
+ break;
+ } else {
+ switch (token) {
+ case TT_VARIABLE :
+ ident = identifier;
+ getNextToken();
+ // if (token == TT_ARGOPEN) {
+ // getNextToken();
+ // expressionList();
+ // if (token != TT_ARGCLOSE) {
+ // throwSyntaxError(") expected after variable '" + ident + "'.");
+ // }
+ // getNextToken();
+ // }
+ break;
+ case TT_IDENTIFIER :
+ ident = identifier;
getNextToken();
- expressionList();
- if (token != TT_ARGCLOSE) {
- throwSyntaxError(") expected after identifier '" + ident + "'.");
+ if (token == TT_ARGOPEN) {
+ getNextToken();
+ expressionList();
+ if (token != TT_ARGCLOSE) {
+ throwSyntaxError(") expected after identifier '" + ident + "'.");
+ }
+ getNextToken();
}
+ break;
+ case TT_LISTOPEN :
getNextToken();
- }
- break;
- case TT_LISTOPEN :
- getNextToken();
- expression();
- if (token != TT_LISTCLOSE) {
- throwSyntaxError("} expected in postfix-expression.");
- }
- getNextToken();
- break;
- default :
- throwSyntaxError("Syntax error after '->' token.");
+ expression();
+ if (token != TT_LISTCLOSE) {
+ throwSyntaxError("} expected in postfix-expression.");
+ }
+ getNextToken();
+ break;
+ default :
+ throwSyntaxError("Syntax error after '->' token.");
+ }
}
break;
case TT_INCREMENT :
default :
while_flag = false;
}
+
} while (while_flag);
}
- public void unaryExpression() {
+ private void unaryExpression() throws CoreException {
switch (token) {
case TT_INCREMENT :
getNextToken();
getNextToken();
unaryExpression();
break;
- //'&' '*' '+' '-' '~' '!'
+ // '@' '&' '*' '+' '-' '~' '!'
+ case TT_AT :
+ getNextToken();
+ castExpression();
+ break;
case TT_AMPERSAND :
getNextToken();
castExpression();
}
}
- public void castExpression() {
+ private void castExpression() throws CoreException {
// if (token == TT_ARGOPEN) {
// getNextToken();
// typeName();
unaryExpression();
}
- public void typeName() {
+ private void typeName() throws CoreException {
//'string' 'unset' 'array' 'object'
//'bool' 'boolean'
//'real' 'double' 'float'
throwSyntaxError("Expected type cast '( <type-name> )'; Got '" + ident + "'.");
}
- public void assignExpression() {
+ private void assignExpression() throws CoreException {
castExpression();
if (token == TT_ASSIGN) { // =
getNextToken();
}
}
- public void multiplicativeExpression() {
+ private void multiplicativeExpression() throws CoreException {
do {
assignExpression();
if (token != TT_MULTIPLY && token != TT_DIV && token != TT_MOD) {
} while (true);
}
- public void concatenationExpression() {
+ private void concatenationExpression() throws CoreException {
do {
multiplicativeExpression();
if (token != TT_DOT) {
} while (true);
}
- public void additiveExpression() {
+ private void additiveExpression() throws CoreException {
do {
concatenationExpression();
if (token != TT_ADD && token != TT_SUBTRACT) {
} while (true);
}
- public void shiftExpression() {
+ private void shiftExpression() throws CoreException {
do {
additiveExpression();
if (token != TT_LSHIFT && token != TT_RSHIFT) {
} while (true);
}
- public void relationalExpression() {
+ private void relationalExpression() throws CoreException {
do {
shiftExpression();
if (token != TT_LESS && token != TT_GREATER && token != TT_LESSEQUAL && token != TT_GREATEREQUAL) {
} while (true);
}
- public void identicalExpression() {
+ private void identicalExpression() throws CoreException {
do {
relationalExpression();
if (token != TT_EX_EQUAL && token != TT_EX_UNEQUAL) {
} while (true);
}
- public void equalityExpression() {
+ private void equalityExpression() throws CoreException {
do {
identicalExpression();
if (token != TT_EQUAL && token != TT_UNEQUAL) {
} while (true);
}
- public void ternaryExpression() {
+ private void ternaryExpression() throws CoreException {
equalityExpression();
if (token == TT_QUESTIONMARK) {
getNextToken();
}
}
- public void andExpression() {
+ private void andExpression() throws CoreException {
do {
ternaryExpression();
if (token != TT_AMPERSAND) {
} while (true);
}
- public void exclusiveorExpression() {
+ private void exclusiveorExpression() throws CoreException {
do {
andExpression();
if (token != TT_POW) {
} while (true);
}
- public void inclusiveorExpression() {
+ private void inclusiveorExpression() throws CoreException {
do {
exclusiveorExpression();
if (token != TT_LINE) {
} while (true);
}
- public void booleanandExpression() {
+ private void booleanandExpression() throws CoreException {
do {
inclusiveorExpression();
if (token != TT_AND) {
} while (true);
}
- public void booleanorExpression() {
+ private void booleanorExpression() throws CoreException {
do {
booleanandExpression();
if (token != TT_OR) {
} while (true);
}
- public void logicalandExpression() {
+ private void logicalandExpression() throws CoreException {
do {
booleanorExpression();
if (token != TT_and) {
} while (true);
}
- public void logicalexclusiveorExpression() {
+ private void logicalexclusiveorExpression() throws CoreException {
do {
logicalandExpression();
if (token != TT_xor) {
} while (true);
}
- public void logicalinclusiveorExpression() {
+ private void logicalinclusiveorExpression() throws CoreException {
do {
logicalexclusiveorExpression();
if (token != TT_or) {
// }
// }
- public void variableList() {
+ private void variableList() throws CoreException {
do {
variable();
if (token == TT_COMMA) {
} while (true);
}
- public void variable() {
- if (token == TT_VARIABLE) {
+ private void variable() throws CoreException {
+ if (token == TT_DOLLAROPEN) {
+ getNextToken();
+ expression();
+ ;
+ if (token != TT_LISTCLOSE) {
+ throwSyntaxError("'}' expected after indirect variable token '${'.");
+ }
getNextToken();
} else {
- throwSyntaxError("$-variable expected in variable-list.");
+ if (token == TT_VARIABLE) {
+ getNextToken();
+ if (token == TT_PARTOPEN) {
+ getNextToken();
+ expression();
+ if (token != TT_PARTCLOSE) {
+ throwSyntaxError("']' expected in variable-list.");
+ }
+ getNextToken();
+ } else if (token == TT_ASSIGN) {
+ getNextToken();
+ constant();
+ }
+ } else {
+ throwSyntaxError("$-variable expected in variable-list.");
+ }
}
}
- public void constant() {
+ private void constant() throws CoreException {
+ String ident;
switch (token) {
case TT_ADD :
getNextToken();
case TT_true :
getNextToken();
break;
+ case TT_IDENTIFIER :
+ ident = identifier;
+ getNextToken();
+ if (token == TT_ARGOPEN) {
+ getNextToken();
+ if (token != TT_ARGCLOSE) {
+ expressionList();
+ if (token != TT_ARGCLOSE) {
+ throwSyntaxError("')' expected after identifier '" + ident + "' in postfix-expression.");
+ }
+ }
+ getNextToken();
+ }
+ break;
case TT_STRING_CONSTANT :
getNextToken();
break;
throwSyntaxError("Constant expected.");
}
}
+
+ /**
+ * Call the php parse command ( php -l -f <filename> )
+ * and create markers according to the external parser output
+ */
+ public static void phpExternalParse(IFile file) {
+ //IFile file = (IFile) resource;
+ IPath path = file.getFullPath();
+ IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
+ String filename = file.getLocation().toString();
+
+ String[] arguments = { filename };
+ MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
+ String command = form.format(arguments);
+
+ String parserResult = PHPStartApacheAction.execute(command, "External parser: ");
+ try {
+ // parse the buffer to find the errors and warnings
+ createMarkers(parserResult, file);
+ } catch (CoreException e) {
+ }
+ }
+
+ /**
+ * Create markers according to the external parser output
+ */
+ private static void createMarkers(String output, IFile file) throws CoreException {
+ // delete all markers
+ file.deleteMarkers(IMarker.PROBLEM, false, 0);
+
+ int indx = 0;
+ int brIndx = 0;
+ boolean flag = true;
+ while ((brIndx = output.indexOf("<br />", indx)) != -1) {
+ // newer php error output (tested with 4.2.3)
+ scanLine(output, file, indx, brIndx);
+ indx = brIndx + 6;
+ flag = false;
+ }
+ if (flag) {
+ while ((brIndx = output.indexOf("<br>", indx)) != -1) {
+ // older php error output (tested with 4.2.3)
+ scanLine(output, file, indx, brIndx);
+ indx = brIndx + 4;
+ }
+ }
+ }
+
+ private static void scanLine(String output, IFile file, int indx, int brIndx) throws CoreException {
+ String current;
+ String outLineNumberString;
+ StringBuffer lineNumberBuffer = new StringBuffer(10);
+ char ch;
+ current = output.substring(indx, brIndx);
+
+ if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
+ int onLine = current.indexOf("on line <b>");
+ if (onLine != -1) {
+ lineNumberBuffer.delete(0, lineNumberBuffer.length());
+ for (int i = onLine; i < current.length(); i++) {
+ ch = current.charAt(i);
+ if ('0' <= ch && '9' >= ch) {
+ lineNumberBuffer.append(ch);
+ }
+ }
+
+ int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
+
+ Hashtable attributes = new Hashtable();
+
+ current = current.replaceAll("\n", "");
+ current = current.replaceAll("<b>", "");
+ current = current.replaceAll("</b>", "");
+ MarkerUtilities.setMessage(attributes, current);
+
+ if (current.indexOf(PARSE_ERROR_STRING) != -1)
+ attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
+ else if (current.indexOf(PARSE_WARNING_STRING) != -1)
+ attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
+ else
+ attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
+ MarkerUtilities.setLineNumber(attributes, lineNumber);
+ MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
+ }
+ }
+ }
}
\ No newline at end of file