HART现场总线设备描述语言(DDL)中的条件编译
HART DDL支持类似于标准C++指定的预处理器。总结预处理指令包含在本节中。
HART DDL中的预处理器支持:
- 包含头文件。当一个DD被分成几个源文件时,他们应该使用.dd这个扩展名。定义宏的头文件通常使用.h这个扩展名。
- 宏扩展。您可以定义宏,就是任意C代码片段的缩写,然后C预处理器将用宏的定义替换所有代码中使用的宏
- 条件标记化。使用特殊的预处理指令,可以包括或排除部分DD。
注意:在预处理标记中,空格只能作为标题名或名称的一部分出现在字符文字或字符串文字中的引号字符之间。唯一的空格应出现在预处理指令中预处理标记之间的字符是空格和水平标签。
preprocessor-directives:
directiveopt
directive:
directive
directive if-section
directive control-line
if-section:
if-group elif-groupsopt else-groupopt endif-line
if-group:
#if constant-expression new-line directiveopt
#ifdef identifier new-line directiveopt
#ifndef identifier new-line directiveopt
elif-groups:
elif-group
elif-groups elif-group
elif-group:
#elif constant-expression new-line directiveopt
else-group:
#else new-line directiveopt
endif-line:
#endif new-line
control-line:
#include header-name new-line
#define identifier replacement-list new-line
#define identifier( identifier-listopt ) replacement-list new-line
#undef identifier new-line
#line integer " file-name "opt new-line
#error source-char-sequence new-line
#pragma source-char-sequence new-line
#new-line
header-name:
< source-char-sequence >
" source-char-sequence "
new-line:
the new-line character
DDL中的注释
HART的DDL支持两种形式的注释:
/* source-char-sequence */ // source-char-sequence up to the first new-line character
一个/*开始一条注释,以*/结尾。这些注释并不重要。注释字符//和/*在/*注释中没有特殊含义。
//开始一条注释,以下一个新行字符结束。注释字符//、/*和*/在//注释中没有特殊含义。
每个注释都替换为一个空格字符。
DDL中的#define宏定义
处理完所有注释后,所有宏都会展开。紧跟在#define后面的定义被称为宏名。预处理器扫描DDL源代码,并在遇到宏名称时,标识符将替换为#define中的文本。然后重新扫描替换列表以获取更多宏名称,并继续递归地进行宏扩展。
#define的第一种形式是
#define identifier replacement-list new-line
只需执行一个令牌替换,将替换列表替换为宏名称。长替换列表应根据需要使用续行机制继续替换列表。宏保持定义状态,直到相应的#unde指令被激活遇到。
第二种形式允许在更换过程中使用参数:
#define identifier( identifier-listopt ) replacement-list new-line
DDL中的#操作符
#操作符允许将参数转换为字符串。当参数的前缀为#替换列表中的字符都将替换为相应的字符串发生膨胀时的参数。这意味着参数被转换为字符串文字包含参数的文本。参数中的任何空白都将成为一个空格结果字符串文本中的字符。
##操作符-串联
##操作符允许将参数与替换列表实际上是从两个相邻的令牌创建一个新令牌。##可以跟随或者在替换列表中的参数之前,或者它可以出现在替换列表中任意两个标记之间替换列表。对于所有宏调用,每个##都会被删除,并且前面和后面的标记都会被删除连接在一起形成一个新的标记。生成的令牌可用于进一步的宏操作替换只有在该处理完成后,才能重新检查替换列表。重新扫描和进一步替换一旦替换列表替换了宏名称和替换的所有参数相应的参数,重新扫描生成的预处理令牌序列。有新的宏吗名称已确定,宏扩展仍在继续。当前正在执行的任何宏的名称在当前扩展完成之前,将忽略扩展。
DDL中预定义的宏名称
以下是DDL中预定义的标准宏:
- __LINE_uu当前源行的行号(一个整数常量)。
- __FILE_u; DDL源文件的名称(字符串文本)。
- __DATE_uu源文件标记化的日期(格式的字符串文本“MM dd yyyy”)。
- __TIME_uu翻译源文件的时间(格式的字符串文本“hh:mm:ss”)。
- __TOKVER_u 100倍于用于翻译DD的标记器的版本号(整数常量)。
预定义的宏 __DATE__ __TIME__和_TOKVER__的值保持不变在整个标记化过程中。
#if,#ifdef和#ifndef
以#if,#ifdef和#ifndef control conditional开头的预处理器指令序列包含DDL源。控制表达式必须解析为整数(即零或零)非零)在标记化时间。DDL源也相应地包括在内。除了正常常量表达式外,还可以使用定义的预处理器关键字确定宏是否已定义。这个一元运算符表示为
defined identifier
或者
defined ( identifier )
如果标识符当前定义为宏名称,则其计算结果为1,否则为零。
#line
#line允许更改行号和文件(可选)名。宏__FILE__和__LINE__的值会相应更改。
#error
#error导致指令后面的文本输出。通常,错误消息使用一个或多个更多预定义宏,为错误消息提供上下文。
#pragma
#pragma指令允许调用特定于实现的选项。文本表示要调用的选项或要执行的操作。
#include
#include标识要处理并插入DD源文件的头文件或源文件。
#include的格式如下:
#include < source-char-sequence > new-line
导致在标准的已知目录中搜索指定的文件。DDL源字符序列不能包含“//*或转义序列。当使用如下格式的#include时:
#include " source-char-sequence " new-line
DDL源字符序列不能包含''///*或转义序列。
#include <macros.h>
所有DD中都应包含macros.h文件。该文件由HCF控制,包含:
- DDL规范支持的宏。例如,标准颜色的定义。
- HART公共表的访问。这些宏简化了中常用表的使用枚举和位枚举。例如
#define UNITS_CODE(N) { N, units_code(N) }
- HART应用层定义。支持过程变量状态的定义,动态_变量(即PV、SV、TV、QV)声明和常见响应代码定义。