AFSim 仿真系统----脚本

news2025/1/12 2:44:48

概述

        脚本为用户提供了一种在模拟中基于发生的事件执行复杂指令集的方式。该语言类似于 C# 和 Java,对于具备基本编程技能的人来说应该会很熟悉。它采用块结构,包含熟悉的声明、赋值和控制流语句,允许用户检查和操作模拟环境。

        脚本本质上是由脚本编译器生成的一系列指令,脚本编译器理解脚本语言的语法并能够将其翻译成相应的指令。一旦编译完成,脚本可以在脚本上下文(执行上下文)中执行,该上下文负责解释脚本的指令并提供脚本与应用程序(即模拟)层之间的接口。在 WSF 中,执行上下文是链式结构,形成树状结构,允许子上下文继承由其父上下文定义的脚本(参见下图)。

        如所示,全球仿真实例、平台及某些平台部件包含一个脚本上下文,使它们能够执行脚本。在仿真的“全局”上下文中定义的脚本对所有平台和平台部件可用。正如在特定平台中定义的脚本对其所有平台部件可用一样。然而,反向情况并不适用。平台无法访问其平台部件上定义的脚本。

为了完整起见,这里定义了脚本语法:脚本语言语法。

基本类型

脚本有 4 种基本类型。基本类型在赋值给变量或传递给函数时会被复制。基本类型包括:

int
一个 32 位整数:

int prime5 = 11;  

bool
一个布尔值。可以是“true”或“false”:

bool isTrue = true;  

double
一个双精度浮点值:

double gravity = 9.8;  

string
一串字符:

string text = "Hello World";  

基本类型支持多种运算符。‘int’ 和 ‘double’ 都支持基本的算术运算和比较:

// 算术 ( +, -, *, / )  
double abc = (5 + 2.5) / 2.0 - 1.0;  
// 算术赋值: ( +=, -=, *=, /= )  
abc += 5.0;  // 将 5 加到 abc  
// 比较 ( >, >=, <, <=, ==, != )  
bool isPositive = abc > 0.0;  

‘string’ 支持比较运算符和 ‘+’ 作为连接:

string alphabet = "alphabet";  
string zoo = "zoo";  
bool trueVal = alphabet < zoo;  
string combine = alphabet + " " + zoo;  

‘bool’ 支持比较运算符,如预期的那样:

bool trueVal = true != false;  

脚本

用户定义的函数称为“脚本”。通常脚本具有以下语法:

script <type> <script-name>([<variable-declaration-list>])
   <script-commands...>
end_script

脚本可以调用在同一上下文中定义的其他脚本或在父上下文中定义的脚本。请看这个例子:  

script bool global_script()
   writeln("Global script called");
   return true;
end_script

platform plat WSF_PLATFORM
   script void local_script()
      writeln("Local script");
   end_script

   // on_initialize is an example of a different script syntax.
   on_initialize
      // Call a global script, accessible anywhere
      global_script();
      // Call a local script, only accessible on this platform
      local_script();

      // To call a script defined later, you must declare it with 'extern'
      extern bool global_later(double);

      global_later(123.0);

   end_on_initialize
end_platform

script bool global_later(double value)
   writeln("global_later(", value, ")");
end_script

platform plat2 WSF_PLATFORM
   // this platform doesn't have direct access to scripts on 'plat'
   //
   script void call_plat1()
      // Find the platform defined above
      WsfPlatform plat = WsfSimulation.FindPlatform("plat");

      // Here, the '.' operator cannot be used to call local_script() on 'plat'
      // The '->' operator allows access to other objects, but that access is not
      // checked at startup.
      plat->local_script();

      // If a mistake is made, an error is issued at run-time.
      // This would result in a run-time error:
      // plat->bad_script();
   end_script
end_platform

全局变量

全局变量允许在多个脚本中存储和访问值。当定义一个全局变量时,它仅对其父上下文是全局的。例如,在一个平台上定义一个全局变量只允许从该特定平台访问该变量。定义全局变量的方式有多种:

 

// variables defined in a 'script_variables' block outside of a platform are always global.
// 'x' is a true 'global' variable available anywhere
script_variables
   double x = 1.0;
end_script_variables

