blob: 95754d660c702ac60255719fec520598af194440 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.php.editor.parser;
import java.util.*;
import org.netbeans.modules.php.editor.parser.astnodes.*;
import org.openide.util.Pair;
parser code {:
private static short[][] getActionTable() {}
protected final static Integer IMPLICIT_PUBLIC = Integer.valueOf(BodyDeclaration.Modifier.IMPLICIT_PUBLIC);
protected final static Integer PUBLIC = Integer.valueOf(BodyDeclaration.Modifier.PUBLIC);
protected final static Integer PRIVATE = Integer.valueOf(BodyDeclaration.Modifier.PRIVATE);
protected final static Integer PROTECTED = Integer.valueOf(BodyDeclaration.Modifier.PROTECTED);
protected final static Integer ABSTRACT = Integer.valueOf(BodyDeclaration.Modifier.ABSTRACT);
protected final static Integer FINAL = Integer.valueOf(BodyDeclaration.Modifier.FINAL);
protected final static Integer STATIC = Integer.valueOf(BodyDeclaration.Modifier.STATIC);
private ErrorStrategy defaultStrategy = new DefaultErrorStrategy();;
private ErrorStrategy errorStrategy = defaultStrategy;
private ParserErrorHandler errorHandler = null;
private String fileName = null;
private int anonymousClassCounter = 0;
public void setErrorHandler (ParserErrorHandler handler) {
this.errorHandler = handler;
}
public ParserErrorHandler getErrorHandler () {
return this.errorHandler;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
assert fileName != null;
this.fileName = fileName;
}
public int incrementAndGetAnonymousClassCounter() {
anonymousClassCounter++;
return anonymousClassCounter;
}
public VariableBase createDispatch(VariableBase dispatcher, Pair<Expression, Boolean> pair, List dimensions) {
VariableBase dispatch = null;
Expression property = pair.first();
boolean isStatic = pair.second();
if (property instanceof DereferencedArrayAccess) {
DereferencedArrayAccess arrayAccess = (DereferencedArrayAccess) property;
dimensions = new LinkedList();
dimensions.add(arrayAccess.getDimension());
while (arrayAccess.getDispatcher() instanceof DereferencedArrayAccess) {
arrayAccess = (DereferencedArrayAccess) arrayAccess.getDispatcher();
((LinkedList) dimensions).addFirst(arrayAccess.getDimension());
}
property = arrayAccess.getDispatcher();
}
if (property instanceof Variable) {
if (isStatic) {
Variable variable = (Variable) property;
if (variable.isDollared() || variable instanceof ArrayAccess) {
dispatch = new StaticFieldAccess(dispatcher.getStartOffset(), property.getEndOffset(), dispatcher, (Variable) property);
} else {
Expression varName = variable.getName();
// it should always be identifier
String name = varName instanceof Identifier ? ((Identifier) varName).getName() : "";
dispatch = new StaticConstantAccess(dispatcher.getStartOffset(), property.getEndOffset(), dispatcher,
new Identifier(variable.getStartOffset(), variable.getEndOffset(), name));
}
} else {
dispatch = new FieldAccess(dispatcher.getStartOffset(), property.getEndOffset(), dispatcher, (Variable)property);
}
} else if (property instanceof FunctionInvocation) {
if (isStatic) {
dispatch = new StaticMethodInvocation(dispatcher.getStartOffset(), property.getEndOffset(), dispatcher, (FunctionInvocation)property);
} else {
dispatch = new MethodInvocation(dispatcher.getStartOffset(), property.getEndOffset(), dispatcher, (FunctionInvocation)property);
}
} else if (property instanceof ExpressionArrayAccess || property instanceof Identifier) {
dispatch = new StaticConstantAccess(dispatcher.getStartOffset(), property.getEndOffset(), dispatcher, property);
} else {
throw new IllegalArgumentException("Unexpected class: " + property.getClass().getName());
}
if (dimensions != null) {
for (Object i : dimensions) {
ArrayDimension index = (ArrayDimension) i;
dispatch = new DereferencedArrayAccess(dispatch.getStartOffset(), index.getEndOffset(), dispatch, index);
}
}
return dispatch;
}
public VariableBase createDispatch(VariableBase dispatcher, VariableBase property, List dimensions) {
return createDispatch(dispatcher, Pair.of(property, false), null);
}
public VariableBase createDispatch(VariableBase dispatcher, VariableBase property) {
return createDispatch(dispatcher, property, null);
}
public VariableBase createDispatch(boolean isStatic, VariableBase var, Expression memberProperty, int memberPropertyleft, int memberPropertyright,
List<Expression> paramsList, int paramsListright, List propertyList, List aa) {
Expression firstVarProperty = null;
if (paramsList == null) {
firstVarProperty = memberProperty;
} else {
FunctionName functionName = new FunctionName(memberPropertyleft, memberPropertyright, memberProperty);
firstVarProperty = new FunctionInvocation(memberPropertyleft, paramsListright, functionName, paramsList);
}
// then get the aggregated list of properties ([->|::]...[->|::]...[->|::]...)
LinkedList list = (LinkedList) propertyList;
list.addFirst(Pair.of(firstVarProperty, isStatic));
// now create the dispatch(es) nodes
VariableBase dispatch = null;
VariableBase dispatcher = var;
List arrayDimensiones = aa;
Iterator listIt = list.iterator();
while (listIt.hasNext()) {
Pair<Expression, Boolean> property = (Pair<Expression, Boolean>) listIt.next();
dispatch = createDispatch(dispatcher, property, arrayDimensiones);
dispatcher = dispatch;
arrayDimensiones = new LinkedList();
}
return dispatch;
}
public Pair<Expression, Boolean> createDispatchProperty(boolean isStatic, Expression memberProperty, int memberPropertyleft, int memberPropertyright,
List<Expression> paramsList, int paramsListright, List aa) {
Expression result = null;
if (paramsList == null) {
result = memberProperty;
} else {
FunctionName functionName = new FunctionName(memberPropertyleft, memberPropertyright, memberProperty);
result = new FunctionInvocation(memberPropertyleft, paramsListright, functionName, paramsList);
}
if (result instanceof VariableBase) {
for (Object i : aa) {
ArrayDimension index = (ArrayDimension) i;
result = new DereferencedArrayAccess(result.getStartOffset(), index.getEndOffset(), (VariableBase) result, index);
}
}
return Pair.of(result, isStatic);
}
interface ErrorStrategy {
public boolean errorRecovery(boolean debug) throws Exception;
}
class DefaultErrorStrategy implements ErrorStrategy {
public boolean errorRecovery(boolean debug) throws Exception {
return ASTPHP5Parser.super.error_recovery(debug);
}
}
/**
* Attempt to recover from a syntax error. This returns false if recovery fails,
* true if it succeeds.
* @param debug should we produce debugging messages as we parse.
*/
protected boolean error_recovery(boolean debug) throws java.lang.Exception {
return errorStrategy.errorRecovery(debug);
}
/**
* Report a non fatal error (or warning). This method takes a message
* string and an additional object (to be used by specializations implemented in subclasses).
* The super class prints the message to System.err.
* @param message an error message.
* @param info an extra object reserved for use by specialized subclasses.
*/
public void report_error(String message, Object info) {
System.out.print("report_eror" + message);
}
/**
* This method is called when a syntax error has been detected and recovery is about to be invoked.
* The super class just emit a "Syntax error" error message.
* @param cur_token the current lookahead Symbol.
*/
public void syntax_error(java_cup.runtime.Symbol cur_token) {
java_cup.runtime.Symbol symbol = (java_cup.runtime.Symbol)stack.peek();
int state = symbol.parse_state;
short[] rowOfProbe = action_tab[state];
if (errorHandler != null) {
errorHandler.handleError(ParserErrorHandler.Type.SYNTAX_ERROR, rowOfProbe, cur_token, symbol);
}
}
/**
* Report a fatal error. This method takes a message string and an additional object
* (to be used by specializations implemented in subclasses).
* The super class reports the error then throws an exception.
* @param message an error message.
* @param info an extra object reserved for use by specialized subclasses.
*/
public void report_fatal_error(String message, Object info) throws Exception {
if (errorHandler != null) {
errorHandler.handleError(ParserErrorHandler.Type.FATAL_PARSER_ERROR, null, cur_token, null);
}
}
protected int error_sync_size() {
return 1;
}
:}
/* terminals */
terminal String T_EXIT;
terminal String T_IF;
terminal String T_LNUMBER;
terminal String T_DNUMBER;
terminal String T_STRING;
terminal String T_STRING_VARNAME;
terminal String T_VARIABLE;
terminal String T_NUM_STRING;
terminal T_INLINE_HTML;
terminal String T_ENCAPSED_AND_WHITESPACE;
terminal String T_CONSTANT_ENCAPSED_STRING;
terminal String T_ECHO;
terminal String T_DO;
terminal String T_WHILE;
terminal String T_ENDWHILE;
terminal String T_FOR;
terminal String T_ENDFOR;
terminal String T_FOREACH;
terminal String T_ENDFOREACH;
terminal String T_DECLARE;
terminal String T_ENDDECLARE;
terminal String T_INSTANCEOF;
terminal String T_CLONE;
terminal String T_AS;
terminal String T_SWITCH;
terminal String T_ENDSWITCH;
terminal String T_CASE;
terminal String T_DEFAULT;
terminal String T_BREAK;
terminal String T_CONTINUE;
terminal String T_GOTO;
terminal String T_FN;
terminal String T_FUNCTION;
terminal String T_CONST;
terminal String T_RETURN;
terminal String T_YIELD;
terminal T_YIELD_FROM;
terminal String T_TRY;
terminal String T_CATCH;
terminal String T_THROW;
terminal String T_FINALLY;
terminal String T_USE;
terminal String T_GLOBAL;
terminal String T_VAR;
terminal String T_UNSET;
terminal String T_ISSET;
terminal String T_EMPTY;
terminal T_HALT_COMPILER;
terminal String T_CLASS;
terminal String T_INTERFACE;
terminal String T_EXTENDS;
terminal String T_IMPLEMENTS;
terminal T_OBJECT_OPERATOR;
terminal T_DOUBLE_ARROW;
terminal String T_LIST;
terminal String T_ARRAY;
terminal String T_CALLABLE;
terminal String T_CLASS_C;
terminal String T_TRAIT_C;
terminal String T_METHOD_C;
terminal String T_FUNC_C;
terminal String T_LINE;
terminal String T_FILE;
terminal T_START_HEREDOC;
terminal T_END_HEREDOC;
terminal T_DOLLAR_OPEN_CURLY_BRACES;
terminal T_CURLY_OPEN_WITH_DOLAR;
terminal T_CURLY_OPEN;
terminal T_CURLY_CLOSE;
terminal T_PAAMAYIM_NEKUDOTAYIM;
terminal String T_NAMESPACE;
terminal String T_NS_C;
terminal String T_DIR;
terminal T_NS_SEPARATOR;
terminal String T_VAR_COMMENT;
terminal String T_DEFINE;
terminal String T_INCLUDE,T_INCLUDE_ONCE,T_EVAL,T_REQUIRE,T_REQUIRE_ONCE;
terminal T_COMMA;
terminal String T_LOGICAL_OR,T_LOGICAL_XOR,T_LOGICAL_AND,T_PRINT;
terminal T_EQUAL;
terminal T_PLUS_EQUAL,T_MINUS_EQUAL,T_MUL_EQUAL,T_DIV_EQUAL,T_CONCAT_EQUAL,T_MOD_EQUAL,T_AND_EQUAL,T_OR_EQUAL,T_XOR_EQUAL,T_SL_EQUAL,T_SR_EQUAL;
terminal T_QUESTION_MARK;
terminal T_SEMICOLON;
terminal T_BOOLEAN_OR, T_BOOLEAN_AND;
terminal T_OR;
terminal T_KOVA;
terminal T_REFERENCE;
terminal T_IS_EQUAL,T_IS_NOT_EQUAL,T_IS_IDENTICAL,T_IS_NOT_IDENTICAL;
terminal T_IS_SMALLER_OR_EQUAL,T_IS_GREATER_OR_EQUAL;
terminal T_SPACESHIP;
terminal T_RGREATER;
terminal T_LGREATER;
terminal T_SL,T_SR;
terminal T_PLUS;
terminal T_MINUS;
terminal T_TIMES;
terminal T_DIV;
terminal T_PRECENT;
terminal T_NOT;
terminal T_TILDA;
terminal T_NEKUDA;
terminal T_INC,T_DEC,T_INT_CAST,T_DOUBLE_CAST,T_STRING_CAST,T_ARRAY_CAST,T_OBJECT_CAST,T_BOOL_CAST,T_UNSET_CAST;
terminal T_AT;
terminal T_OPEN_RECT,T_CLOSE_RECT;
terminal String T_NEW;
terminal String T_ENDIF;
terminal String T_ELSEIF;
terminal String T_ELSE;
terminal String T_STATIC, T_ABSTRACT, T_FINAL, T_PRIVATE, T_PROTECTED, T_PUBLIC;
terminal T_OPEN_PARENTHESE,T_CLOSE_PARENTHESE;
terminal T_NEKUDOTAIM;
terminal T_DOLLAR;
terminal T_QUATE,T_BACKQUATE;
terminal T_START_NOWDOC, T_END_NOWDOC;
terminal String T_TRAIT;
terminal String T_INSTEADOF;
terminal T_POW;
terminal T_POW_EQUAL;
terminal T_ELLIPSIS;
terminal T_COALESCE;
terminal T_COALESCE_EQUAL;
/* Non terminals */
non terminal Program thestart;
non terminal List namespace_name;
non terminal NamespaceName namespace_name_access;
non terminal List group_namespace_parts;
non terminal List non_empty_group_namespace_parts;
non terminal SingleUseStatementPart group_namespace_part;
non terminal UseStatementPart use_declaration;
non terminal List use_declarations;
non terminal List top_statement_list;
non terminal Statement top_statement;
non terminal Statement statement;
non terminal List inner_statement_list;
non terminal Statement inner_statement;
non terminal Statement unticked_statement;
non terminal List unset_variables;
non terminal VariableBase unset_variable;
non terminal Expression use_filename;
non terminal Expression foreach_optional_arg;
non terminal Expression foreach_variable;
non terminal Statement for_statement;
non terminal Statement foreach_statement;
non terminal Statement declare_statement;
non terminal List[] declare_list;
non terminal Block switch_case_list;
non terminal List case_list;
non terminal case_separator;
non terminal Statement while_statement;
non terminal List[] elseif_list;
non terminal List[] new_elseif_list;
non terminal Statement else_single;
non terminal Statement new_else_single;
non terminal List parameter_list;
non terminal List lexical_vars;
non terminal List lexical_var_list;
non terminal List non_empty_parameter_list;
non terminal FormalParameter parameter;
non terminal List function_call_parameter_list;
non terminal List non_empty_function_call_parameter_list;
non terminal List global_var_list;
non terminal VariableBase global_var;
non terminal List static_var_list;
non terminal List class_statement_list;
non terminal Statement class_statement;
non terminal Boolean is_reference;
non terminal Boolean is_variadic;
non terminal List echo_expr_list;
non terminal List for_expr;
non terminal List non_empty_for_expr;
non terminal Expression expr_without_variable;
non terminal Expression expr_without_variable_and_class_instance;
non terminal Expression callable_expr;
non terminal VariableBase function_call;
non terminal Expression exit_expr;
non terminal List ctor_arguments;
non terminal Expression common_scalar;
non terminal Expression static_scalar;
non terminal Expression static_scalar_value;
non terminal Expression static_operation;
non terminal Expression scalar;
non terminal List static_array_pair_list;
non terminal possible_comma;
non terminal List non_empty_static_array_pair_list;
non terminal Expression expr;
non terminal Expression expr_with_yields;
non terminal Expression expr_with_yields_and_error;
non terminal Expression expr_without_class_instance;
non terminal Expression yield_expr;
non terminal Expression yield_from_expr;
non terminal ParenthesisExpression parenthesis_expr;
non terminal Variable reference_variable;
non terminal Variable variable_class_name;
non terminal Variable compound_variable;
non terminal Expression dim_offset;
non terminal ArrayDimension array_dimension;
non terminal ArrayDimension array_dimension_with_static_scalar_value;
non terminal List array_access_or_not;
non terminal Expression static_property;
non terminal VariableBase object_property;
non terminal VariableBase object_dim_list;
non terminal VariableBase variable_name;
non terminal Integer simple_indirect_reference;
non terminal List array_pair_list;
non terminal ArrayElement possible_array_pair;
non terminal ArrayElement array_pair;
non terminal List non_empty_array_pair_list;
non terminal List encaps_list;
non terminal VariableBase encaps_var;
non terminal Expression encaps_var_offset;
non terminal Expression internal_functions_in_yacc;
non terminal String string_st;
non terminal Integer interface_entry;
non terminal List interface_extends_list;
non terminal List use_traits;
non terminal Block use_traits_body;
non terminal List use_traits_body_statement_list;
non terminal Statement use_traits_body_statement;
non terminal Statement trait_conflict_resolution_declaration;
non terminal Statement trait_method_alias_declaration;
non terminal TraitMethodAliasDeclaration.Modifier traits_alias_modifier;
non terminal List trait_statement_list;
non terminal Statement trait_statement;
non terminal List interface_statement_list;
non terminal Statement interface_statement;
non terminal UseTraitStatementPart use_trait;
non terminal Quote heredoc;
non terminal VariableBase field_or_method_access;
non terminal Expression expression_array_access;
non terminal Expression constant_array_access;
non terminal Expression array_creation;
non terminal VariableBase array_creation_with_access;
non terminal ClassInstanceCreation anonymous_class;
non terminal VariableBase w_variable;
non terminal Expression class_name;
non terminal NamespaceName fully_qualified_class_name;
non terminal List class_variable_declaration;
non terminal Identifier reserved_non_modifiers_without_class;
non terminal Identifier semi_reserved_without_class;
non terminal Identifier identifier_without_class;
non terminal Identifier identifier;
non terminal List class_constant_declaration;
non terminal List constant_declaration;
non terminal Integer constant_modifiers;
non terminal Integer method_modifiers;
non terminal Block method_body;
non terminal List method_or_not;
non terminal List variable_properties;
non terminal FunctionDeclaration function_declaration_statement;
non terminal Statement class_declaration_statement;
non terminal VariableBase variable;
non terminal List additional_catches;
non terminal List non_empty_additional_catches;
non terminal CatchClause additional_catch;
non terminal List catch_class_names;
non terminal List additional_catch_class_names;
non terminal List non_empty_additional_catch_class_names;
non terminal Expression additional_catch_class_name;
non terminal FinallyClause additional_finally;
non terminal FunctionDeclaration unticked_function_declaration_statement;
non terminal Statement unticked_class_declaration_statement;
non terminal ClassDeclaration.Modifier class_entry_type;
non terminal Expression extends_from;
non terminal List implements_list;
non terminal List interface_list;
non terminal Expression optional_class_type;
non terminal Expression class_type;
non terminal Expression optional_return_type;
non terminal VariableBase r_variable;
non terminal Integer variable_modifiers;
non terminal VariableBase rw_variable;
non terminal Variable variable_without_objects;
non terminal Pair<Expression, Boolean> variable_property;
non terminal VariableBase static_member;
non terminal List isset_variables;
non terminal Expression isset_variable;
non terminal Variable tracked_variable;
non terminal Integer static_modifier;
non terminal Integer ppp_modifiers;
non terminal Integer af_modifiers;
non terminal ClassName class_name_reference;
non terminal StaticConstantAccess class_constant;
non terminal Expression reference_constant;
non terminal ClassName dynamic_class_name_reference;
non terminal VariableBase dereferencable_variable;
non terminal VariableBase base_variable;
non terminal VariableBase base_variable_without_reference_variable;
non terminal List dynamic_class_name_variable_properties;
non terminal VariableBase dynamic_class_name_variable_property;
non terminal StaticConstantAccess static_class_constant;
non terminal Expression static_reference_constant;
non terminal Expression static_array_creation_with_access;
non terminal Expression static_constant_array_access;
non terminal Expression static_class_constant_array_access;
non terminal Expression static_array_creation;
non terminal VariableBase base_variable_with_function_calls;
non terminal List class_name_list;
precedence left T_INCLUDE, T_INCLUDE_ONCE, T_EVAL, T_REQUIRE, T_REQUIRE_ONCE;
precedence left T_COMMA;
precedence left T_LOGICAL_OR;
precedence left T_LOGICAL_XOR;
precedence left T_LOGICAL_AND;
precedence right T_PRINT;
precedence right T_YIELD;
precedence right T_DOUBLE_ARROW;
precedence right T_YIELD_FROM;
precedence left T_EQUAL, T_PLUS_EQUAL,T_MINUS_EQUAL,T_MUL_EQUAL,T_DIV_EQUAL,T_CONCAT_EQUAL,T_MOD_EQUAL,T_AND_EQUAL,T_OR_EQUAL,T_XOR_EQUAL,T_SL_EQUAL,T_SR_EQUAL,T_POW_EQUAL,T_COALESCE_EQUAL;
precedence right T_POW;
precedence left T_QUESTION_MARK,T_SEMICOLON;
precedence left T_BOOLEAN_OR;
precedence left T_BOOLEAN_AND;
precedence left T_OR;
precedence left T_KOVA;
precedence left T_REFERENCE;
precedence left T_ELLIPSIS;
precedence left T_COALESCE;
precedence nonassoc T_IS_EQUAL,T_IS_NOT_EQUAL,T_IS_IDENTICAL,T_IS_NOT_IDENTICAL;
precedence nonassoc T_RGREATER,T_IS_SMALLER_OR_EQUAL,T_LGREATER,T_IS_GREATER_OR_EQUAL,T_SPACESHIP;
precedence left T_SL,T_SR;
precedence left T_PLUS,T_MINUS,T_NEKUDA;
precedence left T_TIMES,T_DIV,T_PRECENT;
precedence right T_NOT;
precedence nonassoc T_INSTANCEOF;
precedence right T_TILDA,T_INC,T_DEC,T_INT_CAST,T_DOUBLE_CAST,T_STRING_CAST,T_ARRAY_CAST,T_OBJECT_CAST,T_BOOL_CAST,T_UNSET_CAST,T_AT;
precedence right T_CLOSE_PARENTHESE;
precedence right T_OPEN_RECT, T_CURLY_OPEN, T_OPEN_PARENTHESE;
precedence nonassoc T_NEW, T_CLONE;
precedence left T_ELSEIF;
precedence left T_ELSE;
precedence left T_ENDIF;
precedence right T_STATIC, T_ABSTRACT, T_FINAL, T_PRIVATE, T_PROTECTED, T_PUBLIC;
thestart ::=
top_statement_list:statementList
{:
ASTPHP5Scanner phpAstLexer5 = (ASTPHP5Scanner) parser.getScanner();
List commentList = phpAstLexer5.getCommentList();
int endOfProgram = statementListright > phpAstLexer5.getWhitespaceEndPosition() || phpAstLexer5.isEndedPhp() ? statementListright : phpAstLexer5.getWhitespaceEndPosition();
Program program = new Program(statementListleft, endOfProgram, statementList, commentList);
RESULT = program;
:}
;
namespace_name ::=
T_STRING:n
{:
List list = new LinkedList();
list.add(new Identifier(nleft, nright, n));
RESULT = list;
:}
|
T_DEFINE:n
{:
List list = new LinkedList();
list.add(new Identifier(nleft, nright, "define"));
RESULT = list;
:}
|
namespace_name:list T_NS_SEPARATOR T_STRING:n
{:
list.add(new Identifier(nleft, nright, n));
RESULT = list;
:}
;
namespace_name_access ::=
namespace_name:list
{:
RESULT = new NamespaceName(listleft, listright, list, false, false);
:}
| T_NAMESPACE:s T_NS_SEPARATOR namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, false, true);
:}
| T_NS_SEPARATOR:s namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, true, false);
:}
;
reserved_non_modifiers_without_class ::=
T_INCLUDE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_INCLUDE_ONCE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_EVAL:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_REQUIRE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_REQUIRE_ONCE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_LOGICAL_OR:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_LOGICAL_XOR:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_LOGICAL_AND:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_INSTANCEOF:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_NEW:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_CLONE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_EXIT:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_IF:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ELSEIF:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ELSE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ENDIF:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ECHO:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_DO:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_WHILE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ENDWHILE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_FOR:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ENDFOR:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_FOREACH:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ENDFOREACH:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_DECLARE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ENDDECLARE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_AS:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_TRY:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_CATCH:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_FINALLY:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_THROW:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_USE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_INSTEADOF:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_GLOBAL:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_VAR:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_UNSET:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ISSET:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_EMPTY:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_CONTINUE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_GOTO:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_FN:reserved
{:
// PHP 7.4
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_FUNCTION:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_CONST:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_RETURN:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_PRINT:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_YIELD:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_LIST:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_SWITCH:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ENDSWITCH:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_CASE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_DEFAULT:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_BREAK:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_ARRAY:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_CALLABLE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_EXTENDS:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_IMPLEMENTS:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_NAMESPACE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_TRAIT:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_INTERFACE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
/*
| T_CLASS:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
*/
| T_CLASS_C:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_TRAIT_C:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_FUNC_C:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_METHOD_C:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_LINE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_FILE:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_DIR:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
| T_NS_C:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
;
semi_reserved_without_class ::=
reserved_non_modifiers_without_class:reserved
{:
RESULT = reserved;
:}
| T_STATIC:modifier
{:
RESULT = new Identifier(modifierleft, modifierright, modifier, true);
:}
| T_ABSTRACT:modifier
{:
RESULT = new Identifier(modifierleft, modifierright, modifier, true);
:}
| T_FINAL:modifier
{:
RESULT = new Identifier(modifierleft, modifierright, modifier, true);
:}
| T_PRIVATE:modifier
{:
RESULT = new Identifier(modifierleft, modifierright, modifier, true);
:}
| T_PROTECTED:modifier
{:
RESULT = new Identifier(modifierleft, modifierright, modifier, true);
:}
| T_PUBLIC:modifier
{:
RESULT = new Identifier(modifierleft, modifierright, modifier, true);
:}
;
identifier ::=
identifier_without_class:ident
{:
RESULT = ident;
:}
| T_CLASS:reserved
{:
RESULT = new Identifier(reservedleft, reservedright, reserved, true);
:}
;
identifier_without_class ::=
T_STRING:string
{:
RESULT = new Identifier(stringleft, stringright, string);
:}
| T_DEFINE:define
{:
RESULT = new Identifier(defineleft, defineright, define);
:}
| semi_reserved_without_class:reserved
{:
RESULT = reserved;
:}
;
top_statement_list ::=
top_statement_list:sList top_statement:statement
{:
if(statement != null) {
if (!(statement instanceof NamespaceDeclaration) && sList.size() > 0) {
Statement lastStatement = (Statement) ((LinkedList) sList).getLast();
if (lastStatement instanceof NamespaceDeclaration) {
NamespaceDeclaration namespaceDeclaration = (NamespaceDeclaration) lastStatement;
// there should be NO statement outside bracketed namespaces - it's PHP FATAL ERROR
// (that statement doesn't belong to last bracketed namespace)
if (!namespaceDeclaration.isBracketed()) {
namespaceDeclaration.addStatement(statement);
}
} else {
sList.add(statement);
}
} else {
sList.add(statement);
}
}
RESULT = sList;
:}
| /* empty */
{:
RESULT = new LinkedList();
:}
;
top_statement ::=
statement:statement
{:
RESULT = statement;
:}
| function_declaration_statement:statement
{:
RESULT = statement;
:}
| class_declaration_statement:statement
{:
RESULT = statement;
:}
| T_HALT_COMPILER:halt
{:
RESULT = new HaltCompiler(haltleft, haltright);
:}
| T_NAMESPACE:s namespace_name:list T_SEMICOLON:e
{:
RESULT = new NamespaceDeclaration(sleft, eright,
new NamespaceName(listleft, listright, list, false, false), null, false);
:}
| T_NAMESPACE:s namespace_name:list T_CURLY_OPEN:token top_statement_list:sList T_CURLY_CLOSE:e
{:
RESULT = new NamespaceDeclaration(sleft, eright,
new NamespaceName(listleft, listright, list, false, false),
new Block(tokenleft, eright, sList), true);
:}
| T_NAMESPACE:s T_CURLY_OPEN:token top_statement_list:sList T_CURLY_CLOSE:e
{:
RESULT = new NamespaceDeclaration(sleft, eright, null,
new Block(tokenleft, eright, sList), true);
:}
| T_USE:s use_declarations:list T_SEMICOLON:e
{:
RESULT = new UseStatement(sleft, eright, list);
:}
| T_USE:use T_FUNCTION use_declarations:list T_SEMICOLON:e
{:
RESULT = new UseStatement(useleft, eright, list, UseStatement.Type.FUNCTION);
:}
| T_USE:use T_CONST use_declarations:list T_SEMICOLON:e
{:
RESULT = new UseStatement(useleft, eright, list, UseStatement.Type.CONST);
:}
| constant_declaration:list T_SEMICOLON:e
{:
RESULT = new ConstantDeclaration(listleft, eright, ASTPHP5Parser.IMPLICIT_PUBLIC, list, true);
:}
;
use_declarations ::=
use_declarations:list T_COMMA use_declaration:useDecl
{:
list.add(useDecl);
RESULT = list;
:}
| use_declaration:useDecl
{:
List list = new LinkedList();
list.add(useDecl);
RESULT = list;
:}
;
use_declaration ::=
namespace_name:list
{:
RESULT = new SingleUseStatementPart(listleft, listright,
new NamespaceName(listleft, listright, list, false, false), null);
:}
| namespace_name:list T_AS T_STRING:aliasName
{:
RESULT = new SingleUseStatementPart(listleft, aliasNameright,
new NamespaceName(listleft, listright, list, false, false),
new Identifier(aliasNameleft, aliasNameright, aliasName));
:}
| namespace_name:basens T_NS_SEPARATOR:s T_CURLY_OPEN:open group_namespace_parts:parts T_CURLY_CLOSE:close
{:
RESULT = new GroupUseStatementPart(basensleft, closeright, new NamespaceName(basensleft, basensright, basens, false, false), parts);
:}
| T_NS_SEPARATOR:s namespace_name:list
{:
RESULT = new SingleUseStatementPart(sleft, listright,
new NamespaceName(sleft, listright, list, true, false), null);
:}
| T_NS_SEPARATOR:s namespace_name:list T_AS T_STRING:aliasName
{:
RESULT = new SingleUseStatementPart(sleft, aliasNameright,
new NamespaceName(sleft, listright, list, true, false),
new Identifier(aliasNameleft, aliasNameright, aliasName));
:}
| T_NS_SEPARATOR:s namespace_name:basens T_NS_SEPARATOR:ss T_CURLY_OPEN:open group_namespace_parts:parts T_CURLY_CLOSE:close
{:
RESULT = new GroupUseStatementPart(sleft, closeright, new NamespaceName(basensleft, basensright, basens, true, false), parts);
:}
;
// used only in group uses
group_namespace_parts ::=
non_empty_group_namespace_parts:list possible_comma
{:
RESULT = list;
:}
| /* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
;
non_empty_group_namespace_parts ::=
non_empty_group_namespace_parts:list T_COMMA group_namespace_part:part
{:
list.add(part);
RESULT = list;
:}
| group_namespace_part:part
{:
List list = new LinkedList();
list.add(part);
RESULT = list;
:}
;
group_namespace_part ::=
namespace_name:part
{:
RESULT = new SingleUseStatementPart(partleft, partright, new NamespaceName(partleft, partright, part, false, false), null);
:}
| namespace_name:part T_AS T_STRING:alias
{:
RESULT = new SingleUseStatementPart(partleft, aliasright, new NamespaceName(partleft, partright, part, false, false), new Identifier(aliasleft, aliasright, alias));
:}
| T_FUNCTION:f namespace_name:part
{:
RESULT = new SingleUseStatementPart(fleft, partright, UseStatement.Type.FUNCTION, new NamespaceName(partleft, partright, part, false, false), null);
:}
| T_FUNCTION:f namespace_name:part T_AS T_STRING:alias
{:
RESULT = new SingleUseStatementPart(fleft, aliasright, UseStatement.Type.FUNCTION, new NamespaceName(partleft, partright, part, false, false), new Identifier(aliasleft, aliasright, alias));
:}
| T_CONST:c namespace_name:part
{:
RESULT = new SingleUseStatementPart(cleft, partright, UseStatement.Type.CONST, new NamespaceName(partleft, partright, part, false, false), null);
:}
| T_CONST:c namespace_name:part T_AS T_STRING:alias
{:
RESULT = new SingleUseStatementPart(cleft, aliasright, UseStatement.Type.CONST, new NamespaceName(partleft, partright, part, false, false), new Identifier(aliasleft, aliasright, alias));
:}
;
inner_statement_list ::=
inner_statement_list:statementList inner_statement:statement
{:
// Ignore null statements
if(statement != null) {
statementList.add(statement);
}
RESULT = statementList;
:}
| /* empty */
{:
RESULT = new LinkedList();
:}
;
inner_statement ::=
statement:statement
{:
RESULT = statement;
:}
| function_declaration_statement:statement
{:
RESULT = statement;
:}
| class_declaration_statement:statement
{:
RESULT = statement;
:}
;
statement ::=
unticked_statement:statement
{:
RESULT = statement;
:}
| T_STRING:label T_NEKUDOTAIM:e
{:
RESULT = new GotoLabel(labelleft, eright, new Identifier(labelleft, labelright, label));
:}
;
unticked_statement ::=
T_CURLY_OPEN:token inner_statement_list:statementList T_CURLY_CLOSE:end
{:
Block block = new Block(tokenleft, endright, statementList);
RESULT = block;
:}
| T_IF:token T_OPEN_PARENTHESE expr:condition T_CLOSE_PARENTHESE statement:iftrue elseif_list:elseif else_single:iffalse
{:
Expression innerCondition = null;
Statement trueStatement = null;
Statement falseStatement = iffalse;
for (int i=0 ; i < elseif[0].size() ; i++) {
innerCondition = (Expression)elseif[0].get(i);
trueStatement = (Statement)elseif[1].get(i);
int start = ((Integer)elseif[2].get(i)).intValue();
falseStatement = new IfStatement(start, iffalseright, innerCondition, trueStatement, falseStatement);
}
IfStatement ifStatement = new IfStatement(tokenleft, iffalseright, condition, iftrue, falseStatement);
RESULT = ifStatement;
:}
| T_IF:token T_OPEN_PARENTHESE expr:condition T_CLOSE_PARENTHESE T_NEKUDOTAIM:colon inner_statement_list:ifTrueStatementList new_elseif_list:elseif new_else_single:iffalse T_ENDIF T_SEMICOLON:end
{:
Expression innerCondition = null;
Statement trueStatement = null;
Statement falseStatement = iffalse;
for (int i=0 ; i < elseif[0].size() ; i++) {
innerCondition = (Expression)elseif[0].get(i);
trueStatement = (Statement)elseif[1].get(i);
int start = ((Integer)elseif[2].get(i)).intValue();
falseStatement = new IfStatement(start, iffalseright, innerCondition, trueStatement, falseStatement);
}
Block block = new Block(colonleft, ifTrueStatementListright, ifTrueStatementList, false);
IfStatement ifStatement = new IfStatement(tokenleft, iffalseright, condition, block, falseStatement);
RESULT = ifStatement;
:}
| T_WHILE:token T_OPEN_PARENTHESE expr:expr T_CLOSE_PARENTHESE while_statement:statement
{:
WhileStatement whileStatement = new WhileStatement(tokenleft, statementright, expr, statement);
RESULT = whileStatement;
:}
| T_DO:token statement:statement T_WHILE T_OPEN_PARENTHESE expr:expr T_CLOSE_PARENTHESE T_SEMICOLON:end
{:
DoStatement doStatement = new DoStatement(tokenleft, endright, expr, statement);
RESULT = doStatement;
:}
| T_FOR:token T_OPEN_PARENTHESE for_expr:initializations T_SEMICOLON for_expr:conditions T_SEMICOLON for_expr:increasements T_CLOSE_PARENTHESE for_statement:statement
{:
ForStatement forStatement = new ForStatement(tokenleft, statementright, initializations, conditions, increasements, statement);
RESULT = forStatement;
:}
| T_SWITCH:token T_OPEN_PARENTHESE expr:expr T_CLOSE_PARENTHESE switch_case_list:caseBlock
{:
SwitchStatement switchStatement = new SwitchStatement(tokenleft, caseBlockright, expr, caseBlock);
RESULT = switchStatement;
:}
| T_BREAK:token T_SEMICOLON:end
{:
RESULT = new BreakStatement(tokenleft, endright);
:}
| T_BREAK:token expr:expr T_SEMICOLON:end
{:
RESULT = new BreakStatement(tokenleft, endright, expr);
:}
| T_CONTINUE:token T_SEMICOLON:end
{:
RESULT = new ContinueStatement(tokenleft, endright);
:}
| T_CONTINUE:token expr:expr T_SEMICOLON:end
{:
RESULT = new ContinueStatement(tokenleft, endright, expr);
:}
| T_RETURN:token T_SEMICOLON:end
{:
RESULT = new ReturnStatement(tokenleft, endright);
:}
| T_RETURN:token expr_without_variable:expr T_SEMICOLON:end
{:
RESULT = new ReturnStatement(tokenleft, endright, expr);
:}
| T_RETURN:token variable:expr T_SEMICOLON:end
{:
RESULT = new ReturnStatement(tokenleft, endright, expr);
:}
| T_RETURN:token yield_from_expr:expr T_SEMICOLON:end
{:
RESULT = new ReturnStatement(tokenleft, endright, expr);
:}
| T_GLOBAL:start global_var_list:list T_SEMICOLON:end
{:
GlobalStatement global = new GlobalStatement(startleft, endright, list);
RESULT = global;
:}
| T_STATIC:start static_var_list:list T_SEMICOLON:end
{:
StaticStatement s = new StaticStatement(startleft, endright, list);
RESULT = s;
:}
| T_ECHO:start echo_expr_list:exprList T_SEMICOLON:end
{:
RESULT = new EchoStatement(startleft, endright, exprList);
:}
| T_INLINE_HTML:html
{:
InLineHtml inLineHtml = new InLineHtml(htmlleft, htmlright);
RESULT = inLineHtml;
:}
| expr_with_yields:expr T_SEMICOLON:end
{:
ExpressionStatement expressionStatement = new ExpressionStatement(exprleft, endright, expr);
RESULT = expressionStatement;
:}
| T_USE:start use_filename:expr T_SEMICOLON:end
{:
List list = new LinkedList();
list.add(expr);
Identifier id = new Identifier(startleft, startright, "use");
FunctionName functionName = new FunctionName(startleft, startright, id);
FunctionInvocation functionInvocation = new FunctionInvocation(startleft, exprright, functionName, list);
ExpressionStatement expressionStatement = new ExpressionStatement(startleft, endright, functionInvocation);
RESULT = expressionStatement;
:}
| T_UNSET:start T_OPEN_PARENTHESE unset_variables:list possible_comma T_CLOSE_PARENTHESE:closePar T_SEMICOLON:end
{:
Identifier id = new Identifier(startleft, startright, "unset");
FunctionName functionName = new FunctionName(startleft, startright, id);
FunctionInvocation functionInvocation = new FunctionInvocation(startleft, closeParright, functionName, list);
ExpressionStatement expressionStatement = new ExpressionStatement(startleft, endright, functionInvocation);
RESULT = expressionStatement;
:}
| T_FOREACH:token T_OPEN_PARENTHESE variable:expr T_AS foreach_variable:var foreach_optional_arg:arg T_CLOSE_PARENTHESE foreach_statement:statement
{:
ForEachStatement forEachStatement = null;
if (arg == null) {
forEachStatement = new ForEachStatement(tokenleft, statementright, expr, var, statement);
} else {
forEachStatement = new ForEachStatement(tokenleft, statementright, expr, var, arg, statement);
}
RESULT = forEachStatement;
:}
| T_FOREACH:token T_OPEN_PARENTHESE expr_without_variable:expr T_AS foreach_variable:var foreach_optional_arg:arg T_CLOSE_PARENTHESE foreach_statement:statement
{:
ForEachStatement forEachStatement = null;
if (arg == null) {
forEachStatement = new ForEachStatement(tokenleft, statementright, expr, var, statement);
} else {
forEachStatement = new ForEachStatement(tokenleft, statementright, expr, var, arg, statement);
}
RESULT = forEachStatement;
:}
| T_DECLARE:start T_OPEN_PARENTHESE declare_list:lists T_CLOSE_PARENTHESE declare_statement:statement
{:
DeclareStatement declare = new DeclareStatement(startleft, statementright, lists[0], lists[1], statement);
RESULT = declare;
:}
| T_SEMICOLON:token /* empty statement */
{:
RESULT = new EmptyStatement(tokenleft, tokenright);
:}
| T_TRY:start T_CURLY_OPEN:tryBlockStart inner_statement_list:tryList T_CURLY_CLOSE:tryBlockEnd T_FINALLY:finally_word T_CURLY_OPEN:finallyBlockStart inner_statement_list:finallyList T_CURLY_CLOSE:finallyBlockEnd
{:
Block tryBlock = new Block(tryBlockStartleft, tryBlockEndright, tryList);
Block finallyBlock = new Block(finallyBlockStartleft, finallyBlockEndright, finallyList);
FinallyClause finallyClause = new FinallyClause(finally_wordleft, finallyBlockEndright, finallyBlock);
TryStatement tryStatement = new TryStatement(startleft, finallyBlockEndright, tryBlock, null, finallyClause);
RESULT = tryStatement;
:}
| T_TRY:start T_CURLY_OPEN:tryBlockStart inner_statement_list:tryList T_CURLY_CLOSE:tryBlockEnd T_CATCH:catch_word T_OPEN_PARENTHESE catch_class_names:classNames tracked_variable:var T_CLOSE_PARENTHESE
T_CURLY_OPEN:catchBlockStart inner_statement_list:catchList T_CURLY_CLOSE:catchBlockEnd additional_catches:catchesList additional_finally:finallyBlock
{:
Block tryBlock = new Block(tryBlockStartleft, tryBlockEndright, tryList);
Block catchBlock = new Block(catchBlockStartleft, catchBlockEndright, catchList);
CatchClause catchClause = new CatchClause(catch_wordleft, catchBlockEndright, classNames, var, catchBlock);
((LinkedList) catchesList).addFirst(catchClause);
int end = finallyBlock == null ? catchesListright : finallyBlockright;
TryStatement tryStatement = new TryStatement(startleft, end, tryBlock, catchesList, finallyBlock);
RESULT = tryStatement;
:}
| T_THROW:token expr:expr T_SEMICOLON:end
{:
RESULT = new ThrowStatement(tokenleft, endright, expr);
:}
| T_GOTO:s T_STRING:label T_SEMICOLON:e
{:
RESULT = new GotoStatement(sleft, eright, new Identifier(labelleft, labelright, label));
:}
| error:theError /* error statement */
{:
ASTError error = new ASTError(theErrorleft, theErrorright);
RESULT = error;
:}
| T_VAR_COMMENT:varComment
{:
// TODO: var comment should be added as parser.ast node
:}
;
additional_catches ::=
non_empty_additional_catches:list
{:
RESULT = list;
:}
| /* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
;
non_empty_additional_catches ::=
additional_catch:catch_statement
{:
List list = new LinkedList();
list.add(catch_statement);
RESULT = list;
:}
| non_empty_additional_catches:list additional_catch:catch_statement
{:
list.add(catch_statement);
RESULT = list;
:}
;
additional_catch ::=
T_CATCH:catch_word T_OPEN_PARENTHESE catch_class_names:classNames T_VARIABLE:var T_CLOSE_PARENTHESE
T_CURLY_OPEN:catchBlockStart inner_statement_list:catchList T_CURLY_CLOSE:catchBlockEnd
{:
Block catchBlock = new Block(catchBlockStartleft, catchBlockEndright, catchList);
Variable variable = new Variable(varleft, varright, var);
CatchClause catchClause = new CatchClause(catch_wordleft, catchBlockEndright, classNames, variable, catchBlock);
RESULT = catchClause;
:}
;
additional_finally ::=
/* empty */
{:
RESULT = null;
:}
| T_FINALLY:finally_word T_CURLY_OPEN:finallyBlockStart inner_statement_list:finallyList T_CURLY_CLOSE:finallyBlockEnd
{:
Block finallyBlock = new Block(finallyBlockStartleft, finallyBlockEndright, finallyList);
FinallyClause finallyClause = new FinallyClause(finally_wordleft, finallyBlockEndright, finallyBlock);
RESULT = finallyClause;
:}
;
catch_class_names ::=
fully_qualified_class_name:className additional_catch_class_names:list
{:
((LinkedList) list).addFirst(className);
RESULT = list;
:}
;
additional_catch_class_names ::=
non_empty_additional_catch_class_names:list
{:
RESULT = list;
:}
| /* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
;
non_empty_additional_catch_class_names ::=
additional_catch_class_name:className
{:
List list = new LinkedList();
list.add(className);
RESULT = list;
:}
| non_empty_additional_catch_class_names:list additional_catch_class_name:className
{:
list.add(className);
RESULT = list;
:}
;
additional_catch_class_name ::=
T_OR fully_qualified_class_name:className
{:
RESULT = className;
:}
;
unset_variables ::=
unset_variable:var
{:
List list = new LinkedList();
list.add(var);
RESULT = list;
:}
| unset_variables:list T_COMMA unset_variable:var
{:
list.add(var);
RESULT = list;
:}
;
unset_variable ::=
variable:var
{:
RESULT = var;
:}
;
use_filename ::=
T_CONSTANT_ENCAPSED_STRING:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, scalar, Scalar.Type.STRING);
RESULT = s;
:}
| T_OPEN_PARENTHESE:start T_CONSTANT_ENCAPSED_STRING:scalar T_CLOSE_PARENTHESE:end
{:
Scalar s = new Scalar(startleft, endright, scalar, Scalar.Type.STRING);
RESULT = s;
:}
;
function_declaration_statement ::=
unticked_function_declaration_statement:functionDeclaration
{:
RESULT = functionDeclaration;
:}
;
class_declaration_statement ::=
unticked_class_declaration_statement:classDeclaration
{:
RESULT = classDeclaration;
:}
;
is_reference ::=
/* empty */
{:
RESULT = Boolean.FALSE;
:}
| T_REFERENCE
{:
RESULT = Boolean.TRUE;
:}
;
is_variadic ::=
/* empty */
{:
RESULT = Boolean.FALSE;
:}
| T_ELLIPSIS
{:
RESULT = Boolean.TRUE;
:}
;
unticked_function_declaration_statement ::=
T_FUNCTION:start is_reference:isReference string_st:functionName
T_OPEN_PARENTHESE parameter_list:paramList T_CLOSE_PARENTHESE
optional_return_type:returnType
T_CURLY_OPEN:blockStart inner_statement_list:statementList T_CURLY_CLOSE:blockEnd
{:
Identifier functionId = new Identifier(functionNameleft, functionNameright, functionName);
Block block = new Block(blockStartleft, blockEndright, statementList);
FunctionDeclaration functionDeclaration = new FunctionDeclaration(startleft, blockEndright, functionId, paramList, returnType, block, isReference.booleanValue());
RESULT = functionDeclaration;
:}
;
unticked_class_declaration_statement ::=
class_entry_type:modifier T_STRING:className
extends_from:superClass implements_list:interfaces
T_CURLY_OPEN:blockStart class_statement_list:statementList T_CURLY_CLOSE:blockEnd
{:
Identifier classId = new Identifier(classNameleft, classNameright, className);
Block block = new Block(blockStartleft, blockEndright, statementList);
ClassDeclaration classDeclaration = new ClassDeclaration(modifierleft ,blockEndright, modifier, classId, superClass, interfaces, block);
RESULT = classDeclaration;
:}
|
interface_entry:start T_STRING:className
interface_extends_list:interfaces
T_CURLY_OPEN:blockStart interface_statement_list:statementList T_CURLY_CLOSE:blockEnd
{:
Identifier classId = new Identifier(classNameleft, classNameright, className);
Block block = new Block(blockStartleft, blockEndright, statementList);
InterfaceDeclaration interfaceDeclaration = new InterfaceDeclaration(startleft ,blockEndright, classId, interfaces, block);
RESULT = interfaceDeclaration;
:}
|
T_TRAIT:start T_STRING:traitName
T_CURLY_OPEN:blockStart trait_statement_list:statementList T_CURLY_CLOSE:blockEnd
{:
Identifier traitId = new Identifier(traitNameleft, traitNameright, traitName);
Block block = new Block(blockStartleft, blockEndright, statementList);
TraitDeclaration traitDeclaration = new TraitDeclaration(startleft, blockEndright, traitId, block);
RESULT = traitDeclaration;
:}
;
interface_statement_list ::=
interface_statement_list:list interface_statement:interfaceStatement
{:
list.add(interfaceStatement);
RESULT = list;
:}
| /* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
;
interface_statement ::=
constant_modifiers:modifier class_constant_declaration:list T_SEMICOLON:end
{:
int constantStart = modifier == null ? listleft : modifierleft;
modifier = modifier == null ? ASTPHP5Parser.IMPLICIT_PUBLIC : modifier;
ConstantDeclaration classConstantDeclaration = new ConstantDeclaration(constantStart, endright, modifier, list, false);
RESULT = classConstantDeclaration;
:}
| method_modifiers:modifier T_FUNCTION:start is_reference:isReference identifier:functionId
T_OPEN_PARENTHESE parameter_list:paramList T_CLOSE_PARENTHESE
optional_return_type:returnType
T_SEMICOLON:end
{:
int methodStart = modifier == null ? startleft : modifierleft;
modifier = modifier == null ? ASTPHP5Parser.PUBLIC : modifier;
Block block = new Block(endleft, endright, Collections.EMPTY_LIST, false);
FunctionDeclaration functionDeclaration = new FunctionDeclaration(startleft, endright, functionId, paramList, returnType, block, isReference.booleanValue());
MethodDeclaration methodDeclaration = new MethodDeclaration(methodStart, endright, modifier.intValue(), functionDeclaration, true);
RESULT = methodDeclaration;
:}
| T_VAR_COMMENT:varComment
{:
:}
;
trait_statement_list ::=
trait_statement_list:list trait_statement:traitStatement
{:
list.add(traitStatement);
RESULT = list;
:}
| /* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
;
trait_statement ::=
variable_modifiers:modifier optional_class_type:fieldType class_variable_declaration:decList T_SEMICOLON:end
{:
FieldsDeclaration fieldsDeclaration = new FieldsDeclaration(modifierleft, endright, modifier.intValue(), fieldType, decList);
RESULT = fieldsDeclaration;
:}
| method_modifiers:modifier T_FUNCTION:start is_reference:isReference identifier:functionId
T_OPEN_PARENTHESE parameter_list:paramList T_CLOSE_PARENTHESE
optional_return_type:returnType
method_body:body
{:
int methodStart = modifier == null ? startleft : modifierleft;
modifier = modifier == null ? ASTPHP5Parser.PUBLIC : modifier;
FunctionDeclaration functionDeclaration = new FunctionDeclaration(startleft, bodyright, functionId, paramList, returnType, body, isReference.booleanValue());
MethodDeclaration methodDeclaration = new MethodDeclaration(methodStart, bodyright, modifier.intValue(), functionDeclaration, true);
RESULT = methodDeclaration;
:}
| T_VAR_COMMENT:varComment
{:
:}
| T_USE:s use_traits:list use_traits_body:body
{:
RESULT = new UseTraitStatement(sleft, bodyright, list, body);
:}
;
class_entry_type ::=
T_CLASS
{:
RESULT = ClassDeclaration.Modifier.NONE;
:}
| T_ABSTRACT T_CLASS
{:
RESULT = ClassDeclaration.Modifier.ABSTRACT;
:}
| T_FINAL T_CLASS
{:
RESULT = ClassDeclaration.Modifier.FINAL;
:}
;
extends_from ::=
/* empty */
{:
RESULT = null;
:}
| T_EXTENDS fully_qualified_class_name:className
{:
RESULT = className;
:}
;
/* do nothing */
interface_entry ::=
T_INTERFACE
;
interface_extends_list ::=
/* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
| T_EXTENDS interface_list:list
{:
RESULT = list;
:}
;
implements_list ::=
/* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
| T_IMPLEMENTS interface_list:list
{:
RESULT = list;
:}
;
interface_list ::=
fully_qualified_class_name:className
{:
List list = new LinkedList();
list.add(className);
RESULT = list;
:}
| interface_list:list T_COMMA fully_qualified_class_name:className
{:
list.add(className);
RESULT = list;
:}
;
foreach_optional_arg ::=
/* empty */
{:
RESULT = null;
:}
| T_DOUBLE_ARROW foreach_variable:var
{:
RESULT = var;
:}
;
foreach_variable ::=
variable:var
{:
RESULT = var;
:}
| T_REFERENCE:start variable:var
{:
Reference reference = new Reference (startleft, varright, var);
RESULT = reference;
:}
| T_LIST:start T_OPEN_PARENTHESE array_pair_list:varList T_CLOSE_PARENTHESE:end
{:
ListVariable vars = new ListVariable(startleft, endright, varList, ListVariable.SyntaxType.OLD);
RESULT = vars;
:}
| T_OPEN_RECT:start array_pair_list:varList T_CLOSE_RECT:end
{:
ListVariable vars = new ListVariable(startleft, endright, varList, ListVariable.SyntaxType.NEW);
RESULT = vars;
:}
;
for_statement ::=
statement:statement
{:
RESULT = statement;
:}
| T_NEKUDOTAIM:start inner_statement_list:statementList T_ENDFOR T_SEMICOLON
{:
Block block = new Block(startleft, statementListright, statementList, false);
RESULT = block;
:}
;
foreach_statement ::=
statement:statement
{:
RESULT = statement;
:}
| T_NEKUDOTAIM:start inner_statement_list:statementList T_ENDFOREACH T_SEMICOLON
{:
Block block = new Block(startleft, statementListright, statementList, false);
RESULT = block;
:}
;
declare_statement ::=
statement:statement
{:
RESULT = statement;
:}
| T_NEKUDOTAIM:start inner_statement_list:statementList T_ENDDECLARE T_SEMICOLON
{:
Block block = new Block(startleft, statementListright, statementList, false);
RESULT = block;
:}
;
// this rule returns a pair of keys and values of directives to the declare statement
declare_list ::=
string_st:key T_EQUAL static_scalar:value
{:
List listKeys = new LinkedList();
List listValues = new LinkedList();
Identifier id = new Identifier(keyleft, keyright, key);
listKeys.add(id);
listValues.add(value);
List[] returnList = new List[] { listKeys, listValues };
RESULT = returnList;
:}
| declare_list:lists T_COMMA string_st:key T_EQUAL static_scalar:value
{:
Identifier id = new Identifier(keyleft, keyright, key);
lists[0].add(id);
lists[1].add(value);
RESULT = lists;
:}
;
switch_case_list ::=
T_CURLY_OPEN:start case_list:caseList T_CURLY_CLOSE:end
{:
Block block = new Block(startleft, endright, caseList);
RESULT = block;
:}
| T_CURLY_OPEN:start T_SEMICOLON case_list:caseList T_CURLY_CLOSE:end
{:
Block block = new Block(startleft, endright, caseList);
RESULT = block;
:}
| T_NEKUDOTAIM:start case_list:caseList T_ENDSWITCH T_SEMICOLON:end
{:
Block block = new Block(startleft, endright, caseList, false);
RESULT = block;
:}
| T_NEKUDOTAIM:start T_SEMICOLON case_list:caseList T_ENDSWITCH T_SEMICOLON:end
{:
Block block = new Block(startleft, endright, caseList, false);
RESULT = block;
:}
;
case_list ::=
/* empty */
{:
RESULT = new LinkedList(); // of SwitchCase
:}
| case_list:caseList T_CASE:token expr:expr case_separator inner_statement_list:statements
{:
SwitchCase switchCase = new SwitchCase(tokenleft, statementsright, expr, statements, false);
if (caseList == null) {
caseList = new LinkedList(); // of switchCase
}
caseList.add(switchCase);
RESULT = caseList;
:}
| case_list:caseList T_DEFAULT:token case_separator inner_statement_list:statements
{:
SwitchCase switchCase = new SwitchCase(tokenleft, statementsright, null, statements, true);
if (caseList == null) {
caseList = new LinkedList(); // of SwitchCase
}
caseList.add(switchCase);
RESULT = caseList;
:}
;
/* Note: we don't capture seperator type */
case_separator ::=
T_NEKUDOTAIM
| T_SEMICOLON
;
while_statement ::=
statement:statement
{:
RESULT = statement;
:}
| T_NEKUDOTAIM:colon inner_statement_list:statementList T_ENDWHILE T_SEMICOLON
{:
Block block = new Block(colonleft, statementListright, statementList, false);
RESULT = block;
:}
;
elseif_list ::=
/* empty */
{:
List listConditions = new LinkedList();
List listStatements = new LinkedList();
List listTokens = new LinkedList();
List[] returnList = new List[] { listConditions, listStatements, listTokens };
RESULT = returnList;
:}
| elseif_list:elseifList T_ELSEIF:token T_OPEN_PARENTHESE expr:condition T_CLOSE_PARENTHESE statement:iftrue
{:
((LinkedList)elseifList[0]).addFirst(condition);
((LinkedList)elseifList[1]).addFirst(iftrue);
((LinkedList)elseifList[2]).addFirst(Integer.valueOf(tokenleft));
RESULT = elseifList;
:}
;
new_elseif_list ::=
/* empty */
{:
List listConditions = new LinkedList();
List listStatements = new LinkedList();
List listTokens = new LinkedList();
List[] returnList = new List[] { listConditions, listStatements, listTokens };
RESULT = returnList;
:}
| new_elseif_list:elseifList T_ELSEIF:token T_OPEN_PARENTHESE expr:condition T_CLOSE_PARENTHESE T_NEKUDOTAIM:colon inner_statement_list:statementList
{:
Block block = new Block(colonleft, statementListright, statementList, false);
((LinkedList)elseifList[0]).addFirst(condition);
((LinkedList)elseifList[1]).addFirst(block);
((LinkedList)elseifList[2]).addFirst(Integer.valueOf(tokenleft));
RESULT = elseifList;
:}
;
else_single ::=
/* empty */
{:
RESULT = null;
:}
| T_ELSE statement:statement
{:
RESULT = statement;
:}
;
new_else_single ::=
/* empty */
{:
RESULT = null;
:}
| T_ELSE T_NEKUDOTAIM:colon inner_statement_list:statementList
{:
Block block = new Block(colonleft, statementListright, statementList, false);
RESULT = block;
:}
;
parameter_list ::=
non_empty_parameter_list:list
{:
RESULT = list;
:}
| /* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
;
non_empty_parameter_list ::=
parameter:parameter
{:
List list = new LinkedList();
list.add(parameter);
RESULT = list;
:}
| non_empty_parameter_list:list T_COMMA parameter:parameter
{:
list.add(parameter);
RESULT = list;
:}
;
parameter ::=
optional_class_type:classType is_variadic:isVariadic T_VARIABLE:var
{:
int start = classType == null ? (isVariadic ? isVariadicleft : varleft) : classTypeleft;
Variable v = new Variable(varleft, varright, var);
Expression argument = v;
if (isVariadic) {
argument = new Variadic(isVariadicleft, varright, v);
}
FormalParameter parameter = new FormalParameter(start, varright, classType, argument);
RESULT = parameter;
:}
| optional_class_type:classType T_REFERENCE:ref T_VARIABLE:var
{:
int start = classType == null ? refleft : classTypeleft;
Variable v = new Variable(varleft, varright, var);
Reference ref_var = new Reference (refleft, varright, v);
FormalParameter parameter = new FormalParameter(start, varright, classType, ref_var);
RESULT = parameter;
:}
| optional_class_type:classType T_REFERENCE:ref T_ELLIPSIS:ell T_VARIABLE:var
{:
int start = classType == null ? refleft : classTypeleft;
Variable v = new Variable(varleft, varright, var);
Variadic variadic = new Variadic(ellleft, varright, v);
Reference ref_var = new Reference (refleft, varright, variadic);
FormalParameter parameter = new FormalParameter(start, varright, classType, ref_var);
RESULT = parameter;
:}
| optional_class_type:classType is_variadic:isVariadic T_VARIABLE:var T_EQUAL static_scalar:scalar
{:
int start = classType == null ? (isVariadic ? isVariadicleft : varleft) : classTypeleft;
Variable v = new Variable(varleft, varright, var);
Expression argument = v;
if (isVariadic) {
argument = new Variadic(isVariadicleft, varright, v);
}
FormalParameter parameter = new FormalParameter(start, scalarright, classType, argument, scalar);
RESULT = parameter;
:}
| optional_class_type:classType T_REFERENCE:ref T_VARIABLE:var T_EQUAL static_scalar:scalar
{:
int start = classType == null ? refleft : classTypeleft;
Variable v = new Variable(varleft, varright, var);
Reference ref_var = new Reference (refleft, varright, v);
FormalParameter parameter = new FormalParameter(start, scalarright, classType, ref_var, scalar);
RESULT = parameter;
:}
;
optional_return_type ::=
/* empty */
{:
RESULT = null;
:}
| T_NEKUDOTAIM:e class_type:className
{:
RESULT = className;
:}
| T_NEKUDOTAIM:e T_QUESTION_MARK:nullable class_type:className
{:
RESULT = new NullableType(nullableleft, classNameright, className);
:}
;
optional_class_type ::=
/* empty */
{:
RESULT = null;
:}
| class_type:className
{:
RESULT = className;
:}
| T_QUESTION_MARK:start class_type:className
{:
RESULT = new NullableType(startleft, classNameright, className);
:}
;
class_type ::=
fully_qualified_class_name:className
{:
RESULT = className;
:}
| T_ARRAY:array
{:
Identifier classId = new Identifier(arrayleft, arrayright, "array");
RESULT = classId;
:}
| T_CALLABLE:callable
{:
Identifier classId = new Identifier(callableleft, callableright, "callable");
RESULT = classId;
:}
;
function_call_parameter_list ::=
non_empty_function_call_parameter_list:paramsList possible_comma
{:
RESULT = paramsList;
:}
| /* empty */
{:
RESULT = new LinkedList();
:}
;
non_empty_function_call_parameter_list ::=
is_variadic:isVariadic expr_without_variable:var
{:
List paramsList = new LinkedList();
Expression param = var;
if (isVariadic) {
param = new Variadic(isVariadicleft, varright, var);
}
paramsList.add(param);
RESULT = paramsList;
:}
| is_variadic:isVariadic variable:var
{:
List paramsList = new LinkedList();
Expression param = var;
if (isVariadic) {
param = new Variadic(isVariadicleft, varright, var);
}
paramsList.add(param);
RESULT = paramsList;
:}
| T_REFERENCE:start w_variable:var
{:
List paramsList = new LinkedList();
Expression var_ref = new Reference(startleft, varright, var);
paramsList.add(var_ref);
RESULT = paramsList;
:}
| non_empty_function_call_parameter_list:paramsList T_COMMA is_variadic:isVariadic expr_without_variable:var
{:
Expression param = var;
if (isVariadic) {
param = new Variadic(isVariadicleft, varright, var);
}
paramsList.add(param);
RESULT = paramsList;
:}
| non_empty_function_call_parameter_list:paramsList T_COMMA is_variadic:isVariadic variable:var
{:
Expression param = var;
if (isVariadic) {
param = new Variadic(isVariadicleft, varright, var);
}
paramsList.add(param);
RESULT = paramsList;
:}
| non_empty_function_call_parameter_list:paramsList T_COMMA T_REFERENCE:start w_variable:var
{:
Expression var_ref = new Reference(startleft, varright, var);
paramsList.add(var_ref);
RESULT = paramsList;
:}
;
global_var_list ::=
global_var_list:list T_COMMA global_var:var
{:
list.add(var);
RESULT = list;
:}
| global_var:var
{:
List list = new LinkedList();
list.add(var);
RESULT = list;
:}
;
global_var ::=
T_VARIABLE:var
{:
Variable variable = new Variable(varleft, varright, var);
RESULT = variable;
:}
| T_DOLLAR:start r_variable:var
{:
ReflectionVariable ref = new ReflectionVariable(startleft, varright, var);
RESULT = ref;
:}
| T_DOLLAR:start T_CURLY_OPEN expr:varName T_CURLY_CLOSE:end
{:
ReflectionVariable var = new ReflectionVariable(startleft, endright, varName);
RESULT = var;
:}
;
static_var_list ::=
static_var_list:list T_COMMA T_VARIABLE:var
{:
Variable v = new Variable(varleft, varright, var);
list.add(v);
RESULT = list;
:}
| static_var_list:list T_COMMA T_VARIABLE:var T_EQUAL static_scalar:expr
{:
Variable v = new Variable(varleft, varright, var);
Assignment assignment = new Assignment(varleft, exprright, v, Assignment.Type.EQUAL, expr);
list.add(assignment);
RESULT = list;
:}
| T_VARIABLE:var
{:
Variable v = new Variable(varleft, varright, var);
List list = new LinkedList();
list.add(v);
RESULT = list;
:}
| T_VARIABLE:var T_EQUAL static_scalar:expr
{:
Variable v = new Variable(varleft, varright, var);
Assignment assignment = new Assignment(varleft, exprright, v, Assignment.Type.EQUAL, expr);
List list = new LinkedList();
list.add(assignment);
RESULT = list;
:}
;
class_statement_list ::=
class_statement_list:list class_statement:classStatement
{:
list.add(classStatement);
RESULT = list;
:}
| /* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
;
class_statement ::=
variable_modifiers:modifier optional_class_type:fieldType class_variable_declaration:decList T_SEMICOLON:end
{:
FieldsDeclaration fieldsDeclaration = new FieldsDeclaration(modifierleft, endright, modifier.intValue(), fieldType, decList);
RESULT = fieldsDeclaration;
:}
| constant_modifiers:modifier class_constant_declaration:list T_SEMICOLON:end
{:
int constantStart = modifier == null ? listleft : modifierleft;
modifier = modifier == null ? ASTPHP5Parser.IMPLICIT_PUBLIC : modifier;
ConstantDeclaration classConstantDeclaration = new ConstantDeclaration(constantStart, endright, modifier, list, false);
RESULT = classConstantDeclaration;
:}
| method_modifiers:modifier T_FUNCTION:start is_reference:isReference identifier:functionId
T_OPEN_PARENTHESE parameter_list:paramList T_CLOSE_PARENTHESE
optional_return_type:returnType
method_body:body
{:
int methodStart = modifier == null ? startleft : modifierleft;
modifier = modifier == null ? ASTPHP5Parser.PUBLIC : modifier;
FunctionDeclaration functionDeclaration = new FunctionDeclaration(startleft, bodyright, functionId, paramList, returnType, body, isReference.booleanValue());
MethodDeclaration methodDeclaration = new MethodDeclaration(methodStart, bodyright, modifier.intValue(), functionDeclaration, true);
RESULT = methodDeclaration;
:}
| T_VAR_COMMENT:varComment
{:
:}
| T_USE:s use_traits:list use_traits_body:body
{:
RESULT = new UseTraitStatement(sleft, bodyright, list, body);
:}
;
use_traits ::=
use_traits:list T_COMMA use_trait:useDecl
{:
list.add(useDecl);
RESULT = list;
:}
| use_trait:useDecl
{:
List list = new LinkedList();
list.add(useDecl);
RESULT = list;
:}
;
use_trait ::=
namespace_name:list
{:
RESULT = new UseTraitStatementPart(listleft, listright, new NamespaceName(listleft, listright, list, false, false));
:}
| T_NS_SEPARATOR:s namespace_name:list
{:
RESULT = new UseTraitStatementPart(sleft, listright, new NamespaceName(sleft, listright, list, true, false));
:}
;
use_traits_body ::=
T_SEMICOLON:e
{:
RESULT = null;
:}
| T_CURLY_OPEN:start use_traits_body_statement_list:statementList T_CURLY_CLOSE:end
{:
Block block = new Block(startleft, endright, statementList);
RESULT = block;
:}
;
use_traits_body_statement_list ::=
use_traits_body_statement_list:statementList use_traits_body_statement:statement
{:
// Ignore null statements
if(statement != null) {
statementList.add(statement);
}
RESULT = statementList;
:}
| /* empty */
{:
RESULT = new LinkedList();
:}
;
use_traits_body_statement ::=
trait_conflict_resolution_declaration:statement
{:
RESULT = statement;
:}
| trait_method_alias_declaration:statement
{:
RESULT = statement;
:}
;
class_name_list ::=
class_name_list:classNameList T_COMMA class_name:className
{:
classNameList.add(className);
RESULT = classNameList;
:}
| class_name:className
{:
List classNameList = new LinkedList();
classNameList.add(className);
RESULT = classNameList;
:}
;
trait_conflict_resolution_declaration ::=
class_name:preferredTraitName T_PAAMAYIM_NEKUDOTAYIM string_st:methodName T_INSTEADOF class_name_list:suppressedTraitNames T_SEMICOLON:end
{:
Identifier methodId = new Identifier(methodNameleft, methodNameright, methodName);
RESULT = new TraitConflictResolutionDeclaration(preferredTraitNameleft, endright, preferredTraitName, methodId, suppressedTraitNames);
:}
;
trait_method_alias_declaration ::=
class_name:traitName T_PAAMAYIM_NEKUDOTAYIM string_st:oldMethodName T_AS traits_alias_modifier:modifier string_st:newMethodName T_SEMICOLON:end
{:
Identifier oldMethodId = new Identifier(oldMethodNameleft, oldMethodNameright, oldMethodName);
Identifier newMethodId = new Identifier(newMethodNameleft, newMethodNameright, newMethodName);
RESULT = new TraitMethodAliasDeclaration(traitNameleft, endright, oldMethodId, newMethodId, traitName, modifier);
:}
| class_name:traitName T_PAAMAYIM_NEKUDOTAYIM string_st:oldMethodName T_AS string_st:newMethodName T_SEMICOLON:end
{:
Identifier oldMethodId = new Identifier(oldMethodNameleft, oldMethodNameright, oldMethodName);
Identifier newMethodId = new Identifier(newMethodNameleft, newMethodNameright, newMethodName);
RESULT = new TraitMethodAliasDeclaration(traitNameleft, endright, oldMethodId, newMethodId, traitName, null);
:}
| string_st:oldMethodName T_AS traits_alias_modifier:modifier T_SEMICOLON:end
{:
Identifier oldMethodId = new Identifier(oldMethodNameleft, oldMethodNameright, oldMethodName);
Identifier newMethodId = new Identifier(oldMethodNameleft, oldMethodNameright, oldMethodName);
RESULT = new TraitMethodAliasDeclaration(oldMethodNameleft, endright, oldMethodId, newMethodId, null, modifier);
:}
| string_st:oldMethodName T_AS traits_alias_modifier:modifier string_st:newMethodName T_SEMICOLON:end
{:
Identifier oldMethodId = new Identifier(oldMethodNameleft, oldMethodNameright, oldMethodName);
Identifier newMethodId = new Identifier(newMethodNameleft, newMethodNameright, newMethodName);
RESULT = new TraitMethodAliasDeclaration(oldMethodNameleft, endright, oldMethodId, newMethodId, null, modifier);
:}
| string_st:oldMethodName T_AS string_st:newMethodName T_SEMICOLON:end
{:
Identifier oldMethodId = new Identifier(oldMethodNameleft, oldMethodNameright, oldMethodName);
Identifier newMethodId = new Identifier(newMethodNameleft, newMethodNameright, newMethodName);
RESULT = new TraitMethodAliasDeclaration(oldMethodNameleft, endright, oldMethodId, newMethodId, null, null);
:}
;
traits_alias_modifier ::=
T_PUBLIC
{:
RESULT = TraitMethodAliasDeclaration.Modifier.PUBLIC;
:}
| T_PROTECTED
{:
RESULT = TraitMethodAliasDeclaration.Modifier.PROTECTED;
:}
| T_PRIVATE
{:
RESULT = TraitMethodAliasDeclaration.Modifier.PRIVATE;
:}
;
method_body ::=
T_SEMICOLON /* abstract method */
{:
RESULT = null;
:}
| T_CURLY_OPEN:start inner_statement_list:statementList T_CURLY_CLOSE:end
{:
Block block = new Block(startleft, endright, statementList);
RESULT = block;
:}
;
constant_modifiers ::=
/* empty */
{:
RESULT = null;
:}
| ppp_modifiers:modifier
{:
RESULT = modifier;
:}
;
variable_modifiers ::=
ppp_modifiers:modifier
{:
RESULT = modifier;
:}
| static_modifier:modifier
{:
RESULT = modifier;
:}
| static_modifier:fModifier ppp_modifiers:sModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| ppp_modifiers:fModifier static_modifier:sModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| T_VAR
{:
RESULT = ASTPHP5Parser.PUBLIC;
:}
;
method_modifiers ::=
/* empty */
{:
RESULT = null;
:}
| af_modifiers:modifier
{:
RESULT = modifier;
:}
| static_modifier:modifier
{:
RESULT = modifier;
:}
| ppp_modifiers:modifier
{:
RESULT = modifier;
:}
| static_modifier:fModifier ppp_modifiers:sModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| static_modifier:fModifier af_modifiers:sModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| ppp_modifiers:fModifier static_modifier:sModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| ppp_modifiers:fModifier af_modifiers:sModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| af_modifiers:fModifier static_modifier:sModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| af_modifiers:fModifier ppp_modifiers:sModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| static_modifier:fModifier ppp_modifiers:sModifier af_modifiers:tModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
result |= tModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| static_modifier:fModifier af_modifiers:sModifier ppp_modifiers:tModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
result |= tModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| ppp_modifiers:fModifier static_modifier:sModifier af_modifiers:tModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
result |= tModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| ppp_modifiers:fModifier af_modifiers:sModifier static_modifier:tModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
result |= tModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| af_modifiers:fModifier static_modifier:sModifier ppp_modifiers:tModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
result |= tModifier.intValue();
RESULT = Integer.valueOf(result);
:}
| af_modifiers:fModifier ppp_modifiers:sModifier static_modifier:tModifier
{:
int result = 0;
result |= fModifier.intValue();
result |= sModifier.intValue();
result |= tModifier.intValue();
RESULT = Integer.valueOf(result);
:}
;
static_modifier ::=
T_STATIC
{:
RESULT = ASTPHP5Parser.STATIC;
:}
;
ppp_modifiers ::=
T_PUBLIC
{:
RESULT = ASTPHP5Parser.PUBLIC;
:}
| T_PROTECTED
{:
RESULT = ASTPHP5Parser.PROTECTED;
:}
| T_PRIVATE
{:
RESULT = ASTPHP5Parser.PRIVATE;
:}
;
af_modifiers ::=
T_ABSTRACT
{:
RESULT = ASTPHP5Parser.ABSTRACT;
:}
| T_FINAL
{:
RESULT = ASTPHP5Parser.FINAL;
:}
;
class_variable_declaration ::=
class_variable_declaration:list T_COMMA T_VARIABLE:var
{:
Variable varId = new Variable(varleft, varright, var);
list.add(new ASTNode[] {varId, null});
RESULT = list;
:}
| class_variable_declaration:list T_COMMA T_VARIABLE:var T_EQUAL static_scalar:expr
{:
Variable varId = new Variable(varleft, varright, var);
list.add(new ASTNode[] {varId, expr});
RESULT = list;
:}
| T_VARIABLE:var
{:
List list = new LinkedList();
Variable varId = new Variable(varleft, varright, var);
list.add(new ASTNode[] {varId, null});
RESULT = list;
:}
| T_VARIABLE:var T_EQUAL static_scalar:expr
{:
List list = new LinkedList();
Variable varId = new Variable(varleft, varright, var);
list.add(new ASTNode[] {varId, expr});
RESULT = list;
:}
;
constant_declaration ::=
constant_declaration:list T_COMMA string_st:constName T_EQUAL static_scalar_value:expr
{:
Identifier constId = new Identifier(constNameleft, constNameright, constName);
list.add(new ASTNode[] {constId, expr});
RESULT = list;
:}
| T_CONST string_st:constName T_EQUAL static_scalar_value:expr
{:
List list = new LinkedList();
Identifier constId = new Identifier(constNameleft, constNameright, constName);
list.add(new ASTNode[] {constId, expr});
RESULT = list;
:}
;
class_constant_declaration ::=
class_constant_declaration:list T_COMMA identifier_without_class:constName T_EQUAL static_scalar_value:expr
{:
list.add(new ASTNode[] {constName, expr});
RESULT = list;
:}
| T_CONST identifier_without_class:constId T_EQUAL static_scalar_value:expr
{:
List list = new LinkedList();
list.add(new ASTNode[] {constId, expr});
RESULT = list;
:}
;
echo_expr_list ::=
echo_expr_list:exprList T_COMMA expr:expr
{:
exprList.add(expr);
RESULT = exprList;
:}
| expr:expr
{:
List exprList = new LinkedList();
exprList.add(expr);
RESULT = exprList;
:}
;
for_expr ::=
/* empty */
{:
RESULT = new LinkedList();
:}
| non_empty_for_expr:exprList
{:
RESULT = exprList;
:}
;
non_empty_for_expr ::=
non_empty_for_expr:exprList T_COMMA expr:expr
{:
exprList.add(expr);
RESULT = exprList;
:}
| expr:expr
{:
List exprList = new LinkedList();
exprList.add(expr);
RESULT = exprList;
:}
;
expr_without_variable ::=
expr_without_variable_and_class_instance:ex
{:
RESULT = ex;
:}
| anonymous_class:ex
{:
RESULT = ex;
:}
| T_NEW:start class_name_reference:className ctor_arguments:ctor
{:
ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(startleft, ctorright, className, ctor);
RESULT = classInstanceCreation;
:}
| T_CLONE:start expr:expr
{:
CloneExpression clone = new CloneExpression(startleft, exprright, expr);
RESULT = clone;
:}
;
expr_without_variable_and_class_instance ::=
T_LIST:start T_OPEN_PARENTHESE array_pair_list:varList T_CLOSE_PARENTHESE:close T_EQUAL expr:expr
{:
ListVariable vars = new ListVariable(startleft, closeright, varList, ListVariable.SyntaxType.OLD);
Assignment list = new Assignment(startleft, exprright, vars, Assignment.Type.EQUAL, expr);
RESULT = list;
:}
| T_OPEN_RECT:start array_pair_list:varList T_CLOSE_RECT:close T_EQUAL expr:expr
{:
ListVariable vars = new ListVariable(startleft, closeright, varList, ListVariable.SyntaxType.NEW);
Assignment list = new Assignment(startleft, exprright, vars, Assignment.Type.EQUAL, expr);
RESULT = list;
:}
| variable:var T_EQUAL expr_with_yields:expr
{:
RESULT = new Assignment(varleft, exprright, var, Assignment.Type.EQUAL, expr);
:}
| variable:var T_EQUAL T_REFERENCE:reftoken variable:refvar
{:
RESULT = new Assignment(varleft, refvarright, var, Assignment.Type.EQUAL, new Reference(reftokenleft, refvarright, refvar));
:}
| variable:var T_EQUAL T_REFERENCE:reftoken T_NEW:start class_name_reference:className ctor_arguments:ctor
{:
ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(startleft, ctorright, className, ctor);
Reference reference = new Reference(reftokenleft, ctorright, classInstanceCreation);
Assignment assignment = new Assignment(varleft, ctorright, var, Assignment.Type.EQUAL, reference);
RESULT = assignment;
:}
| variable:var T_POW_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.POW_EQUAL, expr);
:}
| variable:var T_PLUS_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.PLUS_EQUAL, expr);
:}
| variable:var T_MINUS_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.MINUS_EQUAL, expr);
:}
| variable:var T_MUL_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.MUL_EQUAL, expr);
:}
| variable:var T_DIV_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.DIV_EQUAL, expr);
:}
| variable:var T_CONCAT_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.CONCAT_EQUAL, expr);
:}
| variable:var T_MOD_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.MOD_EQUAL, expr);
:}
| variable:var T_AND_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.AND_EQUAL, expr);
:}
| variable:var T_OR_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.OR_EQUAL, expr);
:}
| variable:var T_XOR_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.XOR_EQUAL, expr);
:}
| variable:var T_SL_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.SL_EQUAL, expr);
:}
| variable:var T_SR_EQUAL expr:expr
{:
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.SR_EQUAL, expr);
:}
| variable:var T_COALESCE_EQUAL expr:expr
{:
// PHP 7.4 Null Coalescing Assignment Operator
// https://wiki.php.net/rfc/null_coalesce_equal_operator
RESULT = new Assignment(varleft, exprright, var , Assignment.Type.COALESCE_EQUAL, expr);
:}
| rw_variable:var T_INC:token
{:
RESULT = new PostfixExpression(varleft, tokenright, var , PostfixExpression.Operator.INC);
:}
| T_INC:token rw_variable:var
{:
RESULT = new PrefixExpression(tokenleft, varright, var , PrefixExpression.Operator.INC);
:}
| rw_variable:var T_DEC:token
{:
RESULT = new PostfixExpression(varleft, tokenright, var , PostfixExpression.Operator.DEC);
:}
| T_DEC:token rw_variable:var
{:
RESULT = new PrefixExpression(tokenleft, varright, var , PrefixExpression.Operator.DEC);
:}
| expr:expr1 T_BOOLEAN_OR expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.BOOL_OR, expr2);
:}
| expr:expr1 T_BOOLEAN_AND expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.BOOL_AND, expr2);
:}
| expr:expr1 T_LOGICAL_OR expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.STRING_OR, expr2);
:}
| expr:expr1 T_LOGICAL_AND expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.STRING_AND, expr2);
:}
| expr:expr1 T_LOGICAL_XOR expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.STRING_XOR, expr2);
:}
| expr:expr1 T_OR expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.OR, expr2);
:}
| expr:expr1 T_REFERENCE expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.AND, expr2);
:}
| expr:expr1 T_KOVA expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.XOR, expr2);
:}
| expr:expr1 T_NEKUDA expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.CONCAT, expr2);
:}
| expr:expr1 T_POW expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.POW, expr2);
:}
| expr:expr1 T_PLUS expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.PLUS, expr2);
:}
| expr:expr1 T_MINUS expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.MINUS, expr2);
:}
| expr:expr1 T_TIMES expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.MUL, expr2);
:}
| expr:expr1 T_DIV expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.DIV, expr2);
:}
| expr:expr1 T_PRECENT expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.MOD, expr2);
:}
| expr:expr1 T_SL expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.SL, expr2);
:}
| expr:expr1 T_SR expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.SR, expr2);
:}
| T_PLUS:token expr:expr
{:
RESULT = new UnaryOperation(tokenleft, exprright, expr , UnaryOperation.Operator.PLUS);
:}
| T_MINUS:token expr:expr
{:
RESULT = new UnaryOperation(tokenleft, exprright, expr , UnaryOperation.Operator.MINUS);
:}
| T_NOT:token expr:expr
{:
RESULT = new UnaryOperation(tokenleft, exprright, expr , UnaryOperation.Operator.NOT);
:}
| T_TILDA:token expr:expr
{:
RESULT = new UnaryOperation(tokenleft, exprright, expr , UnaryOperation.Operator.TILDA);
:}
| expr:expr1 T_IS_IDENTICAL expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_IDENTICAL, expr2);
:}
| expr:expr1 T_IS_NOT_IDENTICAL expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_NOT_IDENTICAL, expr2);
:}
| expr:expr1 T_IS_EQUAL expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_EQUAL, expr2);
:}
| expr:expr1 T_IS_NOT_EQUAL expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_NOT_EQUAL, expr2);
:}
| expr:expr1 T_RGREATER expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.RGREATER, expr2);
:}
| expr:expr1 T_IS_SMALLER_OR_EQUAL expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_SMALLER_OR_EQUAL, expr2);
:}
| expr:expr1 T_LGREATER expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.LGREATER, expr2);
:}
| expr:expr1 T_IS_GREATER_OR_EQUAL expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_GREATER_OR_EQUAL, expr2);
:}
| expr:expr1 T_SPACESHIP expr:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.SPACESHIP, expr2);
:}
| expr:expr T_INSTANCEOF class_name_reference:className
{:
RESULT = new InstanceOfExpression(exprleft, classNameright, expr , className);
:}
| parenthesis_expr:expr
{:
RESULT = expr;
:}
| expr:condition T_QUESTION_MARK expr:ifTrue T_NEKUDOTAIM expr:ifFalse
{:
RESULT = new ConditionalExpression(conditionleft, ifFalseright, condition, ConditionalExpression.OperatorType.QUESTION_MARK, ifTrue, ifFalse);
:}
| expr:cond T_QUESTION_MARK T_NEKUDOTAIM expr:ifFalse
{:
RESULT = new ConditionalExpression(condleft, ifFalseright, cond, ConditionalExpression.OperatorType.ELVIS, null, ifFalse);
:}
| expr:cond T_COALESCE expr:ifFalse
{:
RESULT = new ConditionalExpression(condleft, ifFalseright, cond, ConditionalExpression.OperatorType.COALESCE, null, ifFalse);
:}
| internal_functions_in_yacc:expr
{:
RESULT = expr;
:}
| T_INT_CAST:token expr:expr
{:
RESULT = new CastExpression(tokenleft, exprright, expr , CastExpression.Type.INT);
:}
| T_DOUBLE_CAST:token expr:expr
{:
RESULT = new CastExpression(tokenleft, exprright, expr , CastExpression.Type.REAL);
:}
| T_STRING_CAST:token expr:expr
{:
RESULT = new CastExpression(tokenleft, exprright, expr , CastExpression.Type.STRING);
:}
| T_ARRAY_CAST:token expr:expr
{:
RESULT = new CastExpression(tokenleft, exprright, expr , CastExpression.Type.ARRAY);
:}
| T_OBJECT_CAST:token expr:expr
{:
RESULT = new CastExpression(tokenleft, exprright, expr , CastExpression.Type.OBJECT);
:}
| T_BOOL_CAST:token expr:expr
{:
RESULT = new CastExpression(tokenleft, exprright, expr , CastExpression.Type.BOOL);
:}
| T_UNSET_CAST:token expr:expr
{:
RESULT = new CastExpression(tokenleft, exprright, expr , CastExpression.Type.UNSET);
:}
| T_EXIT:start exit_expr:expr
{:
List expList = new LinkedList();
if (expr != null) {
expList.add(expr);
}
Identifier id = new Identifier(startleft, startright, start);
FunctionName name = new FunctionName(startleft, startright, id);
FunctionInvocation result = new FunctionInvocation(startleft, exprright, name, expList);
RESULT = result;
:}
| T_AT:start expr:expr
{:
IgnoreError ignoreError = new IgnoreError(startleft, exprright, expr);
RESULT = ignoreError;
:}
| scalar:scalar
{:
RESULT = scalar;
:}
| array_creation:array
{:
RESULT = array;
:}
| T_BACKQUATE:start encaps_list:list T_BACKQUATE:end
{:
BackTickExpression backTickExpression = new BackTickExpression(startleft, endright, list);
RESULT = backTickExpression;
:}
| T_PRINT:start expr:expr
{:
List expList = new LinkedList();
if (expr != null) {
expList.add(expr);
}
Identifier id = new Identifier(startleft, startright, "print");
FunctionName name = new FunctionName(startleft, startright, id);
FunctionInvocation result = new FunctionInvocation(startleft, exprright, name, expList);
RESULT = result;
:}
| T_FUNCTION:s is_reference:isReference
T_OPEN_PARENTHESE parameter_list:paramList T_CLOSE_PARENTHESE
lexical_vars:varsList
optional_return_type:returnType
T_CURLY_OPEN:blockStart inner_statement_list:list T_CURLY_CLOSE:blockEnd
{:
RESULT = new LambdaFunctionDeclaration(sleft, blockEndright, paramList, returnType, varsList,
new Block(blockStartleft, blockEndright, list), isReference.booleanValue(), false);
:}
| T_STATIC:st T_FUNCTION:s is_reference:isReference
T_OPEN_PARENTHESE parameter_list:paramList T_CLOSE_PARENTHESE
lexical_vars:varsList
optional_return_type:returnType
T_CURLY_OPEN:blockStart inner_statement_list:list T_CURLY_CLOSE:blockEnd
{:
RESULT = new LambdaFunctionDeclaration(sleft, blockEndright, paramList, returnType, varsList,
new Block(blockStartleft, blockEndright, list), isReference.booleanValue(), true);
:}
| T_FN:s is_reference:isReference T_OPEN_PARENTHESE parameter_list:paramList T_CLOSE_PARENTHESE optional_return_type:returnType T_DOUBLE_ARROW expr_with_yields_and_error:expr
{:
// PHP 7.4
RESULT = new ArrowFunctionDeclaration(sleft, exprright, paramList, returnType, expr, isReference.booleanValue(), false);
:}
| T_STATIC:st T_FN:s is_reference:isReference T_OPEN_PARENTHESE parameter_list:paramList T_CLOSE_PARENTHESE optional_return_type:returnType T_DOUBLE_ARROW expr_with_yields_and_error:expr
{:
// PHP 7.4
RESULT = new ArrowFunctionDeclaration(stleft, exprright, paramList, returnType, expr, isReference.booleanValue(), true);
:}
| expression_array_access:eaa
{:
RESULT = eaa;
:}
;
lexical_vars ::=
/* empty */
{:
RESULT = null;
:}
| T_USE:s T_OPEN_PARENTHESE lexical_var_list:list T_CLOSE_PARENTHESE:e
{:
RESULT = list;
:}
;
lexical_var_list ::=
lexical_var_list:list T_COMMA T_VARIABLE:var
{:
Variable v = new Variable(varleft, varright, var);
list.add(v);
RESULT = list;
:}
| lexical_var_list:list T_COMMA T_REFERENCE:ref T_VARIABLE:var
{:
list.add(new Reference (refleft, varright, new Variable(varleft, varright, var)));
RESULT = list;
:}
| T_VARIABLE:var
{:
List list = new LinkedList();
list.add(new Variable(varleft, varright, var));
RESULT = list;
:}
| T_REFERENCE:ref T_VARIABLE:var
{:
List list = new LinkedList();
list.add(new Reference (refleft, varright, new Variable(varleft, varright, var)));
RESULT = list;
:}
;
function_call ::=
namespace_name:list T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new FunctionInvocation(listleft, eright,
new FunctionName(listleft, listright,
new NamespaceName(listleft, listright, list, false, false)), parameters);
:}
| T_NAMESPACE:s T_NS_SEPARATOR namespace_name:list T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new FunctionInvocation(sleft, eright,
new FunctionName(sleft, listright,
new NamespaceName(sleft, listright, list, false, true)), parameters);
:}
| T_NS_SEPARATOR:s namespace_name:list T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new FunctionInvocation(sleft, eright,
new FunctionName(sleft, listright,
new NamespaceName(sleft, listright, list, true, false)), parameters);
:}
| class_name:className T_PAAMAYIM_NEKUDOTAYIM identifier:fn T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new StaticMethodInvocation(classNameleft, eright, className,
new FunctionInvocation(fnleft, eright,
new FunctionName(fnleft, fnright, fn), parameters));
:}
| class_name:className T_PAAMAYIM_NEKUDOTAYIM variable_without_objects:reflectionName T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new StaticMethodInvocation(classNameleft, eright, className,
new FunctionInvocation(reflectionNameleft, eright,
new FunctionName(reflectionNameleft, reflectionNameright, reflectionName), parameters));
:}
| class_name:className T_PAAMAYIM_NEKUDOTAYIM T_CURLY_OPEN:o expr:expr T_CURLY_CLOSE:c T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
ReflectionVariable reflectionVariable = new ReflectionVariable(oleft, cright, expr);
RESULT = new StaticMethodInvocation(classNameleft, eright, className,
new FunctionInvocation(oleft, eright,
new FunctionName(oleft, cright, reflectionVariable), parameters));
:}
| variable_class_name:className T_PAAMAYIM_NEKUDOTAYIM identifier:fn T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new StaticMethodInvocation(classNameleft, eright, className,
new FunctionInvocation(fnleft, eright,
new FunctionName(fnleft, fnright, fn), parameters));
:}
| variable_class_name:className T_PAAMAYIM_NEKUDOTAYIM variable_without_objects:reflectionName T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new StaticMethodInvocation(classNameleft, eright, className,
new FunctionInvocation(reflectionNameleft, eright,
new FunctionName(reflectionNameleft, reflectionNameright, reflectionName), parameters));
:}
| variable_class_name:className T_PAAMAYIM_NEKUDOTAYIM T_CURLY_OPEN:o expr:expr T_CURLY_CLOSE:c T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
ReflectionVariable reflectionVariable = new ReflectionVariable(oleft, cright, expr);
RESULT = new StaticMethodInvocation(classNameleft, eright, className,
new FunctionInvocation(oleft, eright,
new FunctionName(oleft, cright, reflectionVariable), parameters));
:}
| variable_without_objects:reflectionName T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new FunctionInvocation(reflectionNameleft, eright,
new FunctionName(reflectionNameleft, reflectionNameright, reflectionName), parameters);
:}
| callable_expr:start T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new FunctionInvocation(startleft, eright,
new FunctionName(startleft, startright, start), parameters);
:}
| function_call:var array_dimension:ad
{:
RESULT = new DereferencedArrayAccess(varleft, adright, var, ad);
:}
| function_call:call T_OPEN_PARENTHESE function_call_parameter_list:parameters T_CLOSE_PARENTHESE:e
{:
RESULT = new FunctionInvocation(callleft, eright,
new FunctionName(callleft, callright, call), parameters);
:}
;
callable_expr ::=
parenthesis_expr:expr
{:
RESULT = expr;
:}
| dereferencable_variable:dereferencableVariable
{:
RESULT = dereferencableVariable;
:}
| field_or_method_access:fma
{:
RESULT = fma;
:}
| T_OPEN_PARENTHESE:start anonymous_class:cls T_CLOSE_PARENTHESE:end
{:
AnonymousObjectVariable anonymous= new AnonymousObjectVariable(startleft, endright, cls);
RESULT = anonymous;
:}
| T_OPEN_PARENTHESE:start T_NEW:n class_name_reference:className ctor_arguments:ctor T_CLOSE_PARENTHESE:end
{:
ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(nleft, ctorright, className, ctor);
AnonymousObjectVariable anonymous = new AnonymousObjectVariable(startleft, endright, classInstanceCreation);
RESULT = anonymous;
:}
| T_CONSTANT_ENCAPSED_STRING:scalar
{:
RESULT = new Scalar(scalarleft, scalarright, scalar, Scalar.Type.STRING);
:}
| array_creation:array
{:
RESULT = array;
:}
;
class_name ::=
T_STATIC:s
{:
RESULT = new Identifier(sleft, sright, "static");
:}
| namespace_name:list
{:
RESULT = new NamespaceName(listleft, listright, list, false, false);
:}
| T_NAMESPACE:s T_NS_SEPARATOR namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, false, true);
:}
| T_NS_SEPARATOR:s namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, true, false);
:}
;
fully_qualified_class_name ::=
namespace_name:list
{:
RESULT = new NamespaceName(listleft, listright, list, false, false);
:}
| T_NAMESPACE:s T_NS_SEPARATOR namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, false, true);
:}
| T_NS_SEPARATOR:s namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, true, false);
:}
;
class_name_reference ::=
class_name:className
{:
RESULT = new ClassName(classNameleft, classNameright, className);
:}
| dynamic_class_name_reference:className
{:
RESULT = className;
:}
;
dynamic_class_name_reference ::=
base_variable:var T_OBJECT_OPERATOR object_property:firstVarProperty dynamic_class_name_variable_properties:propertyList
{:
// then get the aggregated list of properties (->...->...->...)
LinkedList list = (LinkedList) propertyList;
list.addFirst(firstVarProperty);
// now create the dispatch(es) nodes
VariableBase dispatch = null;
VariableBase dispatcher = var;
Iterator listIt = list.iterator();
while (listIt.hasNext()) {
VariableBase property = (VariableBase)listIt.next();
dispatch = parser.createDispatch(dispatcher, property);
dispatcher = dispatch;
}
// create class name from the dispatch
ClassName name = new ClassName(varleft, propertyListright, dispatch);
RESULT = name;
:}
| base_variable:var
{:
ClassName name = new ClassName(varleft, varright, var);
RESULT = name;
:}
;
dynamic_class_name_variable_properties ::=
dynamic_class_name_variable_properties:variables dynamic_class_name_variable_property:var
{:
variables.add(var);
RESULT = variables;
:}
| /* empty */
{:
RESULT = new LinkedList();
:}
;
dynamic_class_name_variable_property ::=
T_OBJECT_OPERATOR object_property:var
{:
RESULT = var;
:}
;
exit_expr ::=
/* empty */
{:
RESULT = null;
:}
| T_OPEN_PARENTHESE T_CLOSE_PARENTHESE
{:
RESULT = null;
:}
| T_OPEN_PARENTHESE expr:expr T_CLOSE_PARENTHESE
{:
RESULT = expr;
:}
;
ctor_arguments ::=
/* empty */
{:
RESULT = new LinkedList();
:}
| T_OPEN_PARENTHESE function_call_parameter_list:paramsList T_CLOSE_PARENTHESE
{:
RESULT = paramsList;
:}
;
common_scalar ::=
T_LNUMBER:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, scalar, Scalar.Type.INT);
RESULT = s;
:}
| T_DNUMBER:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, scalar, Scalar.Type.REAL);
RESULT = s;
:}
| T_CONSTANT_ENCAPSED_STRING:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, scalar, Scalar.Type.STRING);
RESULT = s;
:}
| T_LINE:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, "__LINE__", Scalar.Type.SYSTEM);
RESULT = s;
:}
| T_FILE:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, "__FILE__", Scalar.Type.SYSTEM);
RESULT = s;
:}
| T_DIR:scalar
{:
RESULT = new Scalar(scalarleft, scalarright, "__DIR__", Scalar.Type.SYSTEM);
:}
| T_CLASS_C:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, "__CLASS__", Scalar.Type.SYSTEM);
RESULT = s;
:}
| T_TRAIT_C:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, "__TRAIT__", Scalar.Type.SYSTEM);
RESULT = s;
:}
| T_METHOD_C:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, "__METHOD__", Scalar.Type.SYSTEM);
RESULT = s;
:}
| T_FUNC_C:scalar
{:
Scalar s = new Scalar(scalarleft, scalarright, "__FUNCTION__", Scalar.Type.SYSTEM);
RESULT = s;
:}
| T_NS_C:scalar
{:
RESULT = new Scalar(scalarleft, scalarright, "__NAMESPACE__", Scalar.Type.SYSTEM);
:}
| T_START_NOWDOC:start T_ENCAPSED_AND_WHITESPACE:scalar T_END_NOWDOC:end
{:
Scalar s = new Scalar(startleft, endright, scalar, Scalar.Type.STRING);
RESULT = s;
:}
| T_START_NOWDOC:start T_END_NOWDOC:end
{:
Scalar s = new Scalar(startleft, endright, "", Scalar.Type.STRING); //NOI18N
RESULT = s;
:}
;
static_scalar_value ::=
common_scalar:scalar
{:
RESULT = scalar;
:}
| namespace_name:list
{:
if (list.size() == 1) {
String itemName = ((Identifier)list.get(0)).getName();
String itemNameLower = itemName.toLowerCase();
if ("true".equals(itemNameLower) || "false".equals(itemNameLower)) { //NOI18N
RESULT = new Scalar(listleft, listright, itemName, Scalar.Type.STRING);
} else {
RESULT = new NamespaceName(listleft, listright, list, false, false);
}
} else {
RESULT = new NamespaceName(listleft, listright, list, false, false);
}
:}
| T_NAMESPACE:s T_NS_SEPARATOR namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, false, true);
:}
| T_NS_SEPARATOR:s namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, true, false);
:}
| static_class_constant:classConstant
{:
RESULT = classConstant;
:}
| heredoc:doc
{:
RESULT = doc;
:}
| static_operation:operation
{:
RESULT = operation;
:}
;
static_operation ::=
/*static_scalar_value T_OPEN_RECT static_scalar_value T_CLOSE_RECT
{:
RESULT = ???;
:}
| */
static_array_creation:arrayCreation
{:
RESULT = arrayCreation;
:}
| static_array_creation_with_access:arrayAccess
{:
RESULT = arrayAccess;
:}
| static_constant_array_access:arrayAccess
{:
RESULT = arrayAccess;
:}
| T_ENCAPSED_AND_WHITESPACE:str array_dimension_with_static_scalar_value:ad
{:
RESULT = new ExpressionArrayAccess(strleft, adright, new Identifier(strleft, strright, str), ad);
:}
| T_CONSTANT_ENCAPSED_STRING:str array_dimension_with_static_scalar_value:ad
{:
RESULT = new ExpressionArrayAccess(strleft, adright, new Identifier(strleft, strright, str), ad);
:}
| static_scalar_value:expr1 T_PLUS static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1, InfixExpression.OperatorType.PLUS, expr2);
:}
| static_scalar_value:expr1 T_MINUS static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1, InfixExpression.OperatorType.MINUS, expr2);
:}
| static_scalar_value:expr1 T_TIMES static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1, InfixExpression.OperatorType.MUL, expr2);
:}
| static_scalar_value:expr1 T_POW static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1, InfixExpression.OperatorType.POW, expr2);
:}
| static_scalar_value:expr1 T_DIV static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1, InfixExpression.OperatorType.DIV, expr2);
:}
| static_scalar_value:expr1 T_PRECENT static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1, InfixExpression.OperatorType.MOD, expr2);
:}
| T_NOT:token static_scalar_value:expr
{:
RESULT = new UnaryOperation(tokenleft, exprright, expr , UnaryOperation.Operator.NOT);
:}
| T_TILDA:token static_scalar_value:expr
{:
RESULT = new UnaryOperation(tokenleft, exprright, expr , UnaryOperation.Operator.TILDA);
:}
| static_scalar_value:expr1 T_OR static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.OR, expr2);
:}
| static_scalar_value:expr1 T_REFERENCE static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.AND, expr2);
:}
| static_scalar_value:expr1 T_KOVA static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.XOR, expr2);
:}
| static_scalar_value:expr1 T_SL static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.SL, expr2);
:}
| static_scalar_value:expr1 T_SR static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.SR, expr2);
:}
| static_scalar_value:expr1 T_NEKUDA static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.CONCAT, expr2);
:}
| static_scalar_value:expr1 T_LOGICAL_XOR static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.STRING_XOR, expr2);
:}
| static_scalar_value:expr1 T_LOGICAL_AND static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.STRING_AND, expr2);
:}
| static_scalar_value:expr1 T_LOGICAL_OR static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.STRING_OR, expr2);
:}
| static_scalar_value:expr1 T_BOOLEAN_AND static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.BOOL_AND, expr2);
:}
| static_scalar_value:expr1 T_BOOLEAN_OR static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.BOOL_OR, expr2);
:}
| static_scalar_value:expr1 T_IS_IDENTICAL static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_IDENTICAL, expr2);
:}
| static_scalar_value:expr1 T_IS_NOT_IDENTICAL static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_NOT_IDENTICAL, expr2);
:}
| static_scalar_value:expr1 T_IS_EQUAL static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_EQUAL, expr2);
:}
| static_scalar_value:expr1 T_IS_NOT_EQUAL static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_NOT_EQUAL, expr2);
:}
| static_scalar_value:expr1 T_RGREATER static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.RGREATER, expr2);
:}
| static_scalar_value:expr1 T_LGREATER static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.LGREATER, expr2);
:}
| static_scalar_value:expr1 T_IS_SMALLER_OR_EQUAL static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_SMALLER_OR_EQUAL, expr2);
:}
| static_scalar_value:expr1 T_IS_GREATER_OR_EQUAL static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.IS_GREATER_OR_EQUAL, expr2);
:}
| static_scalar_value:expr1 T_SPACESHIP static_scalar_value:expr2
{:
RESULT = new InfixExpression(expr1left, expr2right, expr1 , InfixExpression.OperatorType.SPACESHIP, expr2);
:}
| static_scalar_value:cond T_QUESTION_MARK T_NEKUDOTAIM static_scalar_value:ifFalse
{:
RESULT = new ConditionalExpression(condleft, ifFalseright, cond, ConditionalExpression.OperatorType.ELVIS, null, ifFalse);
:}
| static_scalar_value:condition T_QUESTION_MARK static_scalar_value:ifTrue T_NEKUDOTAIM static_scalar_value:ifFalse
{:
RESULT = new ConditionalExpression(conditionleft, ifFalseright, condition, ConditionalExpression.OperatorType.QUESTION_MARK, ifTrue, ifFalse);
:}
| static_scalar_value:cond T_COALESCE static_scalar_value:ifFalse
{:
RESULT = new ConditionalExpression(condleft, ifFalseright, cond, ConditionalExpression.OperatorType.COALESCE, null, ifFalse);
:}
| T_PLUS:start static_scalar_value:expr
{:
UnaryOperation op = new UnaryOperation(startleft, exprright, expr, UnaryOperation.Operator.PLUS);
RESULT = op;
:}
| T_MINUS:start static_scalar_value:expr
{:
UnaryOperation op = new UnaryOperation(startleft, exprright, expr, UnaryOperation.Operator.MINUS);
RESULT = op;
:}
| T_OPEN_PARENTHESE static_scalar_value:expr T_CLOSE_PARENTHESE
{:
RESULT = expr;
:}
;
static_scalar ::= /* compile-time evaluated scalars */
static_scalar_value:scalar
{:
RESULT = scalar;
:}
;
static_class_constant ::=
class_name:className T_PAAMAYIM_NEKUDOTAYIM static_reference_constant:constant
{:
RESULT = new StaticConstantAccess(classNameleft, constantright, className, constant);
:}
;
static_reference_constant ::=
static_class_constant_array_access:arrayAccess
{:
RESULT = arrayAccess;
:}
| identifier:constantName
{:
RESULT = constantName;
:}
;
static_class_constant_array_access ::=
static_class_constant_array_access:arrayAccess T_OPEN_RECT:o static_scalar_value:index T_CLOSE_RECT:end
{:
RESULT = new ExpressionArrayAccess(arrayAccessleft, endright, arrayAccess, new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_ARRAY));
:}
| identifier:constantName T_OPEN_RECT:o static_scalar_value:index T_CLOSE_RECT:end
{:
RESULT = new ExpressionArrayAccess(constantNameleft, endright, constantName, new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_ARRAY));
:}
;
static_constant_array_access ::=
static_constant_array_access:arrayAccess T_OPEN_RECT:o static_scalar_value:index T_CLOSE_RECT:end
{:
RESULT = new ExpressionArrayAccess(arrayAccessleft, endright, arrayAccess, new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_ARRAY));
:}
| T_STRING:constantName T_OPEN_RECT:o static_scalar_value:index T_CLOSE_RECT:end
{:
RESULT = new ExpressionArrayAccess(constantNameleft, endright, new Identifier(constantNameleft, constantNameright, constantName), new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_ARRAY));
:}
| namespace_name_access:namespace T_OPEN_RECT:o static_scalar_value:index T_CLOSE_RECT:end
{:
RESULT = new ExpressionArrayAccess(namespaceleft, endright, namespace, new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_ARRAY));
:}
;
static_array_creation_with_access ::=
static_array_creation:arr array_dimension_with_static_scalar_value:ad
{:
RESULT = new ExpressionArrayAccess(arrleft, adright, arr, ad);
:}
| static_array_creation_with_access:acc array_dimension_with_static_scalar_value:ad
{:
RESULT = new ExpressionArrayAccess(accleft, adright, acc, ad);
:}
;
static_array_creation ::=
T_ARRAY:start T_OPEN_PARENTHESE:o static_array_pair_list:list T_CLOSE_PARENTHESE:end
{:
Expression expr = new ArrayCreation(startleft, endright, list, ArrayCreation.Type.OLD);
RESULT = expr;
:}
| T_OPEN_RECT:start static_array_pair_list:list T_CLOSE_RECT:end
{:
Expression expr = new ArrayCreation(startleft, endright, list, ArrayCreation.Type.NEW);
RESULT = expr;
:}
;
scalar ::=
T_STRING_VARNAME:scalar
{:
RESULT = new Scalar(scalarleft, scalarright, scalar, Scalar.Type.STRING);
:}
| class_constant:classConstant
{:
RESULT = classConstant;
:}
| namespace_name:list
{:
if (list.size() == 1) {
String itemName = ((Identifier)list.get(0)).getName();
String itemNameLower = itemName.toLowerCase();
if ("true".equals(itemNameLower) || "false".equals(itemNameLower)) { //NOI18N
RESULT = new Scalar(listleft, listright, itemName, Scalar.Type.STRING);
} else {
RESULT = new NamespaceName(listleft, listright, list, false, false);
}
} else {
RESULT = new NamespaceName(listleft, listright, list, false, false);
}
:}
| T_NAMESPACE:s T_NS_SEPARATOR namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, false, true);
:}
| T_NS_SEPARATOR:s namespace_name:list
{:
RESULT = new NamespaceName(sleft, listright, list, true, false);
:}
| common_scalar:scalar
{:
RESULT = scalar;
:}
| T_QUATE:start encaps_list:list T_QUATE:end
{:
Quote quote = new Quote(startleft, endright, list, Quote.Type.QUOTE);
RESULT = quote;
:}
| heredoc:doc
{:
RESULT = doc;
:}
;
heredoc ::=
T_START_HEREDOC:start encaps_list:list T_END_HEREDOC:end
{:
Quote hereDoc = new Quote(startleft, endright, list, Quote.Type.HEREDOC);
RESULT = hereDoc;
:}
;
static_array_pair_list ::=
/* empty */
{:
List list = new LinkedList();
RESULT = list;
:}
| non_empty_static_array_pair_list:list possible_comma
{:
RESULT = list;
:}
;
/* do nothing */
possible_comma ::=
/* empty */
| T_COMMA
;
non_empty_static_array_pair_list ::=
non_empty_static_array_pair_list:list T_COMMA static_scalar:key T_DOUBLE_ARROW static_scalar:value
{:
ArrayElement element = new ArrayElement(keyleft, valueright, key, value);
list.add(element);
RESULT = list;
:}
| non_empty_static_array_pair_list:list T_COMMA static_scalar:value
{:
ArrayElement element = new ArrayElement(valueleft, valueright, value);
list.add(element);
RESULT = list;
:}
| non_empty_static_array_pair_list:list T_COMMA T_ELLIPSIS:ell static_scalar:value
{:
// PHP 7.4 Spread Operator In Array Expression
UnpackableArrayElement element = new UnpackableArrayElement(ellleft, valueright, value);
list.add(element);
RESULT = list;
:}
| static_scalar:key T_DOUBLE_ARROW static_scalar:value
{:
List list = new LinkedList();
ArrayElement element = new ArrayElement(keyleft, valueright, key, value);
list.add(element);
RESULT = list;
:}
| T_ELLIPSIS:ell static_scalar:value
{:
// PHP 7.4 Spread Operator In Array Expression
List list = new LinkedList();
UnpackableArrayElement element = new UnpackableArrayElement(ellleft, valueright, value);
list.add(element);
RESULT = list;
:}
| static_scalar:value
{:
List list = new LinkedList();
ArrayElement element = new ArrayElement(valueleft, valueright, value);
list.add(element);
RESULT = list;
:}
;
parenthesis_expr ::=
T_OPEN_PARENTHESE:start expr_without_class_instance:expr T_CLOSE_PARENTHESE:end
{:
ParenthesisExpression parenthesisExpression = new ParenthesisExpression(startleft, endright, expr);
RESULT = parenthesisExpression;
:}
;
yield_expr ::=
T_YIELD:s
{:
RESULT = new YieldExpression(sleft, sright, null);
:}
| T_YIELD:s yield_expr:expr
{:
RESULT = new YieldExpression(sleft, exprright, expr);
:}
| T_YIELD:s yield_from_expr:expr
{:
RESULT = new YieldExpression(sleft, exprright, expr);
:}
| T_YIELD:s expr:expr
{:
RESULT = new YieldExpression(sleft, exprright, expr);
:}
| T_YIELD:s expr:expr1 T_DOUBLE_ARROW expr:expr2
{:
RESULT = new YieldExpression(sleft, expr2right, expr1, expr2);
:}
| T_OPEN_PARENTHESE:start yield_expr:expr T_CLOSE_PARENTHESE:end
{:
ParenthesisExpression parenthesisExpression = new ParenthesisExpression(startleft, endright, expr);
RESULT = parenthesisExpression;
:}
;
yield_from_expr ::=
T_YIELD_FROM:s expr:expr
{:
RESULT = new YieldFromExpression(sleft, exprright, expr);
:}
| T_OPEN_PARENTHESE:start yield_from_expr:expr T_CLOSE_PARENTHESE:end
{:
ParenthesisExpression parenthesisExpression = new ParenthesisExpression(startleft, endright, expr);
RESULT = parenthesisExpression;
:}
;
expr_without_class_instance ::=
r_variable:var
{: RESULT = var; :}
| expr_without_variable_and_class_instance:ewv
{: RESULT = ewv; :}
;
expr ::=
r_variable:var
{: RESULT = var; :}
| expr_without_variable:ewv
{: RESULT = ewv; :}
;
expr_with_yields ::=
expr:expr
{:
RESULT = expr;
:}
| yield_expr:expr
{:
RESULT = expr;
:}
| yield_from_expr:expr
{:
RESULT = expr;
:}
;
expr_with_yields_and_error ::=
expr_with_yields:expr
{:
RESULT = expr;
:}
| error:expr
{:
RESULT = new ASTErrorExpression(exprleft, exprright);
:}
;
r_variable ::=
variable:var
{: RESULT = var; :}
;
w_variable ::=
variable:var
{: RESULT = var; :}
;
rw_variable ::=
variable:var
{: RESULT = var; :}
;
field_or_method_access ::=
base_variable_with_function_calls:var T_OBJECT_OPERATOR object_property:memberProperty method_or_not:paramsList array_access_or_not:aa variable_properties:propertyList
{:
RESULT = parser.createDispatch(false, var, memberProperty, memberPropertyleft, memberPropertyright, paramsList, paramsListright, propertyList, aa);
:}
//| base_variable_with_function_calls:var T_PAAMAYIM_NEKUDOTAYIM object_property:memberProperty method_or_not:paramsList array_access_or_not:aa variable_properties:propertyList
| function_call:var T_PAAMAYIM_NEKUDOTAYIM static_property:memberProperty method_or_not:paramsList array_access_or_not:aa variable_properties:propertyList
{:
RESULT = parser.createDispatch(true, var, memberProperty, memberPropertyleft, memberPropertyright, paramsList, paramsListright, propertyList, aa);
:}
| base_variable_without_reference_variable:var T_PAAMAYIM_NEKUDOTAYIM static_property:memberProperty method_or_not:paramsList array_access_or_not:aa variable_properties:propertyList
{:
RESULT = parser.createDispatch(true, var, memberProperty, memberPropertyleft, memberPropertyright, paramsList, paramsListright, propertyList, aa);
:}
| parenthesis_expr:pe T_OBJECT_OPERATOR object_property:memberProperty method_or_not:paramsList array_access_or_not:aa variable_properties:propertyList
{:
// e.g. ($uvs = new UVS())->method();
DereferencableVariable var = new DereferencableVariable(peleft, peright, pe.getExpression());
RESULT = parser.createDispatch(false, var, memberProperty, memberPropertyleft, memberPropertyright, paramsList, paramsListright, propertyList, aa);
:}
| parenthesis_expr:pe T_PAAMAYIM_NEKUDOTAYIM static_property:memberProperty method_or_not:paramsList array_access_or_not:aa variable_properties:propertyList
{:
// e.g. ($uvs = new UVS())::staticMethod();
DereferencableVariable var = new DereferencableVariable(peleft, peright, pe.getExpression());
RESULT = parser.createDispatch(true, var, memberProperty, memberPropertyleft, memberPropertyright, paramsList, paramsListright, propertyList, aa);
:}
;
variable ::=
field_or_method_access:acc
{:
RESULT = acc;
:}
| base_variable_with_function_calls:var
{:
RESULT = var;
:}
;
variable_properties ::=
variable_properties:variables variable_property:variableProperty
{:
variables.add(variableProperty);
RESULT = variables;
:}
| /* empty */
{:
RESULT = new LinkedList();
:}
;
variable_property ::=
T_OBJECT_OPERATOR object_property:memberProperty method_or_not:paramsList array_access_or_not:aa
{:
RESULT = parser.createDispatchProperty(false, memberProperty, memberPropertyleft, memberPropertyright, paramsList, paramsListright, aa);
:}
| T_PAAMAYIM_NEKUDOTAYIM static_property:memberProperty method_or_not:paramsList array_access_or_not:aa
{:
RESULT = parser.createDispatchProperty(true, memberProperty, memberPropertyleft, memberPropertyright, paramsList, paramsListright, aa);
:}
;
method_or_not ::=
T_OPEN_PARENTHESE function_call_parameter_list:paramsList T_CLOSE_PARENTHESE
{:
RESULT = paramsList;
:}
| /* empty */
{:
RESULT = null;
:}
;
array_dimension ::=
T_OPEN_RECT:o dim_offset:index T_CLOSE_RECT:end
{:
RESULT = new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_ARRAY);
:}
| T_CURLY_OPEN:o dim_offset:index T_CURLY_CLOSE:end
{:
RESULT = new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_HASHTABLE);
:}
;
array_dimension_with_static_scalar_value ::=
T_OPEN_RECT:o static_scalar_value:index T_CLOSE_RECT:end
{:
RESULT = new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_ARRAY);
:}
| T_CURLY_OPEN:o static_scalar_value:index T_CURLY_CLOSE:end
{:
RESULT = new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_HASHTABLE);
:}
;
array_access_or_not ::=
array_dimension:ad
{:
List list = new LinkedList();
list.add(ad);
RESULT = list;
:}
| array_access_or_not:list array_dimension:ad
{:
list.add(ad);
RESULT = list;
:}
| /* empty */
{:
RESULT = new LinkedList();
:}
;
variable_without_objects ::=
reference_variable:var
{:
RESULT = var;
:}
| simple_indirect_reference:ref_count reference_variable:var
{:
// the ref_count counts the number of reflection (DOLLAR sign) so now we should
// accomulate the dolars into reflection variables
Variable finalVar = var;
for (int i=0; i<ref_count.intValue(); i++) {
finalVar = new ReflectionVariable(ref_countright - i - 1, varright, finalVar);
}
RESULT = finalVar;
:}
;
static_member ::=
class_name:className T_PAAMAYIM_NEKUDOTAYIM variable_without_objects:var
{:
RESULT = new StaticFieldAccess(classNameleft, varright, className, var);
:}
| variable_class_name:className T_PAAMAYIM_NEKUDOTAYIM variable_without_objects:var
{:
RESULT = new StaticFieldAccess(classNameleft, varright, className, var);
:}
;
variable_class_name ::=
reference_variable:var
{:
RESULT = var;
:}
;
base_variable_with_function_calls ::=
base_variable:var
{: RESULT = var; :}
| function_call:var
{: RESULT = var; :}
;
expression_array_access ::=
constant_array_access:arrayAccess
{:
RESULT = arrayAccess;
:}
| T_ENCAPSED_AND_WHITESPACE:str array_dimension:ad
{:
RESULT = new ExpressionArrayAccess(strleft, adright, new Identifier(strleft, strright, str), ad);
:}
| T_CONSTANT_ENCAPSED_STRING:str array_dimension:ad
{:
RESULT = new ExpressionArrayAccess(strleft, adright, new Identifier(strleft, strright, str), ad);
:}
;
constant_array_access ::=
constant_array_access:arrayAccess array_dimension:ad
{:
RESULT = new ExpressionArrayAccess(arrayAccessleft, adright, arrayAccess, ad);
:}
| T_STRING:constantName array_dimension:ad
{:
RESULT = new ExpressionArrayAccess(constantNameleft, adright, new Identifier(constantNameleft, constantNameright, constantName), ad);
:}
| namespace_name_access:namespace array_dimension:ad
{:
RESULT = new ExpressionArrayAccess(namespaceleft, adright, namespace, ad);
:}
;
array_creation_with_access ::=
array_creation:arr array_dimension:ad
{:
RESULT = new ExpressionArrayAccess(arrleft, adright, arr, ad);
:}
| array_creation_with_access:acc array_dimension:ad
{:
RESULT = new ExpressionArrayAccess(accleft, adright, acc, ad);
:}
;
array_creation ::=
T_ARRAY:start T_OPEN_PARENTHESE array_pair_list:list T_CLOSE_PARENTHESE:end
{:
Expression expr = new ArrayCreation(startleft, endright, list, ArrayCreation.Type.OLD);
RESULT = expr;
:}
| T_OPEN_RECT:start array_pair_list:list T_CLOSE_RECT:end
{:
Expression expr = new ArrayCreation(startleft, endright, list, ArrayCreation.Type.NEW);
RESULT = expr;
:}
;
base_variable ::=
reference_variable:var
{:
RESULT = var;
:}
| base_variable_without_reference_variable:variable
{:
RESULT = variable;
:}
;
base_variable_without_reference_variable ::=
T_OPEN_PARENTHESE:start anonymous_class:cls T_CLOSE_PARENTHESE:end
{:
RESULT = new AnonymousObjectVariable(startleft, endright, cls);
:}
| T_OPEN_PARENTHESE:start T_NEW:n class_name_reference:className ctor_arguments:ctor T_CLOSE_PARENTHESE:end
{:
ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(nleft, ctorright, className, ctor);
RESULT = new AnonymousObjectVariable(startleft, endright, classInstanceCreation);
:}
| T_OPEN_PARENTHESE:start T_CLONE:c expr:expr T_CLOSE_PARENTHESE:end
{:
CloneExpression clone = new CloneExpression(cleft, exprright, expr);
RESULT = new AnonymousObjectVariable(startleft, endright, clone);
:}
| simple_indirect_reference:ref_count reference_variable:var
{:
// the ref_count counts the number of reflection (DOLLAR sign) so now we should
// accomulate the dolars into reflection variables
VariableBase finalVar = var;
for (int i=0; i<ref_count.intValue(); i++) {
finalVar = new ReflectionVariable(ref_countright - i - 1, varright, finalVar);
}
RESULT = finalVar;
:}
| static_member:staticFieldAccess
{:
RESULT = staticFieldAccess;
:}
| array_creation_with_access:arrayCreationWithAccess
{:
RESULT = arrayCreationWithAccess;
:}
| dereferencable_variable:dereferencableVariable
{:
RESULT = dereferencableVariable;
:}
;
dereferencable_variable ::=
T_OPEN_PARENTHESE:start variable:var T_CLOSE_PARENTHESE:end
{:
RESULT = new DereferencableVariable(startleft, endright, var);
:}
| parenthesis_expr:pe array_dimension:ad
{:
// e.g. ((string) $variable->something)[0];
DereferencableVariable dereferencableVariable = new DereferencableVariable(peleft, peright, pe.getExpression());
RESULT = new DereferencedArrayAccess(peleft, adright, dereferencableVariable, ad);
:}
| dereferencable_variable:var array_dimension:ad
{:
RESULT = new DereferencedArrayAccess(varleft, adright, var, ad);
:}
;
reference_variable ::=
reference_variable:varName array_dimension:ad
{:
Variable var = new ArrayAccess(varNameleft, adright, varName, ad);
RESULT = var;
:}
| compound_variable:comp_var
{: RESULT = comp_var; :}
;
compound_variable ::=
tracked_variable:var
{: RESULT = var; :}
| T_DOLLAR:start T_CURLY_OPEN expr:expr T_CURLY_CLOSE:end
{:
ReflectionVariable var = new ReflectionVariable(startleft, endright, expr);
RESULT = var;
:}
;
dim_offset ::=
/* empty */
{:
RESULT = null;
:}
| expr:expr
{:
RESULT = expr;
:}
;
static_property ::=
variable_without_objects:var
{:
RESULT = var;
:}
| static_reference_constant:var
{:
RESULT = var;
:}
;
object_property ::=
object_dim_list:var
{:
RESULT = var;
:}
| variable_without_objects:var
{:
RESULT = var;
:}
;
object_dim_list ::=
object_dim_list:var array_dimension:ad
{:
Variable varArray = new ArrayAccess(varleft, adright, var, ad);
RESULT = varArray;
:}
| variable_name:var
{: RESULT = var; :}
;
variable_name ::=
string_st:varName
{:
RESULT = new Variable(varNameleft, varNameright, varName);
:}
| T_CURLY_OPEN:start expr:expr T_CURLY_CLOSE:end
{:
RESULT = new ReflectionVariable(startleft, endright, expr);
:}
;
simple_indirect_reference ::=
T_DOLLAR
{:
RESULT = Integer.valueOf(1);
:}
| simple_indirect_reference:ref T_DOLLAR
{:
RESULT = Integer.valueOf(1 + ref.intValue());
:}
;
array_pair_list ::=
non_empty_array_pair_list:list
{:
RESULT = list;
:}
;
non_empty_array_pair_list ::=
non_empty_array_pair_list:list T_COMMA possible_array_pair:pair
{:
if(pair != null) {
list.add(pair);
}
RESULT = list;
:}
| possible_array_pair:pair
{:
List list = new LinkedList();
if(pair != null) {
list.add(pair);
}
RESULT = list;
:}
;
possible_array_pair ::=
/* empty */
{:
RESULT = null;
:}
| array_pair:pair
{:
RESULT = pair;
:}
;
array_pair ::=
expr:key T_DOUBLE_ARROW expr:value
{:
ArrayElement element = new ArrayElement(keyleft, valueright, key, value);
RESULT = element;
:}
| expr:expr
{:
ArrayElement element = new ArrayElement(exprleft, exprright, expr);
RESULT = element;
:}
| T_ELLIPSIS:ell expr:expr
{:
// PHP 7.4 Spread Operator In Array Expression
// https://wiki.php.net/rfc/spread_operator_for_array
UnpackableArrayElement unpack = new UnpackableArrayElement(ellleft, exprright, expr);
RESULT = unpack;
:}
| expr:expr T_DOUBLE_ARROW T_REFERENCE:start w_variable:var
{:
Reference value = new Reference(startleft, varright, var);
ArrayElement element = new ArrayElement(exprleft, varright, expr, value);
RESULT = element;
:}
| T_REFERENCE:start w_variable:var
{:
Reference ref = new Reference(startleft, varright, var);
ArrayElement element = new ArrayElement(startleft, varright, ref);
RESULT = element;
:}
| expr:expr T_DOUBLE_ARROW T_LIST:start T_OPEN_PARENTHESE array_pair_list:varList T_CLOSE_PARENTHESE:end
{:
ListVariable value = new ListVariable(startleft, endright, varList, ListVariable.SyntaxType.OLD);
ArrayElement element = new ArrayElement(exprleft, endright, expr, value);
RESULT = element;
:}
| T_LIST:start T_OPEN_PARENTHESE array_pair_list:varList T_CLOSE_PARENTHESE:end
{:
ListVariable vars = new ListVariable(startleft, endright, varList, ListVariable.SyntaxType.OLD);
ArrayElement element = new ArrayElement(startleft, endright, vars);
RESULT = element;
:}
;
encaps_list ::=
encaps_list:list encaps_var:var
{:
list.add(var);
RESULT = list;
:}
| encaps_list:list T_ENCAPSED_AND_WHITESPACE:string
{:
Scalar scalar = new Scalar(stringleft, stringright, string, string == null ? Scalar.Type.UNKNOWN : Scalar.Type.STRING);
list.add(scalar);
RESULT = list;
:}
| /* empty */
{:
RESULT = new LinkedList();
:}
;
encaps_var ::=
tracked_variable:var
{:
RESULT = var;
:}
| tracked_variable:varName T_OPEN_RECT:o encaps_var_offset:index T_CLOSE_RECT:end
{:
Variable var = new ArrayAccess(varNameleft, endright, varName, new ArrayDimension(oleft, endright, index, ArrayDimension.Type.VARIABLE_ARRAY));
RESULT = var;
:}
| tracked_variable:var T_OBJECT_OPERATOR string_st:string
{:
Variable property = new Variable(stringleft, stringright, string);
VariableBase dispatch = parser.createDispatch(var, property);
RESULT = dispatch;
:}
| T_DOLLAR_OPEN_CURLY_BRACES:start expr:expr T_CURLY_CLOSE:end
{:
ReflectionVariable var = new ReflectionVariable(startleft, endright, expr);
RESULT = var;
:}
| T_DOLLAR_OPEN_CURLY_BRACES:start T_STRING_VARNAME:varName T_OPEN_RECT:o expr:index T_CLOSE_RECT:c T_CURLY_CLOSE:end
{:
Variable var = new Variable(varNameleft, varNameright, varName);
Variable indexedVar = new ArrayAccess(startleft, endright, var, new ArrayDimension(oleft, cright, index, ArrayDimension.Type.VARIABLE_ARRAY));
RESULT = indexedVar;
:}
| T_CURLY_OPEN_WITH_DOLAR:start variable:var T_CURLY_CLOSE:end
{:
ReflectionVariable ref = new ReflectionVariable(startleft, endright, var);
RESULT = ref;
:}
;
encaps_var_offset ::=
string_st:string
{:
Identifier id = new Identifier(stringleft, stringright, string);
RESULT = id;
:}
| T_NUM_STRING:num
{:
Scalar scalar = new Scalar(numleft,numright, num, Scalar.Type.REAL);
RESULT = scalar;
:}
| tracked_variable:var
{:
RESULT = var;
:}
;
internal_functions_in_yacc ::=
T_ISSET:start T_OPEN_PARENTHESE isset_variables:varList possible_comma T_CLOSE_PARENTHESE:end
{:
Identifier id = new Identifier(startleft, startright, "isset");
FunctionName name = new FunctionName(startleft, startright, id);
FunctionInvocation result = new FunctionInvocation(startleft, endright, name, varList);
RESULT = result;
:}
| T_EMPTY:start T_OPEN_PARENTHESE variable:var T_CLOSE_PARENTHESE:end
{:
Identifier id = new Identifier(startleft, startright, "empty");
FunctionName name = new FunctionName(startleft, startright, id);
LinkedList varList = new LinkedList();
varList.add(var);
FunctionInvocation result = new FunctionInvocation(startleft, endright, name, varList);
RESULT = result;
:}
| T_EMPTY:start T_OPEN_PARENTHESE expr_without_variable:expr T_CLOSE_PARENTHESE:end
{:
Identifier id = new Identifier(startleft, startright, "empty");
FunctionName name = new FunctionName(startleft, startright, id);
LinkedList exprList = new LinkedList();
exprList.add(expr);
FunctionInvocation result = new FunctionInvocation(startleft, endright, name, exprList);
RESULT = result;
:}
| T_INCLUDE:include expr:expr
{:
Include result = new Include(includeleft, exprright, expr, Include.Type.INCLUDE);
RESULT = result;
:}
| T_INCLUDE_ONCE:include expr:expr
{:
Include result = new Include(includeleft, exprright, expr, Include.Type.INCLUDE_ONCE);
RESULT = result;
:}
| T_EVAL:start T_OPEN_PARENTHESE expr:expr T_CLOSE_PARENTHESE:end
{:
Identifier id = new Identifier(startleft, startright, "eval");
FunctionName name = new FunctionName(startleft, startright, id);
LinkedList exprList = new LinkedList();
exprList.add(expr);
FunctionInvocation result = new FunctionInvocation(startleft, endright, name, exprList);
RESULT = result;
:}
| T_REQUIRE:include expr:expr
{:
Include result = new Include(includeleft, exprright, expr, Include.Type.REQUIRE);
RESULT = result;
:}
| T_REQUIRE_ONCE:include expr:expr
{:
Include result = new Include(includeleft, exprright, expr, Include.Type.REQUIRE_ONCE);
RESULT = result;
:}
;
isset_variables ::=
isset_variable:var
{:
List list = new LinkedList();
list.add(var);
RESULT = list;
:}
| isset_variables:varList T_COMMA isset_variable:var
{:
varList.add(var);
RESULT = varList;
:}
;
isset_variable ::=
variable:var
{:
RESULT = var;
:}
| expression_array_access:arrayAccess
{:
RESULT = arrayAccess;
:}
| class_name:className T_PAAMAYIM_NEKUDOTAYIM constant_array_access:arrayAccess
{:
RESULT = new StaticConstantAccess(classNameleft, arrayAccessright, className, arrayAccess);
:}
| variable_class_name:className T_PAAMAYIM_NEKUDOTAYIM constant_array_access:arrayAccess
{:
RESULT = new StaticConstantAccess(classNameleft, arrayAccessright, className, arrayAccess);
:}
;
class_constant ::=
class_name:className T_PAAMAYIM_NEKUDOTAYIM reference_constant:constant
{:
RESULT = new StaticConstantAccess(classNameleft, constantright, className, constant);
:}
| variable_class_name:className T_PAAMAYIM_NEKUDOTAYIM reference_constant:constant
{:
RESULT = new StaticConstantAccess(classNameleft, constantright, className, constant);
:}
;
reference_constant ::=
reference_constant:constant array_dimension:ad
{:
RESULT = new ExpressionArrayAccess(constantleft, adright, constant, ad);
:}
| identifier:constantName
{:
RESULT = constantName;
:}
;
tracked_variable ::=
T_VARIABLE:varName
{:
RESULT = new Variable(varNameleft, varNameright, varName);
:}
;
string_st ::=
T_STRING:value
{: RESULT = value; :}
| T_DEFINE:value
{: RESULT = value; :}
;
anonymous_class ::=
T_NEW:start T_CLASS:c ctor_arguments:ctor
extends_from:superClass implements_list:interfaces
T_CURLY_OPEN:blockStart class_statement_list:statementList T_CURLY_CLOSE:blockEnd
{:
final int counter = parser.incrementAndGetAnonymousClassCounter();
Block block = new Block(blockStartleft, blockEndright, statementList);
ClassInstanceCreation classInstance = ClassInstanceCreation.anonymous(parser.getFileName(), counter, startleft, blockEndright, cleft, ctor, superClass, interfaces, block);
RESULT = classInstance;
:}
;