热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

初探PLC的ST语言转换成C++的方法

自动控制软件绕不开ST(StructureText)语言。它是IEC61131-3标准中唯一的一个高级语言。目前,大多数PLC产品支持ST

自动控制软件绕不开ST (StructureText ) 语言。它是IEC61131-3 标准中唯一的一个高级语言。目前,大多数PLC 产品支持ST语言。在IEC61499 中,根据IEC61499的定义,功能块的内部算法可以使用若干语言来描述,虽然可以是C,或者java 这样的通用高级语言,但是为了符合OT 工程的使用习惯,几个主要的IEC61499 开发工具也都以STL语言作为功能块内部算法的语言,在著名的IEC61499 开源项目4diac 中,除了ST 以外,还可以采用lua 脚本语言。不过对于OT 工程师而言,大概也不会使用lua 这样的语言。
   另一方面,在IEC61499  或IEC61131 的运行时中,通常是使用C++,或者java 这样的通用程序设计语言编写的。在这样的运行时中运行ST 程序的方式无非是两种方式。第一种方式是将ST 翻译成为一种中间语言,由运行时解释执行。第二种方式是将ST转换成C++ 。与运行时源码一起编译。4diac 采取的是后一种方法。

      ST 语言是一种类似PASCAL 的语言,将它转换成为C++ 代码并非易事。传统的方式与编译器没有什么两样,一般采取两趟编译,第一趟词法分析,第二趟语法分析。只是产生的目标代码是C++罢了。这样的程序过于复杂。将它们融入自己的开发环境,工作量也不小。本博文讨论基于xtext 的方式,实现ST 转换成C++ 的技术方案。


ST 程序实例

ST 编写的程序长成这个样子:

PROGRAM stexampleVARx : BOOL;END_VARx := TRUE;REPEATx := FALSE;UNTIL x := FALSE;END_REPEAT;
END_PROGRAM;

可以看出,ST与pascal有几分神似,也有很大的差别。所以如果将pascal 2 C 的程序修改成为ST to C++ ,改动也不小。而改动一个编译器并不是容易的事情。


xtext 与DSL 语言

        作者一直在寻找实现ST 语言到C++ 转换的其它技术路线。万般无奈之时,硬着头皮研究了4diac IDE 的源代码。结果发现4diac中,它采取了Eclipse xtext 项目的技术。于是开始关注xtext

官网:https://www.eclipse.org/Xtext/

     按照xtext官网的说法,Xtext 是开发程序设计语言和领域特定语言(DSL:domain-specific languages)的架构。于是又引入了一个术语DSL。这才发现,Xtext和DSL 是语言工程方面的一个重要的工具和概念,网络上有许多信息,而且有一本完整的书来介绍-《Implementing Domain-Specific Languages with Xtext and Xtend - Second Edition》。本博文没有办法全面地介绍Xtext和DSL 。只是提一下基本概念。在后续的博文中我会继续介绍这方面的内容(如果有人点赞的话)。


DSL语言

       网络上将DSL 语言翻译成为领域特定语言,这是一种面向专有领域的小型语言,例如SQL 语言就是一种DSL,它是数据库查询的专有语言。其实DSL 是相对于通用程序设计语言(GPL) 而言的。比如Java。C++,PASCAL 等等。IEC61131-3 中的ST 是工业控制领域的专用语言。DSL 的另一个特点当然是它们普遍都比较小。

定义(Wikipedia):DSL 是特定领域的专用计算机语言。

这种定义完全是相对而言的,ST相对于java ,ST是一种DSL 语言,而java 相对于 英语,java 是一种DSL 语言。所以没有严格之分。

  那么,为什么要DSL呢?它们主要的用途是什么呢?

DSL 的特点:


  1. 更多的表达,更少的冗余

                 这意味着更高的效率。


  1. 更好的学习曲线
  2. 有助于和领域专家交流
  3. 能自成文档(self-documenting)
  4. 领域特定验证

   软件开发大师Martin Flowler 指出:任何一个傻子都能够写成计算机能懂的代码。好的程序员能够编写人类能够读懂的代码。DSL 能够使代码更加容易让人理解。特别是让非计算机人士理解。这非常重要。D。Knuth 曾经指出:好的算法必需看上去令人信服( An algorithm must be see to believed)。计算机语言通常比较地复杂,使人们不能集中精力去关注算法本身。例如XML 是一种普遍使用的结构化文本描述语言。在PLCOpen 和IEC61499 中采用XML 来描述程序,功能块,设备,系统等各种模型。这相对于PLC 厂商私有的文档格式,是一大进步。但是XML 恐怕只适合计算机程序处理,仍然不适合人类阅读。例如:


