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 ...
随机推荐
- ThreadLocal线程范围内的共享变量
模拟ThreadLocal类实现:线程范围内的共享变量,每个线程只能访问他自己的,不能访问别的线程. package com.ljq.test.thread; import java.util.Has ...
- 我的fckeditor实践
一开始我不懂这个ConnectorServlet是何用处,后来发现是专门用于文件上传的,因为fckeditor默认是不支持这个功能的. ConnectorServlet: /* * FCKeditor ...
- js中关于动态添加事件,不能使用循环变量的问题
在编写事件的时候,我们难免会遇到以下这种情况:<!DOCTYPE html><html lang="en"><head> <meta ch ...
- Leetcode 8 String to Integer (atoi) 字符串处理
题意:将字符串转化成数字. 前置有空格,同时有正负号,数字有可能会溢出,这里用long long解决(leetcode用的是g++编译器),这题还是很有难度的. class Solution { pu ...
- 前端与Server端(路由)
路由(前端):原理:只有几个XHR请求,就能实现页面无刷新闪烁更改URL 前端:1. ajax承担数据通信以及相对应的逻辑(交互逻辑) ajax进行数据交互,跟URL打交道,让数据交互的变化反映到UR ...
- windows远程连接Linux(Ubuntu)的方法
需要做的工作: 1.在Linux(Ubuntu)端安装.设置好SSH 2.下载putty,并通过putty的SSH连接登录Linux 一 .如何在Linux(Ubuntu)端安装.设置好SSH,获取I ...
- android: 使用 IntentService
9.5.2 使用 IntentService 话说回来,在本章一开始的时候我们就已经知道,服务中的代码都是默认运行在主线程 当中的,如果直接在服务里去处理一些耗时的逻辑,就很容易出现 ANR(Appl ...
- Python学习笔记(1):列表元组结构
Python的列表元组功能强大,令人印象深刻.一是非常灵活,二是便于集体操作.特别是以元组作为列表项的结构,和数据访问的结果能够对应起来,和习惯的二维表理解上也一致,有很多的用途. 以学习笔记(3)中 ...
- 多台linux服务器时间同步
1,设置A机时间服务器: a,修改 /etc/ntp.conf,如下: # Undisciplined Local Clock. This is a fake driver intended for ...
- 发布EWM RF ITS Mobile 相关服务
发布EWM RF ITS Mobile 相关服务 TCODE:SIAC_PUBLISH_ALL_INT ~XSRFCHECK = 0 SICF 参数: ~THEME 99 ~TRANSACTI ...