platform plat WSF_PLATFORM
   // y is a global variable only available to scripts located on 'plat'
   script_variables
      double y = x;
   end_script_variables

   script void test()
      // global variables can be used just like regular variables
      y += x;

      // global variables can also be defined in any script using the 'global' keyword:
      global double z = y;
   end_script

end_platform

script void test2()
   // Find the platform defined above
   WsfPlatform plat = WsfSimulation.FindPlatform("plat");
   // the '->' operator can be used to access variables belonging to an object.
   plat->y -= x;
end_script

静态变量

静态变量是只有一个实例且仅初始化一次的变量。、
 

script void test_static()
   // In this example, x is initialized to 1.0 the first time in this script.
   // x's value is maintained between calls to test_static().
   // This would output 1234... one number for each call to test_static().
   static double x = 1.0;
   write(x);
   x += 1;
end_script

 

类型转换

类型转换将一个值从一种类型转换为另一种类型。类型转换的语法为:(<type>)value。基本类型之间可以自由地进行类型转换:

 

int five = (int) 5.5;
string fivePointFive = (string)5.5;

允许在非基本类型之间进行类型转换,但用户应谨慎操作。

WsfMessage msg = GetControlMessage();
((WsfControlMessage)msg).SetResource("my_resource");

操作符号

.

The ‘.’ operator is used to call Methods on script class objects, or static methods on script classes.

->

The ‘->’ operator is used to call user-defined scripts on objects, and get/set user-defined script variables on objects.

+

Add numeric values, and concatenate strings

-

Subtract numeric values; 1 - 1

*

Multiply numeric values; 2 * 2

/

Divide numeric values; 4 / 2

>

Test for greater-than; 1 > 0

>=

Test for greater-than or equal to; 1 >= 1

<

Test for less-than; 0 < 1

<=

Test for less-than or equal to; 0 <= 1

==

Test for equal-to; 1 == 1

!=

Test for not-equal-to; 1 != 0

!

Boolean-not; true == !false

()

Ordering expressions; (1+1)*2 == 4

(<type>)

Casting operator

=

Assignment operator; double x = 2.0;

详细信息

这是关于脚本语法的详细文档。

符号说明

尖括号(< >)包围类别标签。

方括号([ ])包围可选项。

大括号({ })包围重复项。

单引号(‘ ’)包围字面量项。

粗体文本表示保留字。

注意:该语言的完整语法可以在《脚本语言语法》中找到。

命令模板

脚本使用以下序列定义:

script <type> <script-name>([<variable-declaration-list>])
   <script-commands>
end_script

语言描述

该语言由以下构造组成:

<标识符>


标识符表示变量或函数的名称。标识符以字母(大写或小写)开头,后面可以跟零个或多个字母、数字(0-9)或下划线(‘_’)。标识符是区分大小写的。因此,标识符‘x1’和‘X1’代表不同的变量。有效标识符的示例:

i
X1
aLongIdentifier
x_2

<类型>


每个变量都有一个‘类型’,它定义了变量可以包含的数据类型。数据主要分为两种类型:<基本类型>和<复杂类型>。所有类型都派生自一个称为Object的‘基’类型。

Object


一个所有其他类型都兼容的‘基’类型。

例如:

Object myObject;
myObject = 'hello';
myObject = 19;

<基本类型>


脚本语言的类型与大多数现代编程语言提供的类型匹配:

int

double

bool

string

<复杂类型>


这些是更复杂的类型,通常由多个基本类型或其他复杂类型组成,并通常包括可以访问和操作该类型内数据的函数。复杂类型无法在脚本中定义;它们在C++中定义并导出以供脚本使用。复杂类型的完整列表可在脚本类型部分找到。

<存储类型>


当声明变量时(见下文),内存存储类型会被隐式或显式设置。默认情况下(如果未指定存储类型),变量被认为是自动变量,意味着它们在当前<块>的内存空间中创建。这也意味着它们仅在当前<块>及其内部嵌套的<块>中可用。 除了自动变量,还有全局变量和静态变量。全局变量在全局内存中分配,并在所有脚本中可用。静态变量的工作方式与自动变量相同,只是它们的内存(及其当前值)在对给定脚本的多次调用之间被保留。

<表达式>


表达式是任何结果为单一值的内容。

例如:

10 * 3
('platform-1' == platform.Name()) && (5 < mX)
Foo()
mX
MATH.Pi()
(9.99 >= 1.0)
1.23

