package net.sourceforge.phpeclipse.phpeditor;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Hashtable;
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.ui.texteditor.MarkerUtilities;
/**********************************************************************
Copyright (c) 2000, 2002 IBM Corp. and others.
public class PHPParser extends PHPKeywords {
+ public static final int ERROR = 2;
+ public static final int WARNING = 1;
+ public static final int INFO = 0;
+ private IFile fileToParse;
+ private ArrayList phpList;
+
+ private int currentPHPString;
+ private boolean phpEnd;
+
private static HashMap keywordMap = null;
private String str;
final static int TT_AMPERSAND = 52;
final static int TT_DOLLARLISTOPEN = 53;
final static int TT_TILDE = 54;
+ final static int TT_TILDEASSIGN = 55;
+ final static int TT_MODASSIGN = 56;
+ final static int TT_POWASSIGN = 57;
+ final static int TT_RSHIFTASSIGN = 58;
+ final static int TT_LSHIFTASSIGN = 59;
+ final static int TT_ANDASSIGN = 60;
+ final static int TT_QUESTIONMARK = 61;
final static int TT_ARGOPEN = 128;
final static int TT_ARGCLOSE = 129;
*@param sess Description of Parameter
*@see
*/
- public PHPParser() {
+ public PHPParser(IFile fileToParse) {
if (keywordMap == null) {
keywordMap = new HashMap();
for (int i = 0; i < PHP_KEYWORS.length; i++) {
keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
}
}
+ this.currentPHPString = 0;
+ this.fileToParse = fileToParse;
+ this.phpList = null;
this.str = "";
this.token = TT_EOF;
this.chIndx = 0;
this.rowCount = 1;
this.columnCount = 0;
+ this.phpEnd = false;
+
+ // getNextToken();
+ }
- getNextToken();
+ /**
+ * Create marker for the parse error
+ */
+ protected void setMarker(String message, int lineNumber, int errorLevel) throws CoreException {
+ setMarker(fileToParse, message, lineNumber, errorLevel);
+ }
+
+ public static void setMarker(IFile file, String message, int lineNumber, int errorLevel) throws CoreException {
+
+ Hashtable attributes = new Hashtable();
+ MarkerUtilities.setMessage(attributes, message);
+ switch (errorLevel) {
+ case ERROR :
+ attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
+ break;
+ case WARNING :
+ attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
+ break;
+ case INFO :
+ attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
+ break;
+ }
+ MarkerUtilities.setLineNumber(attributes, lineNumber);
+ MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
}
private void throwSyntaxError(String error) {
chIndx = str.length() + 1;
ch = ' ';
- token = TT_EOF;
+ // token = TT_EOF;
+ phpEnd = true;
}
/**
* gets the next token from input
*/
void getNextToken() {
+ phpEnd = false;
+
while (str.length() > chIndx) {
ch = str.charAt(chIndx++);
token = TT_UNDEFINED;
columnCount = chIndx;
continue; // while loop
}
-
+ if (str.length() == chIndx) {
+ phpEnd = true;
+ }
if (!Character.isWhitespace(ch)) {
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') || (ch == '$') || (ch == '@')) {
getIdentifier();
token = TT_COMMA;
break;
+ case '?' :
+ token = TT_QUESTIONMARK;
+ break;
case '~' :
token = TT_TILDE;
+ if (str.length() > chIndx) {
+ if (str.charAt(chIndx) == '=') {
+ chIndx++;
+ token = TT_TILDEASSIGN;
+ break;
+ }
+ }
break;
case '.' :
token = TT_DOT;
break;
case '%' :
token = TT_MOD;
+ if (str.length() > chIndx) {
+ if (str.charAt(chIndx) == '=') {
+ chIndx++;
+ token = TT_MODASSIGN;
+ break;
+ }
+ }
break;
case ';' :
token = TT_SEMICOLON;
break;
case '^' :
token = TT_POW;
+ if (str.length() > chIndx) {
+ if (str.charAt(chIndx) == '=') {
+ chIndx++;
+ token = TT_POWASSIGN;
+ break;
+ }
+ }
break;
case '/' :
token = TT_DIV;
if (str.charAt(chIndx) == '=') {
chIndx++;
token = TT_GREATEREQUAL;
-
break;
}
if (str.charAt(chIndx) == '>') {
chIndx++;
token = TT_RSHIFT;
-
+ if (str.length() > chIndx) {
+ if (str.charAt(chIndx) == '=') {
+ chIndx++;
+ token = TT_RSHIFTASSIGN;
+ break;
+ }
+ }
break;
}
}
if (str.charAt(chIndx) == '<') {
chIndx++;
token = TT_LSHIFT;
-
+ if (str.length() > chIndx) {
+ if (str.charAt(chIndx) == '=') {
+ chIndx++;
+ token = TT_LSHIFTASSIGN;
+ break;
+ }
+ }
break;
}
}
break;
case '&' :
+ token = TT_AMPERSAND;
if (str.length() > chIndx) {
if (str.charAt(chIndx) == '&') {
chIndx++;
token = TT_AND;
-
break;
- } else {
- token = TT_AMPERSAND;
-
+ }
+ if (str.charAt(chIndx) == '=') {
+ chIndx++;
+ token = TT_ANDASSIGN;
break;
}
+ break;
}
break;
chIndx = str.length() + 1;
ch = ' ';
token = TT_EOF;
+ phpEnd = true;
+ PHPString temp;
+ if (phpList != null) {
+ if (currentPHPString < phpList.size()) {
+ token = TT_UNDEFINED;
+ temp = (PHPString) phpList.get(currentPHPString++);
+ this.str = temp.getPHPString();
+ this.token = TT_EOF;
+ this.chIndx = 0;
+ this.rowCount = temp.getLineNumber();
+ this.columnCount = 0;
+ getNextToken();
+ phpEnd = true;
+ } else {
+ token = TT_UNDEFINED;
+ return;
+ }
+ }
}
void getIdentifier() {
}
}
- public void start(String s, int rowCount) throws SyntaxError {
- // start up
- this.str = s;
- this.token = TT_EOF;
- this.chIndx = 0;
- this.rowCount = rowCount;
- this.columnCount = 0;
- getNextToken();
- if (token != TT_EOF) {
- statementList();
- }
- if (token != TT_EOF) {
- if (token == TT_ARGCLOSE) {
- throwSyntaxError("too many closing ')'; end-of-file not reached");
+ 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;
+ char ch;
+ char ch2;
+ boolean phpMode = false;
+ boolean phpFound = false;
+
+ phpList = new ArrayList();
+
+ 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) {
+ 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 == '/')) {
+ ch2 = input.charAt(i++);
+ if (ch2 == '/') {
+ lineCommentMode = true;
+ continue;
+ } else if (ch2 == '*') {
+ multiLineCommentMode = true;
+ continue;
+ } else {
+ i--;
+ }
+ } else if (ch == '*' && multiLineCommentMode) {
+ ch2 = input.charAt(i++);
+ if (ch2 == '/') {
+ multiLineCommentMode = false;
+ continue;
+ } else {
+ i--;
+ }
+ } else if (ch == '\\' && stringMode) {
+ ch2 = input.charAt(i++);
+ if (ch2 == '"') {
+ continue;
+ } else {
+ i--;
+ }
+ } else if ((!lineCommentMode) && (!multiLineCommentMode) && (ch == '"')) {
+ if (stringMode) {
+ stringMode = false;
+ } else {
+ stringMode = true;
+ }
+ continue;
+ }
+ if (lineCommentMode || multiLineCommentMode || stringMode) {
+ continue;
+ }
+
+ if (ch == '?') {
+ ch2 = input.charAt(i++);
+ if (ch2 == '>') {
+ // php end
+ phpMode = false;
+ phpList.add(new PHPString(input.substring(startIndex, i - 2), startLineNumber));
+ continue;
+ }
+ i--;
+ }
+ } else {
+ }
}
- if (token == TT_LISTCLOSE) {
- throwSyntaxError("too many closing '}'; end-of-file not reached");
+ if (!phpFound) {
+ setMarker("No PHP source code found.", lineNumber, PHPParser.INFO);
+ } else {
+ // for (int j=0;j<phpList.size();j++) {
+ // String temp = ((PHPString)phpList.get(j)).getPHPString();
+ // int startIndx = temp.length()-10;
+ // if (startIndx<0) {
+ // startIndx = 0;
+ // }
+ // System.out.println(temp.substring(startIndx)+"?>");
+ // }
+ phpParse(null, 1);
+ // PHPString temp;
+ // for(int j=0;j<phpList.size();j++) {
+ // temp = (PHPString) phpList.get(j);
+ // parser.start(temp.getPHPString(), temp.getLineNumber());
+ // }
+ }
+ } catch (CoreException e) {
+ }
+ }
+
+ public void phpParse(String s, int rowCount) throws CoreException {
+ // start up
+ try {
+ this.str = s;
+ if (s == null) {
+ if (phpList.size() != 0) {
+ this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
+ }
}
- if (token == TT_PARTCLOSE) {
- throwSyntaxError("too many closing ']'; end-of-file not reached");
+ this.token = TT_EOF;
+ this.chIndx = 0;
+ this.rowCount = rowCount;
+ this.columnCount = 0;
+ this.phpEnd = false;
+ getNextToken();
+ if (token != TT_EOF && token != TT_UNDEFINED) {
+ statementList();
}
+ if (token != TT_EOF && token != TT_UNDEFINED) {
+ if (token == TT_ARGCLOSE) {
+ throwSyntaxError("too many closing ')'; end-of-file not reached");
+ }
+ if (token == TT_LISTCLOSE) {
+ throwSyntaxError("too many closing '}'; end-of-file not reached");
+ }
+ if (token == TT_PARTCLOSE) {
+ throwSyntaxError("too many closing ']'; end-of-file not reached");
+ }
- if (token == TT_ARGOPEN) {
- throwSyntaxError("read character '('; end-of-file not reached");
- }
- if (token == TT_LISTOPEN) {
- throwSyntaxError("read character '{'; end-of-file not reached");
+ if (token == TT_ARGOPEN) {
+ throwSyntaxError("read character '('; end-of-file not reached");
+ }
+ if (token == TT_LISTOPEN) {
+ throwSyntaxError("read character '{'; end-of-file not reached");
+ }
+ if (token == TT_PARTOPEN) {
+ throwSyntaxError("read character '['; end-of-file not reached");
+ }
+
+ throwSyntaxError("end-of-file not reached");
}
- if (token == TT_PARTOPEN) {
- throwSyntaxError("read character '['; end-of-file not reached");
+ } catch (SyntaxError err) {
+ if (s != null) {
+ throw err;
+ } else {
+ setMarker(err.getMessage(), err.getLine(), ERROR);
}
-
- throwSyntaxError("end-of-file not reached");
}
-
}
- public void statementList() {
+ public void statementList() throws CoreException {
do {
statement();
if ((token == TT_LISTCLOSE)
|| (token == TT_endforeach)
|| (token == TT_endwhile)
|| (token == TT_endswitch)
- || (token == TT_EOF)) {
+ || (token == TT_EOF)
+ || (token == TT_UNDEFINED)) {
return;
}
} while (true);
}
- public void compoundStatement() {
+ public void compoundStatement() throws CoreException {
// '{' [statement-list] '}'
if (token == TT_LISTOPEN) {
getNextToken();
}
}
- public void statement() {
+ public void statement() throws CoreException {
if (token > TT_KEYWORD && token != TT_list) {
String keyword = identifier;
if (token == TT_include || token == TT_include_once) {
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- if (token != TT_EOF) {
+ if (!phpEnd) {
throwSyntaxError("';' character after 'include' or 'include_once' expected.");
}
}
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- if (token != TT_EOF) {
+ if (!phpEnd) {
throwSyntaxError("';' character after 'require' or 'require_once' expected.");
}
}
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- if (token != TT_EOF) {
+ if (!phpEnd) {
throwSyntaxError("';' expected after do-while statement.");
}
}
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- if (token != TT_EOF) {
+ if (!phpEnd) {
throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
}
}
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- if (token != TT_EOF) {
+ if (!phpEnd) {
throwSyntaxError("';' expected after 'echo' statement.");
}
}
return;
-
} else if (token == TT_print) {
getNextToken();
expression();
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- if (token != TT_EOF) {
+ if (!phpEnd) {
throwSyntaxError("';' expected after 'print' statement.");
}
}
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- if (token != TT_EOF) {
+ if (!phpEnd) {
throwSyntaxError("';' expected after 'global' or 'static' statement.");
}
}
if (token == TT_SEMICOLON) {
getNextToken();
} else {
- if (token != TT_EOF) {
+ 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 (token != TT_EOF) {
- throwSyntaxError("';' expected after 'exit' or 'die' 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_SEMICOLON) {
getNextToken();
} else {
- if (token != TT_EOF) {
+ if (!phpEnd) {
throwSyntaxError("';' expected after 'define' statement.");
}
}
getNextToken();
return;
} else {
- if (token != TT_EOF) {
+ if (!phpEnd) {
throwSyntaxError("';' expected after expression.");
}
}
}
}
- public void classBody() {
+ public void classBody() throws CoreException {
//'{' [class-element-list] '}'
if (token == TT_LISTOPEN) {
getNextToken();
}
}
- public void classElementList() {
+ public void classElementList() throws CoreException {
do {
classElement();
- } while (token != TT_function || token != TT_var);
+ } while (token == TT_function || token == TT_var);
}
- public void classElement() {
+ public void classElement() throws CoreException {
//class-property
//function-definition
if (token == TT_function) {
}
}
- public void functionDefinition() {
+ public void functionDefinition() throws CoreException {
functionDeclarator();
compoundStatement();
}
}
}
- public void labeledStatementList() {
+ public void labeledStatementList() throws CoreException {
if (token != TT_case && token != TT_default) {
throwSyntaxError("'case' or 'default' expected.");
}
if (token == TT_DDOT) {
getNextToken();
statementList();
+ } else if (token == TT_SEMICOLON) {
+ setMarker("':' expected after 'case' keyword found ';'.", rowCount, PHPParser.INFO);
+ getNextToken();
+ statementList();
} else {
throwSyntaxError("':' character after 'case' constant expected.");
}
// public void definitionStatement() {
// }
- public void ifStatement() {
+ public void ifStatement() throws CoreException {
// ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
if (token == TT_DDOT) {
getNextToken();
}
}
}
- public void elseifStatementList() {
+ public void elseifStatementList() throws CoreException {
do {
elseifStatement();
switch (token) {
} while (true);
}
- public void elseifStatement() {
+ public void elseifStatement() throws CoreException {
if (token == TT_ARGOPEN) {
getNextToken();
expression();
}
}
- public void switchStatement() {
+ public void switchStatement() throws CoreException {
if (token == TT_DDOT) {
// ':' [labeled-statement-list] 'endswitch' ';'
getNextToken();
}
}
- public void forStatement() {
+ public void forStatement() throws CoreException {
if (token == TT_DDOT) {
getNextToken();
statementList();
}
}
- public void whileStatement() {
+ public void whileStatement() throws CoreException {
// ':' statement-list 'endwhile' ';'
if (token == TT_DDOT) {
getNextToken();
}
}
- public void foreachStatement() {
+ public void foreachStatement() throws CoreException {
if (token == TT_DDOT) {
getNextToken();
statementList();
throwSyntaxError("'(' expected after 'list' keyword.");
}
break;
+ // case TT_exit :
+ // getNextToken();
+ // if (token != TT_SEMICOLON) {
+ // exitStatus();
+ // }
+ // if (token == TT_SEMICOLON) {
+ // getNextToken();
+ // } else {
+ // if (!phpEnd) {
+ // throwSyntaxError("';' expected after 'exit' expression.");
+ // }
+ // }
+ // break;
+ // case TT_die :
+ // getNextToken();
+ // if (token != TT_SEMICOLON) {
+ // exitStatus();
+ // }
+ // if (token == TT_SEMICOLON) {
+ // getNextToken();
+ // } else {
+ // if (!phpEnd) {
+ // throwSyntaxError("';' expected after 'die' expression.");
+ // }
+ // }
+ // break;
+
// case TT_array :
// getNextToken();
// if (token == TT_ARGOPEN) {
} else if (token == TT_DIVIDEBY) { // *=
getNextToken();
logicalinclusiveorExpression();
+ } else if (token == TT_MODASSIGN) { // %=
+ getNextToken();
+ logicalinclusiveorExpression();
+ } else if (token == TT_ANDASSIGN) { // &=
+ getNextToken();
+ logicalinclusiveorExpression();
+ } else if (token == TT_POWASSIGN) { // ^=
+ getNextToken();
+ logicalinclusiveorExpression();
+ } else if (token == TT_LSHIFTASSIGN) { // <<=
+ getNextToken();
+ logicalinclusiveorExpression();
+ } else if (token == TT_RSHIFTASSIGN) { // >>=
+ getNextToken();
+ logicalinclusiveorExpression();
+ } else if (token == TT_TILDEASSIGN) { // ~=
+ getNextToken();
+ logicalinclusiveorExpression();
}
}
} while (true);
}
+ public void ternaryExpression() {
+ equalityExpression();
+ if (token == TT_QUESTIONMARK) {
+ getNextToken();
+ expression();
+ if (token == TT_DDOT) {
+ getNextToken();
+ expression();
+ } else {
+ throwSyntaxError("':' expected in ternary operator '? :'.");
+ }
+ }
+ }
+
public void andExpression() {
do {
- equalityExpression();
+ ternaryExpression();
if (token != TT_AMPERSAND) {
return;
}
public void constant() {
switch (token) {
+ case TT_ADD :
+ getNextToken();
+ switch (token) {
+ case TT_DOUBLE_NUMBER :
+ getNextToken();
+ break;
+ case TT_INT_NUMBER :
+ getNextToken();
+ break;
+ default :
+ throwSyntaxError("Constant expected after '+' presign.");
+ }
+ break;
+ case TT_SUBTRACT :
+ getNextToken();
+ switch (token) {
+ case TT_DOUBLE_NUMBER :
+ getNextToken();
+ break;
+ case TT_INT_NUMBER :
+ getNextToken();
+ break;
+ default :
+ throwSyntaxError("Constant expected after '-' presign.");
+ }
+ break;
case TT_null :
getNextToken();
break;