根據上一個例子,可知要添加乘法和除法運算是很簡單的,咱們只需在詞法描述部分添加以下兩個token:java
TOKEN : { < TIMES : "*" > } TOKEN : { < DIVIDE : "/" > }
接下來咱們修改Expression這個生產式,對它的修改跟上一步添加減號運算所作的修改很類似:測試
Expression --> Primary (PLUS Primary | MINUS Primary | TIMES Primary | DIVIDE Primary)*
從純粹的句法角度來看,上面這種方法沒有什麼錯,可是它與咱們的計算方法不太吻合,由於它沒有認識到乘法和除法應該比加法和減法具備更高的優先級。例如,若是咱們計算下式:code
2*3+4*5
那麼根據咱們的表達式,咱們得到的結果就會是((2×3) + 4)×5,結果是50,而不是(2×3) + (4×5)。
所以,咱們將生產式修改爲以下:orm
Expression --> Term (PLUS Term | MINUS Term)* Term --> Primary (TIMES Primary | DIVIDE Primary)*
這樣一來,咱們就將每一個表達式拆分紅了一個或多個式子(terms)相加或相減。在咱們的例子中,式子(terms)就是兩個大括號中的內容:blog
[ 2*3 ] +[ 4*5 ]
對Expression來講,它的改變就是修改原先對Primary的引用,把它修改到對Term的引用,以下所示:token
double Expression() throws NumberFormatException : { double i ; double value ; } { value = Term() ( <PLUS> i = Term() { value += i ; } | <MINUS> i = Term() { value -= i ; } )* { return value ; } }
而Term的生產式以下所示:io
double Term() throws NumberFormatException : { double i ; double value ; } { value = Primary() ( <TIMES> i = Primary() { value *= i ; } | <DIVIDE> i = Primary() { value /= i ; } )* { return value ; } }
根據上面的修改,最終獲得的calculator2.jj文件內容以下:class
/* calculator0.jj An interactive calculator. */ options { STATIC = false ; } PARSER_BEGIN(Calculator) import java.io.PrintStream ; 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"])+ > } void Start(PrintStream printStream) throws NumberFormatException : {} { ( previousValue = Expression() <EOL> { printStream.println( previousValue ) ; } )* <EOF> } 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 ; } { t = <NUMBER> { return Double.parseDouble( t.image ) ; } }
先來測試1+2:
import
計算 2 * 3.3:
引用
計算 9. / 3 :
最後,計算23+45 :
能夠看到,乘除的優先級確實高於加減。