From d4278211cc956f13ea634f0d719a0ebef8c5d7cc Mon Sep 17 00:00:00 2001 From: khartlage Date: Wed, 27 Nov 2002 22:50:05 +0000 Subject: [PATCH] improved php parser --- .../phpeclipse/phpeditor/PHPParser.java | 975 ++++++++++++-------- .../phpeclipse/phpeditor/SyntaxError.java | 4 +- .../phpeclipse/phpeditor/php/HTMLCodeScanner.java | 4 +- .../phpeclipse/phpeditor/php/PHPCodeScanner.java | 184 ++-- .../phpeclipse/phpeditor/php/PHPKeywords.java | 12 +- .../phpeditor/php/PHPPartitionScanner.java | 268 +++--- .../phpeditor/util/HTMLColorProvider.java | 58 ++ .../phpeditor/util/PHPColorProvider.java | 10 +- 8 files changed, 888 insertions(+), 627 deletions(-) create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/util/HTMLColorProvider.java diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java index 98ce451..91620bc 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java @@ -1,3 +1,13 @@ +/********************************************************************** +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.util.ArrayList; @@ -10,18 +20,6 @@ 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. -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 { public static final int ERROR = 2; @@ -90,7 +88,10 @@ public class PHPParser extends PHPKeywords { 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_DOLLAROPEN = 127; final static int TT_ARGOPEN = 128; final static int TT_ARGCLOSE = 129; final static int TT_LISTOPEN = 130; @@ -153,7 +154,7 @@ public class PHPParser extends PHPKeywords { /** * 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); } @@ -198,7 +199,7 @@ public class PHPParser extends PHPKeywords { * *@see */ - void getChar() { + private void getChar() { if (str.length() > chIndx) { ch = str.charAt(chIndx++); @@ -214,7 +215,7 @@ public class PHPParser extends PHPKeywords { /** * gets the next token from input */ - void getNextToken() { + private void getNextToken() throws CoreException { phpEnd = false; while (str.length() > chIndx) { @@ -229,7 +230,18 @@ public class PHPParser extends PHPKeywords { 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; } @@ -313,6 +325,29 @@ public class PHPParser extends PHPKeywords { } token = TT_STRING_CONSTANT; return; + } else if (ch == '`') { + // read string until end + boolean openString = true; + 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."); + } + setMarker("Other string delimiters prefered (found \"`\").", rowCount, PHPParser.INFO); + token = TT_STRING_CONSTANT; + return; } switch (ch) { @@ -348,6 +383,9 @@ public class PHPParser extends PHPKeywords { case '?' : token = TT_QUESTIONMARK; break; + case '@' : + token = TT_AT; + break; case '~' : token = TT_TILDE; if (str.length() > chIndx) { @@ -603,7 +641,12 @@ public class PHPParser extends PHPKeywords { break; case ':' : token = TT_DDOT; - + if (str.length() > chIndx) { + if (str.charAt(chIndx) == ':') { + chIndx++; + token = TT_DDOT2; + } + } break; case '#' : token = TT_HASH; @@ -648,7 +691,7 @@ public class PHPParser extends PHPKeywords { } } - void getIdentifier() { + private void getIdentifier() { StringBuffer ident = new StringBuffer(); ident.append(ch); @@ -671,7 +714,7 @@ public class PHPParser extends PHPKeywords { } } - void getNumber() { + private void getNumber() { StringBuffer inum = new StringBuffer(); char dFlag = ' '; int numFormat = 10; @@ -757,11 +800,6 @@ public class PHPParser extends PHPKeywords { } 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; @@ -826,53 +864,91 @@ public class PHPParser extends PHPKeywords { } 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 @@ -882,12 +958,16 @@ public class PHPParser extends PHPKeywords { } 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 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(); @@ -1102,198 +1212,170 @@ public class PHPParser extends PHPKeywords { } 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(); - expression(); - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - if (!phpEnd) { - throwSyntaxError("';' expected after 'print' statement."); - } + } else { + if (!phpEnd) { + throwSyntaxError("';' expected after 'print' statement."); } - return; + } + return; - } else if (token == TT_global || token == TT_static) { + } else if (token == TT_global || token == TT_static) { + getNextToken(); + variableList(); + if (token == TT_SEMICOLON) { getNextToken(); - variableList(); - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - if (!phpEnd) { - throwSyntaxError("';' expected after 'global' or 'static' statement."); - } + } else { + if (!phpEnd) { + throwSyntaxError("';' expected after 'global' or 'static' statement."); } - return; + } + return; - } else if (token == TT_unset) { + // } 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(); - 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 'define' keyword."); + } + 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) { + } else { + throwSyntaxError("',' expected after first 'define' constant."); + } + expression(); + if (token == TT_COMMA) { getNextToken(); - functionDefinition(); - return; - } else if (token == TT_class) { + expression(); + } + if (token == TT_ARGCLOSE) { getNextToken(); - classDeclarator(); - classBody(); - return; } else { - throwSyntaxError("Unexpected keyword '" + keyword + "'"); + throwSyntaxError("')' expected after 'define' statement."); } - + if (token == TT_SEMICOLON) { + getNextToken(); + } else { + 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(); @@ -1319,10 +1401,9 @@ public class PHPParser extends PHPKeywords { } } } - } - public void classDeclarator() { + private void classDeclarator() throws CoreException { //identifier //identifier 'extends' identifier if (token == TT_IDENTIFIER) { @@ -1340,7 +1421,7 @@ public class PHPParser extends PHPKeywords { } } - public void classBody() throws CoreException { + private void classBody() throws CoreException { //'{' [class-element-list] '}' if (token == TT_LISTOPEN) { getNextToken(); @@ -1357,13 +1438,13 @@ public class PHPParser extends PHPKeywords { } } - 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) { @@ -1377,36 +1458,41 @@ public class PHPParser extends PHPKeywords { } } - 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) { @@ -1425,7 +1511,7 @@ public class PHPParser extends PHPKeywords { } } // - public void parameterList() { + private void parameterList() throws CoreException { //parameter-declaration //parameter-list ',' parameter-declaration do { @@ -1437,9 +1523,17 @@ public class PHPParser extends PHPKeywords { } 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(); @@ -1451,7 +1545,7 @@ public class PHPParser extends PHPKeywords { } } - public void labeledStatementList() throws CoreException { + private void labeledStatementList() throws CoreException { if (token != TT_case && token != TT_default) { throwSyntaxError("'case' or 'default' expected."); } @@ -1461,10 +1555,16 @@ public class PHPParser extends PHPKeywords { 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."); @@ -1504,11 +1604,11 @@ public class PHPParser extends PHPKeywords { // } // } - public void expressionStatement() { - } + // public void expressionStatement() { + // } - public void inclusionStatement() { - } + // private void inclusionStatement() { + // } // public void compoundStatement() { // } @@ -1534,7 +1634,7 @@ public class PHPParser extends PHPKeywords { // 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(); @@ -1591,7 +1691,8 @@ public class PHPParser extends PHPKeywords { } } } - public void elseifStatementList() throws CoreException { + + private void elseifStatementList() throws CoreException { do { elseifStatement(); switch (token) { @@ -1618,7 +1719,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void elseifStatement() throws CoreException { + private void elseifStatement() throws CoreException { if (token == TT_ARGOPEN) { getNextToken(); expression(); @@ -1634,7 +1735,7 @@ public class PHPParser extends PHPKeywords { } } - public void switchStatement() throws CoreException { + private void switchStatement() throws CoreException { if (token == TT_DDOT) { // ':' [labeled-statement-list] 'endswitch' ';' getNextToken(); @@ -1664,7 +1765,7 @@ public class PHPParser extends PHPKeywords { } } - public void forStatement() throws CoreException { + private void forStatement() throws CoreException { if (token == TT_DDOT) { getNextToken(); statementList(); @@ -1681,7 +1782,7 @@ public class PHPParser extends PHPKeywords { } } - public void whileStatement() throws CoreException { + private void whileStatement() throws CoreException { // ':' statement-list 'endwhile' ';' if (token == TT_DDOT) { getNextToken(); @@ -1699,7 +1800,7 @@ public class PHPParser extends PHPKeywords { } } - public void foreachStatement() throws CoreException { + private void foreachStatement() throws CoreException { if (token == TT_DDOT) { getNextToken(); statementList(); @@ -1716,7 +1817,7 @@ public class PHPParser extends PHPKeywords { } } - public void exitStatus() { + private void exitStatus() throws CoreException { if (token == TT_ARGOPEN) { getNextToken(); } else { @@ -1732,7 +1833,7 @@ public class PHPParser extends PHPKeywords { } } - public void expressionList() { + private void expressionList() throws CoreException { do { expression(); if (token == TT_COMMA) { @@ -1743,7 +1844,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void expression() { + private void expression() throws CoreException { // if (token == TT_STRING_CONSTANT || token == TT_INTERPOLATED_STRING) { // getNextToken(); // } else { @@ -1754,7 +1855,7 @@ public class PHPParser extends PHPKeywords { // } } - public void postfixExpression() { + private void postfixExpression() throws CoreException { String ident; boolean castFlag = false; switch (token) { @@ -1813,6 +1914,14 @@ public class PHPParser extends PHPKeywords { 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(); @@ -1823,6 +1932,15 @@ public class PHPParser extends PHPKeywords { 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 : @@ -1918,43 +2036,59 @@ public class PHPParser extends PHPKeywords { } 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 : @@ -1966,10 +2100,11 @@ public class PHPParser extends PHPKeywords { default : while_flag = false; } + } while (while_flag); } - public void unaryExpression() { + private void unaryExpression() throws CoreException { switch (token) { case TT_INCREMENT : getNextToken(); @@ -1979,7 +2114,11 @@ public class PHPParser extends PHPKeywords { getNextToken(); unaryExpression(); break; - //'&' '*' '+' '-' '~' '!' + // '@' '&' '*' '+' '-' '~' '!' + case TT_AT : + getNextToken(); + castExpression(); + break; case TT_AMPERSAND : getNextToken(); castExpression(); @@ -2009,7 +2148,7 @@ public class PHPParser extends PHPKeywords { } } - public void castExpression() { + private void castExpression() throws CoreException { // if (token == TT_ARGOPEN) { // getNextToken(); // typeName(); @@ -2021,7 +2160,7 @@ public class PHPParser extends PHPKeywords { unaryExpression(); } - public void typeName() { + private void typeName() throws CoreException { //'string' 'unset' 'array' 'object' //'bool' 'boolean' //'real' 'double' 'float' @@ -2040,7 +2179,7 @@ public class PHPParser extends PHPKeywords { throwSyntaxError("Expected type cast '( )'; Got '" + ident + "'."); } - public void assignExpression() { + private void assignExpression() throws CoreException { castExpression(); if (token == TT_ASSIGN) { // = getNextToken(); @@ -2084,7 +2223,7 @@ public class PHPParser extends PHPKeywords { } } - public void multiplicativeExpression() { + private void multiplicativeExpression() throws CoreException { do { assignExpression(); if (token != TT_MULTIPLY && token != TT_DIV && token != TT_MOD) { @@ -2094,7 +2233,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void concatenationExpression() { + private void concatenationExpression() throws CoreException { do { multiplicativeExpression(); if (token != TT_DOT) { @@ -2104,7 +2243,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void additiveExpression() { + private void additiveExpression() throws CoreException { do { concatenationExpression(); if (token != TT_ADD && token != TT_SUBTRACT) { @@ -2114,7 +2253,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void shiftExpression() { + private void shiftExpression() throws CoreException { do { additiveExpression(); if (token != TT_LSHIFT && token != TT_RSHIFT) { @@ -2124,7 +2263,7 @@ public class PHPParser extends PHPKeywords { } 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) { @@ -2134,7 +2273,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void identicalExpression() { + private void identicalExpression() throws CoreException { do { relationalExpression(); if (token != TT_EX_EQUAL && token != TT_EX_UNEQUAL) { @@ -2144,7 +2283,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void equalityExpression() { + private void equalityExpression() throws CoreException { do { identicalExpression(); if (token != TT_EQUAL && token != TT_UNEQUAL) { @@ -2154,7 +2293,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void ternaryExpression() { + private void ternaryExpression() throws CoreException { equalityExpression(); if (token == TT_QUESTIONMARK) { getNextToken(); @@ -2168,7 +2307,7 @@ public class PHPParser extends PHPKeywords { } } - public void andExpression() { + private void andExpression() throws CoreException { do { ternaryExpression(); if (token != TT_AMPERSAND) { @@ -2178,7 +2317,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void exclusiveorExpression() { + private void exclusiveorExpression() throws CoreException { do { andExpression(); if (token != TT_POW) { @@ -2188,7 +2327,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void inclusiveorExpression() { + private void inclusiveorExpression() throws CoreException { do { exclusiveorExpression(); if (token != TT_LINE) { @@ -2198,7 +2337,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void booleanandExpression() { + private void booleanandExpression() throws CoreException { do { inclusiveorExpression(); if (token != TT_AND) { @@ -2208,7 +2347,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void booleanorExpression() { + private void booleanorExpression() throws CoreException { do { booleanandExpression(); if (token != TT_OR) { @@ -2218,7 +2357,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void logicalandExpression() { + private void logicalandExpression() throws CoreException { do { booleanorExpression(); if (token != TT_and) { @@ -2228,7 +2367,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void logicalexclusiveorExpression() { + private void logicalexclusiveorExpression() throws CoreException { do { logicalandExpression(); if (token != TT_xor) { @@ -2238,7 +2377,7 @@ public class PHPParser extends PHPKeywords { } while (true); } - public void logicalinclusiveorExpression() { + private void logicalinclusiveorExpression() throws CoreException { do { logicalexclusiveorExpression(); if (token != TT_or) { @@ -2260,7 +2399,7 @@ public class PHPParser extends PHPKeywords { // } // } - public void variableList() { + private void variableList() throws CoreException { do { variable(); if (token == TT_COMMA) { @@ -2271,15 +2410,37 @@ public class PHPParser extends PHPKeywords { } 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(); @@ -2316,6 +2477,20 @@ public class PHPParser extends PHPKeywords { 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; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/SyntaxError.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/SyntaxError.java index 3ba2e99..da1cf8b 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/SyntaxError.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/SyntaxError.java @@ -52,7 +52,9 @@ public class SyntaxError extends Error { // } // buf.append('^'); // return buf.toString(); - System.err.println(currentLine); + + + // System.err.println(currentLine); return error; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCodeScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCodeScanner.java index ccc6b92..a93a542 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCodeScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCodeScanner.java @@ -30,7 +30,7 @@ import org.eclipse.jface.text.rules.WhitespaceRule; import org.eclipse.jface.text.rules.WordRule; /** - * A Java code scanner. + * A HTML code scanner. */ public class HTMLCodeScanner extends RuleBasedScanner { @@ -110,7 +110,7 @@ public class HTMLCodeScanner extends RuleBasedScanner { public HTMLCodeScanner(PHPColorProvider provider) { keyword = new Token(new TextAttribute(provider.getColor(PHPColorProvider.KEYWORD))); - IToken type = new Token(new TextAttribute(provider.getColor(PHPColorProvider.TYPE))); + IToken type = new Token(new TextAttribute(provider.getColor(PHPColorProvider.FUNCTION_NAME))); IToken string = new Token(new TextAttribute(provider.getColor(PHPColorProvider.STRING))); IToken comment = new Token(new TextAttribute(provider.getColor(PHPColorProvider.SINGLE_LINE_COMMENT))); IToken multi_comment = new Token(new TextAttribute(provider.getColor(PHPColorProvider.MULTI_LINE_COMMENT))); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java index 97d996e..ccbc66a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java @@ -14,9 +14,13 @@ package net.sourceforge.phpeclipse.phpeditor.php; import java.util.ArrayList; import java.util.List; +import net.sourceforge.phpeclipse.IPreferenceConstants; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider; import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector; import net.sourceforge.phpeclipse.phpeditor.util.PHPWordDetector; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.text.TextAttribute; import org.eclipse.jface.text.rules.EndOfLineRule; import org.eclipse.jface.text.rules.ICharacterScanner; @@ -33,111 +37,109 @@ import org.eclipse.jface.text.rules.WordRule; /** * PHP Code Scanner */ -public class PHPCodeScanner extends RuleBasedScanner { +public class PHPCodeScanner extends RuleBasedScanner implements IPreferenceConstants { - - - private IToken variable; - - private class PHPWordRule extends WordRule { - private StringBuffer fBuffer= new StringBuffer(); - public PHPWordRule(IWordDetector detector) { - super(detector, Token.UNDEFINED); - } + private class PHPWordRule extends WordRule { + private StringBuffer fBuffer = new StringBuffer(); + + public PHPWordRule(IWordDetector detector) { + super(detector, Token.UNDEFINED); + } - public PHPWordRule(IWordDetector detector, IToken defaultToken) { - super(detector, defaultToken); - } + public PHPWordRule(IWordDetector detector, IToken defaultToken) { + super(detector, defaultToken); + } - public IToken evaluate(ICharacterScanner scanner) { - int c = scanner.read(); + public IToken evaluate(ICharacterScanner scanner) { + int c = scanner.read(); boolean isVariable = false; - if (fDetector.isWordStart((char) c)) { - if (c=='$') { + if (fDetector.isWordStart((char) c)) { + if (c == '$') { isVariable = true; } - if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) { + if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) { - fBuffer.setLength(0); - do { - fBuffer.append((char) c); - c = scanner.read(); - } while (c != scanner.EOF && fDetector.isWordPart((char) c)); - scanner.unread(); + fBuffer.setLength(0); + do { + fBuffer.append((char) c); + c = scanner.read(); + } while (c != scanner.EOF && fDetector.isWordPart((char) c)); + scanner.unread(); if (isVariable) { return variable; } - IToken token = (IToken) fWords.get(fBuffer.toString()); - if (token != null) - return token; - - if (fDefaultToken.isUndefined()) - unreadBuffer(scanner); - - return fDefaultToken; - } - } - - scanner.unread(); - return Token.UNDEFINED; - } - } - - private static String[] fgConstants = { "__LINE__", "__FILE__", "true", "false" }; - private TextAttribute fComment; - private TextAttribute fKeyword; - private TextAttribute fType; - private TextAttribute fString; - private PHPColorProvider fColorProvider; - - /** - * Creates a Java code scanner - */ - public PHPCodeScanner(PHPColorProvider provider) { - - IToken keyword = new Token(new TextAttribute(provider.getColor(PHPColorProvider.KEYWORD))); - IToken type = new Token(new TextAttribute(provider.getColor(PHPColorProvider.TYPE))); - IToken string = new Token(new TextAttribute(provider.getColor(PHPColorProvider.STRING))); - IToken comment = new Token(new TextAttribute(provider.getColor(PHPColorProvider.SINGLE_LINE_COMMENT))); - IToken multi_comment = new Token(new TextAttribute(provider.getColor(PHPColorProvider.MULTI_LINE_COMMENT))); - IToken other = new Token(new TextAttribute(provider.getColor(PHPColorProvider.DEFAULT))); + IToken token = (IToken) fWords.get(fBuffer.toString()); + if (token != null) + return token; + + if (fDefaultToken.isUndefined()) + unreadBuffer(scanner); + + return fDefaultToken; + } + } + + scanner.unread(); + return Token.UNDEFINED; + } + } + + private static String[] fgConstants = { "__LINE__", "__FILE__", "true", "false", "null", "object", "array" }; + private TextAttribute fComment; + private TextAttribute fKeyword; + private TextAttribute fType; + private TextAttribute fString; + private PHPColorProvider fColorProvider; + + /** + * Creates a Java code scanner + */ + public PHPCodeScanner(PHPColorProvider provider) { + final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore(); + + IToken keyword = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_KEYWORD)))); + IToken functionName = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_FUNCTIONNAME)))); + IToken string = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_STRING)))); + IToken comment = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_SINGLELINE_COMMENT)))); + IToken multi_comment = + new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_MULTILINE_COMMENT)))); + IToken other = new Token(new TextAttribute(provider.getColor(PreferenceConverter.getColor(store, PHP_DEFAULT)))); variable = new Token(new TextAttribute(provider.getColor(PHPColorProvider.VARIABLE))); - - List rules = new ArrayList(); - - // Add rule for single line comments. - rules.add(new EndOfLineRule("//", comment)); //$NON-NLS-1$ - // EndOfLineRule endOfLine = new EndOfLineRule("#", comment); - // endOfLine.setColumnConstraint(0); - rules.add(new EndOfLineRule("#", comment)); - - // Add rule for strings and character constants. - rules.add(new MultiLineRule("\"", "\"", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ - rules.add(new SingleLineRule("'", "'", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ - - // rules.add(new SingleLineRule("//", "//", php_comment)); - rules.add(new MultiLineRule("/*", "*/", multi_comment)); - - // Add generic whitespace rule. - rules.add(new WhitespaceRule(new PHPWhitespaceDetector())); - - // Add word rule for keywords, types, and constants. - PHPWordRule wordRule = new PHPWordRule(new PHPWordDetector(), other); - for (int i = 0; i < PHPKeywords.PHP_KEYWORS.length; i++) - wordRule.addWord(PHPKeywords.PHP_KEYWORS[i], keyword); - for (int i = 0; i < PHPFunctionNames.FUNCTION_NAMES.length; i++) - wordRule.addWord(PHPFunctionNames.FUNCTION_NAMES[i], type); - for (int i = 0; i < fgConstants.length; i++) - wordRule.addWord(fgConstants[i], type); - rules.add(wordRule); - - IRule[] result = new IRule[rules.size()]; - rules.toArray(result); - setRules(result); - } + List rules = new ArrayList(); + + // Add rule for single line comments. + rules.add(new EndOfLineRule("//", comment)); //$NON-NLS-1$ + // EndOfLineRule endOfLine = new EndOfLineRule("#", comment); + // endOfLine.setColumnConstraint(0); + rules.add(new EndOfLineRule("#", comment)); + + // Add rule for strings and character constants. + rules.add(new MultiLineRule("\"", "\"", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ + rules.add(new SingleLineRule("'", "'", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ + + // rules.add(new SingleLineRule("//", "//", php_comment)); + rules.add(new MultiLineRule("/*", "*/", multi_comment)); + + // Add generic whitespace rule. + rules.add(new WhitespaceRule(new PHPWhitespaceDetector())); + + // Add word rule for keywords, types, and constants. + PHPWordRule wordRule = new PHPWordRule(new PHPWordDetector(), other); + for (int i = 0; i < PHPKeywords.PHP_KEYWORS.length; i++) + wordRule.addWord(PHPKeywords.PHP_KEYWORS[i], keyword); + for (int i = 0; i < PHPFunctionNames.FUNCTION_NAMES.length; i++) + wordRule.addWord(PHPFunctionNames.FUNCTION_NAMES[i], functionName); + for (int i = 0; i < fgConstants.length; i++) + wordRule.addWord(fgConstants[i], functionName); + rules.add(wordRule); + + IRule[] result = new IRule[rules.size()]; + rules.toArray(result); + setRules(result); + } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java index ce19628..3df4172 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java @@ -51,13 +51,16 @@ public class PHPKeywords { // "empty", // "array", // "isset", - "echo", "var", "as", "print", "unset", + "echo", "var", "as", "print", + // "unset", // "exit", "die", "and", "or", "xor", "list", "null", "false", "true" }; public final static String[] PHP_TYPES = - { "string", "unset", "array", "object", "bool", "boolean", "real", "double", "float", "int", "integer", }; + { "string", "unset", + //"array", + "object", "bool", "boolean", "real", "double", "float", "int", "integer", }; public final static int TT_KEYWORD = 1000; public final static int TT_if = 1001; @@ -96,7 +99,7 @@ public class PHPKeywords { public final static int TT_var = 1034; public final static int TT_as = 1035; public final static int TT_print = 1036; - public final static int TT_unset = 1037; + // public final static int TT_unset = 1037; // public final static int TT_exit = 1038; // public final static int TT_die = 1039; public final static int TT_and = 1040; @@ -142,7 +145,8 @@ public class PHPKeywords { // TT_empty, // TT_array, // TT_isset, - TT_echo, TT_var, TT_as, TT_print, TT_unset, + TT_echo, TT_var, TT_as, TT_print, + // TT_unset, //TT_exit, TT_die, TT_and, TT_or, TT_xor, TT_list, TT_null, TT_false, TT_true }; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java index bebcc1f..85aa0d2 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java @@ -33,15 +33,16 @@ public class PHPPartitionScanner extends RuleBasedPartitionScanner { public final static String HTML_MULTILINE_COMMENT = "__html_multiline_comment"; //$NON-NLS-1$ // public final static String JAVA_DOC= "__java_javadoc"; //$NON-NLS-1$ public final static String PHP = "__php"; -// public final static String HTML = "__html"; + // public final static String HTML = "__html"; public final static IToken php = new Token(PHP); -// public final static IToken html = new Token(HTML); + // public final static IToken html = new Token(HTML); public final static IToken comment = new Token(HTML_MULTILINE_COMMENT); protected final static char[] php0EndSequence = { '<', '?' }; protected final static char[] php1EndSequence = { '<', '?', 'p', 'h', 'p' }; protected final static char[] php2EndSequence = { '<', '?', 'P', 'H', 'P' }; + private StringBuffer test; public class PHPMultiLineRule extends MultiLineRule { @@ -64,48 +65,65 @@ public class PHPPartitionScanner extends RuleBasedPartitionScanner { char[][] delimiters = scanner.getLegalLineDelimiters(); while ((c = scanner.read()) != ICharacterScanner.EOF) { - if (lineCommentMode && (c == '\n')) { - lineCommentMode = false; - // read until end of line - } else if ((!stringMode) && (c == '#')) { + if (c == '#') { // read until end of line - lineCommentMode = true; - continue; - } else if ((!stringMode) && (!multiLineCommentMode) && (c == '/')) { - c2 = scanner.read(); - if (c2 == '/') { - lineCommentMode = true; - continue; - } else if (c2 == '*') { - multiLineCommentMode = true; - continue; - } else { - scanner.unread(); + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (fEndSequence.length > 0 && c == fEndSequence[0]) { + // Check if the specified end sequence has been found. + if (sequenceDetected(scanner, fEndSequence, true)) + return true; + } else if (c == '\n') { + break; + } } - } else if (c == '*' && multiLineCommentMode) { - c2 = scanner.read(); - if (c2 == '/') { - multiLineCommentMode = false; + continue; + } else if (c == '/' && (c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '/') { + // read until end of line + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (fEndSequence.length > 0 && c == fEndSequence[0]) { + // Check if the specified end sequence has been found. + if (sequenceDetected(scanner, fEndSequence, true)) + return true; + } else if (c == '\n') { + break; + } + } continue; - } else { - scanner.unread(); - } - } else if (c == '\\' && stringMode) { - c2 = scanner.read(); - if (c2 == '"') { + } else if (c == '*') { + // multi-line comment + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '*' && (c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '/') { + break; + } + scanner.unread(); + } + } + continue; } else { scanner.unread(); } - } else if ((!lineCommentMode) && (!multiLineCommentMode) && (c == '"')) { - if (stringMode) { - stringMode = false; - } else { - stringMode = true; + } else if (c == '"') { + // string mode + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '\\') { + c = scanner.read(); + } else if (c == '"') { + break; + } } continue; - } - if (lineCommentMode || multiLineCommentMode || stringMode) { + } else if (c == '\'') { + // string mode + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '\\') { + c = scanner.read(); + } else if (c == '\'') { + break; + } + } continue; } @@ -123,95 +141,99 @@ public class PHPPartitionScanner extends RuleBasedPartitionScanner { return true; } } + } + boolean phpMode = false; + if (c == ICharacterScanner.EOF) { + phpMode = true; } scanner.unread(); - return false; + return phpMode; } } -// public class HTMLMultiLineRule extends MultiLineRule { -// -// public HTMLMultiLineRule(String startSequence, String endSequence, IToken token) { -// super(startSequence, endSequence, token); -// } -// -// public HTMLMultiLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter) { -// super(startSequence, endSequence, token, escapeCharacter); -// } -// -// protected boolean endSequenceDetected(ICharacterScanner scanner) { -// int c; -// -// char[][] delimiters = scanner.getLegalLineDelimiters(); -// while ((c = scanner.read()) != ICharacterScanner.EOF) { -// if (c == '<') { -// // scanner.unread(); -// if (sequenceDetected(scanner, php2EndSequence, true)) { -// // ", php)); rules.add(new PHPMultiLineRule("", php)); -// rules.add(new HTMLPatternRule(html)); // "<", "