天天看點

java加法器_javacc例子:加法器

1.2第一個例子:加法器

作為第一個例子,我們把以下的一些數相加:

99 + 42 + 0 + 15

除了阿拉伯數字之間外,所有的地方都可以有空格和換行,剩餘的字元必須是10進制數或加号”+”。

這段示例代碼是”adder.jj”檔案的一部分,adder.jj包含JavaCC規則的詞法分析和文法分析代碼,它處理上面的加法算式。

1.2.1選項和類聲明

檔案的第一部分是:

options {

STATIC = false ;

}

PARSER

BEGIN(Adder)

class Adder {

static void main( String[] args )

throws ParseException, TokenMgrError {

Adder parser = new Adder( System.in ) ;

parser.Start() ;

}

}

PARSER

END(Adder)

在開頭的注釋之後,是選項部分,本例除了STATIC選項把預設值true改為false外,其它的都是使用的JavaCC的選項預設值,關于選項更多的資訊可以參考JavaCC文檔,本書的後續部分或者FAQ。接下來是一個稱為Adder的Java類,這裡看到的不是完整的Adder類,JavaCC會在生成Java代碼的過程中添加該類的聲明。這個main方法會抛出ParseException和TokenMgrError這兩個異常,JavaCC會自動生成這兩個異常類。

1.2.2指定一個詞法分析器

在傳回到這個main方法前,先看看詞法分析規則。在這個簡單的例子中,詞法限定在如下的四行中:

SKIP : { ” ” }

SKIP : { ”\n” |

”\r” | ”\r\n” }

TOKEN : { <

PLUS : ”+” > }

TOKEN : { <

NUMBER : ([”0”-”9”])+ > }

第一行是說空格雖然是辨別符,但要跳過,就是說,不傳給文法分析器。第二行是換行,和空格一樣處理。不同的作業系統的換行符是不一樣的,在Unix和Linux系統中使用”\n”,在DOS和Windows下使用”\r\n”,在老的Macintoshes系統(Darwine核心之前,新的Macintoshes系統采用的是Unix方式的換行。譯者注)中使用的是單一的”\r”。我們告訴JavaCC所有的這些可能,使用一個垂線”|”來分開它們。第三行告訴JavaCC加号是一個辨別符,用PLUS符号表示。最後是第四行,告訴JavaCC數字的文法,用NUMBER符号表示這一類型的辨別符。如果你對Perl或者Java的正規表達式包熟悉的話,就容易看懂前面的NUMBER符号了。我們看看正規表達式([”0”-”9”])+,[”0”-”9”]表示任意阿拉伯數字,就是說,是0和9之間的任何unicode字元。形如(x)+的正則式比對一個或者多個字元串,其中每個字元串又比對正則式x。是以([”0”-”9”])+比對一個或多個阿拉伯數字組成的任意序列。這四行都被稱為正則表達産生式。

還有一種辨別符,被稱為EOF,代表輸入序列的結束,沒必要用正規表達式産生EOF,JavaCC自動把檔案的末尾作為EOF。

考慮包含如下字元的一個輸入檔案:

“123 + 456\n”

詞法分析器找到7個辨別符:NUMBER,空格,加号,空格,NUMBER,新行,EOF。被标記為SKIP的正則産生式不傳給文法分析器,是以文法分析器得到的是:

NUMBER, PLUS, NUMBER, EOF

假設不是合法的輸入檔案,包含未知的字元,比如:

“123 - 456\n”

在發現第一個空格後,詞法分析器會找到一個減号。由于沒有減号這個辨別符,詞法分析器會抛出一個TokenMgrError異常。

如果是下面這個字元序列呢?

“123 ++ 456\n”

這次詞法分析也可以把這個序列解析為如下的辨別符:

NUMBER, PLUS, PLUS, NUMBER, EOF

詞法分析器判斷不出這個辨別符序列是否正确,會把這些交給文法分析器。文法分析器會在詞法分析器傳送過來第二個PLUS符号時發現一個錯誤,那麼,它就不再繼續處理剩餘的部分了。是以實際傳送給文法分析器辨別符序列是:

NUMBER, PLUS, PLUS

跳過一個字元或字元序列并不等同于忽略它。考慮一個輸入序列:

“123 456\n”

詞法分析識别出三個辨別符:兩個NUMBER和中間的一個空格,文法分析器會再次報錯。

1.2.3指定一個文法分析器

JavaCC文法規範由NBF産生式構成,看起來有些象Java方法定義。

void Start() :

{}

{

(

)*

}

BNF産生式定義合法的辨別符序列,本例中,序列由NUMBER符号開頭,以EOF結尾,中間包含0個或多個子序列,這個子序列為PLUS符号後面緊跟一個NUMBER辨別符。

前面說的文法分析器隻檢查輸入序列是否含有錯誤,并不真正的計算數的加法。接下來我們修改這個文法分析器來修正這一點。首先,生成Java代碼并運作看看。

1.2.4生成詞法分析器與文法分析器

前面已經構造了adder.jj檔案,下面用JavaCC來處理它。怎樣處理其實是依賴于不同的作業系統的。在Windows NT,2000,XP下面,用“指令提示符”程式(CMD.exe)來運作JavaCC:

D:\home\JavaCC-Book\adder>javacc

adder.jj

Java Compiler

Compiler Version 2.1 (Parser Generator)

Copyright (c)

1996-2001 Sun Microsystems, Inc.

Copyright (c)

1997-2001 WebGain, Inc.

(type

"javacc" with no arguments for help)

Reading from

file adder.jj . . .

File

"TokenMgrError.java" does not exist. Will create one.

File

"ParseException.java" does not exist. Will create one.

File

"Token.java" does not exist. Will create one.

File

"SimpleCharStream.java" does not exist. Will create one.

Parser

generated successfully.

會産生7個Java類,每個都在自身的檔案中:

•TokenMgrError一個簡單的錯誤定義類,用于詞法分析中遇到的錯誤,是Throwable的子類。

•ParseException另一個錯誤定義類,用于文法分析中遇到的錯誤,是Exception進而是Throwable的子類。

•Token辨別符定義類。每個辨別符都用一個整型的變量kind和一個字元串類型的變臉image,kind表示辨別符(PLUS,NUMBER後者EOF)的類型,image是辨別符表示的字元序列。

•SimpleCharStream擴充卡類,把字元串傳給詞法分析器。

•AdderConstants定義了詞法分析和句法分析用到的一些類的接口。

•AdderTokenManager詞法分析器。

•Adder is the parser文法分析器。

現在可以用Java編譯器來編譯這些類了:

D:\home\JavaCC-Book\adder>javac

*.java

注意:本blog中含源代碼的文章推薦使用firefox閱讀,可以獲得較佳的效果。