<表达式列表>


用逗号分隔的<表达式>列表。

<强制转换>


表达式可以使用强制转换操作转换为另一种类型。这在某些情况下是必要的(请参见脚本类型部分中的Iterator、ArrayIterator和MapIterator)。

'(' <类型> ')' <表达式>

例如:

Object obj = 'my string';
string = (string)obj;

int i = 99;
double d = (double)i;

WsfMessage msg = GetControlMessage();
(WsfControlMessage)msg.SetResource('my_resource');

<语句>


语句被定义为以下之一:

<变量声明>


每个变量在使用前必须声明。变量可以简单声明,也可以声明并赋初值。变量声明可以是以下之一:

[<存储类型>] <类型> <标识符> ';'

[<存储类型>] <类型> <标识符> = <表达式> ';'

前者的示例包括:

int i;
static j;
WsfSensor thisSensor;

后者的示例包括:

int i = 0;
global double x = 10.0 * i;
string s = 'Hello, world';
WsfSensor thisSensor = PLATFORM.Sensor('this_sensor');

<变量赋值>


可以使用赋值运算符将简单值、复杂表达式和脚本/函数返回值赋给变量。

<变量> = <表达式> ;

例如:

int x;
x = 10;

<if-else>

if-else语句允许用户根据一个或多个计算为布尔值的表达式选择要执行的语句。第一个计算为true的条件会执行其<block>中的语句。

if '(' <expression> ')' <block> { else if '(' <expression> ')' <block> } [else <block>]

例如:

string name = 'platform-1';  
if (name == 'platform-2')  
{  
   print('Found platform-2');  
}  
else if (name == 'platform-1')  
{  
   print('Found platform-1');  
}  
else  
{  
   print('Couldn\'t find platform 1 or 2');  
}  
<while-loop>

while语句允许用户根据一个计算为布尔值的表达式进行迭代。迭代会持续直到表达式计算为false。

while '(' <expression> ')' <block>

例如:

int i = 0;  
while (i < 10)  
{  
   print('i is ', i);  
   i = i + 1;  
}  

<do-while-loop>

do-while语句允许用户根据一个计算为布尔值的表达式进行迭代。迭代会持续直到表达式计算为false。do-while和while循环之间的区别在于,条件在do-while循环的底部检查,这保证至少执行一次迭代。

do <block> while '(' <expression> ')'

例如:

int i = -1;  
do  
{  
   i = i + 1;  
   print('i is ', i);  
}  
while (i < 10)  
<for-loop>

for语句允许用户根据一个计算为布尔值的表达式进行迭代。迭代会持续直到表达式计算为false。此外,它提供了声明循环计数器和增量操作的空间。

for '(' [<variable-declaration>] ';' [<expression-list>] ';' [<expression-list>] ')' <block>

例如:

for (int i = 0; i < 10; i = i + 1)  
{  
   print('i is ', i);  
}  
<foreach-loop>

foreach循环允许用户遍历容器中的元素,同时提供对键和值的访问。

foreach '(' [<variable-declaration> ':'] <variable-declaration> in <expression> ')' <block>

例如:

Map<string, double> myMap = Map<string, double>();  
myMap['a'] = 1.1;  
myMap['b'] = 2.2;  

// 如果声明了两个循环变量  
// (用冒号分隔),第一个必须是  
// 键,第二个必须是值。  
foreach (string aKey : double aData in myMap)  
{  
   print('key, data ', aKey, ', ', aData);  
}  

// 如果只声明了一个循环变量  
// 它必须是值。  
foreach (double aData in myMap)  
{  
   Print('data ', aData);  
}  
<break>

break语句允许用户跳出当前块。

break ';'

例如:

while (true)  
{  
   if (true)  
   {  
      break;  
   }  
}  

<continue> continue语句允许用户忽略循环中的其余语句并跳到循环的顶部。

continue ';'

例如:

for (int i = 0; i < 10; i = i + 1)  
{  
   if (i == 5)  
   {  
      continue;  
   }  
}  
<return>

return语句允许用户从脚本/函数调用中返回一个值。

return <expression> ';'

例如:

double Multiply(double aA, double aB)  
{  
   return aA * aB;  
}  
<block>

