文档章节

学习 JFlex 和 BYacc/J 简要笔记

刘军兴
 刘军兴
发布于 2014/01/01 18:16
字数 816
阅读 747
收藏 6
点赞 0
评论 4

JFlex 是 The Fast Lexical Analyser Generator, 是 lex/flex 的 java 版本, JLex 的升级.

帮助手册地址: http://www.jflex.de/manual.html
中文的一些资料: http://wenku.baidu.com/view/542645350b4c2e3f57276338.html

lex/flex 的规则文件(spec)的三部分为: 1.声明/选项; 2.模式和动作; 3.代码被复制的.

而 JFlex 的规则文件的三部分为: 1. 类之前用户代码(同flex 3); 2. 声明/选项; 3. 模式和动作.
注意顺序有所不同.

第二部分中, 有一些重要的选项中摘录如下: (全部的参见文档)
%class Yylex -- 生成的 lex 类名字, 缺省为 Yylex; 另有 %implements %extends 等指令可
  指定类的基类和实现的接口等选项.
%{ ... 类中代码... %} -- 放到类中间的代码, 如类方法和成员变量等.
%function -- 指定调用 yylex() 的名字, 缺省为 yylex.
%int -- 指定 yylex() 返回类型为 int, 此情况下对 EOF 返回 -1.
%type -- 指定 yylex() 返回类型为 type, 缺省为 Yytoken 类型, EOF 返回 null.
%debug, %stsandalone -- 可用于生成 main() 方法, 用于调试.
%cup, %byacc -- 可用于和 cup, byacc 组合.

=================================================
例子: word count, 从 flex 中改编(需要调整一些代码和结构)
/* 第一部分: 声明 package, import 略. */
%%
/* 第二部分: 选项,类中代码 */
%class WordCountLexer
%function yylex
%int
%{
  /* 类中代码 */
  public int chars, words, lines;
  public static void main(...) 略
%}
%%
/* 第三部分: 规则和动作 */
[a-zA-Z]  { 匹配一个词 print(yytext()); ++words ... }
\n           { 匹配新行 print("NEWLINE"); ++... }
.             { 匹配其它任何字符. print("OTHER CHAR: " +yytext()); ++... }

需要注意的是, 这里 spec 文件结构要根据 jflex 要求更改. 最后生成一个 java 文件, 测试执行通过.
要点: %int 设置返回值类型; 抄一个 main() 函数.

 

====================================================
例子2: 计算器

/* first part */
package calc;

%%
/* second part */
%{
  public static void print(String s) { System.out.print(s); }
%}

%int
%debug

%%
/* third part */
"+"     { print("PLUS\n"); }
"-"     { print("MINUS\n"); }
"*"     { print("TIMES\n"); }
"/"     { print("DIVIDE\n"); }
[0-9]+  { print("NUMBER: " +yytext() +"\n"); }
\n      { print("NEWLINE"); }
[ \t]   { /*space ignored*/ }
.       { print("Mystery Char: " + yytext() + "\n"); }

与 wc 相似, 模式略微增多一些.

方法论:
  1. 在现有例子中 逐步地 修改,添加, 试验.
  2. 找别人工程中已经使用了的 lex/flex 文件改造.

花絮(八卦): lex 是 1975 年 Mike Lesk 和暑期实习生 Eric Schmidt 编写的, 后者现在是 
  Google 的 CEO.

=======================================================
一个 BYacc/J 的例子: calc.y

%token NUMBER  /* 定义 token */
%type <dval> exp  /* 可用于指定 yylval 值类型 */

%% /* begin second part: rules */
calclist: /*empty*/ | calclist exp EOL ...
exp: exp '+' factor | exp '-' factor ...

%% /* third part: user code */
public static void main() { ... }
public int yylex() { ... } /* 连接 jflex 在这里实现 */

生成文件使用: byaccj -J -Jpackage=calc -Jsemantic=double calc.y
  其中 byaccj 指向 yacc.exe (BYacc/J 的可执行文件)
  -Jpackage=calc 指定包名字.
  -Jsemantic=double 表示语义值类型取为 double (计算器例子中为省事)

