热门标签 | 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是值得研究的课题。


推荐阅读
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • libsodium 1.0.15 发布:引入重大不兼容更新
    最新发布的 libsodium 1.0.15 版本带来了若干不兼容的变更,其中包括默认密码散列算法的更改和其他重要调整。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • 本文探讨了领域驱动设计(DDD)的核心概念、应用场景及其实现方式,详细介绍了其在企业级软件开发中的优势和挑战。通过对比事务脚本与领域模型,展示了DDD如何提升系统的可维护性和扩展性。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
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社区 版权所有