Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  ASTPHP5Parser.cup   Sprache: unbekannt

 
/*
 * 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.csl.api.OffsetRange;
import org.netbeans.modules.php.editor.parser.astnodes.*;
import org.openide.util.Pair;

parser code {:
    private static short[][] getActionTable() {}

    enum Access {
        NON_STATIC, STATIC, NULLSAFE
    }
    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 PUBLIC_SET = Integer.valueOf(BodyDeclaration.Modifier.PUBLIC_SET);
    protected final static Integer PRIVATE_SET = Integer.valueOf(BodyDeclaration.Modifier.PRIVATE_SET);
    protected final static Integer PROTECTED_SET = Integer.valueOf(BodyDeclaration.Modifier.PROTECTED_SET);
    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);
    protected final static Integer READONLY = Integer.valueOf(BodyDeclaration.Modifier.READONLY);

    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, Access> pair, List dimensions) {
        VariableBase dispatch = null;
        Expression property = pair.first();
        Access access = 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 (access == Access.STATIC) {
                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 {
                boolean isNullsafe = access == Access.NULLSAFE;
                dispatch = new FieldAccess(dispatcher.getStartOffset(), property.getEndOffset(), dispatcher, (Variable)property, isNullsafe);
            }
        } else if (property instanceof FunctionInvocation) {
            if (access == Access.STATIC) {
                dispatch = new StaticMethodInvocation(dispatcher.getStartOffset(), property.getEndOffset(), dispatcher, (FunctionInvocation)property);
            } else {
                boolean isNullsafe = access == Access.NULLSAFE;
                dispatch = new MethodInvocation(dispatcher.getStartOffset(), property.getEndOffset(), dispatcher, (FunctionInvocation)property, isNullsafe);
            }
        } 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, Access access) {
        return createDispatch(dispatcher, Pair.of(property, access), null);
    }

    public VariableBase createDispatch(VariableBase dispatcher, VariableBase property, Access access) {
        return createDispatch(dispatcher, property, null, access);
    }

    public VariableBase createDispatch(Access access, 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, access));

        // now create the dispatch(es) nodes
        VariableBase dispatch = null;
        VariableBase dispatcher = var;
        List arrayDimensiones = aa;
        Iterator listIt = list.iterator();
        while (listIt.hasNext()) {
            Pair<Expression, Access> property = (Pair<Expression, Access>) listIt.next();
            dispatch = createDispatch(dispatcher, property, arrayDimensiones);
            dispatcher = dispatch;
            arrayDimensiones = new LinkedList();
        }
        return dispatch;
    }

    public Pair<Expression, Access> createDispatchProperty(Access access, 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, access);
    }

    ClassName createClassName(VariableBase var, VariableBase firstVarProperty, List<Pair<VariableBase, Access>> propertyList, int varleft, int propertyListright, Access access) {
        // then get the aggregated list of properties ([->|?->]...[->|?->]...[->|?->]...)
        LinkedList<Pair<VariableBase, Access>> list = (LinkedList<Pair<VariableBase, Access>>) propertyList;
        list.addFirst(Pair.of(firstVarProperty, access));

        // now create the dispatch(es) nodes
        VariableBase dispatch = null;
        VariableBase dispatcher = var;
        Iterator<Pair<VariableBase, Access>> listIt = list.iterator();
        while (listIt.hasNext()) {
            Pair<VariableBase, Access> property = listIt.next();
            dispatch = createDispatch(dispatcher, property.first(), property.second());
            dispatcher = dispatch;
        }

        // create class name from the dispatch
        return new ClassName(varleft, propertyListright, dispatch);
    }

    Statement createAttributedStatement(Statement statement, List<Attribute> attributes) {
        Statement attributedStatement = statement;
        if (statement instanceof FunctionDeclaration) {
            attributedStatement = FunctionDeclaration.create((FunctionDeclaration) statement, attributes);
        } else if (statement instanceof ClassDeclaration) {
            attributedStatement = ClassDeclaration.create((ClassDeclaration) statement, attributes);
        } else if (statement instanceof InterfaceDeclaration) {
            attributedStatement = InterfaceDeclaration.create((InterfaceDeclaration) statement, attributes);
        } else if (statement instanceof TraitDeclaration) {
            attributedStatement = TraitDeclaration.create((TraitDeclaration) statement, attributes);
        } else if (statement instanceof FieldsDeclaration) {
            attributedStatement = FieldsDeclaration.create((FieldsDeclaration) statement, attributes);
        } else if (statement instanceof ConstantDeclaration) {
            attributedStatement = ConstantDeclaration.create((ConstantDeclaration) statement, attributes);
        } else if (statement instanceof MethodDeclaration) {
            attributedStatement = MethodDeclaration.create((MethodDeclaration) statement, attributes);
        } else if (statement instanceof EnumDeclaration) {
            attributedStatement = EnumDeclaration.create((EnumDeclaration) statement, attributes);
        } else if (statement instanceof CaseDeclaration) {
            attributedStatement = CaseDeclaration.create((CaseDeclaration) statement, attributes);
        } else {
            assert false;
        }
        return attributedStatement;
    }

    List<Identifier> createNamespaceNameSegments(int start, String name) {
        assert name != null;
        String[] names = name.split("\\\\"); // NOI18N
        int startSegment = start;
        List<Identifier> list = new ArrayList<>();
        for (String n : names) {
            if (n.equals("namespace") || n.isEmpty()) { // NOI18N
                startSegment += n.length() + 1; // length + \
                continue;
            }
            list.add(new Identifier(startSegment, startSegment + n.length(), n));
            startSegment += n.length() + 1; // length + \
        }
        return list;
    }

    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);
        }
     }

    void syntax_error() {
        syntax_error(cur_token);
    }

    /**
     * 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
 *
 * To keep existing values(see: ASTPHP5Symbols), add new one to end.
 * If the values are changed, it's incompatible.
 */

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_MATCH;
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_NULLSAFE_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;
terminal T_ATTRIBUTE;
terminal String T_READONLY;
terminal T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG; /* & */
terminal String T_ENUM; /* PHP 8.1 */
terminal String T_NAME_RELATIVE; /* PHP 8.0 namespace\Foo */
terminal String T_NAME_QUALIFIED; /* PHP 8.0 Foo\Bar */
terminal String T_NAME_FULLY_QUALIFIED; /* PHP 8.0 \Foo\Bar */
terminal String T_PUBLIC_SET, T_PROTECTED_SET, T_PRIVATE_SET; /* PHP 8.4 */

