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 ...
随机推荐
- MySQL:InnoDB存储引擎的B+树索引算法
很早之前,就从学校的图书馆借了MySQL技术内幕,InnoDB存储引擎这本书,但一直草草阅读,做的笔记也有些凌乱,趁着现在大四了,课程稍微少了一点,整理一下笔记,按照专题写一些,加深一下印象,不枉读了 ...
- iOS开发之静态库(一)—— 基本概念
在项目开发过程中,经常出现优秀代码重用现象,又或者提供给第三方功能模块却又不想让其看到源代码,这些时候,通常的做法是将代码封装成库或者框架,这些在Windows编程或Linux编程中非常容易实现的过程 ...
- Android MultiDex兼容包怎么使用?
在Android系统中安装应用的时候,需要对Dex进行优化,但由于其处理工具DexOpt的限制,导致其id的数目不能够超过65536个.而MultiDex兼容包的出现,就很好的解决了这个问题,它可以配 ...
- Winform TreeView 查找下一个节点
转载:http://www.cnblogs.com/Ruiky/archive/2013/02/01/2888674.html public static class TreeViewHelper { ...
- Revit如何修改三维视图背景色
Revit中默认的三维视图背景色为白色,有时候为了让现实效果更佳逼真,需要将三维视图背景色设置为天空色,只需在三维视图属性中打开"图形显示选项"即可对三维视图背景色进行设置.
- 为EasyUI 的Tab 标签添加右键菜单
在网上看了很多demo 自己实现了一个效果如下 ps jquery1.7.2 jQuery EasyUI 1.3.6easyui QQ群:15129679 <!doctype html> ...
- Codeforces Round #177 (Div. 1) 题解【ABCD】
Codeforces Round #177 (Div. 1) A. Polo the Penguin and Strings 题意 让你构造一个长度为n的串,且里面恰好包含k个不同字符,让你构造的字符 ...
- python数据结构之二叉树遍历的实现
本篇是实现二叉树的三种遍历,先序遍历,中序遍历,后序遍历 #!/usr/bin/python # -*- coding: utf-8 -*- class TreeNode(object): def _ ...
- 在WPF中使用字体图标
一.源码描述 这是一款基于WPF窗体应用程序的字体图标示例源码, 该源码简单易懂使用于初学者和实战项目应用, 感兴趣的朋友们可以下载看看哦. 二.功能介绍 1.用ICO字体代替 ...
- 获取枚举类型的描述description
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; usin ...