一、前言

  在最开始使用JavaCC的时候,从网上查询了许多资料,但是网上的资料水平是参差不齐的,走了许多弯路,不得已自己查阅了英文版官网文档。令我伤心的是最后我回过头来再看那些博客资料时,发现其实他们写的都是没错的,只不过某些地方少了必要的讲解,以至于新手刚接触的时候是持续懵逼的。

  不管怎样,下面内容是对官方文档的翻译,加上一些自己的理解。

  官方文档连接:https://www.engr.mun.ca/~theo/JavaCC-Tutorial/javacc-tutorial.pdf

  这里所翻译的部分是JavaCC的入门知识,通过由浅入深的几个小例子,可以循序渐进的一步步了解JavaCC技术。

二、 JavaCC概述

  JavaCC全称为Java Compiler Compiler,它是一个生成器,用于生成词法分析器(lexical analysers)和语法分析器(parsers)。它可以通过读取一个词法和语法描述文件(即词法和语法描述是写在同一个文件中的),来生成一个java程序,这个java程序就包括了词法分析器和语法分析器。接着就可以用生成的词法分析器和语法分析器来对我们的输入进行判断,判断输入是否符合我们所要求的语法规则。

  编程语言中的编译器,其实就包含了词法分析器和语法分析器,编译器便是通过这两者来识别我们所编写的代码。除了在编译器中的应用之外,词法分析器和语法分析器在其他程序中也有着广泛的应用。

  那么什么是词法分析器和语法分析器呢?其中,词法分析器可以将一个字符序列拆分为一个个的子单元,这些子单元,在JavaCC中被称之为token——也就是说,词法分析器可以将一个字符序列拆分为一个个的token。这个解释可能依然有点让人摸不着头脑,下面看一个例子。

  假设我们要用词法分析器来解析下面的一段C语言编写的代码:

int main() {
return 0 ;
}

  那么C语言编译器中的词法分析器会将上述代码拆分为如下的token序列:

“int”, “ ”, “main”, “(”, “)”,
“ ”, “{”, “\n”, “\t”, “return”
“ ”, “0”, “ ”, “;”, “\n”,
“}”, “\n”, “” .

  可以看到所谓的拆分就是把int、空格、main、左括号等等各种字符给拆开罢了。那么在JavaCC中,会给拆分后得到的一个个token取一个逻辑上的名字,比如在本例中,我们所取的名称可以如下:

KWINT, SPACE, ID, OPAR, CPAR,
SPACE, OBRACE, SPACE, SPACE, KWRETURN,
SPACE, OCTALCONST, SPACE, SEMICOLON, SPACE,
CBRACE, SPACE, EOF .

  如此一来,KWINT这个token就表示“int”, SPACE这个token就表示“ ”, OPAR就表示左括号“(”等等。因此在JavaCC中,一般说到token的时候,一般指的是KWINT、SPACE、OPAR等这些东西。另外,EOF这个token表示“文件的末尾”。

经过词法分析而得到的tokens序列,在之后将会被传给语法分析器进行语法判断。

在C语言的编译器中,有时语法分析器在分析的时候是不需要所有的token的。比如在本例中,SPACE这个token就可以不用往下传给语法分析器了,那么此时SPACE这个 token应该如何处理掉,将在后面说到。

  在本例中,语法分析器将会对拿到的tokens序列进行分析,判断这些tokens序列是否符合c语言的语法结构。

  此外,词法分析器和语法分析器在分析的时候,还有可能会产生错误信息,即当你的输入并不符合你所定义的词法和语法规范时,就会抛出错误信息。

  最后需要注意的是,JavaCC本身并不是词法分析器和语法分析器,它是一个生成器!JavaCC通过读取一个后缀为.jj的描述文件中的特定描述,来生成词法分析器和语法分析器,并且生成的词法分析器和语法分析器使用Java书写的。)

  至此,已经简单说明了JavaCC是什么,以及词法分析器和语法分析器的作用,还引出了token的概念。下面将通过例子来一步一步进行讲解。

三、示例

