javacc学习
为什么要研究这些,除了个人兴趣之外,还有可以了解语言是怎样解析字符串生成逻辑代码。
他的应用性也是非常之广,如人工智能方面,把复杂的逻辑抽象成简单的文法,不懂编程的人都可以使用
说到人工智能,数据库SQL查询也算是,大家可能会觉得,这也算人工智能?
是的,如果程序员完全用过程方式去写逻辑查询的话,会疯掉,像淘宝级别的数据,假设每天产生一个数据库
如何多天查询?群集数据库如何分布式统计?
还有大型游戏的AI,一个怪物攻击过程有:检查状态->扫描目标->选择技能->计算伤害->保存数据->next ai
如果写一个怪物还好点,但一个游戏不会只有一个怪物吧,成千上万怎么办?
我在这里保证,大家都能学会。哈哈
先来介绍下 bnf 文法,内容我就不复杂了
一些概念简单说下
1.词法元素
2.词法标识
一组元素里包含多个标识,请看具体写法
TOKEN:{
<PLUS:"+">
|<NUMBER:(["0"-"9"])+>
|<NUM: <NUMBER> | (<NUMBER>.<NUMBER> )* >
}
翻译
词法元素:{
<词法标识1:"+">
|<词法标识2:(["0"-"9"])+>
|<词法标识3:<词法标识2>+>
}
多个标识用 | 关联起来,标识也可以嵌套也一标识
标识对应匹配的词,可以用正则书写.总的过讲比正则简单多了,但前提是你会正则
解析过程原理:
1.先定义各种词法元素 可按操作符,变量关键词,逻辑关键词等草划分词法元素
2.所谓的语法表达式 是结构节点编程 如果你精通结构编程,这点难不到你
如元素与元素相似的就用兄弟节点,上下属关系相似性不大就用父子节点
3.提取出来词法标识 相应的值,做逻辑处理。这时候提取出来了,想干嘛就干嘛
下面来自牛人总结一幅图


