文档章节

学习 JFlex 和 BYacc/J 简要笔记

刘军兴
 刘军兴
发布于 2014/01/01 18:16
字数 816
阅读 891
收藏 6

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
博文 184
码字总数 226359
作品 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
1K
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
1K
2
Coursera吴恩达《神经网络与深度学习》课程笔记(2)-- 神经网络基础之逻辑回归

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

红色石头
2017/09/07
0
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
38
0
Scala学习笔记-基础语法

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

OneCoder
2016/09/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Hbase 概述及特点

1、Hbase概述 HBase是一种构建在HDFS之上的分布式、面向列的存储系统。在需要实时读写、随机访问超大规模数据集时,可以使用HBase。 尽管已经有许多数据存储和访问的策略和实现方法,但事实上...

PeakFang-BOK
18分钟前
0
0
TortoiseGit(乌龟git)保存用户名密码的方法

windows下比较比较好用的git客户端有2种: 1. msysgit + TortoiseGit(乌龟git) 2. GitHub for Windows github的windows版也用过一段时间,但还是不太习惯。所以目前仍然青睐与msysgit+乌龟g...

simpower
37分钟前
0
0
Java并发编程:volatile关键字解析

volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生...

engeue
55分钟前
2
0
通过ajax访问远程天气预报服务

http://www.webxml.com.cn/zh_cn/index.aspx 更改wsdl文件 打开文件将15行,51行,101行去掉 然后把文件复制到c盘 然后在桌面上面就生成了文件 将文件打成jar包 package cn.it.ws.weather;...

江戸川
今天
1
0
聊聊storm的tickTuple

序 本文主要研究一下storm的tickTuple 实例 TickWordCountBolt public class TickWordCountBolt extends BaseBasicBolt { private static final Logger LOGGER = LoggerFactory.getLogg......

go4it
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部