块是:

  • 被脚本end_script包围的零个或多个语句
  • 被花括号包围的零个或多个语句

前者的示例是:

script void my_script()  
   int i = 1;  
   print('i = ', i);  
end_script  

后者的示例是:

if (true)  
{  
   int i = 1;  
   print('i = ', i);  
}  
<function-declaration>

可以使用以下语法在脚本中声明函数。函数只能在脚本内声明。如果需要一个在所有脚本中可用的函数,请将其定义为脚本。

<type> <identifier> '(' [<variable-declaration-list>] ')' <block>

例如:

double Magnitude(double aDx, double aDy)  
{  
   return MATH.Sqrt(aDx * aDx + aDy * aDy);  
}  

注意,MATH是一个可在所有脚本中使用的系统变量,提供对各种数学工具的访问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2040226.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】sersync 实时同步

原理 rsync 是不支持实时同步的&#xff0c;通常我们借助于 inotify 这个软件来实时监控文件变化&#xff0c;一旦inotify 监控到文件变化&#xff0c;则立即调用 rsync 进行同步&#xff0c;推送到 rsync 服务端。 环境准备 步骤1&#xff1a;获取数据包 获取 sersync 的包…

UE5学习笔记12-为角色添加蹲下的动作

一、一点说明 1.蹲下使用了ACharacter类中Crouch();函数&#xff0c;函数功能是先检查是否存在运动组件&#xff0c;将bool类型的变量变为true&#xff0c;该变量代表是想要蹲下。 2.通过源码可知存在是否蹲下的bool变量bIsCrouched如图&#xff0c;如果对:1有疑问请搜索C位域 …

C++ | C++中的继承和组合:代码复用的艺术和应用

目录 一、继承&#xff1a;代码复用的艺术 1、继承概念 代码说明1&#xff1a;继承方式和访问控制 代码说明2&#xff1a;作用域与成员访问 代码说明3&#xff1a;构造函数和析构函数 2、基类和派生类对象赋值转换 派生类对象到基类对象的转换(向上转型)&#xff1a; 基…

Jmeter+Influxdb+Grafana平台监控性能测试过程(三种方式)

一、Jmeter自带插件监控 下载地址&#xff1a;Install :: JMeter-Plugins.org 安装&#xff1a;下载后文件为jmeter-plugins-manager-1.3.jar&#xff0c;将其放入jmeter安装目录下的lib/ext目录&#xff0c;然后重启jmeter&#xff0c;即可。 启动Jmeter&#xff0c;测试计…

python-opencv卷积计算代码

目录 # 尝试不同的卷积核 卷积图片如下&#xff1a; 卷积调用类如下&#xff1a; 当我们在图像上应用卷积时&#xff0c;我们在两个维度上执行卷积——水平和竖直方向。我们混合两桶信息&#xff1a;第一桶是输入的图像&#xff0c;由三个矩阵构成——RGB 三通道&#xff0c…

Cobalt—超简单下载器!!【送源码】

我们每天都在网上冲浪&#xff0c;遇到喜欢的视频、音频总想保存下来慢慢回味。很多平台并不直接提供下载功能&#xff0c;或者下载过程繁琐还伴有各种广告。之前了不起给大家介绍过不少开源的下载工具&#xff0c;如Gopeed、lux、Hitomi-Downloader&#xff0c;各有各的特色。…

机械学习—零基础学习日志(如何理解线性代数2)

零基础为了学人工智能&#xff0c;正在快乐学习&#xff0c;每天都长脑子 引言 在平面中&#xff0c;直线的定义可以理解为&#xff0c;任意缩放同一个平面向量得到所有点的集合。 所以要得到一个三维空间中的直线&#xff0c;只需要将这个向量改成三维向量即可。 什么是线…

Python | Leetcode Python题解之第337题打家劫舍III

题目&#xff1a; 题解&#xff1a; # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val x # self.left None # self.right Noneclass Solution:def rob(self, root: TreeNode) -> int:def _rob…

数字图像处理(Matlab实践篇)专栏介绍

专栏导读 数字图像处理技术是计算机视觉、医学成像、遥感探测等领域的基石。Matlab&#xff0c;以其强大的数学计算能力和丰富的图像处理工具箱&#xff0c;成为学习和实践数字图像处理的理想选择。本专栏将带领读者从基础概念出发&#xff0c;逐步深入到高级技术&#xff0c;…