Javacc 简介
JavaCC是一个词法分析器和语法分析器的生成器。
这里列出我收集的资料
//基础
//http://forfuture1978.iteye.com/blog/661678
//http://cs.lmu.edu/~ray/notes/javacc/
//sql
//http://www.codeproject.com/Articles/35748/An-Introduction-to-JavaCC
//http://www.codeproject.com/Articles/50377/Create-Your-Own-Programming-Language
//base
//http://ramkulkarni.com/blog/handling-some-of-the-warnings-and-errors-generated-by-javacc/
Jdk 默认是没有的,要下载安装
执行命令
java -cp E:\javacc-6.0\bin\lib\javacc.jar javacc exp.jj
Javacc 语法简介
他可以跟 bnf 混编写如
int expr() :{
int reslt = 0;
int i = 0;
Token t=null;
}
{
t = <NUM>
{
result =Integer.parseInt(t.image)
return result;
}
}
翻译 混编
int expr() :{ java 局部变量,声明在这里 可以直接访问 bnf }
{
t = <NUM> // 将 匹配的单词赋值给 t
{
//{} JAVA代码必须写在 {}里
//javacc Token 对象有个重要属性 image 是匹配出来的值
result =Integer.parseInt(t.image)
return result;
}
}
一个完整的+-/*运算例子
分析:
逻辑优先级是 () 号,然后是 */ ,再到+-
options
{
static = false;
}
PARSER_BEGIN(Calculator)
package com.jj;
import java.io.PrintStream ;
public class Calculator {
public static void main( String[] args ) throws ParseException, TokenMgrError, NumberFormatException {
Calculator parser = new Calculator( System.in ) ;
parser.start( System.out ) ;
}
double previousValue = 0.0 ;
}
PARSER_END(Calculator)
SKIP : { " " }
TOKEN : { < EOL: "\n" | "\r" | "\r\n" > }
TOKEN : { < PLUS : "+" > }
TOKEN : { < MINUS : "-" > }
TOKEN : { < TIMES : "*" > }
TOKEN : { < DIVIDE : "/" > }
TOKEN : { < NUMBER : <DIGITS> | <DIGITS> "." <DIGITS> | <DIGITS> "." | "." <DIGITS>> }
TOKEN : { < #DIGITS : (["0"-"9"])+ > }
TOKEN : { < OPEN_PAR : "(" > }
TOKEN : { < CLOSE_PAR : ")" > }
TOKEN : { < PREVIOUS : "$" > }
void start(PrintStream printStream) throws NumberFormatException :
{}
{
(
previousValue = Expression()
{ printStream.println( previousValue ) ; }
)*
}
double Expression() throws NumberFormatException :
{
double i ;
double value ;
}
{
value = Term()
(
<PLUS>
i= Term()
{ value += i ; }
|
<MINUS>
i= Term()
{ value -= i ; }
)*
{ return value ; }
}
double Term() throws NumberFormatException :
{
double i ;
double value ;
}
{
value = Primary()
(
<TIMES>
i = Primary()
{ value *= i ; }
|
<DIVIDE>
i = Primary()
{ value /= i ; }
)*
{ return value ; }
}
double Primary() throws NumberFormatException :
{
Token t ;
double d ;
}
{
t=<NUMBER>
{ return Double.parseDouble( t.image ) ; }
|
<PREVIOUS>
{ return previousValue ; }
|
<OPEN_PAR> d=Expression() <CLOSE_PAR>
{ return d ; }
}
如果还觉得复杂,你可以跳过,我还是有信心保证你也会写的
下面直接josql 分析
其中核心代码
void _Query(Query q):
{
List cols = null;
List fromItems = null;
List joins = null;
Expression where = null;
List orderBys = null;
List groupOrderBys = null;
List groupBys = null;
Expression having = null;
Limit limit = null;
Limit grpLimit = null;
Expression from = null;
Map execute = null;
boolean distinct = false;
}
{
<K_SELECT> [ LOOKAHEAD(2) <K_DISTINCT> { q.setWantDistinctResults (true); } ]
cols = SelectItemsList(q)
from = From()
[ where = WhereClause() ]
[ LOOKAHEAD(2) groupBys = GroupBys() ]
[ having = Having() ]
[ LOOKAHEAD(GroupOrderBys()) groupOrderBys = GroupOrderBys() ]
[ orderBys = OrderBys() ]
[ LOOKAHEAD(GroupLimit()) grpLimit = GroupLimit() ]
[ limit = Limit() ]
[ execute = ExecuteOn() ]
{
// We set all the values since they are all dependent on the class
// being available.
q.setFrom (from);
q.setColumns (cols);
q.setWhere (where);
q.setHaving (having);
q.setGroupByOrderColumns (groupOrderBys);
q.setOrderByColumns (orderBys);
q.setGroupByColumns (groupBys);
q.setGroupByLimit (grpLimit);
q.setLimit (limit);
q.setExecuteOnFunctions (execute);
}
}
无非是提取出相应的参数,保存起来做处理而已,然提取过程可能会很复杂但基本是是结构节点编程
下面我来总结一下:
1.以sql 为例语法格式无非是 a指令 a参数 b指令 b参数 N... N个拼起来
2.提取出来的参数再做处理过程
我们来做个抽象演变
a指令 a参数 b指令 b参数 N...
直接抛开解析语法过程
Query( a参数, b参数 , c参数,n...)
这种书写也可以达到工人智能,但不太友好
再来一层抽象
{
a指令 : a参数,
b指令 : b参数,
n....
}
无错,就是JSON
大多数人对JSON 的认识还停留在数据方面
我总结下JSON 几大特精:
1.数据
2.类
3.结构
4.协议
5.文法 (从上面演变)
JS 特性我认为就两大,1是JSON 2.是回调。我个人是非常喜欢JSON的
javacc学习的更多相关文章
- javacc学习总结
在学javacc的时候.发现一个问题,见下: Example.jj文件 PARSER_BEGIN(Example) public class Example { public static void ...
- Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser
一.Lucene的查询语法 Lucene所支持的查询语法可见http://lucene.apache.org/java/3_0_1/queryparsersyntax.html (1) 语法关键字 + ...
- Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser 2014-06-25 14:25 722人阅读 评论(1) 收藏
一.Lucene的查询语法 Lucene所支持的查询语法可见http://lucene.apache.org/java/3_0_1/queryparsersyntax.html (1) 语法关键字 + ...
- java 学习之路
一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://www.jcp.org/en/jsr/detail?id=133 http://i ...
- JAVACC详解
JavaCC(Java Compiler Compiler)是一个用JAVA开发的最受欢迎的语法分析生成器.这个分析生成器工具可以读取上下文无关且有着特殊意义的语法并把它转换成可以识别且匹配该语法的J ...
- Lucene学习总结之七:Lucene搜索过程解析
一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...
- Lucene 学习资料
个机制的结合.关于中文的语言分析算法,大家可以在Google查关键词"wordsegment search"能找到更多相关的资料. 安装和使用 下载:http://jakarta. ...
- JAVA学习资源整理
构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...
- Java学习路线(转)
原文:http://www.hollischuang.com/archives/489 一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http ...
随机推荐
- C#与数据库访问技术总结(十五)之 DataAdapter对象代码示例
DataAdapter对象代码示例 下面的代码将说明如何利用DataAdapter对象填充DataSet对象. private static string strConnect=" data ...
- IOS行货自动打包
通常打包采用xcodebuild和xcrun两个命令,xcodebuild负责编译,xcrun负责将app打成ipa. 常见步骤如下: 1.清理工程 /usr/bin/xcodebuild -ta ...
- phpstorm的安装和破解
1.什么是phpstorm? PhpStorm是一个轻量级且便捷的PHP IDE,其旨在提高用户效率,可深刻理解用户的编码,提供智能代码补全,快速导航以及即时错误检查.但是phpstorm是商业软件, ...
- node.js cluster多进程、负载均衡和平滑重启
1 cluster多进程 cluster经过好几代的发展,现在已经比较好使了.利用cluster,可以自动完成子进程worker分配request的事情,就不再需要自己写代码在master进程中rob ...
- Leetcode 107 Binary Tree Level Order Traversal II 二叉树+BFS
题意是倒过来层次遍历二叉树 下面我介绍下BFS的基本框架,所有的BFS都是这样写的 struct Nodetype { int d;//层数即遍历深度 KeyType m;//相应的节点值 } que ...
- WindowsPhone App如何扩展能够使用的内存
目前手机系统中对App的内存使用都是有限制的,尤其是对于Android和WindowsPhone这样的平台,因为机型很多,配置高低不同因此对于同一个App在不同的手机上运行的效果也不同. WP上通常对 ...
- Windows下提升进程权限
windows的每个用户登录系统后,系统会产生一个访问令牌(access token) ,其中关联了当前用户的权限信息,用户登录后创建的每一个进程都含有用户access token的拷贝,当进程试图执 ...
- AndroidStudio使用第三方jar包报错(Error: duplicate files during packaging of APK)
http://www.kwstu.com/ArticleView/android_201410252131196692 错误描述: Error: duplicate files during pack ...
- C#代码像QQ的右下角消息框一样,无论现在用户的焦点在哪个窗口,消息框弹出后都不影响焦点的变化,那么有两种方法
你QQ的右下角消息框一样,无论现在用户的焦点在哪个窗口,消息框弹出后都不影响焦点的变化,那么有两种方法: 要么重写需要弹出的窗体的事件: protected override CreateParams ...
- 安装redis监控
在修改登录中心的时候,数据存储在redis里面,需要对redis进行监控,使用的是Redis-Live 参考文章: http://www.nkrode.com/article/real-time-da ...