模块声明
模块的声明是使用自己的描述语言完成的,这类似于结构化文本(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_BYOP:以下字符的非空序列:
.:,%()[]{}<>|+-*/@!?^°=\~注:注释标记
//,(*, 和*)具有比操作员更高的优先级。运算符内部不能有注释,例如:+//+将根据最大长度规则解释为运算符而不是+随后是一条评论。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.IDCategoryPath ::= {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,即可打开相应的输入支持。