1603 | prev_declared_program_name |
1604 | prev_declared_program_name |
1604 | prev_declared_global_var_name |
1605 | prev_declared_global_var_name |
1605 ; |
1606 ; |
1606 |
1607 |
1607 |
1608 |
1608 prev_declared_variable_name : prev_declared_variable_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1609 prev_declared_variable_name: prev_declared_variable_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1609 prev_declared_fb_name : prev_declared_fb_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1610 prev_declared_fb_name: prev_declared_fb_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1610 |
1611 |
1611 prev_declared_simple_type_name : prev_declared_simple_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1612 prev_declared_simple_type_name: prev_declared_simple_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1612 prev_declared_subrange_type_name : prev_declared_subrange_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1613 prev_declared_subrange_type_name: prev_declared_subrange_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1613 prev_declared_enumerated_type_name: prev_declared_enumerated_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1614 prev_declared_enumerated_type_name: prev_declared_enumerated_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1614 prev_declared_array_type_name : prev_declared_array_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1615 prev_declared_array_type_name: prev_declared_array_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1615 prev_declared_structure_type_name : prev_declared_structure_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1616 prev_declared_structure_type_name: prev_declared_structure_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1616 prev_declared_string_type_name : prev_declared_string_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1617 prev_declared_string_type_name: prev_declared_string_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; |
1617 prev_declared_ref_type_name : prev_declared_ref_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; /* defined in IEC 61131-3 v3 */ |
1618 prev_declared_ref_type_name: prev_declared_ref_type_name_token {$$ = new derived_datatype_identifier_c($1, locloc(@$));}; /* defined in IEC 61131-3 v3 */ |
1618 |
1619 |
1619 prev_declared_derived_function_name : prev_declared_derived_function_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1620 prev_declared_derived_function_name: prev_declared_derived_function_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1620 prev_declared_derived_function_block_name: prev_declared_derived_function_block_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1621 prev_declared_derived_function_block_name: prev_declared_derived_function_block_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1621 prev_declared_program_type_name : prev_declared_program_type_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1622 prev_declared_program_type_name: prev_declared_program_type_name_token {$$ = new identifier_c($1, locloc(@$));}; |
1622 |
1623 |
1623 |
1624 |
1624 |
1625 |
1625 /***************************/ |
1626 /***************************/ |
1626 /* B 0 - Programming Model */ |
1627 /* B 0 - Programming Model */ |
2603 ; |
2604 ; |
2604 |
2605 |
2605 simple_type_declaration: |
2606 simple_type_declaration: |
2606 /* simple_type_name ':' simple_spec_init */ |
2607 /* simple_type_name ':' simple_spec_init */ |
2607 /* To understand why simple_spec_init was brocken up into its consituent components in the following rules, please see note in the definition of 'enumerated_type_declaration'. */ |
2608 /* To understand why simple_spec_init was brocken up into its consituent components in the following rules, please see note in the definition of 'enumerated_type_declaration'. */ |
|
2609 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
2608 identifier ':' simple_specification {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} |
2610 identifier ':' simple_specification {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} |
|
2611 {if (!get_preparse_state()) ERROR;} |
|
2612 | identifier ':' elementary_type_name {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} ASSIGN constant |
|
2613 {if (!get_preparse_state()) ERROR;} |
|
2614 | identifier ':' prev_declared_simple_type_name {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} ASSIGN constant |
|
2615 {if (!get_preparse_state()) ERROR;} |
|
2616 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
2617 | prev_declared_simple_type_name ':' simple_spec_init |
2609 {$$ = new simple_type_declaration_c($1, $3, locloc(@$));} |
2618 {$$ = new simple_type_declaration_c($1, $3, locloc(@$));} |
2610 | identifier ':' elementary_type_name {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} ASSIGN constant |
2619 /* These three rules can now be safely replaced by the original rule abvoe!! */ |
2611 {$$ = new simple_type_declaration_c($1, new simple_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));} |
2620 /* |
2612 | identifier ':' prev_declared_simple_type_name {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} ASSIGN constant |
2621 | prev_declared_simple_type_name ':' simple_specification |
2613 {$$ = new simple_type_declaration_c($1, new simple_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));} |
2622 {$$ = new simple_type_declaration_c($1, $3, locloc(@$));} |
|
2623 | prev_declared_simple_type_name ':' elementary_type_name ASSIGN constant |
|
2624 {$$ = new simple_type_declaration_c($1, new simple_spec_init_c($3, $5, locf(@3), locl(@5)), locloc(@$));} |
|
2625 | prev_declared_simple_type_name ':' prev_declared_simple_type_name ASSIGN constant |
|
2626 {$$ = new simple_type_declaration_c($1, new simple_spec_init_c($3, $5, locf(@3), locl(@5)), locloc(@$));} |
|
2627 */ |
2614 /* ERROR_CHECK_BEGIN */ |
2628 /* ERROR_CHECK_BEGIN */ |
2615 | error ':' simple_spec_init |
2629 | error ':' simple_spec_init |
2616 {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for data type declaration.");yyerrok;} |
2630 {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for data type declaration.");yyerrok;} |
2617 | identifier simple_spec_init |
2631 | identifier simple_spec_init |
2618 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in simple type declaration."); yynerrs++;} |
2632 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in simple type declaration."); yynerrs++;} |
2681 ; |
2695 ; |
2682 |
2696 |
2683 |
2697 |
2684 subrange_type_declaration: |
2698 subrange_type_declaration: |
2685 /* subrange_type_name ':' subrange_spec_init */ |
2699 /* subrange_type_name ':' subrange_spec_init */ |
2686 identifier ':' subrange_spec_init |
2700 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
2687 {$$ = new subrange_type_declaration_c($1, $3, locloc(@$)); |
2701 identifier ':' subrange_spec_init {library_element_symtable.insert($1, prev_declared_subrange_type_name_token);} |
2688 library_element_symtable.insert($1, prev_declared_subrange_type_name_token); |
2702 {if (!get_preparse_state()) ERROR;} |
2689 } |
2703 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
2704 | prev_declared_subrange_type_name ':' subrange_spec_init |
|
2705 {$$ = new subrange_type_declaration_c($1, $3, locloc(@$));} |
2690 /* ERROR_CHECK_BEGIN */ |
2706 /* ERROR_CHECK_BEGIN */ |
2691 | error ':' subrange_spec_init |
2707 | error ':' subrange_spec_init |
2692 {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for subrange type declaration."); yyerrok;} |
2708 {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for subrange type declaration."); yyerrok;} |
2693 | identifier subrange_spec_init |
2709 | identifier subrange_spec_init |
2694 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in subrange type declaration."); yynerrs++;} |
2710 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in subrange type declaration."); yynerrs++;} |
2756 * |
2772 * |
2757 * If it were not for the above, we could use the rule |
2773 * If it were not for the above, we could use the rule |
2758 * identifier ':' enumerated_spec_init |
2774 * identifier ':' enumerated_spec_init |
2759 * and include the library_element_symtable.insert(...) code in the rule actions! |
2775 * and include the library_element_symtable.insert(...) code in the rule actions! |
2760 */ |
2776 */ |
|
2777 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
2761 identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} |
2778 identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} |
|
2779 {if (!get_preparse_state()) ERROR;} |
|
2780 | identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} ASSIGN enumerated_value |
|
2781 {if (!get_preparse_state()) ERROR;} |
|
2782 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
2783 /* Since the enumerated type name is placed in the library_element_symtable during preparsing, we can now safely use the single rule: */ |
|
2784 | prev_declared_enumerated_type_name ':' enumerated_spec_init |
|
2785 {$$ = new enumerated_type_declaration_c($1, $3, locloc(@$));} |
|
2786 /* These two rules are equivalent to the above rule */ |
|
2787 /* |
|
2788 | prev_declared_enumerated_type_name ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} |
2762 {$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, NULL, locloc(@3)), locloc(@$));} |
2789 {$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, NULL, locloc(@3)), locloc(@$));} |
2763 | identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} ASSIGN enumerated_value |
2790 | prev_declared_enumerated_type_name ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} ASSIGN enumerated_value |
2764 {$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));} |
2791 {$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));} |
|
2792 */ |
2765 /* ERROR_CHECK_BEGIN */ |
2793 /* ERROR_CHECK_BEGIN */ |
2766 | error ':' enumerated_spec_init |
2794 | error ':' enumerated_spec_init |
2767 {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for enumerated type declaration."); yyerrok;} |
2795 {$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for enumerated type declaration."); yyerrok;} |
2768 | identifier enumerated_spec_init |
2796 | identifier enumerated_spec_init |
2769 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in enumerated type declaration."); yynerrs++;} |
2797 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in enumerated type declaration."); yynerrs++;} |
2847 */ |
2875 */ |
2848 |
2876 |
2849 |
2877 |
2850 array_type_declaration: |
2878 array_type_declaration: |
2851 /* array_type_name ':' array_spec_init */ |
2879 /* array_type_name ':' array_spec_init */ |
2852 identifier ':' array_spec_init |
2880 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
2853 {$$ = new array_type_declaration_c($1, $3, locloc(@$)); |
2881 identifier ':' array_spec_init {library_element_symtable.insert($1, prev_declared_array_type_name_token);} |
2854 library_element_symtable.insert($1, prev_declared_array_type_name_token); |
2882 {if (!get_preparse_state()) ERROR;} |
2855 } |
2883 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
2884 | prev_declared_array_type_name ':' array_spec_init |
|
2885 {$$ = new array_type_declaration_c($1, $3, locloc(@$));} |
2856 /* ERROR_CHECK_BEGIN */ |
2886 /* ERROR_CHECK_BEGIN */ |
2857 | identifier array_spec_init |
2887 | identifier array_spec_init |
2858 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in array type declaration."); yynerrs++;} |
2888 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in array type declaration."); yynerrs++;} |
2859 /* ERROR_CHECK_END */ |
2889 /* ERROR_CHECK_END */ |
2860 ; |
2890 ; |
3001 |
3031 |
3002 |
3032 |
3003 |
3033 |
3004 structure_type_declaration: |
3034 structure_type_declaration: |
3005 /* structure_type_name ':' structure_specification */ |
3035 /* structure_type_name ':' structure_specification */ |
3006 identifier ':' structure_specification |
3036 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
3007 {$$ = new structure_type_declaration_c($1, $3, locloc(@$)); |
3037 identifier ':' structure_specification {library_element_symtable.insert($1, prev_declared_structure_type_name_token);} |
3008 library_element_symtable.insert($1, prev_declared_structure_type_name_token); |
3038 {if (!get_preparse_state()) ERROR;} |
3009 } |
3039 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
3040 | prev_declared_structure_type_name ':' structure_specification |
|
3041 {$$ = new structure_type_declaration_c($1, $3, locloc(@$));} |
3010 /* ERROR_CHECK_BEGIN */ |
3042 /* ERROR_CHECK_BEGIN */ |
3011 | identifier structure_specification |
3043 | identifier structure_specification |
3012 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in structure type declaration."); yynerrs++;} |
3044 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between data type name and specification in structure type declaration."); yynerrs++;} |
3013 /* ERROR_CHECK_END */ |
3045 /* ERROR_CHECK_END */ |
3014 ; |
3046 ; |
3186 string_type_name: identifier; |
3218 string_type_name: identifier; |
3187 */ |
3219 */ |
3188 |
3220 |
3189 string_type_declaration: |
3221 string_type_declaration: |
3190 /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ |
3222 /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ |
3191 identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init |
3223 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
3192 {$$ = new string_type_declaration_c($1, $3, $4, $5, locloc(@$)); |
3224 identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init {library_element_symtable.insert($1, prev_declared_string_type_name_token);} |
3193 library_element_symtable.insert($1, prev_declared_string_type_name_token); |
3225 {if (!get_preparse_state()) ERROR;} |
3194 } |
3226 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
3227 | prev_declared_string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init |
|
3228 {$$ = new string_type_declaration_c($1, $3, $4, $5, locloc(@$));} |
3195 ; |
3229 ; |
3196 |
3230 |
3197 |
3231 |
3198 /* helper symbol for string_type_declaration */ |
3232 /* helper symbol for string_type_declaration */ |
3199 string_type_declaration_size: |
3233 string_type_declaration_size: |
4818 */ |
4854 */ |
4819 ; |
4855 ; |
4820 |
4856 |
4821 |
4857 |
4822 derived_function_name: |
4858 derived_function_name: |
4823 identifier |
4859 identifier /* will never occur during normal parsing, only needed for preparsing to change it to a prev_declared_derived_function_name! */ |
4824 | prev_declared_derived_function_name |
4860 | prev_declared_derived_function_name |
4825 {$$ = $1; |
4861 {$$ = $1; |
4826 if (!allow_function_overloading) { |
4862 if (get_preparse_state() && !allow_function_overloading) {print_err_msg(locloc(@$), "Function overloading not allowed. Invalid identifier.\n"); yynerrs++;} |
4827 fprintf(stderr, "Function overloading not allowed. Invalid identifier %s\n", ((token_c *)($1))->value); |
|
4828 ERROR; |
|
4829 } |
|
4830 } |
4863 } |
4831 | AND |
4864 | AND |
4832 {$$ = new identifier_c("AND", locloc(@$)); |
4865 {$$ = new identifier_c("AND", locloc(@$)); |
4833 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"AND\" not allowed. Invalid identifier\n"); |
4866 if (!allow_function_overloading) {print_err_msg(locloc(@$), "Function overloading not allowed. Invalid identifier.\n"); yynerrs++;} |
4834 } |
4867 } |
4835 | OR |
4868 | OR |
4836 {$$ = new identifier_c("OR", locloc(@$)); |
4869 {$$ = new identifier_c("OR", locloc(@$)); |
4837 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"OR\" not allowed. Invalid identifier\n"); |
4870 if (!allow_function_overloading) {print_err_msg(locloc(@$), "Function overloading not allowed. Invalid identifier.\n"); yynerrs++;} |
4838 } |
4871 } |
4839 | XOR |
4872 | XOR |
4840 {$$ = new identifier_c("XOR", locloc(@$)); |
4873 {$$ = new identifier_c("XOR", locloc(@$)); |
4841 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"XOR\" not allowed. Invalid identifier\n"); |
4874 if (!allow_function_overloading) {print_err_msg(locloc(@$), "Function overloading not allowed. Invalid identifier.\n"); yynerrs++;} |
4842 } |
4875 } |
4843 | NOT |
4876 | NOT |
4844 {$$ = new identifier_c("NOT", locloc(@$)); |
4877 {$$ = new identifier_c("NOT", locloc(@$)); |
4845 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"NOT\" not allowed. Invalid identifier\n"); |
4878 if (!allow_function_overloading) {print_err_msg(locloc(@$), "Function overloading not allowed. Invalid identifier.\n"); yynerrs++;} |
4846 } |
4879 } |
4847 | MOD |
4880 | MOD |
4848 {$$ = new identifier_c("MOD", locloc(@$)); |
4881 {$$ = new identifier_c("MOD", locloc(@$)); |
4849 if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"MOD\" not allowed. Invalid identifier\n"); |
4882 if (!allow_function_overloading) {print_err_msg(locloc(@$), "Function overloading not allowed. Invalid identifier.\n"); yynerrs++;} |
4850 } |
4883 } |
4851 ; |
4884 ; |
4852 |
4885 |
4853 |
4886 |
4854 function_declaration: |
4887 function_declaration: |
4855 /* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
4888 /* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
4856 function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4889 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
|
4890 FUNCTION derived_function_name END_FUNCTION /* rule that is only expected to be used during preparse state => MUST print an error if used outside preparse() state!! */ |
|
4891 {$$ = NULL; |
|
4892 if (get_preparse_state()) {library_element_symtable.insert($2, prev_declared_derived_function_name_token);} |
|
4893 else {print_err_msg(locl(@1), locf(@3), "FUNCTION with no variable declarations and no body."); yynerrs++;} |
|
4894 } |
|
4895 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
4896 | function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4857 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
4897 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
4858 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
4898 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
4859 variable_name_symtable.pop(); |
4899 variable_name_symtable.pop(); |
4860 direct_variable_symtable.pop(); |
4900 direct_variable_symtable.pop(); |
4861 if (allow_function_overloading) { |
|
4862 switch (library_element_symtable.find_value($1)) { |
|
4863 case prev_declared_derived_function_name_token: |
|
4864 /* do nothing, already in map. */ |
|
4865 break; |
|
4866 case BOGUS_TOKEN_ID: |
|
4867 /* Not yet in map. Must insert...*/ |
|
4868 library_element_symtable.insert($1, prev_declared_derived_function_name_token); |
|
4869 break; |
|
4870 default: |
|
4871 /* Already in map but associated with something else other than a funtion name! */ |
|
4872 ERROR; |
|
4873 } |
|
4874 } else { |
|
4875 library_element_symtable.insert($1, prev_declared_derived_function_name_token); |
|
4876 } |
|
4877 } |
4901 } |
4878 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
4902 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
4879 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4903 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4880 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
4904 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
4881 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
4905 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
4882 variable_name_symtable.pop(); |
4906 variable_name_symtable.pop(); |
4883 direct_variable_symtable.pop(); |
4907 direct_variable_symtable.pop(); |
4884 if (allow_function_overloading) { |
|
4885 switch (library_element_symtable.find_value($1)) { |
|
4886 case prev_declared_derived_function_name_token: /* do nothing, already in map. */ break; |
|
4887 case BOGUS_TOKEN_ID: library_element_symtable.insert($1, prev_declared_derived_function_name_token); break; |
|
4888 default: ERROR; |
|
4889 } |
|
4890 } else { |
|
4891 library_element_symtable.insert($1, prev_declared_derived_function_name_token); |
|
4892 } |
|
4893 } |
4908 } |
4894 /* ERROR_CHECK_BEGIN */ |
4909 /* ERROR_CHECK_BEGIN */ |
4895 | function_name_declaration elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4910 | function_name_declaration elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4896 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after function name in function declaration."); yynerrs++;} |
4911 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing after function name in function declaration."); yynerrs++;} |
4897 | function_name_declaration derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4912 | function_name_declaration derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
5085 |
5101 |
5086 derived_function_block_name: identifier; |
5102 derived_function_block_name: identifier; |
5087 |
5103 |
5088 |
5104 |
5089 function_block_declaration: |
5105 function_block_declaration: |
5090 FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK |
5106 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
|
5107 FUNCTION_BLOCK derived_function_block_name END_FUNCTION_BLOCK /* rule that is only expected to be used during preparse state => MUST print an error if used outside preparse() state!! */ |
|
5108 {$$ = NULL; |
|
5109 if (get_preparse_state()) {library_element_symtable.insert($2, prev_declared_derived_function_block_name_token);} |
|
5110 else {print_err_msg(locl(@1), locf(@3), "FUNCTION_BLOCK with no variable declarations and no body."); yynerrs++;} |
|
5111 } |
|
5112 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
5113 | FUNCTION_BLOCK prev_declared_derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK |
5091 {$$ = new function_block_declaration_c($2, $3, $4, locloc(@$)); |
5114 {$$ = new function_block_declaration_c($2, $3, $4, locloc(@$)); |
5092 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
5115 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
5093 library_element_symtable.insert($2, prev_declared_derived_function_block_name_token); |
|
5094 /* Clear the variable_name_symtable. Since |
5116 /* Clear the variable_name_symtable. Since |
5095 * we have finished parsing the function block, |
5117 * we have finished parsing the function block, |
5096 * the variable names are now out of scope, so |
5118 * the variable names are now out of scope, so |
5097 * are no longer valid! |
5119 * are no longer valid! |
5098 */ |
5120 */ |
5106 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name in function block declaration."); yyerrok;} |
5128 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid function block name in function block declaration."); yyerrok;} |
5107 | FUNCTION_BLOCK derived_function_block_name function_block_body END_FUNCTION_BLOCK |
5129 | FUNCTION_BLOCK derived_function_block_name function_block_body END_FUNCTION_BLOCK |
5108 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared in function declaration."); yynerrs++;} |
5130 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared in function declaration."); yynerrs++;} |
5109 | FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list END_FUNCTION_BLOCK |
5131 | FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list END_FUNCTION_BLOCK |
5110 {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no body defined in function block declaration."); yynerrs++;} |
5132 {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no body defined in function block declaration."); yynerrs++;} |
|
5133 /* Rule already covered by the rule to handle the preparse state! |
5111 | FUNCTION_BLOCK derived_function_block_name END_FUNCTION_BLOCK |
5134 | FUNCTION_BLOCK derived_function_block_name END_FUNCTION_BLOCK |
5112 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared and body defined in function block declaration."); yynerrs++;} |
5135 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared and body defined in function block declaration."); yynerrs++;} |
|
5136 */ |
5113 | FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_OF_INPUT |
5137 | FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_OF_INPUT |
5114 {$$ = NULL; print_err_msg(locf(@1), locl(@2), "no variable(s) declared and body defined in function block declaration."); yynerrs++;} |
5138 {$$ = NULL; print_err_msg(locf(@1), locl(@2), "no variable(s) declared and body defined in function block declaration."); yynerrs++;} |
5115 | FUNCTION_BLOCK error END_FUNCTION_BLOCK |
5139 | FUNCTION_BLOCK error END_FUNCTION_BLOCK |
5116 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in function block declaration."); yyerrok;} |
5140 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in function block declaration."); yyerrok;} |
5117 /* ERROR_CHECK_END */ |
5141 /* ERROR_CHECK_END */ |
5238 /**********************/ |
5262 /**********************/ |
5239 program_type_name: identifier; |
5263 program_type_name: identifier; |
5240 |
5264 |
5241 |
5265 |
5242 program_declaration: |
5266 program_declaration: |
5243 PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM |
5267 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
|
5268 PROGRAM program_type_name END_PROGRAM /* rule that is only expected to be used during preparse state => MUST print an error if used outside preparse() state!! */ |
|
5269 {$$ = NULL; |
|
5270 if (get_preparse_state()) {library_element_symtable.insert($2, prev_declared_program_type_name_token);} |
|
5271 else {print_err_msg(locl(@1), locf(@3), "PROGRAM with no variable declarations and no body."); yynerrs++;} |
|
5272 } |
|
5273 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
5274 | PROGRAM prev_declared_program_type_name program_var_declarations_list function_block_body END_PROGRAM |
5244 {$$ = new program_declaration_c($2, $3, $4, locloc(@$)); |
5275 {$$ = new program_declaration_c($2, $3, $4, locloc(@$)); |
5245 library_element_symtable.insert($2, prev_declared_program_type_name_token); |
|
5246 /* Clear the variable_name_symtable. Since |
5276 /* Clear the variable_name_symtable. Since |
5247 * we have finished parsing the program declaration, |
5277 * we have finished parsing the program declaration, |
5248 * the variable names are now out of scope, so |
5278 * the variable names are now out of scope, so |
5249 * are no longer valid! |
5279 * are no longer valid! |
5250 */ |
5280 */ |
5254 /* ERROR_CHECK_BEGIN */ |
5284 /* ERROR_CHECK_BEGIN */ |
5255 | PROGRAM program_var_declarations_list function_block_body END_PROGRAM |
5285 | PROGRAM program_var_declarations_list function_block_body END_PROGRAM |
5256 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no program name defined in program declaration.");} |
5286 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no program name defined in program declaration.");} |
5257 | PROGRAM error program_var_declarations_list function_block_body END_PROGRAM |
5287 | PROGRAM error program_var_declarations_list function_block_body END_PROGRAM |
5258 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid program name in program declaration."); yyerrok;} |
5288 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid program name in program declaration."); yyerrok;} |
5259 | PROGRAM program_type_name function_block_body END_PROGRAM |
5289 | PROGRAM prev_declared_program_type_name function_block_body END_PROGRAM |
5260 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared in program declaration."); yynerrs++;} |
5290 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared in program declaration."); yynerrs++;} |
5261 | PROGRAM program_type_name program_var_declarations_list END_PROGRAM |
5291 | PROGRAM prev_declared_program_type_name program_var_declarations_list END_PROGRAM |
5262 {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no body defined in program declaration."); yynerrs++;} |
5292 {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no body defined in program declaration."); yynerrs++;} |
5263 | PROGRAM program_type_name END_PROGRAM |
5293 /* Rule already covered by the rule to handle the preparse state! |
|
5294 | PROGRAM prev_declared_program_type_name END_PROGRAM |
5264 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared and body defined in program declaration."); yynerrs++;} |
5295 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared and body defined in program declaration."); yynerrs++;} |
5265 | PROGRAM program_type_name program_var_declarations_list function_block_body END_OF_INPUT |
5296 */ |
|
5297 | PROGRAM prev_declared_program_type_name program_var_declarations_list function_block_body END_OF_INPUT |
5266 {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed program declaration."); yynerrs++;} |
5298 {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed program declaration."); yynerrs++;} |
5267 | PROGRAM error END_PROGRAM |
5299 | PROGRAM error END_PROGRAM |
5268 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in program declaration."); yyerrok;} |
5300 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in program declaration."); yyerrok;} |
5269 /* ERROR_CHECK_END */ |
5301 /* ERROR_CHECK_END */ |
5270 ; |
5302 ; |
5766 * |
5799 * |
5767 */ |
5800 */ |
5768 resource_type_name: any_identifier; |
5801 resource_type_name: any_identifier; |
5769 |
5802 |
5770 configuration_declaration: |
5803 configuration_declaration: |
5771 CONFIGURATION configuration_name |
5804 /* PRE_PARSING: The rules expected to be applied by the preparser. */ |
|
5805 CONFIGURATION configuration_name END_CONFIGURATION /* rule that is only expected to be used during preparse state */ |
|
5806 {$$ = NULL; |
|
5807 if (get_preparse_state()) {library_element_symtable.insert($2, prev_declared_configuration_name_token);} |
|
5808 else {print_err_msg(locl(@1), locf(@3), "no resource(s) nor program(s) defined in configuration declaration."); yynerrs++;} |
|
5809 } |
|
5810 /* STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
|
5811 | CONFIGURATION prev_declared_configuration_name |
5772 global_var_declarations_list |
5812 global_var_declarations_list |
5773 single_resource_declaration |
5813 single_resource_declaration |
5774 {variable_name_symtable.pop(); |
5814 {variable_name_symtable.pop(); |
5775 direct_variable_symtable.pop();} |
5815 direct_variable_symtable.pop();} |
5776 optional_access_declarations |
5816 optional_access_declarations |
5777 optional_instance_specific_initializations |
5817 optional_instance_specific_initializations |
5778 END_CONFIGURATION |
5818 END_CONFIGURATION |
5779 {$$ = new configuration_declaration_c($2, $3, $4, $6, $7, locloc(@$)); |
5819 {$$ = new configuration_declaration_c($2, $3, $4, $6, $7, locloc(@$)); |
5780 library_element_symtable.insert($2, prev_declared_configuration_name_token); |
|
5781 variable_name_symtable.pop(); |
5820 variable_name_symtable.pop(); |
5782 direct_variable_symtable.pop(); |
5821 direct_variable_symtable.pop(); |
5783 } |
5822 } |
5784 | CONFIGURATION configuration_name |
5823 | CONFIGURATION prev_declared_configuration_name |
5785 global_var_declarations_list |
5824 global_var_declarations_list |
5786 resource_declaration_list |
5825 resource_declaration_list |
5787 optional_access_declarations |
5826 optional_access_declarations |
5788 optional_instance_specific_initializations |
5827 optional_instance_specific_initializations |
5789 END_CONFIGURATION |
5828 END_CONFIGURATION |
5790 {$$ = new configuration_declaration_c($2, $3, $4, $5, $6, locloc(@$)); |
5829 {$$ = new configuration_declaration_c($2, $3, $4, $5, $6, locloc(@$)); |
5791 library_element_symtable.insert($2, prev_declared_configuration_name_token); |
|
5792 variable_name_symtable.pop(); |
5830 variable_name_symtable.pop(); |
5793 direct_variable_symtable.pop(); |
5831 direct_variable_symtable.pop(); |
5794 } |
5832 } |
5795 /* ERROR_CHECK_BEGIN */ |
5833 /* ERROR_CHECK_BEGIN */ |
5796 | CONFIGURATION |
5834 | CONFIGURATION |
5823 resource_declaration_list |
5861 resource_declaration_list |
5824 optional_access_declarations |
5862 optional_access_declarations |
5825 optional_instance_specific_initializations |
5863 optional_instance_specific_initializations |
5826 END_CONFIGURATION |
5864 END_CONFIGURATION |
5827 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;} |
5865 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;} |
|
5866 /* Rule already covered by the rule to handle the preparse state! |
5828 | CONFIGURATION configuration_name |
5867 | CONFIGURATION configuration_name |
5829 global_var_declarations_list |
5868 global_var_declarations_list |
5830 optional_access_declarations |
5869 optional_access_declarations |
5831 optional_instance_specific_initializations |
5870 optional_instance_specific_initializations |
5832 END_CONFIGURATION |
5871 END_CONFIGURATION |
5833 {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no resource(s) defined in configuration declaration."); yynerrs++;} |
5872 {$$ = NULL; print_err_msg(locl(@3), locf(@4), "no resource(s) defined in configuration declaration."); yynerrs++;} |
|
5873 */ |
5834 | CONFIGURATION configuration_name |
5874 | CONFIGURATION configuration_name |
5835 global_var_declarations_list |
5875 global_var_declarations_list |
5836 error |
5876 error |
5837 optional_access_declarations |
5877 optional_access_declarations |
5838 optional_instance_specific_initializations |
5878 optional_instance_specific_initializations |
8484 #define DEF_LIBFILENAME LIBDIRECTORY "/" LIBFILE |
8524 #define DEF_LIBFILENAME LIBDIRECTORY "/" LIBFILE |
8485 |
8525 |
8486 extern const char *INCLUDE_DIRECTORIES[]; |
8526 extern const char *INCLUDE_DIRECTORIES[]; |
8487 |
8527 |
8488 |
8528 |
8489 int stage2__(const char *filename, |
8529 static int parse_files(const char *libfilename, const char *filename) { |
8490 symbol_c **tree_root_ref |
8530 /* first parse the standard library file... */ |
8491 ) { |
8531 /* Do not debug the standard library, even if debug flag is set! |
8492 char *libfilename = NULL; |
|
8493 |
|
8494 if (runtime_options.includedir != NULL) { |
|
8495 INCLUDE_DIRECTORIES[0] = runtime_options.includedir; |
|
8496 } |
|
8497 |
|
8498 /* first parse the standard library file... */ |
|
8499 /* Do not debug the standard library, even if debug flag is set! */ |
|
8500 /* |
|
8501 #if YYDEBUG |
8532 #if YYDEBUG |
8502 yydebug = 1; |
8533 yydebug = 1; |
8503 #endif |
8534 #endif |
8504 */ |
8535 */ |
8505 |
|
8506 if ((libfilename = strdup3(INCLUDE_DIRECTORIES[0], "/", LIBFILE)) == NULL) { |
|
8507 fprintf (stderr, "Out of memory. Bailing out!\n"); |
|
8508 return -1; |
|
8509 } |
|
8510 |
|
8511 FILE *libfile = NULL; |
8536 FILE *libfile = NULL; |
8512 if((libfile = parse_file(libfilename)) == NULL) { |
8537 if((libfile = parse_file(libfilename)) == NULL) { |
8513 char *errmsg = strdup2("Error opening library file ", libfilename); |
8538 char *errmsg = strdup2("Error opening library file ", libfilename); |
8514 perror(errmsg); |
8539 perror(errmsg); |
8515 free(errmsg); |
8540 free(errmsg); |
8522 full_token_loc = runtime_options.full_token_loc; |
8547 full_token_loc = runtime_options.full_token_loc; |
8523 conversion_functions = runtime_options.conversion_functions; |
8548 conversion_functions = runtime_options.conversion_functions; |
8524 allow_ref_dereferencing = runtime_options.ref_standard_extensions; |
8549 allow_ref_dereferencing = runtime_options.ref_standard_extensions; |
8525 allow_ref_to_any = runtime_options.ref_nonstand_extensions; |
8550 allow_ref_to_any = runtime_options.ref_nonstand_extensions; |
8526 allow_ref_to_in_derived_datatypes = runtime_options.ref_nonstand_extensions; |
8551 allow_ref_to_in_derived_datatypes = runtime_options.ref_nonstand_extensions; |
8527 if (yyparse() != 0) |
8552 if (yyparse() != 0) ERROR; |
8528 ERROR; |
|
8529 fclose(libfile); |
8553 fclose(libfile); |
8530 |
8554 |
8531 if (yynerrs > 0) { |
8555 if (yynerrs > 0) { /* NOTE: yynerrs is a global variable */ |
8532 fprintf (stderr, "\n%d error(s) found in %s. Bailing out!\n", yynerrs /* global variable */, libfilename); |
8556 /* Hopefully the libraries do not contain any errors, so this should not occur! */ |
8533 ERROR; |
8557 fprintf (stderr, "\n%d error(s) found in %s. Bailing out!\n", yynerrs, libfilename); |
|
8558 return -2; |
8534 } |
8559 } |
8535 free(libfilename); |
8560 |
8536 |
8561 /* if by any chance the library is not complete, we now add the missing reserved keywords to the list!!! */ |
8537 /* if by any chance the library is not complete, we |
|
8538 * now add the missing reserved keywords to the list!!! |
|
8539 */ |
|
8540 for(int i = 0; standard_function_block_names[i] != NULL; i++) |
8562 for(int i = 0; standard_function_block_names[i] != NULL; i++) |
8541 if (library_element_symtable.find_value(standard_function_block_names[i]) == |
8563 if (library_element_symtable.find_value(standard_function_block_names[i]) == |
8542 library_element_symtable.end_value()) |
8564 library_element_symtable.end_value()) |
8543 library_element_symtable.insert(standard_function_block_names[i], standard_function_block_name_token); |
8565 library_element_symtable.insert(standard_function_block_names[i], standard_function_block_name_token); |
8544 |
8566 |
8571 |
8593 |
8572 if (yynerrs > 0) { |
8594 if (yynerrs > 0) { |
8573 fprintf (stderr, "\n%d error(s) found. Bailing out!\n", yynerrs /* global variable */); |
8595 fprintf (stderr, "\n%d error(s) found. Bailing out!\n", yynerrs /* global variable */); |
8574 exit(EXIT_FAILURE); |
8596 exit(EXIT_FAILURE); |
8575 } |
8597 } |
|
8598 |
|
8599 return 0; |
|
8600 } |
|
8601 |
|
8602 |
|
8603 |
|
8604 |
|
8605 |
|
8606 /* We parse the input source code twice!! |
|
8607 * 1st pass --> Pre-parsing |
|
8608 * ------------------------- |
|
8609 * The intention of the first pass is to fill up the library_element_symtable with the names of all |
|
8610 * the POUs (Functions, FBs, Programs and Configurations), as well as all the Derived Datatypes. |
|
8611 * |
|
8612 * During this pass POUs are only parsed until their name is obtained, and the remaining source |
|
8613 * code (variable declarations and body) is completely thrown away by flex. Datatype declarations |
|
8614 * however are parsed normally! |
|
8615 * |
|
8616 * At the end of the pre-parsing, the AST will contain only the derived datatype declarations, |
|
8617 * and this tree will be trown away (by simply resetting tree_root = NULL). |
|
8618 * More importantly, the library_element_symtable will contain the names of all the POUs and |
|
8619 * derived datatypes. |
|
8620 * |
|
8621 * 2st pass --> Normal parsing |
|
8622 * ---------------------------- |
|
8623 * In this second parse the whole source code is parsed correctly, and the AST is generated |
|
8624 * completely. |
|
8625 * |
|
8626 * However, if the pre-parsing has been done before this normal parsing, the POUs may appear |
|
8627 * in the source code in any order, as calling a POU (e.g. calling a function) that has not yet |
|
8628 * been declared will no longer generate a parsing error because the name of the function being |
|
8629 * called is already in the library_element_symtable. |
|
8630 * |
|
8631 * Declaring variables of datatypes that have not yet been declared will also be possible, as the |
|
8632 * datatypes will also already be in the library_element_symtable! |
|
8633 */ |
|
8634 |
|
8635 int stage2__(const char *filename, |
|
8636 symbol_c **tree_root_ref |
|
8637 ) { |
|
8638 char *libfilename = NULL; |
|
8639 |
|
8640 /* Determine the full path name of the standard library file... */ |
|
8641 if (runtime_options.includedir != NULL) |
|
8642 INCLUDE_DIRECTORIES[0] = runtime_options.includedir; |
|
8643 |
|
8644 if ((libfilename = strdup3(INCLUDE_DIRECTORIES[0], "/", LIBFILE)) == NULL) { |
|
8645 fprintf (stderr, "Out of memory. Bailing out!\n"); |
|
8646 exit(EXIT_FAILURE); |
|
8647 } |
|
8648 |
|
8649 /*******************************/ |
|
8650 /* Do the PRE parsing run...! */ |
|
8651 /*******************************/ |
|
8652 // fprintf (stderr, "----> Starting pre-parsing!\n"); |
|
8653 tree_root = NULL; |
|
8654 set_preparse_state(); |
|
8655 if (parse_files(libfilename, filename) < 0) |
|
8656 exit(EXIT_FAILURE); |
|
8657 // TODO: delete the current AST. For the moment, we leave all the objects in memory (not much of an issue in a program that always runs to completion). |
|
8658 |
|
8659 /*******************************/ |
|
8660 /* Do the main parsing run...! */ |
|
8661 /*******************************/ |
|
8662 // fprintf (stderr, "----> Starting normal parsing!\n"); |
|
8663 tree_root = NULL; |
|
8664 rst_preparse_state(); |
|
8665 if (parse_files(libfilename, filename) < 0) |
|
8666 exit(EXIT_FAILURE); |
8576 |
8667 |
|
8668 |
|
8669 /* Final clean-up... */ |
|
8670 free(libfilename); |
8577 if (tree_root_ref != NULL) |
8671 if (tree_root_ref != NULL) |
8578 *tree_root_ref = tree_root; |
8672 *tree_root_ref = tree_root; |
8579 |
8673 |
8580 return 0; |
8674 return 0; |
8581 } |
8675 } |