的Input方法的语法部分() ("\n"|"\r")* 的含义是:可被这个产生式替代,随后可有任意个回车换行符号,最后以文件结束符结尾(是系统定义的TOKEN,表示文件结束符号) 。
方法的语法部分"{" [ () ] "}"的含义是:一个以{开始,并配对的以}结束的串,期间可以有任意个递归的方法 。
这份解析器可以解析如"{ }", "{ { { { { } } } } }"这样的串; 不能解析"{ { { {", "{ } { }", "{ } }", "{ { } { } }", "{ }", "{x}"这样的串 。
文章插图
4.2.
接下来,我们通过编译运行的方式看一个结合了的例子 。进入到-5.0//目录,先来手工编译一把eg1.jjt 。(本身例子自带ant编译文件,这里了解下编译过程) 。
jjtree eg1.jjt // 生成Node文件及jj文件javacc eg1.jj // 生成Eg1.java及相关解析文件javac *.java // 编译Java源文件
java Eg1 // 运行例子,输入待解析的文本1+1; // 回车生成一个ASTStartExpressionAdditiveExpressionMultiplicativeExpressionUnaryExpressionIntegerMultiplicativeExpressionUnaryExpressionInteger
eg1例子实现了4则运算,先乘除后加减,如果有括号则先解析括号中的 。如上如果是一个简单加法运算,它生成的AST将会包含空节点:sion(乘除)、(括号),除此之外就是一颗树了 。大家可以输入更为复杂的4则运算表达式以观察生成的树的构成 。
例子中通过的dump方法输出了Tree 。是中表示一个节点的父类 。
SimpleNode n = t.Start();n.dump("");.../** Main production. */SimpleNode Start() : {}{Expression() ";"{ return jjtThis; }}
4.2.从源码构建的解析器
看完上面的的简单例子我们就大体上清楚解析器的构建方式 。的解析器需要 3.2版本以上 。
的jjt文件在src//.jjt,产生的jj文件及其他生成的文件在org....包下 。在其子包node下,有jjt文件生成的一组继承自的节点 。
jjtree Parser.jjt // 生成Parser.jj、一组Node的Java文件骨架(需要自行实现Node的功能性代码)等javacc Parser.jj // 生成解析器
最终生成的解析器会在.()方法中调用 。要想完整的理解.jjt文件,还需要进一步阅读-5.0/doc/.html文档,了解相关的扩展语法 。
5.模板渲染
中为了将中的复杂对象merge到模板中渲染呈现,实现了一套自省机制 。可以通过 来对org...util.包下的代码做逆向工程,生成UML图以便阅读代码结构 。如下图是去除枝节后的类图结构:
图1 自省类图
通过类图我们来梳理一下其中的关系 。是主要的自省/反射接口,提供方法如下:
init():初始化getIterator():支持迭代 #foreachgetMethod():支持方法调用 $foo.bar( $woogie )getPropertyGet():支持获取属性值 $bar.woogiegetPropertySet():支持设置属性值 #set($foo.bar = "geir")
的实现,该实现使用完成自省功能 。扩展自基类,增添日志记录 。内部维护了一个,用于缓存已经完成自省的类和方法信息 。l内通过一个维护一个class与其对应的类型信息,类型信息用一个表示 。一个内部维护了一个,用于缓存该类已经解析出得方法信息 。表示一个方法信息 。
- 2023全新UI的AI网址导航系统源码+基于Thinkphp6框架开发的
- 基于Thinkphp6框架全新UI的AI网址导航系统源码
- 【redis源码学习】看看redis的“哈希表”实现
- 5vShop商城系统源码v1.6
- 转 1 x264源码分析:main、parse、encode、x264_en
- php养老院管理系统 毕业设计源码202026
- 基于人脸识别云相册应用源码
- int n=10的sizeof 为什么是四_mongodb内核源码实现、性能调优
- 奇遇网:专注收录开源,利于优化源码收藏下载
- 基于Android的电子书阅读器(Android studio毕业设计