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.io.StringReader; import java.text.MessageFormat; import net.sourceforge.phpeclipse.actions.PHPStartApacheAction; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo; import net.sourceforge.phpdt.internal.compiler.parser.PHPSegmentWithChildren; import net.sourceforge.phpdt.internal.compiler.parser.PHPFunctionDeclaration; import net.sourceforge.phpdt.internal.compiler.parser.PHPClassDeclaration; import net.sourceforge.phpdt.internal.compiler.parser.PHPVarDeclaration; import net.sourceforge.phpdt.internal.compiler.parser.PHPReqIncDeclaration; /** * 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 class PHPParser extends PHPParserSuperclass { 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$ PHPOutlineInfo outlineInfo; private static int errorLevel = ERROR; private static String errorMessage; public PHPParser() { } public void setFileToParse(IFile fileToParse) { this.fileToParse = fileToParse; } public PHPParser(IFile fileToParse) { this(new StringReader("")); this.fileToParse = fileToParse; } public void phpParserTester(String strEval) throws CoreException, ParseException { PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING); StringReader stream = new StringReader(strEval); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); } ReInit(new StringReader(strEval)); phpTest(); } public void htmlParserTester(String strEval) throws CoreException, ParseException { StringReader stream = new StringReader(strEval); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); } ReInit(stream); phpFile(); } public PHPOutlineInfo parseInfo(Object parent, String s) { outlineInfo = new PHPOutlineInfo(parent); currentSegment = outlineInfo.getDeclarations(); StringReader stream = new StringReader(s); if (jj_input_stream == null) { jj_input_stream = new SimpleCharStream(stream, 1, 1); } ReInit(stream); 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"; } setMarker(e); errorMessage = null; } /** * Create marker for the parse error */ private static void setMarker(ParseException e) { try { setMarker(fileToParse, errorMessage, jj_input_stream.tokenBegin, jj_input_stream.tokenBegin + e.currentToken.image.length(), errorLevel, "Line " + e.currentToken.beginLine); } catch (CoreException e2) { PHPeclipsePlugin.log(e2); } } /** * Create markers according to the external parser output */ private static void createMarkers(String output, IFile file) throws CoreException { // delete all markers file.deleteMarkers(IMarker.PROBLEM, false, 0); int indx = 0; int brIndx = 0; boolean flag = true; while ((brIndx = output.indexOf("
", 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(String output, IFile file, int indx, 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 void parse(String s) throws CoreException { ReInit(new StringReader(s)); 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(IFile file) { IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore(); String filename = file.getLocation().toString(); String[] arguments = { filename }; MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF)); String command = form.format(arguments); String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: "); try { // parse the buffer to find the errors and warnings createMarkers(parserResult, file); } catch (CoreException e) { PHPeclipsePlugin.log(e); } } public void parse() throws ParseException { phpFile(); } } PARSER_END(PHPParser) TOKEN : { : PHPPARSING } TOKEN : { "> : DEFAULT } SKIP : { < ~[] > } /* WHITE SPACE */ SKIP : { " " | "\t" | "\n" | "\r" | "\f" } /* COMMENTS */ MORE : { "//" : IN_SINGLE_LINE_COMMENT | <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT | "/*" : IN_MULTI_LINE_COMMENT } SPECIAL_TOKEN : { " > : PHPPARSING } SPECIAL_TOKEN : { : PHPPARSING } SPECIAL_TOKEN : { : PHPPARSING } MORE : { < ~[] > } /* KEYWORDS */ TOKEN : { | | | | | | } /* LANGUAGE CONSTRUCT */ TOKEN : { | | | | | | | | "> | | "> } /* RESERVED WORDS AND LITERALS */ TOKEN : { < BREAK: "break" > | < CASE: "case" > | < CONST: "const" > | < CONTINUE: "continue" > | < _DEFAULT: "default" > | < DO: "do" > | < EXTENDS: "extends" > | < FALSE: "false" > | < FOR: "for" > | < GOTO: "goto" > | < NEW: "new" > | < NULL: "null" > | < RETURN: "return" > | < SUPER: "super" > | < SWITCH: "switch" > | < THIS: "this" > | < TRUE: "true" > | < WHILE: "while" > | < ENDWHILE : "endwhile" > } /* 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 : { < LPAREN: "(" > | < RPAREN: ")" > | < LBRACE: "{" > | < RBRACE: "}" > | < LBRACKET: "[" > | < RBRACKET: "]" > | < SEMICOLON: ";" > | < COMMA: "," > | < DOT: "." > } /* OPERATORS */ TOKEN : { | | " > | | | | | | =" > | | | | | | | | | | | | | | >" > | >>" > | | >=" > | | | } catch (ParseException e) { errorMessage = "'var', 'function' or '}' expected"; errorLevel = ERROR; throw e; } } void ClassBodyDeclaration() : {} { MethodDeclaration() | FieldDeclaration() } void FieldDeclaration() : { PHPVarDeclaration variableDeclaration; } { variableDeclaration = VariableDeclarator() {currentSegment.add(variableDeclaration);} ( variableDeclaration = VariableDeclarator() {currentSegment.add(variableDeclaration);} )* try { } catch (ParseException e) { errorMessage = "';' expected after variable declaration"; errorLevel = ERROR; throw e; } } PHPVarDeclaration VariableDeclarator() : { String varName; String varValue = null; int pos = jj_input_stream.bufpos; } { varName = VariableDeclaratorId() [ try { varValue = VariableInitializer() } catch (ParseException e) { errorMessage = "Literal expression expected in variable initializer"; errorLevel = ERROR; throw e; } ] { if (varValue == null) { return new PHPVarDeclaration(currentSegment,varName,pos); } return new PHPVarDeclaration(currentSegment,varName,pos,varValue); } } String VariableDeclaratorId() : { String expr; 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; throw e; } } String Variable(): { String expr = null; Token token; } { token = [ expr = Expression() ] { if (expr == null) { return token.image; } return token + "{" + expr + "}"; } | expr = VariableName() {return "$" + expr;} } String VariableName(): { String expr = null; Token token; } { expr = Expression() {return "{"+expr+"}";} | token = [ expr = Expression() ] { if (expr == null) { return token.image; } return token + "{" + expr + "}"; } | expr = VariableName() {return "$" + expr;} | token = [expr = VariableName()] { if (expr == null) { return token.image; } return token.image + expr; } } String VariableInitializer() : { String expr; 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; StringBuffer buff = new StringBuffer(); } { expr = Expression() {buff.append(expr);} [ expr = Expression() {buff.append("=>").append(expr);}] {return buff.toString();} } String ArrayInitializer() : { String expr = null; StringBuffer buff = new StringBuffer("("); } { [ expr = ArrayVariable() {buff.append(expr);} ( LOOKAHEAD(2) expr = ArrayVariable() {buff.append(",").append(expr);} )* ] { buff.append(")"); return buff.toString(); } } void MethodDeclaration() : { PHPFunctionDeclaration functionDeclaration; } { functionDeclaration = MethodDeclarator() { currentSegment.add(functionDeclaration); currentSegment = functionDeclaration; } Block() { currentSegment = (PHPSegmentWithChildren) currentSegment.getParent(); } } PHPFunctionDeclaration MethodDeclarator() : { Token identifier; StringBuffer methodDeclaration = new StringBuffer(); String formalParameters; int pos = jj_input_stream.bufpos; } { [ {methodDeclaration.append("&");} ] identifier = {methodDeclaration.append(identifier);} formalParameters = FormalParameters() { methodDeclaration.append(formalParameters); return new PHPFunctionDeclaration(currentSegment,methodDeclaration.toString(),pos); } } String FormalParameters() : { String expr; final StringBuffer buff = new StringBuffer("("); } { try { } catch (ParseException e) { errorMessage = "Formal parameter expected after function identifier"; errorLevel = ERROR; jj_consume_token(token.kind); } [ expr = FormalParameter() {buff.append(expr);} ( expr = FormalParameter() {buff.append(",").append(expr);} )* ] try { } catch (ParseException e) { errorMessage = "')' expected"; errorLevel = ERROR; throw e; } { buff.append(")"); return buff.toString(); } } String FormalParameter() : { PHPVarDeclaration variableDeclaration; StringBuffer buff = new StringBuffer(); } { [ {buff.append("&");}] variableDeclaration = VariableDeclarator() { buff.append(variableDeclaration.toString()); return buff.toString(); } } String Type() : {} { {return "string";} | {return "bool";} | {return "boolean";} | {return "real";} | {return "double";} | {return "float";} | {return "int";} | {return "integer";} } String Expression() : { String expr; String assignOperator = null; String expr2 = null; } { expr = PrintExpression() {return expr;} | expr = ConditionalExpression() [ assignOperator = AssignmentOperator() try { expr2 = Expression() } catch (ParseException e) { errorMessage = "expression expected"; errorLevel = ERROR; throw e; } ] { if (expr2 == null) { return expr; } else { return expr + assignOperator + expr2; } } } String AssignmentOperator() : {} { {return "=";} | {return "*=";} | {return "/=";} | {return "%=";} | {return "+=";} | {return "-=";} | {return "<<=";} | {return ">>=";} | {return "&=";} | {return "|=";} | {return "|=";} | {return ".=";} | {return "~=";} } String ConditionalExpression() : { 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; String expr2 = null; StringBuffer buff = new StringBuffer(); } { expr = ConditionalAndExpression() { buff.append(expr); } ( (operator = | operator = <_ORL>) expr2 = ConditionalAndExpression() { buff.append(operator.image); buff.append(expr2); } )* { return buff.toString(); } } String ConditionalAndExpression() : { String expr; Token operator; String expr2 = null; StringBuffer buff = new StringBuffer(); } { expr = ConcatExpression() { buff.append(expr); } ( (operator = | operator = <_ANDL>) expr2 = ConcatExpression() { buff.append(operator.image); buff.append(expr2); } )* { return buff.toString(); } } String ConcatExpression() : { String expr; String expr2 = null; StringBuffer buff = new StringBuffer(); } { expr = InclusiveOrExpression() { buff.append(expr); } ( expr2 = InclusiveOrExpression() { buff.append("."); buff.append(expr2); } )* { return buff.toString(); } } String InclusiveOrExpression() : { String expr; String expr2 = null; StringBuffer buff = new StringBuffer(); } { expr = ExclusiveOrExpression() { buff.append(expr); } ( expr2 = ExclusiveOrExpression() { buff.append("|"); buff.append(expr2); } )* { return buff.toString(); } } String ExclusiveOrExpression() : { String expr; String expr2 = null; StringBuffer buff = new StringBuffer(); } { expr = AndExpression() { buff.append(expr); } ( expr2 = AndExpression() { buff.append("^"); buff.append(expr2); } )* { return buff.toString(); } } String AndExpression() : { String expr; String expr2 = null; StringBuffer buff = new StringBuffer(); } { expr = EqualityExpression() { buff.append(expr); } ( expr2 = EqualityExpression() { buff.append("&"); buff.append(expr2); } )* { return buff.toString(); } } String EqualityExpression() : { String expr; Token operator; String expr2; StringBuffer buff = new StringBuffer(); } { expr = RelationalExpression() {buff.append(expr);} ( ( operator = | operator = | operator = | operator = ) expr2 = RelationalExpression() { buff.append(operator.image); buff.append(expr2); } )* {return buff.toString();} } String RelationalExpression() : { String expr; Token operator; String expr2; StringBuffer buff = new StringBuffer(); } { expr = ShiftExpression() {buff.append(expr);} ( ( operator = | operator = | operator = | operator = ) expr2 = ShiftExpression() { buff.append(operator.image); buff.append(expr2); } )* {return buff.toString();} } String ShiftExpression() : { String expr; Token operator; String expr2; StringBuffer buff = new StringBuffer(); } { expr = AdditiveExpression() {buff.append(expr);} ( (operator = | operator = | operator = ) expr2 = AdditiveExpression() { buff.append(operator.image); buff.append(expr2); } )* {return buff.toString();} } String AdditiveExpression() : { String expr; Token operator; String expr2; StringBuffer buff = new StringBuffer(); } { expr = MultiplicativeExpression() {buff.append(expr);} ( ( operator = | operator = ) expr2 = MultiplicativeExpression() { buff.append(operator.image); buff.append(expr2); } )* {return buff.toString();} } String MultiplicativeExpression() : { String expr, expr2; Token operator; final StringBuffer buff = new StringBuffer();} { expr = UnaryExpression() {buff.append(expr);} ( ( operator = | operator = | operator = ) expr2 = UnaryExpression() { buff.append(operator.image); buff.append(expr2); } )* {return buff.toString();} } /** * An unary expression starting with @, & or nothing */ String UnaryExpression() : { String expr; 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() : { String expr; Token token; } { ( token = | token = ) expr = UnaryExpression() { return token.image + expr; } | expr = PreIncrementExpression() {return expr;} | expr = PreDecrementExpression() {return expr;} | expr = UnaryExpressionNotPlusMinus() {return expr;} } String PreIncrementExpression() : { String expr; } { expr = PrimaryExpression() {return "++"+expr;} } String PreDecrementExpression() : { String expr; } { expr = PrimaryExpression() {return "--"+expr;} } String UnaryExpressionNotPlusMinus() : { String expr; } { expr = UnaryExpression() {return "!" + expr;} | LOOKAHEAD( Type() ) expr = CastExpression() {return expr;} | expr = PostfixExpression() {return expr;} | expr = Literal() {return expr;} | expr = Expression() {return "("+expr+")";} } String CastExpression() : { String type; String expr; } { type = Type() expr = UnaryExpression() {return "(" + type + ")" + expr;} } String PostfixExpression() : { String expr; Token operator = null; } { expr = PrimaryExpression() [ operator = | operator = ] { if (operator == null) { return expr; } return expr + operator.image; } } String PrimaryExpression() : { 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() : { String expr; } { expr = ArrayInitializer() {return "array" + expr;} } String PrimaryPrefix() : { String expr; Token token = null; } { token = {return token.image;} | expr = ClassIdentifier() { return "new " + expr; } | expr = VariableDeclaratorId() {return expr;} } String ClassIdentifier(): { String expr; Token token; } { token = {return token.image;} | expr = VariableDeclaratorId() {return expr;} } String PrimarySuffix() : { String expr; } { expr = Arguments() {return expr;} | expr = VariableSuffix() {return expr;} } String VariableSuffix() : { String expr = null; } { expr = VariableName() {return "->" + expr;} | [ expr = Expression() ] try { } catch (ParseException e) { errorMessage = "']' expected"; errorLevel = ERROR; throw e; } { if(expr == null) { return "[]"; } return "[" + expr + "]"; } } String Literal() : { String expr; Token token; } { token = {return token.image;} | token = {return token.image;} | token = {return token.image;} | expr = BooleanLiteral() {return expr;} | expr = NullLiteral() {return expr;} } String BooleanLiteral() : {} { {return "true";} | {return "false";} } String NullLiteral() : {} { {return "null";} } String Arguments() : { String expr = null; } { [ expr = ArgumentList() ] try { } catch (ParseException e) { errorMessage = "')' expected to close the argument list"; errorLevel = ERROR; throw e; } { if (expr == null) { return "()"; } return "(" + expr + ")"; } } String ArgumentList() : { String expr; StringBuffer buff = new StringBuffer(); } { expr = Expression() {buff.append(expr);} ( try { expr = Expression() } catch (ParseException e) { errorMessage = "expression expected after a comma in argument list"; errorLevel = ERROR; throw e; } { buff.append(",").append("expr"); } )* {return buff.toString();} } /* * Statement syntax follows. */ void Statement() : {} { LOOKAHEAD(2) Expression() try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected"; errorLevel = ERROR; throw e; } | LOOKAHEAD(2) LabeledStatement() | Block() | EmptyStatement() | StatementExpression() try { } catch (ParseException e) { errorMessage = "';' expected after expression"; errorLevel = ERROR; throw e; } | SwitchStatement() | IfStatement() | WhileStatement() | DoStatement() | ForStatement() | BreakStatement() | ContinueStatement() | ReturnStatement() | EchoStatement() | [] IncludeStatement() | StaticStatement() | GlobalStatement() } void IncludeStatement() : { String expr; int pos = jj_input_stream.bufpos; } { expr = Expression() {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require",pos,expr));} try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected"; errorLevel = ERROR; throw e; } | expr = Expression() {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require_once",pos,expr));} try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected"; errorLevel = ERROR; throw e; } | expr = Expression() {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include",pos,expr));} try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected"; errorLevel = ERROR; throw e; } | expr = Expression() {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include_once",pos,expr));} try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected"; errorLevel = ERROR; throw e; } } String PrintExpression() : { StringBuffer buff = new StringBuffer("print "); String expr; } { expr = Expression() { buff.append(expr); return buff.toString(); } } void EchoStatement() : {} { Expression() ( Expression())* try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected after 'echo' statement"; errorLevel = ERROR; throw e; } } void GlobalStatement() : {} { VariableDeclaratorId() ( VariableDeclaratorId())* try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected"; errorLevel = ERROR; throw e; } } void StaticStatement() : {} { VariableDeclarator() ( VariableDeclarator())* try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected"; errorLevel = ERROR; throw e; } } void LabeledStatement() : {} { Statement() } void Block() : {} { try { } catch (ParseException e) { errorMessage = "'{' expected"; errorLevel = ERROR; throw e; } ( BlockStatement() )* } void BlockStatement() : {} { Statement() | ClassDeclaration() | MethodDeclaration() } void LocalVariableDeclaration() : {} { VariableDeclarator() ( VariableDeclarator() )* } void EmptyStatement() : {} { } void StatementExpression() : {} { PreIncrementExpression() | PreDecrementExpression() | PrimaryExpression() [ | | AssignmentOperator() Expression() ] } void SwitchStatement() : {} { Expression() ( SwitchLabel() ( BlockStatement() )* )* } void SwitchLabel() : {} { Expression() | <_DEFAULT> } void IfStatement() : /* * The disambiguating algorithm of JavaCC automatically binds dangling * else's to the innermost if statement. The LOOKAHEAD specification * is to tell JavaCC that we know what we are doing. */ {} { Condition("if") Statement() ( LOOKAHEAD(1) ElseIfStatement() )* [ LOOKAHEAD(1) Statement() ] } void Condition(String keyword) : {} { try { } catch (ParseException e) { errorMessage = "'(' expected after " + keyword + " keyword"; errorLevel = ERROR; throw e; } Expression() try { } catch (ParseException e) { errorMessage = "')' expected after " + keyword + " keyword"; errorLevel = ERROR; throw e; } } void ElseIfStatement() : {} { Condition("elseif") Statement() } void WhileStatement() : {} { Condition("while") WhileStatement0() } void WhileStatement0() : {} { (Statement())* try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected"; errorLevel = ERROR; throw e; } | Statement() } void DoStatement() : {} { Statement() Condition("while") try { ( | "?>") } catch (ParseException e) { errorMessage = "';' expected"; errorLevel = ERROR; throw e; } } void ForStatement() : {} { [ ForInit() ] [ Expression() ] [ ForUpdate() ] Statement() } void ForInit() : {} { LOOKAHEAD(LocalVariableDeclaration()) LocalVariableDeclaration() | StatementExpressionList() } void StatementExpressionList() : {} { StatementExpression() ( StatementExpression() )* } void ForUpdate() : {} { StatementExpressionList() } void BreakStatement() : {} { [ ] } void ContinueStatement() : {} { [ ] } void ReturnStatement() : {} { [ Expression() ] }