James
Smith
50


John
Anderson
40

XML不愧为是结构性语言,XML 中太多<> 括起的tag 。使我们很难看出内容 。这也称为“信息噪声”太大。如果使用 ad-hoc DSL描述:

person {
name=James
surname=Smith
age=50
}
person employed {
name=John
surname=Anderson
age=40
}

显然它们要清晰多了。它是低噪声的,信息更能理解。进一步地,如果按如下方式描述,显然更加清晰。 

James Smith (50)
John Anderson (40) employed

DSL的实现

   对于最终用户而言,使用DSL 要比XML 代码容易多了,但是俗话说:“话越少,事越大“。开发DSL 的主要任何就是如何实现它。实现DSL 意味着能够阅读DSL 编写的文本,对它语法分析,处理它,和转换成为其它语言的代码。这个过程类似与编译器(compiler) ,涉及词法分析,语法分析和代码生成。具体的方式是采用一种语法描述语言来描述DSL语言的语法(这种语法描述语言其实也是DSL),然后通过语言工具(语法生成器(parser generators)或者编译器的编译器(compiler-compiler)来编译DSL 语言编写的代码。

 Bison 和Flex 是非常著名的基于C语言的语法描述语言,Bison 用于语法规范,Flex 用于词法规范。Bison 是Yacc(Yet Another Compiler-compiler)的实现。在java 的世界,ANTLR 非常出名。github 有一个开源项目:https://github.com/nucleron/matiec。不过这个编译器需要4 个stage。看上去比较复杂。

实现DSL 的另一种方法是基于eclipse 的Xtext项目。


进入Xtext

Xtext 是Eclipse 用于实现程序设计语言和DSL 的软件架构。它包含了一个完整的语言基础设施,从语法分析开始,代码生成或者解释,直到完整的EclipseIDE集成,实现一个DSL语言非常快。。Xtext 最惊喜的事情是实现DSL 语言,只需要一个语法规范就可以了。Xtext 的语法规范类似于ANTLR。


安装Eclipse Xtext

         安装Eclips 的方法是首先从Eclipse 官网下载一个eclipse-install ,然后安装一个Eclipse Modling Tools。在Eclipse Modling 下,安装Xtext 插件。就可以使用了。如果你点赞,我会在后面的博文中介绍安装过程的细节。


使用Xtext 实现ST 语言

前面提到,使用Xtext 实现DSL 的需要是编写语言的规范。如果我们要实现ST 语言的编译,首先需要有一个xtex格式的ST语言的规范。他们在4diac IDE 的源代码中可以找到。文件比较长,这里就不列出来了。摘录一些片段。

StructuredTextAlgorithm: {StructuredTextAlgorithm}(&#39;VAR&#39;((localVariables += Var_Decl_Init) &#39;;&#39;)*&#39;END_VAR&#39;)?statements=Stmt_List
;Var_Decl_Init returns libraryElement::VarDeclaration:Var_Decl_Local
;Var_Decl_Local returns libraryElement::LocalVariable:{LocalVariable} (constant ?= &#39;CONSTANT&#39;)? name=ID (located?=&#39;AT&#39; location=Variable)? &#39;:&#39;( array?=&#39;ARRAY&#39; &#39;[&#39; arrayStart=Array_Size &#39;..&#39; arrayStop=Array_Size &#39;]&#39; &#39;OF&#39;)?type=[datatype::DataType|Type_Name]( initalized?=&#39;:=&#39; initialValue=Constant)?
;/************************************************************************statement
************************************************************************/
Stmt_List returns StatementList: {StatementList}((statements += Stmt)? &#39;;&#39;)*
;Stmt returns Statement:Assign_Stmt |Subprog_Ctrl_Stmt |Selection_Stmt |Iteration_Stmt
;Assign_Stmt returns AssignmentStatement:variable=Variable &#39;:=&#39;expression=Expression
;Subprog_Ctrl_Stmt returns Statement:Func_Call |//Invocation |{SuperStatement} &#39;SUPER&#39; &#39;(&#39; &#39;)&#39; |{ReturnStatement} &#39;RETURN&#39;
;Selection_Stmt returns Statement:IF_Stmt | Case_Stmt
;IF_Stmt returns IfStatement:&#39;IF&#39; expression=Expression &#39;THEN&#39;statments=Stmt_List(elseif += ELSIF_Clause)*(else=ELSE_Clause)?&#39;END_IF&#39;
;ELSIF_Clause returns ElseIfClause:&#39;ELSIF&#39; expression=Expression &#39;THEN&#39;statements=Stmt_List
;ELSE_Clause returns ElseClause:&#39;ELSE&#39;statements=Stmt_List
;Case_Stmt returns CaseStatement:&#39;CASE&#39; expression=Expression &#39;OF&#39;(case += Case_Selection)+(else=ELSE_Clause)?&#39;END_CASE&#39;
;Case_Selection returns CaseClause:case += Constant (&#39;,&#39; case += Constant)* &#39;:&#39; //only allow explicit constants herestatements=Stmt_List
;Iteration_Stmt returns Statement:For_Stmt |While_Stmt |Repeat_Stmt |{ExitStatement} &#39;EXIT&#39; |{ContinueStatement} &#39;CONTINUE&#39;
;For_Stmt returns ForStatement:&#39;FOR&#39; variable=Variable_Primary &#39;:=&#39; from=Expression &#39;TO&#39; to=Expression (&#39;BY&#39; by=Expression)? &#39;DO&#39;statements=Stmt_List&#39;END_FOR&#39;
;While_Stmt returns WhileStatement:&#39;WHILE&#39; expression=Expression &#39;DO&#39;statements=Stmt_List&#39;END_WHILE&#39;
;Repeat_Stmt returns RepeatStatement:&#39;REPEAT&#39;statements=Stmt_List&#39;UNTIL&#39; expression=Expression&#39;END_REPEAT&#39;
;

完整的xtext 文件 443 行。

 


语言服务器协议(Language Server Protocol)

Eclipes xtext 项目提供了DSL的所有工具,包括了编辑时的高亮,语法检查,编译,代码生成,验证等等。全部是在Eclipse IDE 下完成的。但是ST语言的编译需要在IEC61131-3 或IEC61499 的IEC 环境下实现/对于4diac 而言,它同样是使用Eclipse IDE来实现的,所以,Xtext 成为了4diac IDE的插件。但是,如果你的IEC61131-3/IEC61499 IDE 采用其他语言和架构来实现的(比如C++,或者Javascript/nodeJS),那么如何将Xtext嵌入到你的IDE 中去呢?这要感谢微软公司开源的语言服务器协议。协议定义了在编辑器或IDE与语言服务器之间使用的协议。比如微软的VS Code 与编译器之间的协议。使用语言服务器协议能够实现云端语言开发环境。

到了Xtext 采用了eclipse 的lsp4j。实际上,xtext 指出web 方式的编辑。

  具体实现时,可以将ST 编译做成一个服务器,甚至可以放置在docker 中。你的IEC61131-3/IEC61499 IDE 通过lsp4j 协议与ST编译服务器交互完成ST语言的转换。既可以本地访问,也可以远程访问。可以实现云端PLC。


小结和今后的工作

本博客介绍了采用Eclipse Xtext 工具实现IEC61131-3/IEC61499 的ST语言的编译方案,并且大致介绍了Xtext和语言服务器协议两个重要的技术。未来,我们会实现一个完整的,独立的ST语言服务器。这里特别要指出的是,Xtext 对于工业自动化领域的开放模型,模型驱动自动化(model driven automation) 同样非常重要,Xtext是值得研究的课题。


推荐阅读
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了绕过WAF的XSS检测机制的方法,包括确定payload结构、测试和混淆。同时提出了一种构建XSS payload的方法,该payload与安全机制使用的正则表达式不匹配。通过清理用户输入、转义输出、使用文档对象模型(DOM)接收器和源、实施适当的跨域资源共享(CORS)策略和其他安全策略,可以有效阻止XSS漏洞。但是,WAF或自定义过滤器仍然被广泛使用来增加安全性。本文的方法可以绕过这种安全机制,构建与正则表达式不匹配的XSS payload。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • Vue基础一、什么是Vue1.1概念Vue(读音vjuː,类似于view)是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不 ... [详细]
  • ①页面初始化----------收到客户端的请求,产生相应页面的Page对象,通过Page_Init事件进行page对象及其控件的初始化.②加载视图状态-------ViewSta ... [详细]
  • 单目标应用:最有价值球员算法(Most Valuable Player Algorithm,MVPA)求解旅行商问题TSP
    一、最有价值球员算法最有价值球员算法(MostValuablePlayerAlgorithm,MVPA)由Bouchekara等人于20 ... [详细]
author-avatar
兰花m123_680
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有