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学习

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 特性我认为就两大,1JSON 2.是回调。我个人是非常喜欢JSON

你可能感兴趣的:(javac)