在 Yylex 中, 需要引用 Parser 生成的 NUMBER 等 token 值. 为给 parser 中设置 yylval 值,
需要在 Yylex 中有 Parser 的引用, 在构造中给出是易用的方式.

 

======================================================

Ant 文件中自动完成 cup, jflex 编译的片段, 供参考用:

<property name="CUPJar" value="lib/java-cup-11a.jar" ></property>
	<property name="JFlexJar" value="lib/JFlex.jar"></property>
	<!-- 定义新任务 cup,jflex -->
	<taskdef name="cup" classname="java_cup.anttask.CUPTask"
	  classpath="${CUPJar}" />
	<taskdef name="jflex" classname="JFlex.anttask.JFlexTask"
		classpath="${JFlexJar}" />
	
	<!-- 使用 cup 编译 'ycalc.cup' -->
	<target name="ycalc_cup" >
		<cup srcfile="src/cup/ycalc.cup"
			destdir="src/cup"
			interface="true"
			package="cup"
			parser="Parser"
			symbols="sym"
		/>
	</target>
	<!-- 使用 jflex 编译 'lcalc.flex' -->
	<target name="lcalc_flex">
		<jflex file="src/cup/lcalc.flex" dot="true"
			/>
	</target>

 

© 著作权归作者所有

共有 人打赏支持
刘军兴
粉丝 54
博文 150
码字总数 226172
作品 0
昌平
加载中

评论(4)

刘军兴
刘军兴

引用来自“小战江湖”的评论

引用来自“刘军兴”的评论

引用来自“小战江湖”的评论

楼主,刚花了半天时间装Jflex,但它具体怎么用啊,这些代码都写在什么地方的,一点头绪都没有

jflex 是 c 系统中 lex/flex 的 java 版本, 想了解 jflex 怎么用, 可先学习 lex/flex 怎么用, 两者是非常相似的.
Flex 的链接: http://www.gnu.org/software/flex/

我们是在上一门课,导师让我用这个软件,也没教我们怎么用。。。请问输入命令是在cmd里面吗,为什么我不能输入任何东西?

jflex/lex 的内容一般写在一个文件如X中, 然后在命令行调用 jflex (java 的 jar), 以该文件X为输入, 输出为 java 语言的解析器. 我看你很多基础知识也需要了解, 不全是jflex的, 请自己多学习吧.
小战江湖

引用来自“刘军兴”的评论

引用来自“小战江湖”的评论

楼主,刚花了半天时间装Jflex,但它具体怎么用啊,这些代码都写在什么地方的,一点头绪都没有

jflex 是 c 系统中 lex/flex 的 java 版本, 想了解 jflex 怎么用, 可先学习 lex/flex 怎么用, 两者是非常相似的.
Flex 的链接: http://www.gnu.org/software/flex/

我们是在上一门课,导师让我用这个软件,也没教我们怎么用。。。请问输入命令是在cmd里面吗,为什么我不能输入任何东西?
刘军兴
刘军兴

引用来自“小战江湖”的评论

楼主,刚花了半天时间装Jflex,但它具体怎么用啊,这些代码都写在什么地方的,一点头绪都没有

jflex 是 c 系统中 lex/flex 的 java 版本, 想了解 jflex 怎么用, 可先学习 lex/flex 怎么用, 两者是非常相似的.
Flex 的链接: http://www.gnu.org/software/flex/
小战江湖
楼主,刚花了半天时间装Jflex,但它具体怎么用啊,这些代码都写在什么地方的,一点头绪都没有
语法分析器生成工具--BYACC/J

BYACC/J 是扩展和兼容自 Berkeley v 1.8 YACC 的Java的语法分析器生成工具。Standard YACC takes a YACC source file, and generates one or more C files from it, which if compiled prop......

匿名 ⋅ 2009/02/22 ⋅ 0

JFlex 1.6.1 发布,语法分析生成器