/* Non terminals */

non terminal Program thestart;
non terminal List namespace_name;
non terminal NamespaceName namespace_name_access;
non terminal NamespaceName legacy_namespace_name;
non terminal List namespace_declaration_name;
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 Expression argument;
non terminal Expression argument_expr;
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_with_class_instance;
non terminal Expression static_scalar_value;
non terminal Expression static_scalar_value_with_class_instance;
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_error;
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 Expression inline_function;
non terminal MatchExpression match;
non terminal List match_arm_list;
non terminal List non_empty_match_arm_list;
non terminal MatchArm match_arm;
non terminal List match_arm_condition_list;
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 Pair<Expression, List<ASTNode[]>> class_constant_declaration;
non terminal List constant_declaration;
non terminal Integer optional_property_modifiers;
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 Map<ClassDeclaration.Modifier, Set<OffsetRange>> class_entry_type;
non terminal Map<ClassDeclaration.Modifier, Set<OffsetRange>> class_modifiers;
non terminal ClassDeclaration.Modifier class_modifier;
non terminal Expression extends_from;
non terminal List implements_list;
non terminal List interface_list;
non terminal Expression optional_class_type_without_static;
non terminal Expression type_expr;
non terminal Expression type_expr_without_static;
non terminal Expression class_type;
non terminal Expression class_type_without_static;
non terminal List<Expression> union_type;
non terminal Expression union_type_element;
non terminal List<Expression> union_type_without_static;
non terminal Expression union_type_without_static_element;
non terminal List<Expression> intersection_type;
non terminal List<Expression> intersection_type_without_static;
non terminal ampersand;
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 Variable optional_tracked_variable;
non terminal Integer abstract_modifier;
non terminal Integer final_modifier;
non terminal Integer readonly_modifier;
non terminal Integer static_modifier;
non terminal Integer ppp_modifiers;
non terminal Integer ppp_set_modifiers;
non terminal Integer af_modifiers;
non terminal Integer member_modifiers;
non terminal Integer non_empty_member_modifiers;

non terminal ClassName class_name_reference;
non terminal StaticConstantAccess class_constant;
non terminal StaticConstantAccess enum_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 Pair<VariableBase, ASTPHP5Parser.Access> dynamic_class_name_variable_property;
non terminal VariableBase 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 class_constant_array_access;
non terminal Expression static_array_creation;
non terminal VariableBase base_variable_with_function_calls;
non terminal Expression new_expr;
non terminal ASTPHP5Parser.Access access_operator;

