1.指针的简单应用
PROGRAM program0
VAR
A : INT := 250;
pt : REF_TO INT;
Data : INT;
END_VAR
pt := REF(A);
Data := pt^;
END_PROGRAM
CONFIGURATION Config0
RESOURCE Res0 ON PLC
TASK task0(INTERVAL := T#20ms,PRIORITY := 0);
PROGRAM instance0 WITH task0 : program0;
END_RESOURCE
END_CONFIGURATION
编译之后的POUS.c
void PROGRAM0_init__(PROGRAM0 *data__, BOOL retain) {
__INIT_VAR(data__->A,250,retain)
__INIT_VAR(data__->PT,NULL,retain)
__INIT_VAR(data__->DATA,0,retain)
}
// Code part
void PROGRAM0_body__(PROGRAM0 *data__) {
// Initialise TEMP variables
__SET_VAR(data__->,PT,,((__GET_VAR_REF(data__->A,))));
__SET_VAR(data__->,DATA,,(*__GET_VAR(data__->PT,)));
goto __end;
__end:
return;
} // PROGRAM0_body__()
2.期望类似于C语言*p=250的应用
PROGRAM program0
VAR
A : INT := 250;
pt : REF_TO INT;
Data : INT;
END_VAR
pt := REF(A);
pt^ := 520;
END_PROGRAM
CONFIGURATION Config0
RESOURCE Res0 ON PLC
TASK task0(INTERVAL := T#20ms,PRIORITY := 0);
PROGRAM instance0 WITH task0 : program0;
END_RESOURCE
END_CONFIGURATION
编译之后的POUS.c
void PROGRAM0_init__(PROGRAM0 *data__, BOOL retain) {
__INIT_VAR(data__->A,250,retain)
__INIT_VAR(data__->PT,NULL,retain)
__INIT_VAR(data__->DATA,0,retain)
}
// Code part
void PROGRAM0_body__(PROGRAM0 *data__) {
// Initialise TEMP variables
__SET_VAR(data__->,PT,,((__GET_VAR_REF(data__->A,))));
__SET_VAR(data__->,(*PT),(*),520); //应该是 __SET_VAR(data__->,*__GET_VAR(data__->PT,),,520);
goto __end;
__end:
return;
} // PROGRAM0_body__()
3.SET_VAR相关的宏定义
#define __SET_VAR(prefix, name, suffix, new_value)\
if (!(prefix name.flags & __IEC_FORCE_FLAG)) prefix name.value suffix = new_value
//
#define __GET_VAR_BY_REF(name, ...)\
((name.flags & __IEC_FORCE_FLAG) ? &(name.fvalue __VA_ARGS__) : &(name.value __VA_ARGS__))
//获取name变量本身的引用
#define __GET_VAR_REF(name, ...)\
(&(name.value __VA_ARGS__))
//获取name变量本身的解引用
#define __GET_VAR_DREF(name, ...)\
(*(name.value __VA_ARGS__))
4.bison中关于变量赋值定义的规则
variable:
symbolic_variable
| prev_declared_direct_variable
| eno_identifier
{$$ = new symbolic_variable_c($1, locloc(@$)); $$->token = $1->token;}
;
symbolic_variable:
/* NOTE: To be entirely correct, variable_name must be replacemed by
* prev_declared_variable_name | prev_declared_fb_name | prev_declared_global_var_name
*/
prev_declared_fb_name
{$$ = new symbolic_variable_c($1, locloc(@$)); $$->token = $1->token;}
| prev_declared_global_var_name
{$$ = new symbolic_variable_c($1, locloc(@$)); $$->token = $1->token;}
| prev_declared_variable_name
{$$ = new symbolic_variable_c($1, locloc(@$)); $$->token = $1->token;}
| multi_element_variable
/*
| identifier
{$$ = new symbolic_variable_c($1, locloc(@$)); $$->token = $1->token;}
*/
| symbolic_variable '^'
/* Dereferencing operator defined in IEC 61131-3 v3. However, implemented here differently then how it is defined in the standard! See following note for explanation! */
{$$ = new deref_operator_c($1, locloc(@$));
if (!allow_ref_dereferencing) {
print_err_msg(locf(@$), locl(@$), "Derefencing REF_TO datatypes with '^' is not allowed (use -r option to activate support for this IEC 61131-3 v3 feature).");
yynerrs++;
}
}
/*自己添加的解引用规则*/
| deref_expression
{$$ = new deref_expression_c($1, locloc(@$));}
;
5.对比codesys