clq9761 发表于 2013-1-26 12:58:27

解释器模式

 解释器模式:给定一个语言,定义它的文法的一种表示。并定义一个解释器,这个解释器使用该表示来解释
                    语言中的句子。
1.如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。
   这样就可以构造一个解释器,该解释器通过解释这些句子来解决该问题。
 2.当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。
 3.使用解释器模式时,可以很容易地改变和扩展文法,因为该模式使用类来表示文法规则,
    可使用继承来改变或扩展该文法。  也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,
    这些类都易于直接编写。
 4.抽象语法树的每一个节点都代表一个语句,而在每个节点上都可以执行解释方法。这个解释方法的
    执行就代表这个语句被解释。
 5.一般系统中很多类使用相似的语法,可以使用一个解释器来代替为每一个规则实现一个解释器。
 6.不足:解释器模式为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。
     建议当文法非常复杂时,使用其它的技术如语法分析程序或编译器生成器来处理。
 
http://dl.iteye.com/upload/attachment/498672/160893a4-f7c9-36f2-accb-c269436cca3c.gif
/** * 抽象表达式,声明一个抽象的解释操作,这个接口为抽象语法树中的所有节点所共享。 */public abstract class AbstractExpression {public abstract void interpret(Context context);} 
/** * 终结符表达式,实现与文法中的终结符相关联的解释操作。 * 文法中每一个终结符都有一个具体的终结表达式与之相对应。 */public class TerminalExpression extends AbstractExpression{@Overridepublic void interpret(Context context) {System.out.println("终端解释器");}} 
/** * 非终结符表达式,为文法中的非终结符实现解释操作。 * 对文法中的每一条规则R1,R2...Rn都需要一个具体的非终结符表达式类。 * 解释操作以递归方式调用上面所提到的代表R1,R2....Rn中的各个符号的实例变量。 */public class NonTerminalExpression extends AbstractExpression{@Overridepublic void interpret(Context context) {System.out.println("非终端解释器");}} 
/** * 包含解释器之外的一些全局信息。 */public class Context {private String intput;private String output;public String getIntput() {return intput;}public void setIntput(String intput) {this.intput = intput;}public String getOutput() {return output;}public void setOutput(String output) {this.output = output;}} 
public class Main {public static void main(String[] args) {// 构建表示该文法定义的语言中一个特定的句子的抽象语法树,调用解释操作。Context context = new Context();List<AbstractExpression> list = new ArrayList<AbstractExpression>();list.add(new TerminalExpression());list.add(new NonTerminalExpression());list.add(new TerminalExpression());list.add(new TerminalExpression());for(AbstractExpression expression:list){expression.interpret(context);}}} 
 解释器模式示例:音乐解释器事例(音符,音阶,音速等) 
 
 
http://dl.iteye.com/upload/attachment/498680/6b45826c-7eeb-3fa3-86c7-37b1d22f2c98.gif
 
/** * 演奏内容类 */public class PlayContext {// 演奏文本private String text;public String getText() {return text;}public void setText(String text) {this.text = text;}} 
/** * 表达式类 */public abstract class Expression {//解释器public void interpret(PlayContext context){if(context.getText().length()==0){return;}else{// 获取playKey和playValue//(例:"O 3 E 0.5 G 0.5 A 3 "playKey为O,playValue为3)char playKey = context.getText().substring(0,1).charAt(0);context.setText(context.getText().substring(2));Double playValue = Double.parseDouble(context.getText() .substring(0,context.getText().indexOf(" ")));// 获得playKey和playValue后,将其从演奏文本中移除// (例:"O 3 E 0.5 G 0.5 A 3 "变成"E 0.5 G 0.5 A 3 ")context.setText(context.getText().substring(context.getText().indexOf(" ")+1));execute(playKey, playValue);}}// 执行,抽象方法执行不同的文法子类,有不同的执行处理。public abstract void execute(char key,Double value);} 
 
/** * 音符类,终结符表达式 */public class Note extends Expression{@Overridepublic void execute(char key, Double value) {String note = "";// 如果获得的key是C则演奏1(do),D则演奏2(Re)switch(key){case 'C':note = "1";break;case 'D':note = "2";break;case 'E':note = "3";break;case 'F':note = "4";break;case 'G':note = "5";break;case 'A':note = "6";break;case 'B':note = "7";break;}System.out.print(note+" ");}} 
/** * 音阶类,终结符表达式 */public class Scale extends Expression{@Overridepublic void execute(char key, Double value) {String scale = "";// 如果获得的key是O并且value是1则演奏低音,2则是中音,3则是高音switch(value.intValue()){case 1:scale = "低音";break;case 2:scale = "中音";break;case 3:scale = "高音";break;}System.out.print(scale+" ");}} 
/** * 音速类,终结符表达式 */public class Speed extends Expression{@Overridepublic void execute(char key, Double value) {// T 1000 表示每节拍一秒,T 500 表示每节拍半秒String speed = "";if(value<500){speed = "快速";}else if(value>=1000){speed = "慢速";}else{speed = "中速";}System.out.print(speed+" ");}} 
public class Main {public static void main(String[] args) {PlayContext context = new PlayContext();System.out.println("上海滩:");context.setText("T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3");Expression expression = null;try{while (context.getText().length()>0){char str = context.getText().substring(0,1).charAt(0);switch (str){case 'O':// 当首字母是O时,表达式实例化为音阶expression= new Scale();break;case 'T':// 当首字母是T时,表达式实例化为音速expression= new Speed();break;case 'C':case 'D':case 'E':case 'F':case 'G':case 'A':case 'B':case 'P':// 当首字母是CDEFGAB以及休止符P时,表达式实例化为音符expression= new Note();break;}expression.interpret(context);}}catch(Exception e){e.printStackTrace();}}} 
 输出结果如下:
 
上海滩:中速 中音 3 5 6 3 5 5 2 3 5 6 高音 1 中音 6 5 1 3  
页: [1]
查看完整版本: 解释器模式