OpenCASCADE Expression Interpreter by Flex & Bison

eryar@163.com

Abstract. OpenCASCADE provide data structure of any expression, relation or function used in mathematics. Flex and Bison are tools for building programs that handle structured input. They were originally tools for building compilers, but they have proven to be useful in many other areas. The Expression Interpreter in OpenCASCADE is made by Flex and Bison. So let’s know something about Flex and Bison.

Key Words. OpenCASCADE, Expression Interpreter, Flex, Bison

1.Introduction

OpenCASCADE的TKMath中提供了数学表达式求解的包Expr和ExprIntrp,用来对数学表达式或函数进行解析计算。所谓的数学表达式如:sin(10)+20*6-6/3等。以前在《数据结构》的书上看到用栈的方式来对简单表达式求值,感觉已经很不错了。但是如果表达式中包含三角函数、对数、指数等,程序就要复杂了。如何简单、优雅地去解决这个问题,当时也是很茫然。

工作中遇到前辈自己写了一个用于定义几何的语言,还可以计算表达式。虽然没有看到源码,对其已是崇拜不已。后来接触了脚本语言,像Tcl/Tk,Python之类,发现原来利用这些开源库,也是可以实现一个简单、稳定的自定义开发语言。因为这类脚本不仅可以计算表达式,还可以计算带参数的表达式,如:

set x
set y
set z [expr sqrt($x*$x+$y*$y)]

只要你在Unix环境中写过程序,你必定会邂逅神秘的Lex&YACC,就如GUN/Linux用户所熟知的Flex&Bison,这里的Flex就是由Vern Paxon实现的一个Lex,Bison则是GNU版本的YACC。学习过《编译原理》的同学们对这两个神器应该不会陌生。使用这两个工具,不仅可以实现一个表达式解析计算器,还可以用来解析SQL语法,如PostgreSQL中就是使用他们实现SQL语法解析。甚至还可以实现一个编译器。

因为是Unix上的工具,在Windows上需要使用winflexbison,可以从sourceforge上下载:https://sourceforge.net/projects/winflexbison/

本文介绍如何使用Flex来理解OpenCASCADE中ExprInterp的实现,开阔视野。OpenCASCADE中ExprInterp的用法见:Evaluate Math Expression

http://www.cppblog.com/eryar/archive/2013/10/09/203625.html

2.Flex Example

FLEX是一个自动化工具,可以按照定义好的规则自动生成一个C函数yylex(),也成为扫描器(Scanner)。这个C函数把文本串作为输入,按照定义好的规则分析文本串中的字符,找到符合规则的一些字符序列后,就执行在规则中定义好的动作(Action)。例如在规则中可以这样定义:如果遇到一个换行字符\n,那么就把行计数器的值加一。

Flex文件就是一个文本文件,内容包括定义好的一系列词法规则。文件的命名习惯上以小写字母l(L)来作为文件后缀。如果为了清晰,也可以用.flx或者.flex作为文件的后缀名。Flex文件完成后,就执行下列命令:

$ flex example.flex

这个命令执行后将生成一个C文件,默认文件名为lex.yy.c。这个C文件主要内容就是函数yylex()的定义。

如果要直接将这个文件编译成为一个可执行程序,还有一些要注意的地方。如果在Flex文件中没有提供main()函数的定义,那么这个C文件中不会有main()函数。此时单独编译这个C文件的时候,一定要加上-lfl的连接库参数;若提供了main()函数,就不必要提供这个连接库参数了。连接库libfl提供了一个缺省的main函数。缺省的main()函数中只是简单地调用yyflex()函数,而自己提供的main()函数则可以根据需要加入许多其他的处理代码。

词法规范定义文件给出了单词构成规则。词法文件在习惯上用字母l(即L的小写)来作为后缀。Flex文件由三个部分组成。或者说三个段。三个段之间用两个%%分隔。

定义段(definitions)

%%

规则段(rules)

%%

用户代码段(user code)

下面给出一个简单的Flex程序,代码如下所示:

/* hello world for Flex. */
%option noyywrap
%{
int char_count = ;
int line_count = ;
%} %% \n { ++char_count; ++line_count; }
. { ++char_count; } %% int main(int argc, char* argv[])
{
yylex(); printf("# of lines = %d, # of chars = %d\n", line_count, char_count); return ;
}

将上述文件保存为hello.lex,然后运行如下图所示命令:

会生成一个lex.yy.c的源程序,将这个C源文件编译,链接即可生成一个可执行程序。运行程序如下图所示:

3.Flex and Bison in occ

在OpenCASCADE的文件夹中也有相关的语法规则定义,如下图所示:

由上图可知,OpenCASCADE的表达式解析功能的实现也是利用了Flex和Bison。

4.Conclusion

借助于Flex和Bison这两个强大的工具,你可以实现一个高级的计算器,即任意数学表达式计算器。

