程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 解析Java的設計形式編程之說明器形式的應用

解析Java的設計形式編程之說明器形式的應用

編輯:關於JAVA

解析Java的設計形式編程之說明器形式的應用。本站提示廣大學習愛好者:(解析Java的設計形式編程之說明器形式的應用)文章只能為提供參考,不一定能成為您想要的結果。以下是解析Java的設計形式編程之說明器形式的應用正文


界說:給定一種說話,界說他的文法的一種表現,並界說一個說明器,該說明器應用該表現來說明說話中句子。
類型:行動類形式
類圖:

說明器形式是一個比擬罕用的形式,自己之前也沒有效過這個形式。上面我們就來一路看一下說明器形式。
 
說明器形式的構造
籠統說明器:聲明一個一切詳細表達式都要完成的籠統接口(或許籠統類),接口中重要是一個interpret()辦法,稱為說明操作。詳細說明義務由它的各個完成類來完成,詳細的說明器分離由終結符說明器TerminalExpression和非終結符說明器NonterminalExpression完成。
終結符表達式:完成與文法中的元素相干聯的說明操作,平日一個說明器形式中只要一個終結符表達式,但有多個實例,對應分歧的終結符。終結符一半是文法中的運算單位,好比有一個簡略的公式R=R1+R2,在外面R1和R2就是終結符,對應的解析R1和R2的說明器就是終結符表達式。                               
非終結符表達式:文法中的每條規矩對應於一個非終結符表達式,非終結符表達式普通是文法中的運算符或許其他症結字,好比公式R=R1+R2中,+就長短終結符,解析+的說明器就是一個非終結符表達式。非終結符表達式依據邏輯的龐雜水平而增長,准繩上每一個文律例則都對應一個非終結符表達式。
情況腳色:這個腳色的義務普通是用來寄存文法中各個終結符所對應的詳細值,好比R=R1+R2,我們給R1賦值100,給R2賦值200。這些信息須要寄存到情況腳色中,許多情形下我們應用Map來充任情況腳色就足夠了。

例子
來舉一個加減乘除的例子吧,完成思緒來自於《java與形式》中的例子。每一個腳色的功效依照下面提到的標准來完成。

//高低文(情況)腳色,應用HashMap來存儲變量對應的數值 
 
class Context 
 
{ 
 
    private Map valueMap = new HashMap(); 
 
    public void addValue(Variable x , int y) 
 
    { 
 
       Integer yi = new Integer(y); 
 
       valueMap.put(x , yi); 
 
    } 
 
    public int LookupValue(Variable x) 
 
    { 
 
       int i = ((Integer)valueMap.get(x)).intValue(); 
 
       return i ; 
 
    } 
 
} 

//籠統表達式腳色,也能夠用接口來完成 
 
abstract class Expression 
 
{ 
 
    public abstract int interpret(Context con); 
 
} 


//終結符表達式腳色 
 
class Constant extends Expression 
 
{ 
 
    private int i ; 
 
    public Constant(int i) 
 
    { 
 
       this.i = i; 
 
    } 
 
    public int interpret(Context con) 
 
    { 
 
       return i ; 
 
    } 
 
} 


class Variable extends Expression 
 
{ 
 
    public int interpret(Context con) 
 
    { 
 
       //this為挪用interpret辦法的Variable對象 
 
       return con.LookupValue(this); 
 
    } 
 
} 


//非終結符表達式腳色 
 
class Add extends Expression 
 
{ 
 
    private Expression left ,right ; 
 
    public Add(Expression left , Expression right) 
 
    { 
 
       this.left = left ; 
 
       this.right= right ; 
 
    } 
 
    public int interpret(Context con) 
 
    { 
 
       return left.interpret(con) + right.interpret(con); 
 
    } 
 
} 


class Subtract extends Expression 
 
{ 
 
    private Expression left , right ; 
 
    public Subtract(Expression left , Expression right) 
 
    { 
 
       this.left = left ; 
 
       this.right= right ; 
 
    } 
 
    public int interpret(Context con) 
 
    { 
 
       return left.interpret(con) - right.interpret(con); 
 
    } 
 
} 

class Multiply extends Expression 
 
{ 
 
    private Expression left , right ; 
 
    public Multiply(Expression left , Expression right) 
 
    { 
 
       this.left = left ; 
 
       this.right= right ; 
 
    } 
 
    public int interpret(Context con) 
 
    { 
 
       return left.interpret(con) * right.interpret(con); 
 
    } 
 
} 

class Division extends Expression 
 
{ 
 
    private Expression left , right ; 
 
    public Division(Expression left , Expression right) 
 
    { 
 
       this.left = left ; 
 
       this.right= right ; 
 
    } 
 
    public int interpret(Context con) 
 
    { 
 
       try{ 
 
              return left.interpret(con) / right.interpret(con); 
 
       }catch(ArithmeticException ae) 
 
       { 
 
           System.out.println("被除數為0!"); 
 
           return -11111; 
 
       } 
 
    } 
 
} 

//測試法式,盤算 (a*b)/(a-b+2) 
 
public class Test 
 
{ 
 
    private static Expression ex ; 
 
    private static Context con ; 
 
    public static void main(String[] args) 
 
    { 
 
       con = new Context(); 
 
       //設置變量、常量 
 
       Variable a = new Variable(); 
 
       Variable b = new Variable(); 
 
       Constant c = new Constant(2); 
 
//為變量賦值 
 
       con.addValue(a , 5); 
 
       con.addValue(b , 7); 
 
//運算,對句子的構造由我們本身來剖析,結構 
 
       ex = new Division(new Multiply(a , b), new Add(new Subtract(a , b) , c)); 
 
       System.out.println("運算成果為:"+ex.interpret(con)); 
 
    } 
 
} 

說明器形式的優缺陷
        說明器是一個簡略的語法剖析對象,它最明顯的長處就是擴大性,修正語律例則只須要修正響應的非終結符便可以了,若擴大語法,只須要增長非終結符類便可以了。
        然則,說明器形式會惹起類的收縮,每一個語法都須要發生一個非終結符表達式,語律例則比擬龐雜時,便可能發生年夜量的類文件,為保護帶來異常多的費事。同時,因為采取遞歸挪用辦法,每一個非終結符表達式只關懷與本身相干的表達式,每一個表達式須要曉得終究的成果,必需經由過程遞歸方法,不管是面向對象的說話照樣面向進程的說話,遞歸都是一個不推舉的方法。因為應用了年夜量的輪回和遞歸,效力是一個不容疏忽的成績。特殊是用於說明一個解析龐雜、冗雜的語法時,效力是難以忍耐的。
 
說明器形式的實用場景
        在以下情形下可使用說明器形式:
有一個簡略的語律例則,好比一個sql語句,假如我們須要依據sql語句停止rm轉換,便可以應用說明器形式來對語句停止說明。
一些反復產生的成績,好比加減乘除四則運算,然則公式每次都分歧,有時是a+b-c*d,有時是a*b+c-d,等等等等個,公式千變萬化,然則都是由加減乘除四個非終結符來銜接的,這時候我們便可以應用說明器形式。


留意事項
       說明器形式真的是一個比擬罕用的形式,由於對它的保護其實是太費事了,想象一下,一坨一坨的非終結符說明器,假設不是事前對文法的規矩管窺蠡測,或許是文法特殊簡略,則很難讀懂它的邏輯。說明器形式在現實的體系開辟中應用的很少,由於他會惹起效力、機能和保護等成績。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved