定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
使用场景: 1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。 2、一些重复出现的问题可以用一种简单的语言来进行表达。 3、一个简单语法需要解释的场景。
实现:定义上下文类,包含一些全局信息,定义抽象表达式类,声明解释方法,入参为待解释的内容,定义实现类用来解释各种文法句子。
优点: 1、可扩展性比较好,灵活。 2、增加了新的解释表达式的方式。 3、易于实现简单文法。
注意事项:可利用场景比较少
代码示例:简单自定义正则表达式解释器,只解释\d匹配数字,\c匹配字母(不区分大小写)
import java.util.ArrayList; import java.util.Arrays; import java.util.List;
public class Context { private String reg; private List<String> regList; private String content; private List<String> result = new ArrayList<String>(); private List<String> chars = new ArrayList<String>(); public Context(String reg, String content) { this.reg = reg; this.content = content; char[] charArray = content.toCharArray(); charsToList(charArray); regList = new ArrayList<String>(Arrays.asList(reg.split("\\\\"))) ; if (regList.get(0).equals("")) { regList.remove(0); } }
private void charsToList(char[] charArray) { for (Character c : charArray) { chars.add(c.toString()); } }
public String getReg() { return reg; }
public void setReg(String reg) { this.reg = reg; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public List<String> getChars() { return chars; }
public void setChars(List<String> chars) { this.chars = chars; }
public List<String> getRegList() { return regList; }
public void setRegList(List<String> regList) { this.regList = regList; }
public List<String> getResult() { return result; }
public void setResult(List<String> result) { this.result = result; } }
public abstract class Expresstion { public abstract boolean excute(Context context);
}
public class NumberExpresstion extends Expresstion {
private List<Integer> list = new ArrayList<Integer>(); public NumberExpresstion() { for (int i = 0; i < 10; i++) { list.add(i); } } @Override public boolean excute(Context context) { try { Integer.valueOf(context.getChars().get(0)); context.getResult().add(context.getChars().get(0)); context.getChars().remove(0); return true; } catch (NumberFormatException e) { return false; } } }
public class Letter extends Expresstion {
@Override public boolean excute(Context context) { if (context.getChars().get(0).matches("[a-zA-Z]")) { context.getResult().add(context.getChars().get(0)); context.getChars().remove(0); return true; }else { return false; } }
} public class Main { public static void main(String[] args) { Context context = new Context("\\d\\d\\c", "22zz"); Expresstion expresstion = null; boolean success = true; for (String string : context.getRegList()) { switch (string) { case "d": expresstion = new NumberExpresstion(); break; case "c": expresstion = new Letter(); break; default: System.out.println("正则表达式错误"); break; } if (expresstion != null ) { if (!expresstion.excute(context)) { System.out.println("匹配失败"); success = false; break; } } } if (success) { System.out.println("匹配结果:"+context.getResult()); } } } 结果:
