发明内容
针对现有技术中存在的上述不足之处,本发明要解决的技术问题是提供一种能够实现任意结构文本语言向梯形图语言的快速转换的将结构文本语言转换为梯形图语言的方法。
为解决上述技术问题,本发明采用的技术方案是:
本发明将结构文本语言转换为梯形图语言的方法包括以下步骤:
将结构文本逻辑语句按照IEC 61131-3标准进行等价规范处理;
根据规范处理后的结构文本逻辑语句确定各个元素在其所处括号中的层次以及前后的逻辑运算符是“AND”还是“OR”,将文本中的元素按照其对应的图元在梯形图中的二维坐标,进行一一定位;
将定位后的结构文本的各个元素转换成中间代码,每个元素的中间代码包含图元的类型、图元坐标和参数信息,利用已编写的画梯形图的各功能函数,将中间代码转换成梯形图。
所述等价规范处理的过程如下:
对于每一个“AND”,在其所处的括号层次内,按照“AND”两端的逻辑部分所包含的“OR”的个数的多少自左向右排序;
将每个“OR”连接的在同一括号层次内的两个逻辑部分,按照其包含的最大连续“AND”的多少自左向右排序。
根据规范化后的结构文本逻辑语句确定各个元素在其所处括号的层次以及前后的逻辑运算符是“AND”还是“OR”,将文本中的元素按照其对应的图元在梯形图中的二维坐标,进行一一定位,过程如下:
普通元素:即结构文本中的逻辑操作数,把此元素存放到二维数组STR中的相应行,在其后面追加一个“;”,用于分隔相邻的两个元素;
左括号:扫描到左括号时,括号总数加一,通过比较当前括号总数与当前左括号数的大小关系来确定当前的括号层次位置;
逻辑“与”:如果扫描到下一个字符为右括号,同时当前左括号数减为零,需要重新计算左括号数;如果扫描到逻辑“与”后面是普通元素,表示前后两个元素在梯形图中的同一行,不需调整输入行;
逻辑“或”:如果当前左括号数等于当前括号总数,表明逻辑“或”当前所处的括号层次需要补齐操作,记录下到了二维数组的第几行,并从首行到二维数组当前最大行逐行补齐横线和空缺,最后调整输入位置。如果此时当前左括号数减为零,说明本次输出是个加法表达式,需要重新计算左括号个数和调整输入位置;
右括号:扫描到右括号时,当前括号总数减一,如果当前左括号数不等于当前括号总数,把当前括号总数值赋予左括号值,同时当前右括号的层次需要和逻辑“或”相同的补齐横线和补齐空缺操作,并把输入位置调整为此括号层次的开始行;当扫描到右括号的下一个元素是逻辑“与”操作符或输出标志符,需要进行补竖线操作;
功能符:功能函数符相当于梯形图中功能指令,不需要装入二维数组STR,直接转换成中间代码;
输出标志:对输出标志直接转换成中间代码,也无需放入二维数组中。
补齐横线和空缺规则如下:
在二维数组中,通过计算其他行中的普通元素和横线总数与首行中普通元素个数的差值,进行补齐横线,如果某行的最后一个元素是普通元素或是横线则补齐相应个数的横线,如果此行的最后一个元素是竖线则用相应个数的“;”填充,最后调整输入位置。
补齐竖线规则如下:
在二维数组中,第一行以外其他行的最后一个元素是普通元素或横线或是“;”,则在本行末尾补上一个竖线;当前行的最后一个元素是竖线则不需要补齐竖线。
调整输入位置规则如下:
如果字符串结束,将输入位置调整为本次逻辑的开始行,否则,下一次的输入位置下调的距离为最后一行的宽度。
将定位后的结构文本的各个元素转换成中间代码,中间代码的格式为:(TYPE,X,Y,PARAMl,PARAM2,...);其中TYPE为该图元的类型,X为图元横坐标,Y为图元纵坐标,PARAM为图元参数,过程如下:
分号:表示一个元素的结束,将当前行的纵坐标后移两个单位长度;
字符串结束标志:表示梯形图的一行结束,将程序的当前行号加一;
普通元素:确定其类型,用当前行号和当前行的纵坐标分别作为它的X,Y坐标,它的名字就是它的参数;
横线:用当前行号和当前行的纵坐标分别作为它的X,Y坐标;
竖线:当前行的纵坐标向后移动一个单位距离,因为竖线端点的横坐标为奇数,其余同横线操作。
由于结构文本中各个元素的类型及其在梯形图中的坐标和参数信息都已经确定,利用已经编写好的画梯形图的各功能函数,将中间代码转换为梯形图。
本发明具有以下有益效果及优点:
1.本发明方法具有通用性,能将任意复杂的结构文本快速、准确无误地转换成梯形图。
2.本发明方法可以示范和帮助用户设计出符合国际标准的规范化的结构文本和梯形图。
3.本发明方法不必重复编写梯形图程序,需要时将结构文本转换成相应的梯形图即可,既便于保存,也能大幅提高工作效率,同时,也易于校正程序中存在的错误。
具体实施方式
本发明将结构文本语言转换为梯形图语言的方法包括以下步骤:
将结构文本逻辑语句按照IEC 61131-3标准进行等价规范处理;
根据规范化后的结构文本逻辑语句确定各个元素在其所处括号中的层次以及前后的逻辑运算符是“AND”还是“OR”,将文本中的元素按照其对应的图元在梯形图中的二维坐标,进行一一定位;
将定位后的结构文本的各个元素转换成中间代码,每个元素的中间代码包含图元的类型、图元坐标和参数信息,利用已编写的画梯形图的各功能函数,将中间代码转换成梯形图。
本实施例在编辑该结构文本逻辑的过程中,为了能够方便的处理结构文本语句,首先把“AND”替换成“*”,把“OR”替换成“+”,“:=”替换成“=”,再把结构文本逻辑语句分解成字符的形式存储在双链表中,具体数据结构如下:
typedef struct_node
{
char data;//语句的字符
struct_node*next;//当前节点的下一个节点
struct_node*prior;//当前节点的上一个节点
}slnode; //节点
按照IEC 61131-3标准规定,在有几个串联回路相并联时,应将触点多的串联回路放在梯形图的上面,而在有几个并联回路相串联时应将触点多的并联回路放在梯形图的左面。
为了便于确定结构文本语句中各元素对应的图元在梯形图中的位置,同时使转换后的梯形图更标准、具有通用性,更符合以上所述的规则,对结构文本语句做如下规范化处理,过程如下:
(i)对于每一个“*”,在其所处的括号层次内,按照此“*”两端的逻辑部分所包含的“+”的个数的多少自左向右排序。
以结构文本语句:A=F*(E+G*(B+C+D))为例,如图3所示:
以左起第一个“*”为中心的逻辑表达式为“F*(E+G*(B+C+D))”,此“*”处在括号的最外层,它的右部分“(E+G*(B+C+D))”中的“+”个数为3,如图3中虚线所示,此“*”左部分逻辑“F”中的“+”数为0,因此规范化后“(E+G*(B+C+D))”应该在此“*”的左边。
对于左起第二个的“*”为中心的逻辑表达式“G*(B+C+D)”,它所处的括号层次为图3中中括号显示的范围,此“*”右部分“(B+C+D)”中的“+”个数为2,左部分“G”中的“+”个数为0,规范化后“(B+C+D)”在此“*”的左边。这样整个结构文本语句在规范化后的等价语句为A=(E+(B+C+D)*G)*F。
在第1步的基础上,将每个“+”连接的在同一括号层次内的两个逻辑部分,按照其包含的最大连续“*”的多少自左向右排序。
构文本语句:A=(E*H+(B*I+C*G*J)*D)*F为经过第一步的转换后的另一个逻辑语句,如图4所示:
对于左起第一个“+”,所处的括号层次为图4中大括号显示的范围,以它为中心的逻辑表达式为“E*H+(B*I+C*G*J)*D”,左部分的“E*H”中的最大连续“*”个数为1,右部分“(B*I+C*G*J)*D”中的最大连续“*”个数为3,如图中虚线所示,因此规范化时,以此“+”为中心,将“(B*I+C*G*J)*D”放在“E*H”的左边。
对于左数第二个“+”,其括号层次为图4中中括号显示的范围,它连接的逻辑表达式为“B*I+C*G*J”,其中,“+”左部分“B*I”中的连续“*”个数为1,右部分“C*G*J”中的连续“*”的个数为2,规范化时将“C*G*J”放在“B*I”的左边。因此整个结构文本语句规范化后的等价语句为A=((C*G*J+B*I)*D+E*H)*F。
为了更直观的展示以上算法,以复杂的结构文本语句4=(1*2+5*((6*7+10*11)*8+12*(13+15)+14))*(3+9)为例,它所对应的梯形图如图5所示;通过以上算法规范化后的结构文本语句为:4=(((6*7+10*11)*8+(13+15)*12*14)*5+1*2)*(3+9),规范化后对应的梯形图如图6所示,两者之间是等价的。
在转换中首先进行规范化,除了有利于将结构文本转换为梯形图的算法实现之外,还可以示范和帮助用户如何设计标准的规范化的结构文本和梯形图。即使用户写的结构文本不标准,本转换算法能自动地将其纠正过来,并将其转换成等价的标准的梯形图。同样,如果用户设计的梯形图不复合上述标准,经过正反两次转换,便可变为等价的符合标准的梯形图。
根据规范处理后的结构文本逻辑语句确定各个元素在其所处括号中的层次以及前后的逻辑运算符是“AND”还是“OR”,将文本中的元素按照其对应的图元在梯形图中的二维坐标,进行一一定位,并存放在二维数组中,过程如下:
处理过程中用到的主要参数说明:
char STR[][]:按照对应的梯形图中各图元的层次和顺序存放结构文本中的各元素;
static int_outline:每个输出的起始行,因为结构文本源程序可以有多个输出,每个输出可能有多行;
int curpos[]:每个输出表达式中每行的纵坐标;
int max_width[]:每行的宽度;
slnode*temp:当前的字符节点;
int row:在STR中的当前行号;
int cur_num_brackets:当前的括号总数,遇到左括号加1,右括号减1;
int pos:当前左括号数,通过比较pos与cur_num_brackets的大小关系来确定当前括号所处的层次位置,进而执行相应的操作;
“|”梯形图中的竖线;
“-”:梯形图中的横线;
“;”:作为每两个元素的分隔,两个分隔符在一起就说明梯形图中有空位。
其中,坐标从0开始,竖线端点(也称虚节点)的横坐标总是为奇数,其余元素包括横线(称实节点)的横坐标总为偶数。
为了符合梯形图中输出在右的形式,把每个结构文本逻辑表达式的输出放在右面,如A=B*C+D*E替换为B*C+D*E=A,然后自左向右顺序扫描结构文本语句,对扫描到的各元素根据其类型进行相应的处理,处理方法如下所示:
(i)普通元素
即结构文本中的逻辑操作数,把此元素存放到STR[][]中的相应行,在其后面追加一个“;”
(ii)左括号
cur_num_brackets++;//括号总数加一,相反遇到‘)’需要
//cur_num_brackets--;
(iii)逻辑与
处理方式如下:
if(temp->next->data==′(′) //如果下一个字符为‘(’
if(pos==0) //如果当前左括号个数减为0,需要重新计算
{pos=count(temp); //count()为计算pos值的函数,如:
//(A+B)*(C+D)=E,当扫描完(A+B)后需要重
//新计算pos的值
} //如果后面是普通元素,表示前后两个元素在
//LD中的同一行,不需调整当前行号继续向后
//扫描字符串
(iv)逻辑或
处理方式如下:
row++;
if(pos==cur_num_brackets)//逻辑“或”当前所处的括号层次需要补齐操作
记录下到了二维数组的第几行,并从首行到二维数组当前最大行逐行补齐横线和空缺,最后调整输入位置。如果此时的左括号数目减为零,说明本次输出是个加法表达式。如:A*B*C+(D+G)*E=F,当扫描到左起第一个“+”,需要重新计算左括号个数和调整输入位置。
补齐横线和空缺的规则:
在二维数组中,通过计算其他行中的普通元素和横线总数与首行中普通元素个数的差值,进行补齐横线,如果某行的最后一个元素是普通元素或是横线则补齐相应个数的横线,如果此行的最后一个元素是竖线则用相应个数的“;”填充,最后调整输入位置。
调整下一次输入行的规则:
如果字符串结束,将输入位置调整为本次逻辑的开始行,否则,下一次的输入位置下调的距离为最后一行的宽度。
(v)右括号
处理方式如下:
cur_num_brackets--;
if(pos!=cur_num_brackets)//当前“)”的层次需要补齐操作
pos=cur_num_brackets;//便于下次计算括号层次。
同时,需要和“或”相同的补齐横线和补齐空缺操作,并把输入行调整为此括号层次的开始行即在此括号层次内的第一个元素的位置。
if(temp->next->data==′*′‖temp->next->data==′=′)
//右括号的下一个元素是“与”操作符或输出标志符,例:(A+B+C)*D=F,最后一个“)”的右边是“*”,需要进行相应的补竖线操作,规则如下:
在二维数组中,第一行以外其他行的最后一个元素是普通元素或横线或是“;”,则在本行末尾补上一个竖线;当前行的最后一个元素是竖线则不需要补齐竖线。
(vi)功能符
功能函数符相当于梯形图中功能指令,不需要装入二维数组STR[][],可以直接转换成中间代码。
(vii)输出标志
对输出进行单独处理,无需放入二维数组中,直接输出即可。
按照前面所提出的方法,以下面所示的规范化后的结构文本为例,将其转换成相应的符号并存放到二维数组中,处理过程见表1。
表1结构文本语句具体处理过程
最后,将STR[][]中的字符串换成中间代码,利用已编写的画梯形图的各功能函数,将中间代码转换成梯形图。根据确定一个梯形图图元所要求的所有信息,制定中间代码的格式为:(TYPE,X,Y,PARAM1,PARAM2,...);其中TYPE为该图元的类型,X为图元横坐标,Y为图元纵坐标,PARAM为图元参数,过程如下:
转换过程当中用到的主要参数:
int line:二维数组中的当前行;
int curpos:某行的当前光标位置;
char*cnt:某行的当前字符。
具体处理过程:
顺序扫描二维数组STR[][],由于各个元素对应在梯形图中的先后顺序及层次关系都已确定,再根据其类型获得每个元素的大小,就可以计算出结构文本中各个元素对应的图元在梯形图中的位置。对于该数组中的各类型变量处理规则如下:
(i)if(*cnt==′;′)
curpos+=2;//遇到分号,表示一个元素的结束,将光标位置后移
(ii)if(*cnt==’\0’)
line++;//当扫描完一行,将程序的当前行加一
(iii)普通元素
确定其类型,用line和curpos分别作为它的X,Y坐标,它的名字就是它的参数。
(iv)if(*cnt==′-′)//横线
curpos+=2;//用当前行号和当前行的纵坐标分别作为它的X,Y坐标
(v)if(*cnt==′|′)//竖线
curpos+=1;//竖线的横坐标为奇数,处理方法同横线
表1中的逻辑表达式转换后的中间代码如表2,格式为:(TYPE,X,Y,PARAM1,PARAM2...);其中常开触点的类型定义为257,竖线的类型定义为256,横线的类型定义为261,输出线圈的类型定义为259。至于其它图元,本例中没有用到,这里不再赘述。
表2转换后的中间代码
由于各个元素的类型及其在梯形图中的坐标和参数信息都已经确定,利用已经编写好的画梯形图的各功能函数,将中间代码转换成梯形图。
本发明方法对结构文本进行等价的规范化后,实现结构文本向梯形图的转换算法。该算法具有通用性,可正确、有效地转换复杂结构文本为梯形图。