non terminal Expression enum_backing_type;
non terminal Statement enum_case;
non terminal Expression enum_case_expr;

non terminal List class_name_list;
/*
 * NETBEANS-4443 PHP 8.0 Attribute Syntax
 * - https://wiki.php.net/rfc/attributes_v2
 * - https://wiki.php.net/rfc/shorter_attribute_syntax
 * - https://wiki.php.net/rfc/shorter_attribute_syntax_change
 */
non terminal Attribute attribute;
non terminal List<Attribute> attributes;
non terminal AttributeDeclaration attribute_decl;
non terminal List<AttributeDeclaration> attribute_group;
non terminal Statement attributed_statement;
non terminal Statement attributed_interface_statement;
non terminal Statement attributed_class_statement;
non terminal Statement attributed_trait_statement;
non terminal FormalParameter attributed_parameter;

precedence nonassoc T_THROW;
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_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG;
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, T_READONLY, T_PUBLIC_SET, T_PROTECTED_SET, T_PRIVATE_SET;

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;
:}

| T_NAME_QUALIFIED:name
{:
    // e.g. Foo\Bar
    RESULT = parser.createNamespaceNameSegments(nameleft, name);
:}
;

namespace_declaration_name ::=
identifier: identifier
{:
    // e.g. Foo
    List list = new LinkedList();
    list.add(identifier);
    RESULT = list;

:}

| T_NAME_QUALIFIED:name
{:
    // e.g. Foo\Bar
    RESULT = parser.createNamespaceNameSegments(nameleft, name);
:}
;

legacy_namespace_name ::=
namespace_name:list
{:
    RESULT = new NamespaceName(listleft, listright, list, false, false);
:}

| T_NAME_FULLY_QUALIFIED:name
{:
    // e.g. \Foo\Bar
    RESULT = NamespaceName.create(nameleft, nameright, name);
:}
;

namespace_name_access ::=
T_STRING:name
{:
    RESULT = NamespaceName.create(nameleft, nameright, name);
:}

| T_DEFINE:name
{:
    RESULT = NamespaceName.create(nameleft, nameright, name);
:}

| T_NAME_QUALIFIED:name
{:
    // e.g. Foo\Bar
    RESULT = NamespaceName.create(nameleft, nameright, name);
:}

| T_NAME_FULLY_QUALIFIED:name
{:
    // e.g. \Foo\Bar
    RESULT = NamespaceName.create(nameleft, nameright, name);
:}

| T_NAME_RELATIVE:name
{:
    // e.g. namespace\Foo\Bar
    RESULT = NamespaceName.create(nameleft, nameright, name);
:}
;

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_MATCH: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);
:}

| T_READONLY: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();
:}
;

attributed_statement ::=
function_declaration_statement:statement
{:
    RESULT = statement;
:}

| class_declaration_statement:statement
{:
    RESULT = statement;
:}
;

top_statement ::=
statement:statement
{:
    RESULT = statement;
:}

| attributed_statement:statement
{:
    RESULT = statement;
:}

| attributes:attributes attributed_statement:statement
{:
    RESULT = parser.createAttributedStatement(statement, attributes);
:}

| T_HALT_COMPILER:halt
{:
    RESULT = new HaltCompiler(haltleft, haltright);
:}

| T_NAMESPACE:s namespace_declaration_name:list T_SEMICOLON:e
{:
    RESULT = new NamespaceDeclaration(sleft, eright,
        new NamespaceName(listleft, listright, list, false, false), null, false);
:}

| T_NAMESPACE:s namespace_declaration_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);
:}
;

attribute_decl ::=
class_name:name
{:
    RESULT = new AttributeDeclaration(nameleft, nameright, name, null);
:}

| class_name:name T_OPEN_PARENTHESE function_call_parameter_list:paramList T_CLOSE_PARENTHESE:e
{:
    RESULT = new AttributeDeclaration(nameleft, eright, name, paramList);
:}
;

attribute_group ::=
attribute_decl:decl
{:
    List list = new LinkedList();
    list.add(decl);
    RESULT = list;
:}

| attribute_group:list T_COMMA attribute_decl:decl
{:
    list.add(decl);
    RESULT = list;
:}
;

attribute ::=
T_ATTRIBUTE:start attribute_group:group possible_comma T_CLOSE_RECT:end
{:
    RESULT = new Attribute(startleft, endright, group);
:}
;

attributes ::=
attribute:attribute
{:
    List list = new LinkedList();
    list.add(attribute);
    RESULT = list;
:}

