options { LOOKAHEAD = 1; CHOICE_AMBIGUITY_CHECK = 2; OTHER_AMBIGUITY_CHECK = 1; STATIC = true; DEBUG_PARSER = false; DEBUG_LOOKAHEAD = false; DEBUG_TOKEN_MANAGER = false; OPTIMIZE_TOKEN_MANAGER = false; ERROR_REPORTING = true; JAVA_UNICODE_ESCAPE = false; UNICODE_INPUT = false; IGNORE_CASE = true; USER_TOKEN_MANAGER = false; USER_CHAR_STREAM = false; BUILD_PARSER = true; BUILD_TOKEN_MANAGER = true; SANITY_CHECK = true; FORCE_LA_CHECK = false; } PARSER_BEGIN(PHPParser) package test; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.ui.texteditor.MarkerUtilities; import org.eclipse.jface.preference.IPreferenceStore; import java.util.Hashtable; import java.util.Enumeration; import java.io.StringReader; import java.io.*; import java.text.MessageFormat; import net.sourceforge.phpeclipse.actions.PHPStartApacheAction; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpdt.internal.compiler.parser.*; import net.sourceforge.phpdt.internal.compiler.ast.*; /** * A new php parser. * This php parser is inspired by the Java 1.2 grammar example * given with JavaCC. You can get JavaCC at http://www.webgain.com * You can test the parser with the PHPParserTestCase2.java * @author Matthieu Casanova */ public final class PHPParser extends PHPParserSuperclass { /** The file that is parsed. */ private static IFile fileToParse; /** The current segment. */ private static PHPSegmentWithChildren currentSegment; private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$ private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$ static PHPOutlineInfo outlineInfo; private static PHPFunctionDeclaration currentFunction; private static boolean assigning; /** The error level of the current ParseException. */ private static int errorLevel = ERROR; /** The message of the current ParseException. If it's null it's because the parse exception wasn't handled */ private static String errorMessage; private static int errorStart = -1; private static int errorEnd = -1; //ast stack private final static int AstStackIncrement = 100; /** The stack of node. */ private static AstNode[] astStack; /** The cursor in expression stack. */ private static int expressionPtr; public final void setFileToParse(final IFile fileToParse) { this.fileToParse = fileToParse; } public PHPParser() { } public PHPParser(final IFile fileToParse) { this(new StringReader("")); this.fileToParse = fileToParse; } public static final void phpParserTester(final String strEval) throws CoreException, ParseException { PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING); final StringReader stream = new StringReader(strEval); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); } ReInit(new StringReader(strEval)); astStack = new AstNode[AstStackIncrement]; phpTest(); } public static final void htmlParserTester(final File fileName) throws CoreException, ParseException { try { final Reader stream = new FileReader(fileName); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); } ReInit(stream); astStack = new AstNode[AstStackIncrement]; phpFile(); } catch (FileNotFoundException e) { e.printStackTrace(); //To change body of catch statement use Options | File Templates. } } public static final void htmlParserTester(final String strEval) throws CoreException, ParseException { final StringReader stream = new StringReader(strEval); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); } ReInit(stream); astStack = new AstNode[AstStackIncrement]; phpFile(); } public final PHPOutlineInfo parseInfo(final Object parent, final String s) { outlineInfo = new PHPOutlineInfo(parent); currentSegment = outlineInfo.getDeclarations(); final StringReader stream = new StringReader(s); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); } ReInit(stream); astStack = new AstNode[AstStackIncrement]; try { parse(); } catch (ParseException e) { processParseException(e); } return outlineInfo; } /** * This method will process the parse exception. * If the error message is null, the parse exception wasn't catched and a trace is written in the log * @param e the ParseException */ private static void processParseException(final ParseException e) { if (errorMessage == null) { PHPeclipsePlugin.log(e); errorMessage = "this exception wasn't handled by the parser please tell us how to reproduce it"; errorStart = jj_input_stream.getPosition(); errorEnd = errorStart + 1; } setMarker(e); errorMessage = null; } /** * Create marker for the parse error * @param e the ParseException */ private static void setMarker(final ParseException e) { try { if (errorStart == -1) { setMarker(fileToParse, errorMessage, jj_input_stream.tokenBegin, jj_input_stream.tokenBegin + e.currentToken.image.length(), errorLevel, "Line " + e.currentToken.beginLine); } else { setMarker(fileToParse, errorMessage, errorStart, errorEnd, errorLevel, "Line " + e.currentToken.beginLine); errorStart = -1; errorEnd = -1; } } catch (CoreException e2) { PHPeclipsePlugin.log(e2); } } /** * Create markers according to the external parser output */ private static void createMarkers(final String output, final IFile file) throws CoreException { // delete all markers file.deleteMarkers(IMarker.PROBLEM, false, 0); int indx = 0; int brIndx; boolean flag = true; while ((brIndx = output.indexOf("
", 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("
", indx)) != -1) { // older php error output (tested with 4.2.3) scanLine(output, file, indx, brIndx); indx = brIndx + 4; } } } private static void scanLine(final String output, final IFile file, final int indx, final int brIndx) throws CoreException { String current; 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 "); 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("", ""); current = current.replaceAll("", ""); 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); } } } public final void parse(final String s) throws CoreException { final StringReader stream = new StringReader(s); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); } ReInit(stream); astStack = new AstNode[AstStackIncrement]; try { parse(); } catch (ParseException e) { processParseException(e); } } /** * Call the php parse command ( php -l -f <filename> ) * and create markers according to the external parser output */ public static void phpExternalParse(final IFile file) { final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore(); final String filename = file.getLocation().toString(); final String[] arguments = { filename }; final MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF)); final String command = form.format(arguments); final String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: "); try { // parse the buffer to find the errors and warnings createMarkers(parserResult, file); } catch (CoreException e) { PHPeclipsePlugin.log(e); } } private static final void parse() throws ParseException { phpFile(); } } PARSER_END(PHPParser) TOKEN : { : PHPPARSING | : PHPPARSING | "> : DEFAULT } /* Skip any character if we are not in php mode */ SKIP : { < ~[] > } /* WHITE SPACE */ SKIP : { " " | "\t" | "\n" | "\r" | "\f" } /* COMMENTS */ SPECIAL_TOKEN : { "//" : IN_SINGLE_LINE_COMMENT | "#" : IN_SINGLE_LINE_COMMENT | <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT | "/*" : IN_MULTI_LINE_COMMENT } SPECIAL_TOKEN : { : PHPPARSING } SPECIAL_TOKEN : { " > : DEFAULT } SPECIAL_TOKEN : { : PHPPARSING } SPECIAL_TOKEN : { : PHPPARSING } MORE : { < ~[] > } /* KEYWORDS */ TOKEN : { | | | | | | | | } /* LANGUAGE CONSTRUCT */ TOKEN : { | | | | | | | | "> | | "> } /* RESERVED WORDS AND LITERALS */ TOKEN : { | | | <_DEFAULT : "default"> | | | | | | | | | | | | | | | | | | | } /* TYPES */ TOKEN : { | | | | | | | | } TOKEN : { <_ORL : "OR"> | <_ANDL : "AND"> } /* LITERALS */ TOKEN : { < INTEGER_LITERAL: (["l","L"])? | (["l","L"])? | (["l","L"])? > | < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* > | < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ > | < #OCTAL_LITERAL: "0" (["0"-"7"])* > | < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* ()? (["f","F","d","D"])? | "." (["0"-"9"])+ ()? (["f","F","d","D"])? | (["0"-"9"])+ (["f","F","d","D"])? | (["0"-"9"])+ ()? ["f","F","d","D"] > | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > | < STRING_LITERAL: ( | | )> | < STRING_1: "\"" ( ~["\"","{","}"] | "\\\"" | "\\" | "{" ~["\""] "}" )* "\"" > | < STRING_2: "'" ( ~["'"] | "\\'" )* "'" > | < STRING_3: "`" ( ~["`"] | "\\`" )* "`" > } /* IDENTIFIERS */ TOKEN : { < IDENTIFIER: (|) (||)* > | < #LETTER: ["a"-"z"] | ["A"-"Z"] > | < #DIGIT: ["0"-"9"] > | < #SPECIAL: "_" | ["\u007f"-"\u00ff"] > } /* SEPARATORS */ TOKEN : { | | | | | | | | } /* COMPARATOR */ TOKEN : { "> | | | ="> | "> | | } /* ASSIGNATION */ TOKEN : { | | | | | | | | | | | | | | | | | | | | >"> | >>"> | >="> } TOKEN : { < DOLLAR_ID: > } void phpTest() : {} { Php() } void phpFile() : {} { try { (PhpBlock())* } catch (TokenMgrError e) { PHPeclipsePlugin.log(e); errorStart = SimpleCharStream.getPosition(); errorEnd = errorStart + 1; errorMessage = e.getMessage(); errorLevel = ERROR; throw generateParseException(); } } /** * A php block is a * or * or */ void PhpBlock() : { final int start = jj_input_stream.getPosition(); } { phpEchoBlock() | [ | {try { setMarker(fileToParse, "You should use ' } catch (ParseException e) { errorMessage = "'?>' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } void phpEchoBlock() : {} { Expression() [ ] } void Php() : {} { (BlockStatement())* } void ClassDeclaration() : { final PHPClassDeclaration classDeclaration; final Token className; final int pos; } { try { {pos = jj_input_stream.getPosition();} className = } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } [ try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } ] { if (currentSegment != null) { classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos); currentSegment.add(classDeclaration); currentSegment = classDeclaration; } } ClassBody() { if (currentSegment != null) { currentSegment = (PHPSegmentWithChildren) currentSegment.getParent(); } } } void ClassBody() : {} { try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image + "', '{' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } ( ClassBodyDeclaration() )* try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', 'var', 'function' or '}' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } /** * A class can contain only methods and fields. */ void ClassBodyDeclaration() : {} { MethodDeclaration() | FieldDeclaration() } /** * A class field declaration : it's var VariableDeclarator() (, VariableDeclarator())*;. */ void FieldDeclaration() : { PHPVarDeclaration variableDeclaration; } { variableDeclaration = VariableDeclarator() { outlineInfo.addVariable(variableDeclaration.getVariable().getName()); if (currentSegment != null) { currentSegment.add(variableDeclaration); } } ( variableDeclaration = VariableDeclarator() { if (currentSegment != null) { currentSegment.add(variableDeclaration); } } )* try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected after variable declaration"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } PHPVarDeclaration VariableDeclarator() : { final String varName, varValue; final int pos = jj_input_stream.getPosition(); } { varName = VariableDeclaratorId() [ try { varValue = VariableInitializer() {return new PHPVarDeclaration(currentSegment,varName,pos,varValue);} } catch (ParseException e) { errorMessage = "Literal expression expected in variable initializer"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } ] {return new PHPVarDeclaration(currentSegment,varName,pos);} } String VariableDeclaratorId() : { String expr; final StringBuffer buff = new StringBuffer(); } { try { expr = Variable() {buff.append(expr);} ( LOOKAHEAD(2) expr = VariableSuffix() {buff.append(expr);} )* {return buff.toString();} } catch (ParseException e) { errorMessage = "'$' expected for variable identifier"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } String Variable(): { String expr = null; final Token token; } { token = [ expr = Expression() ] { if (expr == null && !assigning) { if (currentFunction != null) { PHPVarDeclaration var = currentFunction.getParameter(token.image.substring(1)); if (var != null) { var.getVariable().setUsed(true); } } return token.image.substring(1); } return token + "{" + expr + "}"; } | expr = VariableName() {return expr;} } String VariableName(): { String expr = null; final Token token; } { expr = Expression() {return "{"+expr+"}";} | token = [ expr = Expression() ] { if (expr == null) { if (currentFunction != null) { PHPVarDeclaration var = currentFunction.getParameter(token.image); if (var != null) { var.getVariable().setUsed(true); } } return token.image; } return token + "{" + expr + "}"; } | expr = VariableName() { if (currentFunction != null) { PHPVarDeclaration var = currentFunction.getParameter(expr); if (var != null) { var.getVariable().setUsed(true); } } return "$" + expr; } | token = { if (currentFunction != null) { PHPVarDeclaration var = currentFunction.getParameter(token.image.substring(1)); if (var != null) { var.getVariable().setUsed(true); } } return token.image + expr; } /*| pas besoin ? token = [expr = VariableName()] { if (expr == null) { return token.image; } return token.image + expr; }*/ } String VariableInitializer() : { final String expr; final Token token; } { expr = Literal() {return expr;} | (token = | token = ) {return "-" + token.image;} | (token = | token = ) {return "+" + token.image;} | expr = ArrayDeclarator() {return expr;} | token = {return token.image;} } String ArrayVariable() : { String expr; final StringBuffer buff = new StringBuffer(); } { expr = Expression() {buff.append(expr);} [ expr = Expression() {buff.append("=>").append(expr);}] {return buff.toString();} } String ArrayInitializer() : { String expr; final StringBuffer buff = new StringBuffer("("); } { [ expr = ArrayVariable() {buff.append(expr);} ( LOOKAHEAD(2) expr = ArrayVariable() {buff.append(",").append(expr);} )* ] [ {buff.append(",");}] { buff.append(")"); return buff.toString(); } } /** * A Method Declaration. * function MetodDeclarator() Block() */ void MethodDeclaration() : { final PHPFunctionDeclaration functionDeclaration; Token functionToken; } { functionToken = try { functionDeclaration = MethodDeclarator() {outlineInfo.addVariable(functionDeclaration.getName());} } catch (ParseException e) { if (errorMessage != null) { throw e; } errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } { if (currentSegment != null) { currentSegment.add(functionDeclaration); currentSegment = functionDeclaration; } currentFunction = functionDeclaration; } Block() { Hashtable parameters = currentFunction.getParameters(); Enumeration vars = parameters.elements(); while (vars.hasMoreElements()) { PHPVarDeclaration o = (PHPVarDeclaration) vars.nextElement(); if (!o.getVariable().isUsed()) { try { setMarker(fileToParse, "Parameter "+o.getVariable().getName()+" is never used in function", functionToken.beginLine, WARNING, "Line " + token.beginLine); } catch (CoreException e) { PHPeclipsePlugin.log(e); } } } currentFunction = null; if (currentSegment != null) { currentSegment = (PHPSegmentWithChildren) currentSegment.getParent(); } } } /** * A MethodDeclarator. * [&] IDENTIFIER(parameters ...). * @return a function description for the outline */ PHPFunctionDeclaration MethodDeclarator() : { final Token identifier; final StringBuffer methodDeclaration = new StringBuffer(); final Hashtable formalParameters; final int pos = jj_input_stream.getPosition(); } { [ {methodDeclaration.append("&");} ] identifier = formalParameters = FormalParameters() { methodDeclaration.append(identifier); return new PHPFunctionDeclaration(currentSegment,methodDeclaration.toString(),pos,formalParameters); } } /** * FormalParameters follows method identifier. * (FormalParameter()) */ Hashtable FormalParameters() : { String expr; final StringBuffer buff = new StringBuffer("("); PHPVarDeclaration var; final Hashtable parameters = new Hashtable(); } { try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected after function identifier"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } [ var = FormalParameter() {parameters.put(var.getVariable().getName(),var);} ( var = FormalParameter() {parameters.put(var.getVariable().getName(),var);} )* ] try { } catch (ParseException e) { errorMessage = "')' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } {return parameters;} } /** * A formal parameter. * $varname[=value] (,$varname[=value]) */ PHPVarDeclaration FormalParameter() : { final PHPVarDeclaration variableDeclaration; Token token = null; } { [token = ] variableDeclaration = VariableDeclarator() { if (token != null) { variableDeclaration.getVariable().setReference(true); } return variableDeclaration; } } String Type() : {} { {return "string";} | {return "bool";} | {return "boolean";} | {return "real";} | {return "double";} | {return "float";} | {return "int";} | {return "integer";} | {return "object";} } String Expression() : { final String expr; final String assignOperator; final String expr2; } { expr = PrintExpression() {return expr;} | expr = ListExpression() {return expr;} | LOOKAHEAD(varAssignation()) expr = varAssignation() {return expr;} | expr = ConditionalExpression() {return expr;} } /** * A Variable assignation. * varName (an assign operator) any expression */ String varAssignation() : { String varName,assignOperator,expr2; PHPVarDeclaration variable; final int pos = SimpleCharStream.getPosition(); } { varName = VariableDeclaratorId() assignOperator = AssignmentOperator() try { expr2 = Expression() } catch (ParseException e) { if (errorMessage != null) { throw e; } errorMessage = "expression expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } {return varName + assignOperator + expr2;} } String AssignmentOperator() : {} { {return "=";} | {return "*=";} | {return "/=";} | {return "%=";} | {return "+=";} | {return "-=";} | {return "<<=";} | {return ">>=";} | {return "&=";} | {return "|=";} | {return "|=";} | {return ".=";} | {return "~=";} } String ConditionalExpression() : { final String expr; String expr2 = null; String expr3 = null; } { expr = ConditionalOrExpression() [ expr2 = Expression() expr3 = ConditionalExpression() ] { if (expr3 == null) { return expr; } else { return expr + "?" + expr2 + ":" + expr3; } } } String ConditionalOrExpression() : { String expr; Token operator; final StringBuffer buff = new StringBuffer(); } { expr = ConditionalAndExpression() {buff.append(expr);} ( (operator = | operator = <_ORL>) expr = ConditionalAndExpression() { buff.append(operator.image); buff.append(expr); } )* { return buff.toString(); } } String ConditionalAndExpression() : { String expr; Token operator; final StringBuffer buff = new StringBuffer(); } { expr = ConcatExpression() {buff.append(expr);} ( (operator = | operator = <_ANDL>) expr = ConcatExpression() { buff.append(operator.image); buff.append(expr); } )* {return buff.toString();} } String ConcatExpression() : { String expr; final StringBuffer buff = new StringBuffer(); } { expr = InclusiveOrExpression() {buff.append(expr);} ( expr = InclusiveOrExpression() {buff.append(".").append(expr);} )* {return buff.toString();} } String InclusiveOrExpression() : { String expr; final StringBuffer buff = new StringBuffer(); } { expr = ExclusiveOrExpression() {buff.append(expr);} ( expr = ExclusiveOrExpression() {buff.append("|").append(expr);} )* {return buff.toString();} } String ExclusiveOrExpression() : { String expr; final StringBuffer buff = new StringBuffer(); } { expr = AndExpression() { buff.append(expr); } ( expr = AndExpression() { buff.append("^"); buff.append(expr); } )* { return buff.toString(); } } String AndExpression() : { String expr; final StringBuffer buff = new StringBuffer(); } { expr = EqualityExpression() { buff.append(expr); } ( expr = EqualityExpression() { buff.append("&").append(expr); } )* {return buff.toString();} } String EqualityExpression() : { String expr; Token operator; final StringBuffer buff = new StringBuffer(); } { expr = RelationalExpression() {buff.append(expr);} ( ( operator = | operator = | operator = | operator = | operator = ) try { expr = RelationalExpression() } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected after '"+operator.image+"'"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } { buff.append(operator.image); buff.append(expr); } )* {return buff.toString();} } String RelationalExpression() : { String expr; Token operator; final StringBuffer buff = new StringBuffer(); } { expr = ShiftExpression() {buff.append(expr);} ( ( operator = | operator = | operator = | operator = ) expr = ShiftExpression() {buff.append(operator.image).append(expr);} )* {return buff.toString();} } String ShiftExpression() : { String expr; Token operator; final StringBuffer buff = new StringBuffer(); } { expr = AdditiveExpression() {buff.append(expr);} ( (operator = | operator = | operator = ) expr = AdditiveExpression() { buff.append(operator.image); buff.append(expr); } )* {return buff.toString();} } String AdditiveExpression() : { String expr; Token operator; final StringBuffer buff = new StringBuffer(); } { expr = MultiplicativeExpression() {buff.append(expr);} ( ( operator = | operator = ) expr = MultiplicativeExpression() { buff.append(operator.image); buff.append(expr); } )* {return buff.toString();} } String MultiplicativeExpression() : { String expr; Token operator; final StringBuffer buff = new StringBuffer();} { try { expr = UnaryExpression() } catch (ParseException e) { errorMessage = "unexpected token '"+e.currentToken.next.image+"'"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } {buff.append(expr);} ( ( operator = | operator = | operator = ) expr = UnaryExpression() { buff.append(operator.image); buff.append(expr); } )* {return buff.toString();} } /** * An unary expression starting with @, & or nothing */ String UnaryExpression() : { final String expr; final Token token; final StringBuffer buff = new StringBuffer(); } { token = expr = UnaryExpressionNoPrefix() { if (token == null) { return expr; } return token.image + expr; } | ( {buff.append("@");})* expr = UnaryExpressionNoPrefix() {return buff.append(expr).toString();} } String UnaryExpressionNoPrefix() : { final String expr; final Token token; } { ( token = | token = ) expr = UnaryExpression() { return token.image + expr; } | expr = PreIncDecExpression() {return expr;} | expr = UnaryExpressionNotPlusMinus() {return expr;} } String PreIncDecExpression() : { final String expr; final Token token; } { (token = | token = ) expr = PrimaryExpression() {return token.image + expr;} } String UnaryExpressionNotPlusMinus() : { final String expr; } { expr = UnaryExpression() {return "!" + expr;} | LOOKAHEAD( (Type() | ) ) expr = CastExpression() {return expr;} | expr = PostfixExpression() {return expr;} | expr = Literal() {return expr;} | expr = Expression() try { } catch (ParseException e) { errorMessage = "')' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } {return "("+expr+")";} } String CastExpression() : { final String type, expr; } { (type = Type() | {type = "array";}) expr = UnaryExpression() {return "(" + type + ")" + expr;} } String PostfixExpression() : { final String expr; Token operator = null; } { expr = PrimaryExpression() [ operator = | operator = ] { if (operator == null) { return expr; } return expr + operator.image; } } String PrimaryExpression() : { final Token identifier; String expr; final StringBuffer buff = new StringBuffer(); } { LOOKAHEAD(2) identifier = expr = ClassIdentifier() {buff.append(identifier.image).append("::").append(expr);} ( expr = PrimarySuffix() {buff.append(expr);} )* {return buff.toString();} | expr = PrimaryPrefix() {buff.append(expr);} ( expr = PrimarySuffix() {buff.append(expr);} )* {return buff.toString();} | expr = ArrayDeclarator() {return "array" + expr;} } String ArrayDeclarator() : { final String expr; } { expr = ArrayInitializer() {return "array" + expr;} } String PrimaryPrefix() : { final String expr; final Token token; } { token = {return token.image;} | expr = ClassIdentifier() {return "new " + expr;} | expr = VariableDeclaratorId() {return expr;} } String classInstantiation() : { String expr; final StringBuffer buff = new StringBuffer("new "); } { expr = ClassIdentifier() {buff.append(expr);} [ expr = PrimaryExpression() {buff.append(expr);} ] {return buff.toString();} } String ClassIdentifier(): { final String expr; final Token token; } { token = {return token.image;} | expr = VariableDeclaratorId() {return expr;} } String PrimarySuffix() : { final String expr; } { expr = Arguments() {return expr;} | expr = VariableSuffix() {return expr;} } String VariableSuffix() : { String expr = null; } { try { expr = VariableName() } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function call or field access expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } {return "->" + expr;} | [ expr = Expression() | expr = Type() ] //Not good try { } catch (ParseException e) { errorMessage = "']' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } { if(expr == null) { return "[]"; } return "[" + expr + "]"; } } String Literal() : { final String expr; final Token token; } { token = {return token.image;} | token = {return token.image;} | token = {return token.image;} | expr = BooleanLiteral() {return expr;} | {return "null";} } String BooleanLiteral() : {} { {return "true";} | {return "false";} } String Arguments() : { String expr = null; } { [ expr = ArgumentList() ] try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected to close the argument list"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } { if (expr == null) { return "()"; } return "(" + expr + ")"; } } String ArgumentList() : { String expr; final StringBuffer buff = new StringBuffer(); } { expr = Expression() {buff.append(expr);} ( try { expr = Expression() } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. An expression expected after a comma in argument list"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } {buff.append(",").append(expr);} )* {return buff.toString();} } /** * A Statement without break. */ void StatementNoBreak() : {} { LOOKAHEAD(2) Expression() try { } catch (ParseException e) { if (e.currentToken.next.kind != 4) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } | LOOKAHEAD(2) LabeledStatement() | Block() | EmptyStatement() | StatementExpression() try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } | SwitchStatement() | IfStatement() | WhileStatement() | DoStatement() | ForStatement() | ForeachStatement() | ContinueStatement() | ReturnStatement() | EchoStatement() | [] IncludeStatement() | StaticStatement() | GlobalStatement() } /** * A Normal statement. */ void Statement() : {} { StatementNoBreak() | BreakStatement() } /** * An html block inside a php syntax. */ void htmlBlock() : {} { (phpEchoBlock())* try { ( | ) } catch (ParseException e) { errorMessage = "End of file unexpected, ' | token = | token = | token = ) try { expr = Expression() } catch (ParseException e) { if (errorMessage != null) { throw e; } errorMessage = "unexpected token '"+ e.currentToken.next.image+"', expression expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } { if (currentSegment != null) { currentSegment.add(new PHPReqIncDeclaration(currentSegment, token.image,pos,expr)); } } try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } String PrintExpression() : { final String expr; } { expr = Expression() {return "print " + expr;} } String ListExpression() : { final StringBuffer buff = new StringBuffer("list("); String expr; } { try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } [ expr = VariableDeclaratorId() {buff.append(expr);} ] ( try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } expr = VariableDeclaratorId() {buff.append(",").append(expr);} )* {buff.append(")");} try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } [ expr = Expression() {buff.append("(").append(expr);}] {return buff.toString();} } /** * An echo statement. * echo anyexpression (, otherexpression)* */ void EchoStatement() : {} { Expression() ( Expression())* try { } catch (ParseException e) { if (e.currentToken.next.kind != 4) { errorMessage = "';' expected after 'echo' statement"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } } void GlobalStatement() : { final int pos = jj_input_stream.getPosition(); String expr; } { expr = VariableDeclaratorId() {if (currentSegment != null) { currentSegment.add(new PHPGlobalDeclaration(currentSegment, "global",pos,expr)); }} ( expr = VariableDeclaratorId() {if (currentSegment != null) { currentSegment.add(new PHPGlobalDeclaration(currentSegment, "global",pos,expr)); }} )* try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. a ';' was expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } void StaticStatement() : {} { VariableDeclarator() ( VariableDeclarator())* try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. a ';' was expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } void LabeledStatement() : {} { Statement() } void Block() : {} { try { } catch (ParseException e) { errorMessage = "'{' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } ( BlockStatement() | htmlBlock())* try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.image +"', '}' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } void BlockStatement() : {} { Statement() | ClassDeclaration() | MethodDeclaration() } /** * A Block statement that will not contain any 'break' */ void BlockStatementNoBreak() : {} { StatementNoBreak() | ClassDeclaration() | MethodDeclaration() } void LocalVariableDeclaration() : {} { LocalVariableDeclarator() ( LocalVariableDeclarator() )* } void LocalVariableDeclarator() : {} { VariableDeclaratorId() [ Expression() ] } void EmptyStatement() : {} { } void StatementExpression() : {} { PreIncDecExpression() | PrimaryExpression() [ | | AssignmentOperator() Expression() ] } void SwitchStatement() : { final int pos = jj_input_stream.getPosition(); } { try { } catch (ParseException e) { errorMessage = "'(' expected after 'switch'"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { Expression() } catch (ParseException e) { if (errorMessage != null) { throw e; } errorMessage = "expression expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { } catch (ParseException e) { errorMessage = "')' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } (switchStatementBrace() | switchStatementColon(pos, pos + 6)) } void switchStatementBrace() : {} { ( switchLabel0() )* try { } catch (ParseException e) { errorMessage = "'}' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } /** * A Switch statement with : ... endswitch; * @param start the begin offset of the switch * @param end the end offset of the switch */ void switchStatementColon(final int start, final int end) : {} { {try { setMarker(fileToParse, "Ugly syntax detected, you should switch () {...} instead of switch (): ... enswitch;", start, end, INFO, "Line " + token.beginLine); } catch (CoreException e) { PHPeclipsePlugin.log(e); }} (switchLabel0())* try { } catch (ParseException e) { errorMessage = "'endswitch' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { } catch (ParseException e) { errorMessage = "';' expected after 'endswitch' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } void switchLabel0() : { Token breakToken = null; final int line; } { line = SwitchLabel() ( BlockStatementNoBreak() | htmlBlock() )* [ breakToken = BreakStatement() ] { try { if (breakToken == null) { setMarker(fileToParse, "You should use put a 'break' at the end of your statement", line, INFO, "Line " + line); } } catch (CoreException e) { PHPeclipsePlugin.log(e); } } } Token BreakStatement() : { final Token token; } { token = [ Expression() ] try { } catch (ParseException e) { errorMessage = "';' expected after 'break' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } {return token;} } int SwitchLabel() : { final Token token; } { token = try { Expression() } catch (ParseException e) { if (errorMessage != null) throw e; errorMessage = "expression expected after 'case' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { } catch (ParseException e) { errorMessage = "':' expected after case expression"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } {return token.beginLine;} | token = <_DEFAULT> try { } catch (ParseException e) { errorMessage = "':' expected after 'default' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } {return token.beginLine;} } void IfStatement() : { final Token token; final int pos = jj_input_stream.getPosition(); } { token = Condition("if") IfStatement0(pos,pos+token.image.length()) } void Condition(final String keyword) : {} { try { } catch (ParseException e) { errorMessage = "'(' expected after " + keyword + " keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length(); errorEnd = errorStart +1; processParseException(e); } Expression() try { } catch (ParseException e) { errorMessage = "')' expected after " + keyword + " keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } void IfStatement0(final int start,final int end) : {} { (Statement() | htmlBlock())* (ElseIfStatementColon())* [ElseStatementColon()] {try { setMarker(fileToParse, "Ugly syntax detected, you should if () {...} instead of if (): ... endif;", start, end, INFO, "Line " + token.beginLine); } catch (CoreException e) { PHPeclipsePlugin.log(e); }} try { } catch (ParseException e) { errorMessage = "'endif' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { } catch (ParseException e) { errorMessage = "';' expected after 'endif' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } | (Statement() | htmlBlock()) ( LOOKAHEAD(1) ElseIfStatement() )* [ LOOKAHEAD(1) try { Statement() } catch (ParseException e) { if (errorMessage != null) { throw e; } errorMessage = "unexpected token '"+e.currentToken.next.image+"', a statement was expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } ] } void ElseIfStatementColon() : {} { Condition("elseif") (Statement() | htmlBlock())* } void ElseStatementColon() : {} { (Statement() | htmlBlock())* } void ElseIfStatement() : {} { Condition("elseif") Statement() } void WhileStatement() : { final Token token; final int pos = jj_input_stream.getPosition(); } { token = Condition("while") WhileStatement0(pos,pos + token.image.length()) } void WhileStatement0(final int start, final int end) : {} { (Statement())* {try { setMarker(fileToParse, "Ugly syntax detected, you should while () {...} instead of while (): ... endwhile;", start, end, INFO, "Line " + token.beginLine); } catch (CoreException e) { PHPeclipsePlugin.log(e); }} try { } catch (ParseException e) { errorMessage = "'endwhile' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { } catch (ParseException e) { errorMessage = "';' expected after 'endwhile' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } | Statement() } void DoStatement() : {} { Statement() Condition("while") try { } catch (ParseException e) { errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } void ForeachStatement() : {} { try { } catch (ParseException e) { errorMessage = "'(' expected after 'foreach' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { Variable() } catch (ParseException e) { errorMessage = "variable expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } ( VariableSuffix() )* try { } catch (ParseException e) { errorMessage = "'as' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { Variable() } catch (ParseException e) { errorMessage = "variable expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } [ Expression() ] try { } catch (ParseException e) { errorMessage = "')' expected after 'foreach' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { Statement() } catch (ParseException e) { if (errorMessage != null) throw e; errorMessage = "statement expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } void ForStatement() : { final Token token; final int pos = jj_input_stream.getPosition(); } { token = try { } catch (ParseException e) { errorMessage = "'(' expected after 'for' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } [ ForInit() ] [ Expression() ] [ StatementExpressionList() ] ( Statement() | (Statement())* { try { setMarker(fileToParse, "Ugly syntax detected, you should for () {...} instead of for (): ... endfor;", pos, pos+token.image.length(), INFO, "Line " + token.beginLine); } catch (CoreException e) { PHPeclipsePlugin.log(e); } } try { } catch (ParseException e) { errorMessage = "'endfor' expected"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } try { } catch (ParseException e) { errorMessage = "';' expected after 'endfor' keyword"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } ) } void ForInit() : {} { LOOKAHEAD(LocalVariableDeclaration()) LocalVariableDeclaration() | StatementExpressionList() } void StatementExpressionList() : {} { StatementExpression() ( StatementExpression() )* } void ContinueStatement() : {} { [ Expression() ] try { } catch (ParseException e) { errorMessage = "';' expected after 'continue' statement"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } } void ReturnStatement() : {} { [ Expression() ] try { } catch (ParseException e) { errorMessage = "';' expected after 'return' statement"; errorLevel = ERROR; errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1; errorEnd = jj_input_stream.getPosition() + 1; throw e; } }