1 definitions
Given a language, define a representation of his grammar and define an interpreter that uses that representation to interpret the sentences in the language
2 class Diagram
Role analysis
Abstractexpression abstract interpreter, the specific interpretation task is completed by each implementation class, the specific interpreter is completed by Terminalexpression and Nonterminalexpression, respectively
The terminalexpression terminator expression, which implements interpretation operations related to elements in the grammar, usually has only one terminator expression in an interpreter pattern, but with multiple instances, the enemy battalion is different Terminator
Nonterminalexpression non-terminator, each rule in the grammar corresponds to a non-terminating expression.
Context Environment role,
3 implementation
#pragmaOnce#include<stack>#include<iostream>using namespacestd;classObject;classContext;//an abstract expression//abstract expressions are the key to generating a grammar collection/syntax tree, and each syntax collection completes the specified syntax parsing task, which is accomplished by recursive invocationclassexpression{ Public: Virtualobject* Interpreter (Context *ctx) =0{cout<<"If you Can and you Don ' t"<<Endl; returnNULL; };};//Terminator expression is simple, mainly dealing with the transformation of scene elements and data//Terminator-expressionclassTerminalexpression: Publicexpression{Object* Interpreter (context*CTX) {cout<<"Terminalexpression::interpreter"<<Endl; returnNULL; }};//each non-terminator expression represents a grammar rule, and each grammar rule concerns only the results of the surrounding grammar rules, so there is a recursive invocation//non-Terminator expressionsclassNonterminalexpression: Publicexpression{ Public: nonterminalexpression (Expression*x1, ...) { for(inti =0; I <4; ++i) {_st.push (x1); }} Object*interpreter (context*CTX) { //The core spending is here. Grammar processing, and recursive calls are generated//if (typeID (). Name ()! = "Terminalexpression")//Recursive invocation//Grammar Processing while(!_st.empty ()) {Expression* TP =_st.top (); _st.pop (); cout<<"Noterminalexpression::interpreter"<<Endl; TP-interpreter (CTX); } returnNULL; }Private: Stack<Expression*>_st;};classcontext{};classclient{ Public: void operator() () {Context*ctx =NewContext (); Stack<Expression*>St; for(inti =0; I <5; ++i) {//to make a syntax judgment and produce a recursive callSt.push (Newterminalexpression ()); St.push (NewNonterminalexpression (Newterminalexpression ())); } //for (int i = 0; i < 5; ++i)//{ // //to make a syntax judgment and produce a recursive call//St.push (New Nonterminalexpression (New Terminalexpression ())); //St.push (New Terminalexpression ()); //} //produce a complete syntax tree that is parsed by each specific syntax analysisExpression *exp =St.top (); Exp-interpreter (CTX); }};4 applications
① Advantages: is a simple syntax analysis tool, extensibility is good, modify the syntax only need to modify the corresponding non-terminator expression, extension syntax only need to increase the non-terminator class can be
② Disadvantages
The interpreter pattern causes the class to swell
Using recursive invocation method
Efficiency issues, loops and references too much
③ Usage Scenarios
Recurring events can be used in interpreter mode (log analysis, etc.)
A simple syntax to explain the scenario
Design pattern-Interpreter Mode C + + implementation