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


推荐阅读
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 在创建新的Android项目时,您可能会遇到aapt错误,提示无法打开libstdc++.so.6共享对象文件。本文将探讨该问题的原因及解决方案。 ... [详细]
  • 中科院学位论文排版指南
    随着毕业季的到来,许多即将毕业的学生开始撰写学位论文。本文介绍了使用LaTeX排版学位论文的方法,特别是针对中国科学院大学研究生学位论文撰写规范指导意见的最新要求。LaTeX以其精确的控制和美观的排版效果成为许多学者的首选。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • Struts与Spring框架的集成指南
    本文详细介绍了如何将Struts和Spring两个流行的Java Web开发框架进行整合,涵盖从环境配置到代码实现的具体步骤。 ... [详细]
  • 本文详细介绍了Python中函数的基本概念,包括函数的定义与调用、文档注释、参数传递(形参与实参)、返回值以及函数嵌套。通过具体示例和解释,帮助读者掌握函数在编程中的应用。 ... [详细]
  • 本文详细介绍如何在Linux系统中配置SSH密钥对,以实现从一台主机到另一台主机的无密码登录。内容涵盖密钥对生成、公钥分发及权限设置等关键步骤。 ... [详细]
  • 本文介绍如何将自定义项目设置为Tomcat的默认访问项目,使得通过IP地址访问时直接展示该自定义项目。提供了三种配置方法:修改项目路径、调整配置文件以及使用WAR包部署。 ... [详细]
  • 本文详细介绍了C语言的起源、发展及其标准化过程,涵盖了从早期的BCPL和B语言到现代C语言的演变,并探讨了其在操作系统和跨平台编程中的重要地位。 ... [详细]
  • 在本教程中,我们将深入探讨如何使用 Python 构建游戏的主程序模块。通过逐步实现各个关键组件,最终完成一个功能完善的游戏界面。 ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • 深入理解ExtJS:从入门到精通
    本文详细介绍了ExtJS的功能及其在大型企业前端开发中的应用。通过实例和详细的文件结构解析,帮助初学者快速掌握ExtJS的核心概念,并提供实用技巧和最佳实践。 ... [详细]
  • 本文深入探讨了 Delphi 中类对象成员的核心概念,包括 System 单元的基础知识、TObject 类的定义及其方法、TClass 的作用以及对象的消息处理机制。文章不仅解释了这些概念的基本原理,还提供了丰富的补充和专业解答,帮助读者全面理解 Delphi 的面向对象编程。 ... [详细]
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社区 版权所有