Redis:缓存击穿

缓存击穿 在某些 Key 属于极端热点数据&#xff0c;且并发量很大的情况下&#xff0c;如果这个 Key 过期&#xff0c;可能会在某个瞬间出现大量的并发请求同时回源&#xff0c;相当于大量的并发请求直接打到了数据库。这种情况&#xff0c;就是我们常说的缓存击穿或缓存并发问…

小试牛刀-区块链Solana多签账户

目录 1.什么是多签账户 2.多签账户的特点 2.1 多个签名者 2.2 最小签名要求 2.3 常见应用场景 3.多签账户实现 3.1 账户的创建 3.1.1 创建新账户 3.1.2 获取创建和初始账户事务 3.1.3 账户的签名 3.2 代币转移操作 Welcome to Code Blocks blog 本篇文章主要介绍了 …

第八节AWK报告生成器(1)

第八节AWK报告生成器 一,AWK简介 其名称得自于它的创始人阿尔佛雷德•艾侯(Alfred Aho)、彼得•温伯格(Peter Weinberger) 和布莱恩柯林(Brian Kernighan)姓氏的首个字母 AWK是一个文本处理工具&#xff0c;Linux及Unix环境中现有的功能最强大的数据处理引擎之一 现在默认li…

「C++系列」输入/输出

文章目录 一、输入/输出1. 包含iostream库2. 使用std命名空间3. 输出到控制台4. 从控制台读取输入5. 注意事项 二、库头文件三、标准输出流&#xff08;cout&#xff09;1. 基本用法2. 格式化输出3. 缓冲4. 错误处理5. 注意事项 四、标准输入流&#xff08;cin&#xff09;1. 基…

X-Recon:一款针对Web安全的XSS安全扫描检测工具

关于X-Recon X-Recon是一款功能强大的Web安全扫描与检测工具&#xff0c;该工具能够帮助广大研究人员识别网页端输入数据&#xff0c;并执行XSS扫描任务。 功能介绍 1、子域名发现&#xff1a;检索目标网站的相关子域名并将其整合到白名单中。这些子域名可在抓取过程中使用&am…

重启人生计划-积蓄星火

&#x1f973;&#x1f973;&#x1f973; 茫茫人海千千万万&#xff0c;感谢这一刻你看到了我的文章&#xff0c;感谢观赏&#xff0c;大家好呀&#xff0c;我是最爱吃鱼罐头&#xff0c;大家可以叫鱼罐头呦~&#x1f973;&#x1f973;&#x1f973; 如果你觉得这个【重启人生…

MySQL数据分析进阶(十二)设计数据库——PART4

&#xff1b;※食用指南&#xff1a;文章内容为‘CodeWithMosh’SQL进阶教程系列学习笔记&#xff0c;笔记整理比较粗糙&#xff0c;主要目的自存为主&#xff0c;记录完整的学习过程。&#xff08;图片超级多&#xff0c;慎看&#xff01;&#xff09; 【中字】SQL进阶教程 |…

基于SpringBoot+VUE的员工绩效考核管理系统(源码+文档+部署)

主要内容&#xff1a;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能与大数据、单片机开发、物联网设计与开发设计、简历模板、学习资料、面试题库、技术互助、就业指导等 业务范围&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写…

二级分发域名-子比比

二级分发域名全开源链接 二级分发域名

大数据技术——实战项目:广告数仓(第四部分)

目录 第7章 数据仓库环境准备 7.1 数据仓库运行环境 7.1.1 Hive环境搭建 7.1.2 Yarn环境配置 7.2 数据仓库开发环境 第8章 广告数仓ODS层 8.1 广告信息表 8.2 推广平台表 8.3 产品表 8.4 广告投放表 8.5 日志服务器列表 8.6 广告监测日志表 8.7 数据装载脚本 第7章…

C语言【自定义类型——枚举与联合】详细!!

目录 1、枚举 1.0、什么是枚举 1.1、枚举类型的优点 2、联合体&#xff08;共用体&#xff09; 2.0、什么是联合体 2.1、联合体的特点 2.2、联合体大小的计算 2.2.0、联合体节省空间例子 2.3、联合小练习 1、枚举 1.0、什么是枚举 枚举&#xff0c;顾名思义&#…