数组指针(指向数组的指针)

138 阅读1分钟

1.XML程序

<?xml version="1.0" encoding="utf-8"?>
<project xmlns:ns1="http://www.plcopen.org/xml/tc6.xsd" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201">
    <fileHeader companyName="sugon" productName="sugon" productVersion="1" creationDateTime="2023-12-21T14:55:25"/>
    <contentHeader name="sugon" modificationDateTime="2023-12-21T14:55:25">
    </contentHeader>
    <types>
        <dataTypes></dataTypes>
        <pous>
            <pou name="prg_sfc" pouType="program">
                <interface>
                    <localVars>
                        <variable name="p_glbArr">
                            <type>
                                <pointer>
                                    <baseType>
                                        <array>
                                            <dimension lower="0" upper="2"/>
                                            <dimension lower="0" upper="3"/>
                                            <baseType>
                                                <LINT/>
                                            </baseType>
                                        </array>
                                    </baseType>
                                </pointer>
                            </type>
                            <initialValue>
                                <simpleValue value="REF(A)"/>
                            </initialValue>
                        </variable>
                    </localVars>
                </interface>
                <body>
                </body>
            </pou>
        </pous>
    </types>
    <instances>
        <configurations>
            <configuration name="Config0">
                <resource name="Res0">
                    <task name="task0" priority="1" interval="T#20ms">
                        <pouInstance name="instance0" typeName="prg_sfc"/>
                    </task>
                </resource>
            </configuration>
        </configurations>
    </instances>
</project>

2.ST代码

PROGRAM prg_sfc
    VAR
    A : ARRAY [0..2,0..3] OF LINT := [1,2,3,4,5,6,7,8,9];
  END_VAR
  VAR
    p_glbArr : REF_TO ARRAY [0..2,0..3] OF LINT := REF(A);
  END_VAR

END_PROGRAM


CONFIGURATION Config0
  RESOURCE Res0 ON PLC
    TASK task0(INTERVAL := T#20ms,PRIORITY := 1);
    PROGRAM instance0 WITH task0 : prg_sfc;
  END_RESOURCE
END_CONFIGURATION

3.相关matiec程序

/* NOTE: in IEC 61131-3 v3, the formal syntax definition does not define non_generic_type_name to include FB type names.
 *       However, in section "6.3.4.10 References", example 4 includes a  REF_TO a FB type!
 *       We have therefore explicitly added the "REF_TO function_block_type_name" to this rule!
 * NOTE: the REF_TO ANY is a non-standard extension to the standard. This is basically equivalent to a (void *)
 */
ref_spec_non_recursive: /* helper symbol, used to remove a reduce/reduce conflict in a non-standard syntax I (Mario) have added!! */
  REF_TO non_generic_type_name
	{$$ = new ref_spec_c($2, locloc(@$));}
| REF_TO function_block_type_name
	{$$ = new ref_spec_c($2, locloc(@$));}
| REF_TO ANY
	{$$ = new ref_spec_c(new generic_type_any_c(locloc(@2)), locloc(@$));
	 if (!allow_ref_to_any) {
	   print_err_msg(locf(@$), locl(@$), "REF_TO ANY datatypes are not allowed (use -R option to activate support for this non-standard syntax)."); 
	   yynerrs++;
	 }
	}
;
non_generic_type_name:
  elementary_type_name
| derived_type_name
;
derived_type_name:
  single_element_type_name
| prev_declared_array_type_name
| prev_declared_structure_type_name
| prev_declared_string_type_name
| prev_declared_ref_type_name  /* as defined in IEC 61131-3 v3 */
;

4.普通指针

相关C程序
DECLARE_REFTO_TYPE(__REF_TO_INT, INT*)

__DECLARE_VAR(__REF_TO_INT,PT)
相关matiec程序
this->current_var_type_symbol->accept(*this);
SYM_REF1(ref_spec_c, type_name)
void *visit(ref_spec_c *symbol) { 
  int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id");
  if (implicit_id_count  > 1) ERROR;
  if (implicit_id_count == 1) {
      /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype
       * has already been defined. So, we simly print out the id of that C datatpe...
       */
    return symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*this);
  }
  /* This is NOT part of an implicitly declared datatype (i.e. we are being called from an visit(ref_type_decl_c *),
   * through the visit(ref_spec_init_c*)), so we need to simply print out the name of the datatype we reference to.
   */
  //debug_c::print(symbol); ERROR;
  symbol->type_name->accept(*this);
  s4o.print("*");
  return NULL;
}

5.功能块指针

// FUNCTION_BLOCK FB_ST
// Data part
typedef struct {
  // FB Interface - IN, OUT, IN_OUT variables
  __DECLARE_VAR(BOOL,EN)
  __DECLARE_VAR(BOOL,ENO)
  __DECLARE_VAR(BOOL,FB_ARR1)
  __DECLARE_VAR(BOOL,OUTPUT)

  // FB private variables - TEMP, private and located variables
} FB_ST;

__DECLARE_REFTO_TYPE(__REF_TO_FB_ST, FB_ST*)

__DECLARE_VAR(__REF_TO_FB_ST,PT)

6.修改方案

ref_spec_non_recursive: /* helper symbol, used to remove a reduce/reduce conflict in a non-standard syntax I (Mario) have added!! */
  REF_TO non_generic_type_name
	{$$ = new ref_spec_c($2, locloc(@$));}
| REF_TO function_block_type_name
	{$$ = new ref_spec_c($2, locloc(@$));}
| REF_TO array_specification
    {$$ = new ref_spec_c($2, locloc(@$));}
| REF_TO ANY
	{$$ = new ref_spec_c(new generic_type_any_c(locloc(@2)), locloc(@$));
	 if (!allow_ref_to_any) {
	   print_err_msg(locf(@$), locl(@$), "REF_TO ANY datatypes are not allowed (use -R option to activate support for this non-standard syntax)."); 
	   yynerrs++;
	 }
	}
;

7.生成C程序