JFlex 1.6.1 发布,次版本主要有以下更新: Fixed issue #130, "in caseless mode, chars in regexps not accepted caselessly": Caseless option works again as intended. Fixed issue #13......

oschina ⋅ 2015/03/30 ⋅ 2

Coursera吴恩达《神经网络与深度学习》课程笔记(2)-- 神经网络基础之逻辑回归

我的CSDN博客地址:红色石头的专栏 我的知乎主页:红色石头 我的知乎专栏:红色石头的机器学习之路 欢迎大家关注我!共同学习,共同进步! 上节课我们主要对深度学习(Deep Learning)的概念...

红色石头 ⋅ 2017/09/07 ⋅ 0

JPA 学习资料汇总

1.JPA学习总结(http://shmilyaw-hotmail-com.iteye.com/blog/1969190) 2.JPA学习笔记2——JPA高级(http://blog.csdn.net/chjttony/article/details/6086305) 3.JPA学习笔记(http://www.blogj......

IT追寻者 ⋅ 2016/08/02 ⋅ 0

Scala学习笔记-基础语法

Scala学习笔记-基础语法 OneCoder2016-09-2046 阅读 Scala 上手学习Scala语言。先熟悉一下语法。对于Scala笔者也是完全的新手,对scala的设计思想和实现原理没有太多了解。错误在所难免,还望...

OneCoder ⋅ 2016/09/20 ⋅ 0

Nagios开发自定义插件check_netstat

前言 这几天学习了Nagios的plugin写法,先写了个简单的例子: 类似主机netstat命令的监控,可以监控链接的数量. 学习笔记,以备查阅 @Author duangr @Website http://my.oschina.net/duangr/blo...

一只小逛 ⋅ 2013/12/17 ⋅ 1

如何学好oracle课程

oracle的体系太庞大了,对于初学者来说,难免会有些无从下手的感觉,什么都想学,结果什么都学不好,所以把学习经验共享一下,希望让刚刚入门的人对oracle有一个总体的认识,少走一些弯路。 ...

slence ⋅ 2011/09/03 ⋅ 0

机器学习笔记-standford公开课课程学习笔记

一、回归问题(regression)与分类问题(classification)的区别 二者都属于监督式学习,回归问题和分类问题的本质一样,都是针对一个输入做出一个输出预测,其区别在于输出变量的类型。 分类...

xiaodidadada ⋅ 05/13 ⋅ 0

Machine Learning笔记(二) 单变量线性回归

Machine Learning笔记(二) 单变量线性回归 注:本文内容资源来自 Andrew Ng 在 Coursera上的 Machine Learning 课程,在此向 Andrew Ng 致敬。 一、模型表示(Model Representation) 对于...

Gaussic ⋅ 2015/09/25 ⋅ 0

FakeScript-Java —— 轻量级嵌入式脚本语言

FakeScript-Java是一款轻量级的嵌入式脚本语言,使用Java语言编写,语法吸取自lua、golang、erlang,基于jflex、cup生成语法树,编译成字节码解释执行。 C/C++版本fakescript...

oschina ⋅ 2016/08/06 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring Boot整合模板引擎thymeleaf

项目结构 引入依赖pom.xml <!-- 引入 thymeleaf 模板依赖 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId......

yysue ⋅ 9分钟前 ⋅ 0

ConstraintLayout使用解析

AndroidStudio3.0创建Project默认的布局就是ConstraintLayout。 AndroidStudio3.0前的可以自己修改,使用ConstraintLayout。 为了要使用ConstraintLayout,我们需要在app/build.gradle文件中...

_OUTMAN_ ⋅ 21分钟前 ⋅ 0

OSChina 周三乱弹 —— 这样的女人私生活太混乱了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ 胖达panda :你经历过体验到人生的大起大落吗?我一朋友在10秒内体验了,哈哈。@小小编辑 请点一首《almost lover》送给他。 《almost love...

小小编辑 ⋅ 54分钟前 ⋅ 9

自己动手写一个单链表

文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号:好好学java,获取优质学习资源。 一、概述 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对...

公众号_好好学java ⋅ 今天 ⋅ 0

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部