最近公司会使用DSL描述一个domain service。所以趁这个机会也学习下高深的javacc,以前看到一堆的jj_xxx都很头痛,看代码基本都是跳过。
以前看过velocity, cobar的一下代码,都有使用类似jj_xxx,还有最近公司架构师做的一个anxiety,也使用了jj_xx自定义了一套btrace监控的语法:不需要我们自己写java文件,而是按照他的语法规则,它给我们自动生成btrace script。
还有就是万恶的大学,居然没给我们安排编译原理的课程,导致自己基础太差,理解起来颇为困难。没办法只能是硬着头皮先看一些编译原理的基本内容。
推荐一本书: 《编译原理》, 看完以后基本有了一些概念
- 文法描述定义, 传说中的BNF
1. 记号集合,终结符号
2. 非终结符号
3. 产生式集合 (这个中文版翻译的产生式还真TM的别扭,先不管)
digi := [0-9]
- 词法分析,读入输入流,结合符号表转化为后端使用的符号流。
1. 剔除空白字符
2. 常数处理
3. 识别符号和关键词
- 语法分析,构造语法树。
1. 自定向下,自底向上。 (javacc采用的是自顶向下)
2. 超前扫描(lookahead) , 根据非终结符查找对应的生产式,可能会导致匹配失败,需要进行回溯
3. 预测分析法(递归下降法)。非终结符需要无二义性,可以唯一定义一条生产式,要避免出现左递归。 expr := expr + dis
- 语法制导和翻译
- 代码生成和优化
在学习之前,一定要先弄会BNF文法描述,感觉有点和离散数学的推导论类似。
- 在双引号中的字("word")代表着这些字符本身。而double_quote用来代表双引号。
- 在双引号外的字(有可能有下划线)代表着语法部分。
- 尖括号( < > )内包含的为必选项。
- 方括号( [ ] )内包含的为可选项。
- 大括号( { } )内包含的为可重复0至无数次的项。
- 竖线( | )表示在其左右两边任选一项,相当于"OR"的意思。
- ::= 是“被定义为”的意思。
试着分析anxiety的BNF定义,它的语法:
import com.alibaba.service.template.*;
import com.alibaba.turbine.module.screen.TemplateScreen;
import com.alibaba.turbine.service.rundata.RunData;
import com.alibaba.webx.WebxException;
method=com.alibaba.manometer.module.screen.Shuffle.execute(RunData, TemplateContext)
method=java.lang.Long.valueOf(long)
method=java.util.concurrent.ConcurrentLinkedQueue.poll()
根绝这个目标语法需求,符号表可定义:
TOKEN :
{
<METHOD : "method">
| <IMPORT : "import">
}
TOKEN :
{
<IDENT : <ALPHA> (<ALPHA>|<NUM>)*>
| <ALPHA : (["a"-"z","A"-"Z"])>
| <NUM : (["0"-"9"])>
| <COMMA : ",">
| <SEMICOLON : ";">
| <LPAREN : "(">
| <RPAREN : ")">
| <DOMAIN : ".">
| <ASSIGN : "=">
| <STAR : "*">
}
里面的IDENT代表一个java全限定类名或者方法名,支持数字+字母。理论上java的命名规则是可以支持其他的类似中文,下划线等等,这里先不考虑。
最后定义BNF表达式:
param ::= ((IDENT ('.' IDENT)* ) (IDENT)?)*
method ::= IDENT ('.' IDENT)*
clazz ::= IDENT ('.' IDENT)* (';')*
statMethod ::= METHOD '=' method '(' param (,param)* ')'
impPack ::= IMPORT '=' clazz
parse ::= (impPack|statMethod)
param的一个例子:java.util.String str
method的一个例子: java.lang.Long.valueOf
clazz的一个例子: com.alibaba.turbine.service.rundata.RunData;
这里的clazz需要考虑 java.util.*的情况,会有个超前扫描的过程: [ LOOKAHEAD( { getToken(1).kind == STAR && getToken(2).kind == SEMICOLON } ) <STAR> | <SEMICOLON> ]
根据这个表达式,最后的javacc的对应的java函数为:
parse() : {}
{
(
(
impPack() | statMethod()
)
)*
}
impPack() : {}
{
(
<IMPORT> clazz()
)
}
statMethod() : {}
{
(
<METHOD><ASSIGN>method()<LPAREN>param()
(
<COMMA> param()
)*
<RPAREN>
)
}
method() : {}
{
(
<IDENT>
(
<DOMAIN><IDENT>
)*
)
}
clazz() : {}
{
(
<IDENT>
(
<DOMAIN>
(
<IDENT> | [ LOOKAHEAD( { getToken(1).kind == STAR && getToken(2).kind == SEMICOLON } ) <STAR> | <SEMICOLON> ]
)
)*
(<SEMICOLON>)*
)
}
String param() : {Token t;StringBuilder sb = new StringBuilder();}
{
(
(
<IDENT>
(
<DOMAIN><IDENT>
)*
)
(<IDENT>)?
)*
}
最后剩下的就是填充具体的方法实现了。
通过javacc进行编译生成对应的java文件:
最后
至于其他的jjdoc(用于编写BNF)和jjTree(构建语法树),后续有时间再学习下,javacc只是一些基本的词法分析+简单语义定义的使用。
- 大小: 226.6 KB
分享到:
相关推荐
JavaCC 学习心得 JavaCC 是一种强大的解析器生成器,可以根据用户的需求生成解释器。下面是对 JavaCC 的学习心得,分为工作原理、使用方法和深层认识三个方面。 工作原理: 1.1 结构综述: JavaCC 文件可以分为...
javacc学习手册 javacc是一款功能强大的编译器生成工具,可以生成词法分析器和语法分析器。下面是javacc的详细知识点: javacc安装 1. 安装JDK,并设置环境变量PATH路径。 2. 下载javacc,例如下载4.0版本的zip包...
### JavaCC 学习与应用知识点详解 #### 一、JavaCC 概述 - **定义**:JavaCC(Java Compiler Compiler)是一款用于Java开发的语法分析生成器工具,能够根据给定的文法文件自动生成Java代码,这些Java代码能够解析...
JavaCC学习心得 JavaCC 是一个词法分析生成器和语法分析生成器,能够生成词法分析器和语法分析器的 Java 代码。词法分析器可以将字符串解析为一个一个的标识符(Token),并且可以把这些标识符归类。语法分析器会分析...
在"javacc学习心得"文档中,作者可能分享了以下内容: 1. **JavaCC的基本用法**:如何安装和配置JavaCC,如何编写JJ文件来定义词法规则和语法规则。 2. **示例和实践**:可能包括作者尝试解析的简单CMM程序,以及...
### JAVACC学习心得知识点详解 #### 一、引言 JAVACC是一款强大的解析工具,主要用于构建解析器。本文档旨在分享通过两周多的学习后对JAVACC的理解与心得,主要内容涵盖其工作原理、使用方法及深入认识等方面。 #...
### Javacc学习心得 #### 一、Javacc简介及环境配置 Javacc是一种广泛应用于Java开发中的编译器框架,它主要用于构建解析器(parser)和词法分析器(lexer)。Javacc的功能与Lex和Yacc类似,但它是专门为Java设计...
在压缩包的文件名称列表中,“javacc学习手册.doc”很可能是一个Microsoft Word文档,其中包含了对JavaCC的详细教程和指导,可能包括基本概念、语法定义、使用示例以及常见问题解答等内容。而“javacc-5.0”可能是...
### JAVACC简易教程学习知识点详解 #### 一、JavaCC简介 JavaCC是一个功能强大的解析器生成器和词法分析生成器工具,主要用于帮助开发者快速构建语法解析器和词法分析器。这类工具在语言处理领域尤为重要,尤其是...
这个"javacc6.0安装及学习示例"压缩包文件包含了JavaCC的源代码、学习示例和官方文档,对于想要深入理解和使用JavaCC的人来说,是一份非常宝贵的资源。 首先,让我们了解什么是JavaCC。JavaCC是基于Java的,它通过...
下载JavaCC的相应版本后,你可以根据提供的文档和示例学习如何使用它来创建自己的解析器。 总的来说,JavaCC-4.0和JavaCC-5.0是Java语言中用于生成解析器的重要工具,它们帮助开发者解析和理解结构化的输入数据,...
JavaCC(Java Compiler Compiler)是一款强大的词法分析和语法分析工具,主要用于生成Java语言的解析器和词法分析器...通过深入学习和掌握JavaCC,你可以提高自己在处理文本解析问题上的技能,为各种项目提供解决方案。
5. `samples`目录:可能包含一些示例文法文件和对应的解析器代码,供学习和参考。 安装JavaCC后,开发者可以通过命令行调用`javacc`工具,传入文法文件的路径,JavaCC便会自动生成解析器和词法分析器的Java源代码。...
用户可以从中学习如何使用JavaCC,理解其工作原理,以及如何编写.jj文件。文档对于初学者尤其重要,可以帮助他们快速上手并解决遇到的问题。 **examples**目录:这里包含了一些示例项目,展示了如何使用JavaCC定义...
有许多资源可供学习 JavaCC: - **书籍**:比如《JavaCC 实战》等。 - **在线文章**:在 StackOverflow 和 GitHub 上有很多相关的讨论和技术分享。 - **官方文档**:官方网站上有详尽的使用指南和示例。 **1.11 ...
JavaCC是Java语言的一个工具,用于生成解析器和词法分析器,主要用于处理复杂的语法结构。在本项目中,"JavaCC实现MiniC语言的编译"是一个实践性的任务,目的是利用...这对于学习编译原理和JavaCC的使用非常有帮助。
Java Compiler Compiler,简称JavaCC,是一个强大的工具,用于在Java语言环境中生成词法分析器...通过学习和掌握JavaCC,开发者可以提高生产力,快速实现复杂解析功能,同时避免手动编写解析代码带来的繁琐和错误。
总的来说,"javacc编译原理实习"项目是一次宝贵的学习经验,它将理论知识与实践相结合,让你深入理解编译器是如何将人类可读的代码转化为机器可执行的指令的。通过完成这个项目,你将能够独立设计和实现简单的编译器...