| attributes:list attribute:attribute
{:
    list.add(attribute);
    RESULT = list;
:}
;

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 ::=
legacy_namespace_name:name
{:
    RESULT = new SingleUseStatementPart(nameleft, nameright, name, null);
:}

| legacy_namespace_name:name T_AS T_STRING:aliasName
{:
    RESULT = new SingleUseStatementPart(nameleft, aliasNameright, name,
        new Identifier(aliasNameleft, aliasNameright, aliasName));
:}

| legacy_namespace_name:basens T_NS_SEPARATOR:s T_CURLY_OPEN:open group_namespace_parts:parts T_CURLY_CLOSE:close
{:
    RESULT = new GroupUseStatementPart(basensleft, closeright, basens, 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;
:}

| attributed_statement:statement
{:
    RESULT = statement;
:}

| attributes:attributes attributed_statement:statement
{:
    RESULT = parser.createAttributedStatement(statement, attributes);
:}
;

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 optional_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_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 optional_tracked_variable:variable T_CLOSE_PARENTHESE
 T_CURLY_OPEN:catchBlockStart inner_statement_list:catchList T_CURLY_CLOSE:catchBlockEnd
{:
    Block catchBlock = new Block(catchBlockStartleft, catchBlockEndright, catchList);
    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;
:}

| ampersand
{:
    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:modifiers 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(modifiersleft ,blockEndright, modifiers, 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;
:}

|
T_ENUM:start T_STRING:enumName enum_backing_type:type implements_list:interfaces
T_CURLY_OPEN:blockStart class_statement_list:statementList T_CURLY_CLOSE:blockEnd
{:
    Identifier name = new Identifier(enumNameleft, enumNameright, enumName);
    Block block = new Block(blockStartleft, blockEndright, statementList);
    EnumDeclaration enumDeclaration = new EnumDeclaration(startleft, blockEndright, name, type, interfaces, block);
    RESULT = enumDeclaration;
:}
;

interface_statement_list ::=
interface_statement_list:list interface_statement:interfaceStatement
{:
    list.add(interfaceStatement);
    RESULT = list;
:}

| /* empty */
{:
    List list = new LinkedList();
    RESULT = list;
:}
;

attributed_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 = ConstantDeclaration.create(constantStart, endright, modifier, list.first(), list.second(), 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;
:}
;

interface_statement ::=
attributed_interface_statement:statement
{:
    RESULT = statement;
:}

| attributes:attributes attributed_interface_statement:statement
{:
    RESULT = parser.createAttributedStatement(statement, attributes);
:}

| 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;
:}
;

attributed_trait_statement ::=
attributed_class_statement:statement
{:
    RESULT = statement;
:}
;

trait_statement ::=
attributed_trait_statement:statement
{:
    RESULT = statement;
:}

| attributes:attributes attributed_trait_statement:statement
{:
    RESULT = parser.createAttributedStatement(statement, attributes);
:}

| T_VAR_COMMENT:varComment
{:

:}

| T_USE:s use_traits:list use_traits_body:body
{:
    RESULT = new UseTraitStatement(sleft, bodyright, list, body);
:}
;

class_modifiers ::=
class_modifier:modifier
{:
    Map<ClassDeclaration.Modifier, Set<OffsetRange>> modifiers = new EnumMap<>(ClassDeclaration.Modifier.class);
    Set<OffsetRange> offsetRanges = new HashSet<>();
    offsetRanges.add(new OffsetRange(modifierleft, modifierright));
    modifiers.put(modifier, offsetRanges);
    RESULT = modifiers;
:}

| class_modifiers:modifiers class_modifier:modifier
{:
    Set<OffsetRange> offsetRanges = modifiers.get(modifier);
    if (offsetRanges == null) {
        offsetRanges = new HashSet<>();
    }
    offsetRanges.add(new OffsetRange(modifierleft, modifierright));
    modifiers.put(modifier, offsetRanges);
    RESULT = modifiers;
:}
;

class_modifier ::=
T_ABSTRACT
{:
    RESULT = ClassDeclaration.Modifier.ABSTRACT;
:}

| T_FINAL
{:
    RESULT = ClassDeclaration.Modifier.FINAL;
:}

| T_READONLY
{:
    // PHP 8.2 gh-4725
    RESULT = ClassDeclaration.Modifier.READONLY;
:}
;

class_entry_type ::=
T_CLASS
{:
--> --------------------

--> maximum size reached

--> --------------------

[ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge