SCPI语言解析器设计
1.引言
SCPI语言与过去的仪器语言的不同点,在于命令描述的是正在试图测量的信号,而不是正在用以测量信号的仪器。仪器使用者可花费较多的时间来学习解决实际应用问题,用较少的时间来学习所使用的仪器,这是因为相同的SCPI命令可用于很多不同类型的仪器,这被称为“横向兼容性” (即不同产品类型之间的兼容性)。SCPI 还是可扩展的。这就是它能随着仪器功能的增加而扩大。这样在将来人们可以购买一台比目前所用仪器功能更多的万用表,其基本功能完全可以像以前使用的旧仪器一样程控。这就是“纵向兼容性” (即产品各代之间的兼容性)[1]。鉴于这些优点,目前大部分程控仪器都支持SCPI语言,以方便用户使用和维护。
SCPI语言也像其他语言一样,具有关键字、数据、分隔符等基本元素,SCPI语法规则只定义了这些基本元素的命名规范和组合使用方法,而且允许根据实际应用增减关键字,具有很好的可扩展性。
在程控类的仪器仪表设计中,支持SCPI语言这一特性几乎是必须的,因此设计一套灵活高效的SCPI语言解析器是非常必要的。
本文提出了一种针对SCPI语言的两级解析模型,即解析器分为词法分析和语义分析两部分,将复杂的解析
工作划分为两级处理,每一级只负责一部分工作,降低了解析器的设计难度。词法分析专注于从SCPI语句中提取关键字和数据,并将其映射为内部代码;语义分析则专注于进行语义解释,将内部代码表示的SCPI语句解释为针对仪器的寄存器访问和操作。
本文通过设计实例,介绍了这种两级解析模型的设计与实现过程。文章首先简单介绍了SCPI语言,并以费思泰克电子负载FT6600支持的SCPI语句举例。之后在文章第3部分详细介绍了SCPI语言词法分析器的设计,在文章第4部分详细介绍了SCPI语义分析器的设计。最后在第5章进行了总结,并展望了这一设计技术的进一步改进和应用。
字符串长度大于52.SCPI语言及FT6600程序控制命令简介
SCPI语言是一种用于可编程仪表的标准命令,它定义了一套控制器与程控仪器通讯时命令规则。
SCPI 语言使用层次化结构——“树”形结构,每条“树”命令都是以根层次命令(也称“子系统”)开始,每个根层次命令下面又有许多层次命令。只有按照从
树根到叶子的完整路径发送命令,仪器才能正确执行相应的操作命令。“树”形命令结构如图错误!未定义书签。所示:
图错误!未定义书签。SCPI命令树示例
SCPI语言本身定义了一组基本的子系统关键字,同时允许用户增加或减少关键字,这些关键字通常是一些有意义的英文单词,以方便记忆,也称助记符。助记符有长格式和短格式两种类型,短格式是长格式的缩写,缩写规则[2]如下:
●短型助记符由长型助记符的前4个字符构成,如果长型助记符的字符长度小于
等于4时,长短型助记符相同;
●如果长型助记符的长度大于4,而第四个字符是元音时,短型助记符将舍弃这
个元音而变成3个字符;
关键字之间、数据之间以及语句之间使用一些特殊的字符进行分隔。这些特殊字符主要有分号(;)、空格()、冒号(:)、逗号(,)等,下面简单描述一下这些特殊字符的用法。
●分号(;)的用法。分号用来分隔同一个根命令字符串中的两个子命令,且表
示后一个子命令的首关键字与前一个子命令的叶节点关键字同级。因此使用分号可以简化语句的书写,如:
:CURR:MVAL 5;:CURR:TVAL 10 ……①
:CURR:MVAL 5;TVAL 10 ……②
语句①与语句②的语义是完全相同的。
●空格( )的用法。空格是用来分隔命令域与参数域的。在参数域中,两个参数
之间的空格会被忽略。例如语句①中MVAL与数值5之间要加空格用以区分命令域与参数域。
●逗号(,)的用法。如果一个命令需要一个以上的参数,那么相邻参数之间必
须用逗号分开。如:
CAL:DATA 10.3 , 0.1, 5.5 ……③
语句③是一条校准命令,一次写入3个数据。
●冒号(:)的用法。当冒号位于语句的第一个字符前面时,表示接下来的命令
是根命令。当冒号位于两个关键字之间时,表示从命令树的当前层次向下移动一个层次。
以上简单介绍了SCPI语言的词法和语法规则,下面将以电子负载FT6600为例详细描述如何解析SCPI语句。FT6600是深圳市费思泰克科技有限公司的一款高端的程控电子负载,具有恒流、恒压、恒阻和恒功率四种功能,并支持自定义序列工作模式和瞬态工作模式[3],功能比较复杂,其支持的程控命令语句完全兼容SCPI语法规范。因此,本文选择该仪器作为示例,阐述使用两级解析模型,实现SCPI语言解析器的设计方法。
3.SCPI语言词法分析器的设计
本文提出的两级解析模型,其基本设计思想是:将SCPI语句的解析过程划分为词法分析和语义分析两级,每一级只负责一部分工作,以降低解析器的设计难度。词法分析的主要任务是从SCPI语句中提取关键字和数据,并将其映射为内部代码。而语义分析则在词法分析的基础上,对内部代码表示的SCPI语句进行语义解释,进而执行针对仪器的寄存器访问或操作。
词法分析的关键是如何快速地从ASCII码表示的字符串中识别出系统预定义的关键字和数据,以及检测出非法的关键字和数据类型。本文设计了一个有限状态机,根据当前ASCII字符(字母、数字或特殊字符),进行状态之间的切换和关键字与数据的识别。状态机的具体结构如下:
图错误!未定义书签。SCPI语言词法解析器状态机
词法解析器的四个状态中,Start为起始状态,从语句的第一个字符开始分析,如果该字符是“*”或字母,那么说明接下来应该是关键字,故进入Keyword状态,提取关键字;如果第一个字符是数字,那么进入数值提取状态Value。
在Keyword状态下,如果遇到的字符是字母或者数字,那么将其写入字符串缓冲,并准备读取下一个字符。当遇到语句结束符、关键字分隔符“:”、空格或查询字符“?”时,表示关键字提取完毕,立即将提取的字符串与内部关键字数组进行比对。比对过程中既要比对关键字的短格式也要比对长格式,为提高比对速度,内部关键字数组按照从小到大的顺序排列,然后使用二分法进行比对,最大的比对次数为+1次,其中N为关键字个数。如果比对结果有效,那么将其对应的内部代码(占用一个字节)写入内部命令缓冲区,否则报非法关键字错误。比对完成后,进入Start状态,准备接收下一个关键字或数值。
在Value状态下,如果遇到的字符是数字或小数点“.”,那么将其写入字符串缓冲,并准备读取下一个字符。其他字符时,立即进行字符串到数值的转换,将数值代码写入到内部命令缓冲区,若转换过程出错,那么报非法数据错误。如果字符是“E”或“e”,说明这是一个使用科学计数法表示的浮点数,那么下一状态进入指数域的提取状态Exponent,否则返回到Start状态。
指数域提取状态Exponent的工作过程与数值提取状态Value很类似,如果遇到的字符是数字或小数点“.”,那么将其写入字符串缓冲,准备读取下一个字符。如果是其他字符,那么进行字符串到数值的转
换,并将转换结果(指数)与Value状态提取的数值(尾数)进行合并,生成一个浮点数值的内部代码,覆盖尾数域所在的内部代码区域。之后进入Start状态,准备接收下一个关键字或数值。
按照上述状态转换依次进行提取,直到语句结束,至此,当前语句的词法分析过程结束,然后将内部代码缓冲交给语义解析器进行语义分析。
4.SCPI语言语义分析器的设计
语义解析器要实现的主要工作是将内部代码表示的语句,按照语法规则将其转换为一个个操作或者读写仪器的状态与控制寄存器。由于关键字很多,且语句之间的组合多种多样,因此看起来语义分析是一件很困难的工作。
实际上,SCPI语言毕竟不像C语言、PASCAL语言等专业编程语言那么复杂,只要在词法分析阶段做一些处理,其合法命令的数目是有限的。如语句②的组合表达方式,经过词法分析后,其实是划分成两条命令的——:CURR:MVAL 5;和:CURR:TVAL 10,故本文使用穷举法进行语义分析。其基本思想是:穷举所有可能的命令,将其使用内部代码表示并配合参数信息,一起保留在一个二维数组(合法命令数组)中,每条命令对应的操作函数也组合在一起,形成对应的数组。语义分析过程将转变为提取的内部命令缓冲在合法命令数组内的查过程,查方法仍可以使用二分法以提高查速度,如果查成功,那么执行该命令对应的操作函数,否则报语法错误。
合法命令数组的示意结构如下:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论