OpenCASCADE的ExprInterp使用了Flex和Bison实现了数学表达式的解析计算。当理解了工具的用途,有兴趣的读者不妨结合《编译原理》等理论知识,对工具的原理进行一番探究。

5.References

1. 严蔚敏, 吴伟民. 数据结构(C语言版). 清华大学出版社. 1997

2. 赵建华, 郑滔, 戴新宇 译. 编译原理. 机械工业出版社. 2011

3. John Levine, flex & bison. O’REILLY. 2009

OpenCASCADE Expression Interpreter by Flex & Bison的更多相关文章

  1. 编译器工具 Flex Bison for Windows 简单入门例子

    最近从事一个系统仿真软件的开发,里面定义了自己的描述性语言MSL, MSL语言经FlexBison转换成C语言,然后用C编译器来编译并计算仿真. 现在领域驱动开发比较热门,有机会定义自己的语言对程序员 ...

  2. Windows下 flex + bison 小例子

    .下载flex和bison,网址是http://gnuwin32.sourceforge.net/packages/flex.htm 和http://gnuwin32.sourceforge.net/ ...

  3. Flex & Bison 开始

    Flex 与 Bison 是为编译器和解释器的编程人员特别设计的工具: Flex 用于词法分析(lexical analysis,或称 scanning),把输入分割成一个个有意义的词块,称为记号(t ...

  4. flex/bison 计算器

    flex %{ #include <stdio.h> #include "mycalc.tab.h" ;} %} %% "+" return ADD ...

  5. 应注意的Flex&Bison潜规则

    1.Flex的二义性模式 语法分析器匹配输入时匹配尽可能多的字符串 如果两个模式都可以匹配的话,匹配在程序中更早出的模式. 针对这一点的理解,在语法分析文件当中,token的识别,应从特殊到一般的过程 ...

  6. flex&bison 1

    .   {ECHO;}-----单独的flex使用中有效 .   { yyerror();}--------flex和bison交叉使用,即使不调用yyerror函数,也会报错的 error: syn ...

  7. [flex & bison]编译器杂谈

    flex与bison是编译器设计工具.这里的编译器为广义,其中包括一般的编译器.脚本解析器等,需要进行语言结构解析来得出意义的程序. 当我们需要用一个语言来设计一款编译器时,需要考虑太多设计重心外的东 ...

  8. lex yacc flex bison

    lex与yacc是两个在Unix下的分别作词法分析和语法分析的工具, Linux对应flex与bison. windows:http://sourceforge.net/projects/unxuti ...

  9. flex bison

    https://www.gnu.org/software/bison/manual/bison.html https://blog.csdn.net/sirouni2003/article/detai ...

随机推荐

  1. Asp.net Boilerplate之AbpSession扩展

    当前Abp版本1.2,项目类型为MVC5. 以属性的形式扩展AbpSession,并在"记住我"后,下次自动登录也能获取到扩展属性的值,版权归"角落的白板报"所 ...

  2. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  3. Azure Service Fabric 开发环境搭建

    微服务体系结构是一种将服务器应用程序构建为一组小型服务的方法,每个服务都按自己的进程运行,并通过 HTTP 和 WebSocket 等协议相互通信.每个微服务都在特定的界定上下文(每服务)中实现特定的 ...

  4. ABP框架 - OData 集成

    文档目录 本节内容: 简介 安装 安装Nuget包 设置模块依赖 配置你的实体 创建控制器 示例 获取实体列表 请求 响应 获取单个实体 请求 响应 获取单个实体及导航属性 请求 响应 查询 请求 响 ...

  5. JavaScript Math和Number对象

    目录 1. Math 对象:数学对象,提供对数据的数学计算.如:获取绝对值.向上取整等.无构造函数,无法被初始化,只提供静态属性和方法. 2. Number 对象 :Js中提供数字的对象.包含整数.浮 ...

  6. 转:serialVersionUID作用

    汗,以前学了还忘了... Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本 ...

  7. JavaScript动画-拖拽改变元素大小

    ▓▓▓▓▓▓ 大致介绍 拖拽改变元素大小是在模拟拖拽上增加了一些功能 效果:拖拽改变元素大小 ▓▓▓▓▓▓ 拖拽改变元素大小原理 首先这个方块得知道我们想要改变这个它的大小,所以我给它设定一个范围,当 ...

  8. python+uwsgi导致redis无法长链接引起性能下降问题记录

    今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...

  9. .net Elasticsearch 学习入门笔记

    一. es安装相关1.elasticsearch安装  运行http://localhost:9200/2.head插件3.bigdesk插件安装(安装细节百度:windows elasticsear ...

  10. C#开发微信门户及应用(39)--使用微信JSSDK实现签到的功能

    随着微信开逐步开放更多JSSDK的接口,我们可以利用自定义网页的方式来调用更多微信的接口,实现我们更加丰富的界面功能和效果,例如我们可以在页面中调用各种手机的硬件来获取信息,如摄像头拍照,GPS信息. ...