JavaCC使用小結

jopen 11年前發布 | 132K 次閱讀 JavaCC 語法/詞法分析器

JavaCC是一個很不錯的詞法、語法解析器的生成器,只需要編寫規則就可以生成Java語言的詞法、語法解析器(新版本的JavaCC還支持C/C++作為目標語言)。JavaCC相當與Yacc/Bison+Lex/Flex很類似。


JavaCC首頁:

http://javacc.java.net/

在首頁上下載的JavaCC是最新版的,使用方法和Bison一樣,在命令提示符或者終端中執行、獲得生成的結果。

也可已用javacc eclipse插件:

http://sourceforge.net/projects/eclipse-javacc/files/

下載插件、解壓之后,把plugins和features目錄下的文件分別拷貝到eclipse的相應目錄中即可。

不論哪種方式,所需編寫的規則都是一樣的。

通過JavaCC自帶的example和文檔其實就可以上手了,下面就簡單小結一下:

詞法和語法規則都寫在一個.jj的文件中。這個文件應該這樣寫:

1、開頭:

options
{
  JDK_VERSION = "1.5";
  STATIC = false;
}

這個放在.jj文件的開頭,JDK_VERSION是所生成代碼適用的Jdk版本,1.5、1.6、1.7都可以,STATIC指示是否生成靜態的解析器類,還有其他選項,參考文檔。

2、主類

PARSER_BEGIN(Sparql)
package cn.edu.ruc.iir.sparql;
import cn.edu.ruc.iir.query.*;
import cn.edu.ruc.iir.query.model.*;
import cn.edu.ruc.iir.query.util.*;
import java.text.*;

public class Sparql
{
  public static void main(String args []) throws ParseException
  {
    Sparql parser = new Sparql(System.in);
    int res = 0;
    while (true)
    {
      System.out.print("MyRDF >");
      try
      {
        res = parser.one_query();
        if (res == 0)
        {}
        else if (res == 1)
        {
          break;
        }
        else
        {
          System.out.println("Please correct your query.");
        }
      }
      catch (Exception e)
      {
        System.out.println("NOK.");
        System.out.println(e.getMessage());
        parser.ReInit(System.in);
      }
      catch (Error e)
      {
        System.out.println("Oops.");
        System.out.println(e.getMessage());
        break;
      }
    }
  }
}

PARSER_END(Sparql)

在PARSER_BEGIN和PARSER_END之間定義語法解析器的主類,這是整個解析程序的入口,里面主要有一些引用的包和類以及一個main方法(其他的方法由JavaCC生成)。由于上面把STATIC設為false了,所這這里需要創建一個parser對象,調用一次parser.one_query()就進行一條語句的解析并獲得解析的結果。

3、定義詞法規則

SKIP :
{
  " "
| "\t"
| "\r"
| "\n"
}

TOKEN : /* OPERATORS */
{
  < SELECT :
    "select"
  | "SELECT" >
| < WHERE :
    "where"
  | "WHERE" >
| < OBRACE : "{" >
| < CBARCE : "}" >
}

TOKEN :
{
  < UNKNOWN : "?" < KNOWN > >
| < KNOWN : ([ "<", ">", "a"-"z", "A"-"Z", "0"-"9", ":", "/", "_", "-", "\"", "'", "~", "#" ])+ >
| < MISSEDP : "[" "]" >
| < EXIT :
    "exit"
  | "EXIT" >
}

這部分定義詞法解析器的規則,SKIP定義要忽略的字符串,TOKEN定義要識別的字符串。注意,不是說先將輸入中符合SKIP規則的都去掉再進行解析,那樣的話是不科學的,正常的詞法解析都不會那么干,實際是順序處理輸入串的過程中,通過“大嘴法”識別盡可能長的子串。如果詞法規則有二義性,JavaCC會給出警告,一定不要忽略這些警告。

4、定義語法規則

JavaCC的語法單元形如這樣:

Token subject() :
{
  Token token = null;
}
{
  token = < UNKNOWN >
  {
    return token;
  }
| token = < KNOWN >
  {
    Token token1 = token;
  }
  (
  "." token = < KNOWN >
  {
    token1.image += "."+ token.image; 
  }
  )*
  {
    return token1;
  }
}
開頭是一個聲明,包括返回值類型、規則名和一個冒號。對于這樣一條語法規則,JavaCC就會在語法分析器類中生成一個同名的方法。緊接著的一對花括號中寫一些變量聲明。下一對花括號中寫該規則的具體內容。

一個語法單元中有多個規則時,用|分開。每個規則都有一系列詞法或語法單元組成,每個詞法或者語法單元之后跟著一對花括號,里面寫處理的代碼

基本上就是這樣了。

[引用請注明出處:http://blog.csdn.net/bhq2010/article/details/8763920]

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!