模块声明
模块的声明是使用自己的描述语言完成的,这类似于结构化文本(ST)代码中的变量声明。
模块声明的格式
表单的标题 MODULE<name>
开始声明。接下来是“部分”列表。
每个部分都通过关键字进行介绍 SEC
(“部分”)和唯一的名称。关键词 END_SEC
关闭该部分。节的内容包含由更多节或所谓的定义组成的条目列表。
定义由名称和可选值组成,并以分号结尾。
注释可以像 ST 代码一样使用:“//”用于单行注释,“(*”和“*)”用于多行注释。空白(制表符和空格)和换行符/换行符可用于分隔各部分否则在进一步处理过程中它们将被忽略。
与 ST 代码一样,区分大小写没有区别。
01 MODULE Persistence IMPLEMENTED_BY PersistenceFB 02 SEC MetaData 03 NAME := TL.ChannelName ; 04 DESC := TL.ChannelDesc ; 05 COLLECTION CATEGORY := ’Persistence’TL.Collection ; 06 ICON_16 := IP.Channel16 ; 07 ICON_32 := IP.Channel32 ; 08 END_SEC 09 SEC Toplevel 10 SEC STANDARD_TASK : LOW 11 NAME := LOW ; 12 DESC := TL.TaskLow ; 13 FLAGS := CREATE_IF_MISSING | READONLY ; 14 END_SEC 15 GVL_NAME := 'GVL_%InstanceName%' ; 16 END_SEC
第 01 行定义了模块名称“Persistence”。 IMPLEMENTED_BY
定义包含模块逻辑的功能块“PersitenceFB”。该功能块必须派生自 IModule
。在第 02 行部分 MetaData
从第 08 行开始并结束。本节包含五个定义。嵌套部分的可能性显示在 部分 Toplevel
(第 09-16 行)其中包含以下小节 STANDARD_TASK
(第 10 行)。
模块声明的语法
在本节中,将解释模块声明的语法和允许的语法结构。
在下面的扫描仪标记中,将以大写字母书写(例如: ID
)。语法的非终结符将写在大括号中(例如: {Entry}
)。
词法分析(扫描仪)
在第一步中,将从模块声明的字符(例如:关键字、常量、标识符)创建所谓的标记(或词位)。
空格以及换行符/换行符分隔标记,但否则将被忽略。为了进一步处理该声明,评论也将被忽略。 (注释可以写在一行中(//
")或多行注释((*
和 *)
)如 ST 语言。多行注释可以嵌套。
基本上,令牌始终具有最大长度。例如 a123
将被解释为标识符而不是标识符 a
后面跟着一个字面意思 123
。
下面列表中标记的顺序显示了它们的优先级。例如输入 MODULE
将被理解为关键字而不是标识符。
关键词:
MODULE
,SEC
,END_SEC
,IMPORTS
, 和IMPLEMENTED_BY
OP:以下字符的非空序列:
.:,%()[]{}<>|+-*/@!?^°=\~
注:注释标记
//
,(*
, 和*)
具有比操作员更高的优先级。运算符内部不能有注释,例如:+//+
将根据最大长度规则解释为运算符而不是+
随后是一条评论。LIT:IEC 文字,在 ST 中使用,示例:
1.4
,tod#12:13:14
。这包括布尔文字TRUE
和FALSE
(大小写无关)。注意:带负号的无类型文字 (
-1
,-3.2
) 将被读取为两个标记,即 as 运算符-
后面跟着一个无类型文字。由此产生的无类型数字文字永远不可能是负数。键入的文字 (INT#-34
) 将始终被解释为一个标记。ID:有效的 IEC 标识符(
[a-zA-Z_][a-zA-Z0-9_]*
),其中不允许有两个连续的下划线。与 ST 不同,这还包括 ST 的关键字(即:FUNCTION
,INT
,EXTENDS
,……)分号:字符
;
语法(解析器)
模块声明的语法由以下语法定义。 µ
是一个空序列。
{MDecl} ::= MODULE {QID} {ImplSpec} {ImportsSpec} {MBody} {ImplSpec} ::= IMPLEMENTED_BY {QID} | µ {ImportsSpec} ::= IMPORTS {QID} | µ {MBody} ::= {SecList} {SecList} ::= {Modifiers} {Sec} {SecList} | µ {Sec} ::= SEC {QID} {SecTarget} {EntryList} END_SEC {SecTarget} ::= OP(":") {QID} | µ {Modifiers} ::= OP("[") {ModifierList} OP("]") | µ {ModifierList} ::= {QID} OP(",") {ModifierList} | {QID} {EntryList} ::= {Modifiers} {Entry} {EntryList} {Entry} ::= {Sec} | {Def} {Def} ::= {QID} OP(":=") {ValList} SEMICOLON | {QID} SEMICOLON {ValList} ::= {Val} {ValList} | {Val} {Val} ::= ID | LIT | OP {QID} ::= ID | ID OP(".") {QID}
定义值列表 ({ValList}
) 必须以分号完成。这简化了语法并避免了歧义,因为分号不能是值的一部分({VAL}
),但在字符串文字中除外。
赋值运算符 (:=
)的定义({Def}
)也可以避免歧义({QID}
) 的定义名称和值。
定义的定义类型
文本:ID.ID(文本列表名称和文本列表标识符)-参见 文本列表字符串的本地化
Image:ID.ID(镜像池名称和镜像池标识符)
ID(IEC 标识符)
QID(合格标识符):
{QID} ::= ID | ID.ID
CategoryPath ::= {StringLiteral} | {CategoryPath}
基数:
[{MIN} .. {MAX}]
|[ {MIN} .. INF [
{MIN}
, 和{MAX}
是整数、非负文字。如果{MAX} != INF
, 然后{MIN} <= {MAX}
必须申请。StringLiteral:IEC 字符串文字可能包含换行符。
StdTaskFlags ::= {StdTaskFlag} | StdTaskFlags ::= {StdTaskFlag} | {StdTaskFlags} StdTaskFlag ::=
NONE
|CREATE_IF_MISSING
|READONLY
文字:任何 IEC 文字或 QID(对于枚举常量)
DTBoolFlag:
µ
(空序列)|TRUE
|FALSE
插槽类型:
SUBMODULE
|REFERENCE
编译指示:
[ {PragmaList} ] {PragmaList} ::= {Pragma}
|{Pragma} , {PragmaList} {Pragma} ::= { ( ID
|{StringLiteral}
|{OP2} )+ } {OP2}
: 除{, }, [, ]
和,
。实例路径:
InstancePath ::= {IComp}
|{IComp} . {IComp}
麻省理工学院{IComp} ::= ID {ArrayAccess}*
和{ArrayAccess} ::= [ {IntList} ]
和{IntList} ::= Int
|Int , {IntList}
任务参考:标准_任务。 (
Low
|Medium
|High
) |Custom_Task.ID
实例路径
在模块声明中的某些位置,可以定义实例路径来寻址功能块的变量:用于参数、槽、I/O、具有可变大小的数组和实例引用。
实例路径定义为非空的组件序列,用点分隔: C1.C2…CN
。组件必须是 IEC 标识符或后跟索引表达式的组件 [i1, …, iN]
, 在哪里 i1
到 iN
是整数值。
实例路径始终与实现模块逻辑的功能块相关。实例路径的第一个组成部分是成员 (VAR_INPUT
或者 VAR_OUTPUT
,取决于功能块的用例)。如果实例路径中有其他组件,这些组件将寻址成员内的变量。否则,将针对成员本身进行处理。实例路径可以限制为输入或输出变量(例如:I/O)。对于结构,这些限制无效。这些实例路径分别称为输入实例路径。输出实例路径。
文本列表字符串的本地化
模块中的文本(例如:模块描述、名称、参数描述)可以用不同语言显示。这些文本在文本列表中进行管理。
语言名称的格式
<LanguageCode>[-<Country/Region>]
(例子:en-US
,de-DE
)。<LanguageCode>
是根据 ISO 639-1 的语言名称(示例:de
或者en
)。<Country/Region>
是符合 ISO 3166 的国家/地区代码。当检索文本列表条目时,系统首先查找整个语言名称。如果没有找到任何内容,它会查找
<LanguageCode>
。如果此搜索也失败,将使用默认文本。
语言 | 语言名称 |
---|---|
中国人 | zh-CHS |
英语 | en-US |
法语 | FR-FR |
德语 | 去DE |
意大利语 | 它-IT |
日本人 | ja-JP |
葡萄牙语 | PT-PT |
俄语 | 茹-茹 |
西班牙语 | ES-ES |
派生模块声明
类似于功能块 A 从功能块 B(“EXTENDS”)的面向对象继承,可以通过使用 IMPORTS
关键词。修饰符 UPDATE
和 HIDE
受到特殊对待。
如果导入的模块是在不同的库中定义的,则必须使用命名空间指定该模块的名称。
不允许循环导入,特别是模块不得导入自身。 (循环导入的示例:模块 M_1 导入模块 M_2,M_2 导入 M_3,...,M_N 再次导入 M_1。)
无需定义派生模块
IMPLEMENTED_BY
指示。在这种情况下,将使用基本模块的功能块。如果派生模块指定了功能块(通过使用
MPLEMENTED_BY
),该功能块必须派生自基本模块的功能块或者必须与其相同。派生模块继承基本模块的所有部分。它可以添加新部分或修改现有部分。
可以使用使用修饰符扩展的相同名称和目标在派生模块中修改节
UPDATE
。在这种情况下,其条目会发生更改。派生模块中该节的所有缺失定义将从基本模块接管。修饰符
UPDATE
和HIDE
仅当在基本模块中定义了相应的部分(名称和目标)时才能使用。相反,在基本模块中定义的节只能在派生模块中使用(如果它具有HIDE
或者UPDATE
修饰符。如果只有HIDE
修饰符在该部分而不是UPDATE
,则不允许任何定义。必须更改派生模块中的某些条目(例如:描述)。
MODULE MBase IMPLEMENTED_BY FBBase SEC MetaData DESC := TL.Desc_Base ; END_SEC SEC Parameters SEC Param : paramxIn Variable := xIn ; Name := TL.Param1_Name ; Desc := TL.Param1_Desc ; END_SEC END_SEC MODULE MDerived IMPORTS MBase [UPDATE] SEC MetaData DESC := TL.Desc_Derived ; END_SEC [UPDATE] SEC Parameters [UPDATE,HIDE] SEC Param : paramIn Variable := xIn ; DEFAULT := TRUE ; END_SEC END_SEC
在上面的例子中,参数 paramIn
模块的 MBase
隐藏在派生模块中 MDerived
(通过使用 HIDE
修饰符),同时一个新的默认值(TRUE
) 已设定。
章节和定义的顺序注释
模块头后面的各部分的顺序无关紧要。在这些部分中,顺序可能非常重要。例如,槽声明的顺序定义了模块树中模块的顺序。
定义的顺序始终无关紧要。
基本模块的部分始终在模块本身的部分之前定义。
如果通过使用更改了基本模块的一部分
UPDATE
或者HIDE
,其顺序不受影响。派生模块不可能更改基本模块中定义的顺序。
自动完成和“列出组件”
当开始在模块编辑器中键入时,所有可用/可能的部分定义都会显示在“列表组件”菜单中。仅显示当前位置的有意义的部分和定义。即使某些小节条目与其他节的小节条目具有相同的名称,它也会尝试仅显示匹配的节定义。
如果 返回 完成一个部分的第一行后按下,则该部分将完成所有必要的定义/部分和 END_SEC
。
在变量定义之后,输入/输出变量由“列表组件”定义呈现。标志或预定义值也出现在“列表组件”选择中,其显示可能的标志/值。
定义之后,使用文本列表条目或图像池条目(例如:大多数时候 Desc :=
),显示一个“列表组件”菜单,包括所有可用和可见的文本列表或图像池及其条目。
通过按 F2,即可打开相应的输入支持。