JavaCC從入門到出門

1、JavaCC

  JavaCC是java的compiler compiler。JavaCC是LL解析器生成器,可處理的語法範圍比較狹窄,但支持無限長的token超前掃描。java

  安裝過程:git

  我是從github上down下來的zip壓縮包,而後安裝了下ant, 而後經過ant安裝的javaccgithub

  1. 首先下載下來ant的源碼,而後tar -zvxf apache-ant....tag.gz 解壓縮,而後能夠在解壓出來的bin目錄中看到ant的可執行文件shell

  2. 從github下載javacc, 進入解壓縮的目錄執行xxxxxx/ant。 而後會在target 目錄中看到javacc.jar 包apache

  3. 這個時候能夠經過以下方法將jar包作成一個可執行文件:多線程

    首先建立一個shell腳本:函數

#!/bin/sh
MYSELF=`which "$0" 2>/dev/null`
[ $? -gt 0 -a -f "$0" ] && MYSELF="./$0"
java=java
if test -n "$JAVA_HOME"; then
    java="$JAVA_HOME/bin/java"
fi
exec "$java" $java_args -cp $MYSELF "$@"
exit 1

    命名爲stub.sh, 而後在jar包的所在目錄執行: cat stub.sh javacc.jar > javacc && chmod +x javacc。 這樣一個可執行文件就有了,不過在解析.jj文件時須要帶一個javacc的參數,像這樣: javacc javacc Adder.jjui

2、語法描述文件

一、簡介

  JavaCC的語法描述文件是擴展名爲.jj的文件,通常狀況下,語法描述文件的內容採用以下形式編碼

options { JavaCC的選項 } PARSER_BEGIN(解析器類名) package 包名; import 庫名; public class 解析器類名 { 任意的Java代碼 } PARSER_END(解析器類名) 掃描器的描述 解析器的描述

  JavaCC和java同樣將解析器的內容定義在單個類中,所以會在PARSER_BEGIN和PARSER_END之間描述這個類的相關內容。lua

二、Example

  以下代碼是一個解析正整數加法運算並進行計算的解析器的語法描述文件。

options { STATIC = false; } PARSER_BEGIN(Adder) import java.io.*; class Adder { public static void main(String[] args) { for (String arg : args) { try { System.out.println(evaluate(arg)); } catch (ParseException ex) { System.err.println(ex.getMessage()); } } } public static long evaluate(String src) throws ParseException { Reader reader = new StringReader(src); return new Adder(reader).expr(); } } PARSER_END(Adder) SKIP: { <[" ", "\t", "\r", "\n"]> } TOKEN: { <INTEGER: (["0"-"9"])+> } long expr(): { Token x, y; } { x=<INTEGER> "+" y=<INTEGER> <EOF> { return Long.parseLong(x.image) + Long.parseLong(y.image); } }

  options塊中將STATIC選項設置爲false, 將該選項設置爲true的話JavaCC生成的全部成員及方法都將被定義爲static,若將STATIC設置爲true則所生成的解析器沒法在多線程環境下使用,所以該選項老是被設置爲false。(STATIC的默認值爲true)
  從PARSER_BEING(Adder)到PARSER_END(Adder)是解析器類的定義。解析器類中須要定義的成員和方法也寫在這裏。爲了實現即便只有Adder類也可以運行,這裏定義了main函數。
  以後的SKIP和TOKEN部分定義了掃描器。SKIP表示要跳過空格、製表符(tab)和換行符。TOKEN表示掃描整數字符並生成token。
  long expr...開始到最後的部分定義了狹義的解析器。這部分解析token序列並執行某些操做。

三、運行JavaCC

  要用JavaCC來處理Adder.jj(圖中是demo1.jj),須要使用以下javacc命令

  運行如上命令會生成Adder.java和其餘輔助類。
  要編譯生成的Adder.java,只須要javac命令便可:

 

這樣就生成了Adder.class文件。Adder類是從命令行參數獲取計算式並進行計算的,所以能夠以下這樣從命令行輸入計算式並執行

 

3、啓動JavaCC生成的解析器

  如今解析一下main函數的代碼。   main函數將全部命令行參數的字符串做爲計算對象的算式,依次用evaluate方法進行計算。
  evaluate方法中生成了Adder類的對象實例 。並讓Adder對象來計算(解析)參數字符串src。
  要運行JavaCC生成的解析器類,須要下面2個步驟:

  1. 生成解析器類的對象實例
  2. 用生成的對象調用和須要解析的語句同名的方法

  第1點: JavaCC4.0生成的解析器中默認定義有以下四種類型的構造函數。

  1. Parser(InputStream s)
  2. Parser(InputStream s, String encoding)
  3. Parser(Reader r)
  4. Parser(x x x x TokenManager tm)

  第1種的構造函數是經過傳入InputStream對象來構造解析的。這個構造函數沒法設定輸入字符串的編碼,所以沒法處理中文字符等。
  而地2種的構造函數除了InputStream對象外,還能夠設置輸入字符串的編碼來生成解析器。但若是要解析中文字符串或註釋的話,就必須使用第2種/3種構造函數。
  第3種的構造函數用於解析Reader對象所讀入的內容。
  第4種是將掃描器做爲參數傳入。
  解析器生成後,用這個實例調用和須要解析的語法同名的方法。這裏調用Adder對象的expr方法,接回開始解析,解析正常結束後會返回語義值。

4、中文的處理

  要使JavaCC可以處理中文首先須要將語法描述文件的options快的UNICODE_INPUT選項設置爲true:

options { STATUS = false; DEBUG_PARSER = true; UNICODE_PARSER = true; JDK_VERSION = "1.5"; }

  這樣就會先將輸入的字符轉換成UNICODE後再進行處理。UNICODE_INPUT選項爲false時只能處理ASCII範圍的字符。  另外還須要使用第2/3種構造方法爲輸入的字符串設置適當的編碼。

相關文章
相關標籤/搜索