5.JavaCC官方入门指南-概述的更多相关文章

  1. 11.JavaCC官方入门指南-例6

    例6:计算器--添加括号.一元运算符和历史记录 1.calculator3.jj   我们只需要再添加一些特色,就可以得到一个可用的四则运算计算器.在这一版的修改中 ,我们将使得程序可以接收括号.负值 ...

  2. 9.JavaCC官方入门指南-例4

    例4:计算器--添加减法运算 1. calculator1.jj   为了使得计算器具备更多功能,我们需要更多的操作符,比如减法.乘法和除法.接下来我们添加减法运算.   在词法分析器的描述部分,我们 ...

  3. 8.JavaCC官方入门指南-例3

    例3:计算器-double类型加法   下面我们对上个例子的代码进行进一步的修改,使得代码具有简单的四则运算的功能.   第一步修改,我们将打印出每一行的值,使得计算器更具交互性.一开始,我们只是把数 ...

  4. 7.JavaCC官方入门指南-例2

    例2:整数加法运算--改良版(增强语法分析器) 1.修改   上一个例子中,JavaCC为BNF生产式所生成的方法,比如Start(),这些方法默认只简单的检查输入是否匹配BNF生产式指定的规范.但是 ...

  5. 6.JavaCC官方入门指南-例1

    例1:整数加法运算   在这个例子中,我们将判断如下输入的式子是否是一个合法的加法运算: 99 + 42 + 0 + 15   并且在输入上面式子的时候,数字与加号之间的任何位置,都是可以有空格或者换 ...

  6. 10.JavaCC官方入门指南-例5

    例5:计算器--添加乘除法运算 1.calculator2.jj 根据上一个例子,可知要添加乘法和除法运算是很简单的,我们只需在词法描述部分添加如下两个token: TOKEN : { < TI ...

  7. 分布式服务框架 Zookeeper(三)官方入门指南

    入门指南:使用ZooKeeper来协调分布式应用 这篇文档包含了让你快速上手ZooKeeper的信息.主要是针对那些想要试一把ZooKeeper的开发人员,包含了安装一个单一ZooKeeper服务器的 ...

  8. mxGraph进阶(一)mxGraph教程-开发入门指南

    mxGraph教程-开发入门指南 概述 mxGraph是一个JS绘图组件适用于需要在网页中设计/编辑Workflow/BPM流程图.图表.网络图和普通图形的Web应用程序.mxgraph下载包中包括用 ...

  9. 【转】mxGraph教程-开发入门指南

    原文:https://blog.csdn.net/sunhuaqiang1/article/details/51289580 mxGraph教程-开发入门指南 概述 mxGraph是一个JS绘图组件适 ...

随机推荐

  1. for循环使用element的折叠面板遇到的问题-2

    需求:每次添加一个折叠面板时,让最新的折叠面板展开,其余的关闭 动态控制展开折叠面板,首先绑定name,v-model = activeName 我们的项目中是当添加折叠面板时,直接push进这个数组 ...

  2. Django 注意知识点(一)

    本篇概述 Django Admin后台显示 多对多字段(如何) Django 模板 显示 多对多字段(如何) Django 将表单中上传的多对多字段存入数据库 (如何)   Django 上传文件 ( ...

  3. 039.[转] 基于 Kubernetes 和 Spring Cloud 的微服务化实践

    http://dockone.io/article/2967 基于 Kubernetes 和 Spring Cloud 的微服务化实践 写在前面 网易云容器平台期望能给实施了微服务架构的团队提供完整的 ...

  4. 实时同步sersync实战

    目录 实时同步sersync实战 什么是实时同步 sersync和rsync+inotify对比 sersync项目实战 安装rsync的服务端(backup) NFS服务端部署sersync 实时同 ...

  5. 1. Linux-3.14.12内存管理笔记【系统启动阶段的memblock算法(1)】

    memblock算法是linux内核初始化阶段的一个内存分配器(它取代了原来的bootmem算法),实现较为简单.负责page allocator初始化之前的内存管理和分配请求. 分析memblock ...

  6. java异常处理机制详解

    java异常处理机制详解 程序很难做到完美,不免有各种各样的异常.比如程序本身有bug,比如程序打印时打印机没有纸了,比如内存不足.为了解决这些异常,我们需要知道异常发生的原因.对于一些常见的异常,我 ...

  7. shell通配符, 变量, shell作用域

    1. 指定格式输出当前时间: echo `date +%Y%m%d`  # 注意使用反引号, +号后面不要有空格 反引号中的东西会被当做命令来执行, 并输出执行的结果 2. $uid用于判断当前是否是 ...

  8. python进阶之垃圾回收

    内存使用: 程序在运行的过程需要开辟内存空间,比如创建一个对象需要一片内存空间,定义变量需要内存空间.有内存的开辟,势必也要有内存的释放,不然只进不出那不是貔貅了吗?即使有开辟有释放在短期内还是会有垃 ...

  9. body标签添加ontouchstart属性

    之前看别人的代码,发现他的body标签添加ontouchstart属性.即 <body ontouchstart> 上网查了一下原因,记录一下: 这个操作是进行手机端兼容处理的,防止伪类: ...

  10. webwork遍历数组标签

    WebWork中提供了一个<ww:iterator></ww:iterator>标签用于遍历数组. 01 如果数组中是普通类型,比如String.int等类型,可以通过标签中的 ...