Apache Calcite教程-SQL解析-JavaCC教程

  • JavaCC
    • 语法描述文件
    • JavaCC类介绍
      • SimpleCharStream
      • XXXXXConstants
      • XXXXXTokenManager
      • Token
      • XXXXX
      • ParseException
      • TokenMgrError
    • 常见配置 options
    • JavaCC工作原理
      • 语法二义性解决
    • JavaCC语法
      • Java代码
      • JAVA函数
      • 条件
      • 循环
      • 正则表达式
    • 代码示例
      • Maven编译
      • 简单计算器
      • 简单语法示例
  • 代码示例

Github

JavaCC

使用递归下降语法解析,LL(k)。
其中,第一个L表示从左到右扫描输入;
第二个L表示每次都进行最左推导(在推导语法树的过程中每次都替换句型中最左的非终结符为终结符。类似还有最右推导);
k表示的是每次向前探索(lookahead)k个终结符

官网

语法文件

语法描述文件

options {
    JavaCC的选项
}

PARSER_BEGIN(解析器类名)
package 包名;
import 库名;

public class 解析器类名 {
    任意的Java代码
}
PARSER_END(解析器类名)

扫描器的描述

解析器的描述

JavaCC类介绍

SimpleCharStream

词法分析器的输入流

    // 构造函数种类 ,可以接受Reader和InputStream
public class SimpleCharStream {

   public SimpleCharStream(java.io.Reader dstream, int startline, 
       int startcolumn, int buffersize);
   
   public SimpleCharStream(java.io.Reader dstream, 
       int startline, int startcolumn);
   
   public SimpleCharStream(java.io.Reader dstream);
   
   public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
     int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException;
     
   public SimpleCharStream(java.io.InputStream dstream, int startline,
        int startcolumn, int buffersize);
   
   public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
        int startcolumn) throws java.io.UnsupportedEncodingException;
                         
   public SimpleCharStream(java.io.InputStream dstream, int startline,
                         int startcolumn);
   
   public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException;

   public SimpleCharStream(java.io.InputStream dstream);
}

XXXXXConstants

Token常量,SKIP TOKEN 和TOKEN

// 忽律的字符
SKIP:{
    " "
}


// 关键字
TOKEN:{
    
}
// 和常量申明对应
public interface XXXXXConstants {
    
  int EOF = 0;
  int PLUS = 2;

  int DEFAULT = 0;

  String[] tokenImage = {
    // EOF 文件结尾
    "",
    // 忽律字符串
    "\" \"",
    // PLUSA
    "\"+\"",
  };

}

XXXXXTokenManager

词法分析器

// 常见方法说明
public class XXXXXTokenManager implements XXXXXConstants {
    
    // 输入流
    protected SimpleCharStream input_stream;
    
    // 构造函数
    public XXXXXTokenManager(SimpleCharStream stream);
    
    // 获取下一个Token
    public Token getNextToken();
}

Token

Token类

public class Token {

  // Constants.java的种类
  public int kind;

  // 开始行和开始列,结束行和结束列
  public int beginLine, beginColumn, endLine, endColumn;

  // token的字符串
  public String image;

  // 下一个token
  public Token next;

  // 特殊令牌
  public Token specialToken;

  // Returns the image.
  public String toString()
  {
     return image;
  }


}

XXXXX

解析类入口

ParseException

语法解析异常

TokenMgrError

语法错误提示

常见配置 options

JavaCC工作原理

如图:
Apache Calcite教程-SQL解析-JavaCC教程_第1张图片

语法二义性解决

void S():{}
{
    IFStat()
    |
    E();
}
void IFStat():{}
{
    "if" "(" E() ")"
    S()
    (
        "else" S();
    )?
}

if E if E S else S 

存在两种解释

if E
   if E
     S
   else
     S   
if E
   if E
     S
else
   S

可以借助LOOKAHEAD(K)关键字解决

// 词法分析执行完if-S之后先找slse,找到则匹配最近的if,否则执行后面的语句
void S():{}
{
    IFStat()
    |
    E();
}
void IFStat():{}
{
    "if" "(" E() ")"
    S()
    (
        LOOKAHEAD(1)
        "else" S();
    )?
}

JavaCC语法

Java代码

java代码块用{}声明

// 定义java代码块
void javaCodeDemo():
{}
{
    {
        int i = 0;
        System.out.println(i);
    }
}

JAVA函数

需要用 JAVACODE声明

JAVACODE void print(Token t){
    System.out.println(t);
}

条件

  • if语句
// if语句
void ifExpr():
{}
{
    [
        )?
}
  • if else语句
// if - else
void ifElseExpr():
{}
{
    (
        )*
}
  • while 1~n
// while 1~n
void while2Expr():{
}
{
    (
    | 
    | 
    | 
    | 
    | 
    | 
    | 
    | 
    | 
}

// 定义java代码块
void javaCodeDemo():
{}
{
    {
        int i = 0;
        System.out.println(i);
    }
}

// 函数
void function1():
{
    // 定义局部变量
    int i=0;
}
{
    {return;}
}

// 返回值
double function2():
{
    int i=0;
}
{
    // 带返回值
    {return i;}
}
// 函数调用
double function3():
{
    double i;
}
{
   {i = function2();}
   {return i;}
}

// token复制
void tokenAssignment() :
{
    Token st;
    Token dt;
}
{
     st = 
        {
            System.out.println("if select");
        }
    ]

    // 循环,出现一次
    ( {System.out.println("if else select");}
        |
          {System.out.println("if else update");}
        |
          {System.out.println("if else delete");}
        |
        {
           System.out.println("other");
        }
    )
}

// while 0~n
void while1Expr():{
}
{
    ()+
}


// Java 代码
JAVACODE void print(Token t){
    System.out.println(t);
}

代码示例

https://github.com/quxiucheng/apache-calcite-tutorial/tree/master/calcite-tutorial-2-parser/parser-2-javacc-tutorial

你可能感兴趣的:(calcite)