解釋器模式

  • 定義:
    給定一個語言读虏,定義它的文法的一種表示衙传,并定義一個解釋器吟吝,這個解釋器使用該表示來解釋語言中的句子

  • UML:


    image.png
    • AbstractExpression:定義解釋器的接口,約定解釋器的解釋操作菩佑。
    • TerminalExpression:終結(jié)符解釋器自晰,用來實現(xiàn)語法規(guī)則中和終結(jié)符相關(guān)的操作,不再包含其他的解釋器稍坯。
    • NonterminalExpression:非終結(jié)符解釋器缀磕,用來實現(xiàn)語法規(guī)則中非終結(jié)符相關(guān)的操作,通常一個解釋器對應(yīng)一個語法規(guī)則劣光,可以包含其他解釋器袜蚕。
    • Context:上下文,通常包含各個解釋器需要的數(shù)據(jù)或是公共的功能绢涡。
    • Client:客戶端牲剃,指的是使用解釋器的客戶端,通常在這里將按照語言的語法做的表達式轉(zhuǎn)換成使用解釋器對象描述的抽象語法樹雄可,然后調(diào)用解釋操作凿傅。
  • 模型:四則運算+-實現(xiàn)
    先使用巴科斯范式定義加減的語法:

expression ::= plus | minus | variable | number
plus ::= expression expression '+'
minus ::= expression expression '-'
variable ::= 'a' | 'b' | 'c' | ... | 'z'
digit = '0' | '1' | ... | '9'
number ::= digit | digit number

約定加減乘除使用逆波蘭表式語句如:

a b +                   -> a + b
a b c + -              ->a - b + c
a b + c a - -         ->a+b-c-a

抽象語句

interface Expression {
    public int interpret(final Map<String, Expression> variables);
}

+語句處理類:

class Plus implements Expression {
   //要記錄前后表達式
    Expression leftOperand;
    Expression rightOperand;
    public Plus(final Expression left, final Expression right) {
        leftOperand = left;
        rightOperand = right;
    }

    public int interpret(final Map<String, Expression> variables) {
       //具體操作前后表達式
        return leftOperand.interpret(variables) + rightOperand.interpret(variables);
    }
}

-語句處理類:

class Minus implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Minus(final Expression left, final Expression right) {
        leftOperand = left;
        rightOperand = right;
    }

    public int interpret(final Map<String, Expression> variables) {
        return leftOperand.interpret(variables) - rightOperand.interpret(variables);
    }
}

數(shù)字類:

class Number implements Expression {
    private int number;
    public Number(final int number)       { this.number = number; }
    public int interpret(final Map<String, Expression> variables)  { return number; }
}

變量處理類:

class Variable implements Expression {
    private String name;
    public Variable(final String name)       { this.name = name; }
    public int interpret(final Map<String, Expression> variables) {
        if (null == variables.get(name)) return 0; // Either return new Number(0).
        return variables.get(name).interpret(variables);
    }
}

設(shè)計一個能夠處理=-運算的計算器Client:

class Evaluator implements Expression {
    //輸入的逆波蘭式語句
    private Expression syntaxTree;
    public Evaluator(final String expression) {
        final Stack<Expression> expressionStack = new Stack<Expression>();
        for (final String token : expression.split(" ")) {
            if (token.equals("+")) {
                //將前兩個表達式出棧生成新的+表達式
                final Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop());
                expressionStack.push(subExpression);
            } else if (token.equals("-")) {
                final Expression right = expressionStack.pop();
                final Expression left = expressionStack.pop();
                final Expression subExpression = new Minus(left, right);
                expressionStack.push(subExpression);
            } else
               //將終結(jié)表達式入棧
                expressionStack.push(new Variable(token));
        }
        syntaxTree = expressionStack.pop();
    }

    public int interpret(final Map<String, Expression> context) {
        return syntaxTree.interpret(context);
    }
}

測試:

public class InterpreterExample {
    public static void main(final String[] args) {
        final String expression = "w x z - +";
        final Evaluator sentence = new Evaluator(expression);
        final Map<String, Expression> variables = new HashMap<String, Expression>();
        variables.put("w", new Number(5));
        variables.put("x", new Number(10));
        variables.put("z", new Number(42));
        final int result = sentence.interpret(variables);
        System.out.println(result);
    }
}

輸出:-27 ,執(zhí)行的是 5 + 10 - 42 = -27

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末数苫,一起剝皮案震驚了整個濱河市聪舒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌虐急,老刑警劉巖箱残,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異止吁,居然都是意外死亡被辑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門敬惦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盼理,“玉大人,你說我怎么就攤上這事俄删『暾” “怎么了奏路?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長臊诊。 經(jīng)常有香客問我鸽粉,道長,這世上最難降的妖魔是什么妨猩? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任潜叛,我火速辦了婚禮秽褒,結(jié)果婚禮上壶硅,老公的妹妹穿的比我還像新娘。我一直安慰自己销斟,他們只是感情好庐椒,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蚂踊,像睡著了一般约谈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上犁钟,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天棱诱,我揣著相機與錄音,去河邊找鬼涝动。 笑死迈勋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的醋粟。 我是一名探鬼主播靡菇,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼米愿!你這毒婦竟也來了厦凤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤育苟,失蹤者是張志新(化名)和其女友劉穎较鼓,沒想到半個月后疚沐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沙热,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年馒吴,在試婚紗的時候發(fā)現(xiàn)自己被綠了勇垛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脖母。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖闲孤,靈堂內(nèi)的尸體忽然破棺而出谆级,到底是詐尸還是另有隱情烤礁,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布肥照,位于F島的核電站脚仔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏舆绎。R本人自食惡果不足惜鲤脏,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吕朵。 院中可真熱鬧猎醇,春花似錦、人聲如沸努溃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梧税。三九已至沦疾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間第队,已是汗流浹背哮塞。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凳谦,地道東北人忆畅。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像晾蜘,于是被迫代替她去往敵國和親邻眷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容