javacc jjtree 写法 以及 jj写法 基本语法 以及应用
/***********************************************************/
>我使用的测试jjt,jj文件来自于javacc5.0版本
>dir_hier/javacc-5.0/javacc-5.0/examples/
JJTreeExamples
SimpleExamples
/***********************************************************/
/***********************************************************/
0.javacc(the java Compiler Compiler)概要
>Abstract summary:
javacc一般用于编写某种语言的书写规则,如java的语法规则
变量必须以字母或者$开头或者以数字结尾等,这是一种书写规范,
书写规范是这门语言特有的,他必须满足,那么他是怎么去判断
书写的字符窜符合了规则了,那就需要进行验证,javacc就是
一种用于定义某种特定输入格式字符窜规则的工具,也是验证这种
特定格式字符窜的验证者。定义字符窜输入格式,以及验证输入的
字符窜是javacc的最基本作用。
javacc语法规则描述文件的书写方式有两种一种是一种是.jj文件,
另外一种是.jjt文件,两种文件的书写方式差异性不大,但是jjt文件
比jj文件表达语法规则更加容易,jj文件的可选参数项和jjt有很大的
不同,这是他们最大的区别。
/***********************************************************/
/***********************************************************/
1.javacc语法规则书写操作基本代码
>如何在生产表达式中写条件结构
(
term = < TERM >
|
term = < STAR >
|
term = < PREFIXTERM >
|
term = < WILDTERM >
|
term = < NUMBER >
)
>生成后的代码对应到
分析:
因为在javacc中(<A> | <B>)被表示成了在两个规则中任意选择一个的意思。
switch(tokenkind){
case TERM:
/** doSomthing...*/
break;
case STAR:
/** doSomthing...*/
break;
...
}
void ifExp():{int k=0;/** java局部变量声明处*/}{
{/*在{}中写任意的java代码并且是以面向对象的方式*/}
(
{
if(k==2){break;}
System.out.println("k="+k);
k++;
}
)*
}
>如何在生产表达式中写循环结构
->(
{
if(k==2){break;}
System.out.println("k="+k);
k++;
}
->)*
>生成对应的代码
while(true){
if(k==2){
break;
}
System.out.println("k="+k);
k++;
}
>在生产表达式中调用其他的生产表达式
对应到java中的方法调用
void B():
{
StringBuffer sb = new StringBuffer();
Token t = null;
}{
t = A /** 这里对应生成的java代码t=jj_consume_token(A);
* 因为等于就是要消费一个记号把消费的这记号的应用给t变量
*/
}
void A():{}{}
>javacc中的词法状态介绍
<*>TOKEN:{}
<DEFAULT>TOKEN:{<A:"2001 TO 2002">:DateRange
|
<B:"anything">
}
<DateRange>TOKEN:{}
解析:<*>,<DEFAULT>,<DateRange>是词法状态
定义词法状态的好处是,如果在生产表达式中
正好有一个字符窜匹配到了2001 TO 2002这个字符窜
那么他就会马上把下一个要匹配的模式字符窜定义
为DateRange这种词法状态中定义的Token
>有了循环有了条件结构有了定义变量的方式
javacc语法文件就相当完美了。
/***********************************************************/
/***********************************************************/
2.JJT语法规则描述文件书写方法
>jjt概要
jjt能够很清晰的表达出语法分析的思路,
并且他把每一个生产表达式都作为一个节点来表示,
将这些节点的执行顺序有效的组织成了一颗语法分析树
>.options
>BUILD_NODE_FILES (default: true)
为SimpleNode以及语法中使用的其它节点创建样本实现。
>MULTI(default: false)
创建多模式解析树。
此选项默认为False,生成一个单一模式解析树。
>NODE_DEFAULT_VOID (default: false)
此选项设置为True时,
不在使每个非包装产生式定义一个节点,取而代之为空。
>NODE_FACTORY (default: false)
用下面的方式使用一个工厂方法创建一个节点:
public static Node jjtCreate(int id)
>NODE_PACKAGE (default: "")
被放进生成节点类里的包。默认为解析器的包。
>NODE_PREFIX (default: "AST") AST意思为抽象节点
在多模式中,前缀用来从节点标志符构造节点类名字。
默认前缀为” AST”
>NODE_SCOPE_HOOK (default: false)
在节点作用域入口和出口处插入调用用户自定义的解析方法。
在节点的生命开始和结束之前需要调用的方法被成为钩子。
参见:节点作用域钩子。
>NODE_USES_PARSER (default: false)
是否将当前解析器对象也出入到节点对象的属性中
JJTree会使用一个选择的形式将解析对象传给构造函数。例如:
public static Node MyNode.jjtCreate(MyParser p, int id);
MyNode(MyParser p, int id);
>STATIC (default: true)
为静态解析器生成代码。
选项默认为True。
这必须一致的通过等效的JavaCC选项被使用。
选项的值发布于JavaCC的源码中。
>VISITOR (default: false)
在节点类中插入jjtAccept()方法,
为语法中使用的每个节点类型产生一个访问者实现。
>VISITOR_EXCEPTION (default: "")
如果这个选项被设置,它将使用jjtAccept()和visit()方法的形式。
注意:这个选项将会在以后的某个JJTree版本中删除。如果不影响你请不要使用它。
>JJTREE_OUTPUT_DIRECTORY (default: use value of OUTPUT_DIRECTORY)
默认情况下,在全局OUTPUT_DIRECTORY设置中指定JJTree生成的输出目录。
明确的设置这个选项允许用户从树文件中分离解析器。
/***********************************************************/
/***********************************************************/
3.语法分析树节点(Node)
>javacc把每一个生产表达式都看作为一个简单节点(SimpleNode)在默认
MULTI(default: false)的情况下,javacc已经提供了这个SimpleNode类的简单实现。
>MULTI(default: true)将为每一个节点都按照[NODE_PREFIX_生产表达式的名字]这样
一种形式来提供默认的简单实现类。
>定义节点的方式
明确定义:一个以指定子节点数创建的节点
void AdditiveExpression() #void : {}
{
(
MultiplicativeExpression()
(
( "+" | "-" )MultiplicativeExpression()
)*
)#Add(3)
}
>语法分析树参考结果:
Add
Integer
Integer
Integer
>#void不会为这个生产表达式生成对应的节点
>#Add表示在循环执行过程中生成的所有节点中的前三个节点作为
以Add为命名的儿子节点。
按照条件定义:
void AdditiveExpression() #void : {}
{
(
MultiplicativeExpression()
(
( "+" | "-" ) MultiplicativeExpression()
)*
) #Add(>3)
}
>#Add(>1)另外一种写法#Add(jjtree.arity() > 1)
生成的源码:
jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1);
在执行循环过程中创建的节点个数大于1的话就会将所有的节点
做为Add的子节点然后将Add节点添加到堆栈中,如果条件不满足
那么创建的所有节点将会保留在栈中默认会在做为上一个节点的
子节点
>语法分析树参考结果:
Start /** 因为在执行循环过程中创建的节点数没有达到指定的个数所以是start*/
Integer
Integer
>notes:
( ... ) #N ( a() )
上面表达式逻辑不清,
你必须明确的使用条件式:
( ... ) #N(true) ( a() )
>为产生式的节点指定名称
void ProductExp() #MyNode:{} {//doAnything}
#MyNode为这个生产表达式所对应的节点的名称
>特殊应用
void P3():{}
{
P4() ( P5() )+ #ListOfP5s P6()
}
#name=jjtree.closeNodeScope(jjtn001, true);
#name(3)=jjtree.closeNodeScope(jjtn001, 3);
#name(>3)=jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1);
>什么是jjThis
ASTStart Start() : {}
{
Expression() ";"
{ return jjtThis; }
}
分析:
jjThis代表了当前节点的引用地址,
就好像ASTStart Start()这个生产表达式对应到Start这个
节点那么jjtThis就指向了这个对象,
在其内部的实现代码为:
ASTStart jjtn000 = new ASTStart(JJTSTART);
>什么是NODE_SCOPE_HOOK="true"(默认为true表示有钩子)
这个名气叫的很有味,钩子,正好是在某个节点被创建的
时候调用指定的钩子方法,在节点添加到栈的时候要调用的方法
钩子在open的时候可以做一些预备工作,结束可以做一些后续工作
示例代码:
static final public void AdditiveExpression() throws ParseException {
ASTAdd jjtn001 = new ASTAdd(JJTADD);// 创建节点
boolean jjtc001 = true;
jjtree.openNodeScope(jjtn001); // 这就是钩子
try {
//do something...
} finally {
if (jjtc001) {
jjtree.closeNodeScope(jjtn001, 3);// 这就是钩子
}
}
}
/***********************************************************/
4.jjt文件生成的文件解析
SimpleQueryParser.jjt
SimpleQueryParser.jj
JJTSimpleQueryParserState.java
Node.java
ParseException.java
SimpleCharStream.java
SimpleNode.java
SimpleQueryParser.java
SimpleQueryParserConstants.java
SimpleQueryParserTokenManager.java
SimpleQueryParserTreeConstants.java
Token.java
TokenMgrError.java
>jjt文件可以生成.jj文件
>SimpleQueryParser这个名字在很多类名中都以重复的字眼出现,这是通过
Parser_Begin(SimpleQueryParser)...Parser_End(SimpleQueryParser)
指定的。
>JJTSimpleQueryParserState.java用于记录节点的组织情况
这个类有单独的说明,在JJTSimpleQueryParserState.java
中,他是一个以堆栈形式设计的类。
>Node.java是一个接口jjt中节点必须实现他,在选项MULTI(default: false)
的时候javacc编译器已经帮我们简单的做了实现这个类为SimpleNode.java。
>ParseException.java在语法分析的时候遇到不符合规则的字符时抛出的异常
>SimpleQueryParserConstants.java这个类主要用于关联定义的Token
>SimpleQueryParserTreeConstants.java主要用于关联定义的节点
如果没有给生产表达式命名那么他默认就是用生产表达式的名字做为节点的
名字
>SimpleQueryParserTokenManager.java这是最重要的类他用于生产Token对象
在getNextToken()中体现了这么一点
>Token.java这个对象作为最小的记号单元用于封装SimpleQueryParserTokenManager
生成的记号
>SimpleQueryParser.java将类综合起来提供语法分析服务,他是消费Token对象的,
在jj_consume_Token(token_kind)中可以体现这一点,传入一个记号的类型返回这个
类型的一个token对象
>TokenMgrError.java在生产Token对象的过程中遇到错误
>SimpleCharStream.java用于封装输入的字符窜
>SimpleQueryParserTokenManager.java/**用于产生Token*/
SimpleQueryParserTokenManager.getNextToken()/** 生产Token的方法*/
/** 消费Token的SimpleQueryParser利用这些Token生成特定的逻辑对象*/
SimpleQueryParser.java
SimpleQueryParser.jj_consume_token(int kind);/** 根据指定的类型消费一个token*/
SimpleQueryParser.jj_ntk()/** 如果当前jj_ntk变量为-1
说明当前token对像的下一个token没有找到需要接着要到tokenmanage里面
拿一个token出来作为当前token的next*/
/***********************************************************/
/***********************************************************/
5.jj文件写法解析
>options
>STATIC=false;
意思所有的生产表达式对应到java代码的时候
不是静态的
/***********************************************************/
转载:http://blog.csdn.net/zyb243380456/article/details/7240225
javacc jjtree 写法 以及 jj写法 基本语法 以及应用的更多相关文章
- CSS- ie6,ie7,ie8 兼容性写法,CSS hack写法
css ie6,ie7,ie8 兼容性写法,CSS hack写法 margin-bottom:40px; /*ff的属性*/margin-bottom:140px\9; /* IE6 ...
- C++ //多态案例 -计算器类(普通写法 和 多态写法) //利用多态实现计算器 //多态好处: //1.组织结构清晰 //2.可读性强 //3.对于前期和后期扩展以及维护性高
1 //多态案例 -计算器类(普通写法 和 多态写法) 2 3 #include <iostream> 4 #include <string> 5 using namespac ...
- (转载)robots.txt写法大全和robots.txt语法的作用
1如果允许所有搜索引擎访问网站的所有部分的话 我们可以建立一个空白的文本文档,命名为robots.txt放在网站的根目录下即可.robots.txt写法如下:User-agent: *Disallow ...
- robots.txt写法大全和robots.txt语法的作用
1如果允许所有搜索引擎访问网站的所有部分的话 我们可以建立一个空白的文本文档,命名为robots.txt放在网站的根目录下即可.robots.txt写法如下:User-agent: *Disallow ...
- sql查询一天内的where写法,sql写法
sql查询一天内的写法: 1. where createtime BETWEEN (select date_format(now(),'%Y-%m-%d 00:00:00')) and (select ...
- 背景图片等比缩放的写法background-size简写法
1.背景图片或图标也可像img一样给其宽高就能指定其缩放大小了. 比如一个实际宽高36*28的图标,要缩小一半引用进来的写法就是: background:rgba(0, 0, 0, 0) url(&q ...
- mschart asp chart 用法,包括前台写法与后台写法,还有click事件,如何触发。
纯后台动态生成aspchart ,这种方式没办法实现chart中click事件.click事件点击没有反应,用第二种可以实现点击事件. 两种方式实现同一种效果图: 第一种写法:后台动态生成aspcha ...
- ajax的jquery写法和原生写法
一.ajax的简介 Ajax被认为是(Asynchronous(异步) JavaScript And Xml的缩写).现在,允许浏览器与服务器通信而无须刷新当前页面的技术都被叫做Ajax. 同步是指: ...
- JUC 并发编程--02,生产者和消费者 synchronized的写法 , juc的写法. Condition的用法
synchronized的写法 class PCdemo{ public static void main(String[] args) { //多个线程操作同一资源 Data data = new ...
随机推荐
- Softnet_data
Softnet_data的初始化: 每个CPU的softnet_data是在net_dev_init中初始化的,代码如下: "/net/core/dev.c" "stat ...
- 【bzoj1002】[FJOI2007]轮状病毒
1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4381 Solved: 2393[Submit][Statu ...
- IIS网站打不开错误解决方案集锦(一):编译器错误消息: 编译器失败,错误代码为 -1073741502。
[2015-05-12解决记录] 问题:服务器上的文件一直都是好的,但是运行了很长一段时间以后,发现网站打不开,或者上传不了图片了,怎么办? 错误信息:c:\windows\system32\inet ...
- ACM入门记
[2015.12]零基础进队 [2016.4.10]浙大第十六届程序设计大赛 [2016.6.4]团体程序设计天梯赛初赛 [2016.7.16]团体程序设计天梯赛决赛 赛后总结:比赛的时候好慌,一道题 ...
- js java正则表达式替换手机号4-7位为星*号
需求: 一个手机号13152461111,由于安全性,需要替换4-7位字符串为星号,为131****1111,那么有2中玩法,一种是前端隐藏,一种是后台隐藏. 1. 前台隐藏 <!DOCTYPE ...
- C#获取网页中的验证码图片(转载)
有时候我们需要获得网页上的图片,尤其是向验证码这样的图片.这个方法就是将网页上的图片获取到PictureBox中.效果入下图所示. 右边是使用Webbrowser控件装载的某网站的注册页面,其中包括了 ...
- javascript实现数据结构:线性表--简单示例及线性表的顺序表示和实现
线性表(linear list)是最常用且最简单的一种数据结构.一个线性表是n个数据元素的有限序列.在稍复杂的线性表中,一个数据元素可以由若干个数据项(item)组成. 其中: 数据元素的个数n定义为 ...
- 云计算中iaas、paas、saas的区别和联系
概念: iass : Infrastructure(基础设施)-as-a-Service, paas : Platform(平台)-as-a-Service, saas : Software(软件)- ...
- MEAN实践——LAMP的新时代替代方案(上)
摘要:90 年代,LAMP 曾风靡一时,然而随着需求的变迁和数据流量的激增,LAMP 已不可避免的走下神坛.近日,在 MongoDB Blog 中,Dana Groce 介绍了一个基于新时代架构的实践 ...
- iOS音效
//AudioToolbox.framework是一套基于C语言的框架,使用它来播放音效其本质是将短音频注册到系统声音服务(System Sound Service) //System Sound S ...