解析器模式,它能用在什么地方呢?
解析器模式,它是如何解析的?
解析器模式,它有哪些关键要素?
解析器模式(Interpreter Pattern),给被分析对象定义一个语言,再设计一个解析器来解析语言中的句子。
解释器模式常用于对简单语言的编译或分析。其中涉及到几个关键要素:文法、句子、语法树。
“文法”指语言的语法规则,“句子”是语言集中的元素。
关键代码涉及到四种角色:解析器接口、终结符、非终结符、上下文。
看完上面定义,你是否和我一样一脸迷惑?不懂,不懂,还是看类图吧!
下面看UML类图:
类图说明:IExpression是解析器接口;TerminalExpression实现IExpression接口,是终结符类;AndExpression和OrExpression实现了IExpression接口,是非终结符类,且聚合了多个IExpression接口;context是上下文,定义了语法规则,在创建时聚合了多个IExpression接口的实现类。
下面看代码实现步骤:
1.解析器接口;
/**
* 1.抽象表达式接口(解析器接口)
* @author 程就人生
* @Date
*/
public interface IExpression {
// 解析内容
public boolean interpret(String info);
}
2.非终结符表达式;
/**
* 2.1 具体实现类,非终结符表达式1
* @author 程就人生
* @Date
*/
public class AndExpression implements IExpression {
private IExpression terminalExpression1;
private IExpression terminalExpression2;
public AndExpression(IExpression terminalExpression1, IExpression terminalExpression2){
this.terminalExpression1 = terminalExpression1;
this.terminalExpression2 = terminalExpression2;
}
@Override
public boolean interpret(String info) {
return terminalExpression1.interpret(info) && terminalExpression2.interpret(info);
}
}
/**
* 2.2 具体实现类,非终结符表达式2
* @author 程就人生
* @Date
*/
public class OrExpression implements IExpression {
private IExpression terminalExpression1;
private IExpression terminalExpression2;
public OrExpression(IExpression terminalExpression1, IExpression terminalExpression2){
this.terminalExpression1 = terminalExpression1;
this.terminalExpression2 = terminalExpression2;
}
@Override
public boolean interpret(String info) {
return terminalExpression1.interpret(info) || terminalExpression2.interpret(info);
}
}
3. 终结符表达式;
/**
* 2.3 具体实现类,终结符表达式
* @author 程就人生
* @Date
*/
public class TerminalExperssion implements IExpression{
// 结束符
private String data;
public TerminalExperssion(String data){
this.data = data;
}
@Override
public boolean interpret(String info) {
// 包含时返回true
if(info.contains(data)){
return true;
}
return false;
}
}
4.上下文环境类;
/**
* 4.上下文环境类
* @author 程就人生
* @Date
*/
public class Context {
private static String citys = "苏州";
private static String oldPersion = "老人";
private static String student = "学生";
private IExpression cityPerson;
public Context(){
// 终端字符
IExpression termianlExpression1 = new TerminalExperssion(oldPersion);
IExpression termianlExpression2 = new TerminalExperssion(student);
// 是否为免费人群
IExpression termianlExpression3 = new OrExpression(termianlExpression1, termianlExpression2);
// 城市是否为苏州
IExpression termianlExpression4 = new TerminalExperssion(citys);
cityPerson = new AndExpression(termianlExpression3, termianlExpression4);
}
public void opertion(String info){
if(cityPerson.interpret(info)){
System.out.println(info + ":免费乘车");
}else{
System.out.println(info + ":支付车费2元");
}
}
}
测试代码:
public static void main(String[] argo){
Context context = new Context();
context.opertion("苏州老人");
context.opertion("苏州学生");
context.opertion("上海老人");
context.opertion("苏州成年人");
}
测试结果:
苏州老人:免费乘车
苏州学生:免费乘车
上海老人:支付车费2元
苏州成年人:支付车费2元
这段代码的意思是:刷公交卡乘车,如果是苏州的老人、学生均可免费乘车,其他的都需要支付2元车费。
在上下文Context类中定义了免费乘车的规则,并且使用终结符类、非终结符类来计算满足条件的乘客。终结符可以理解为关键条件,非终结符可以理解为关键条件之间的关系,这两者都继承自解析器接口,而这几个类都被上下文聚合。
在实际使用时,直接输入一句话,即可解析句子并得出是否可以免费乘车的结果。这就是解析器模式的简单使用。
最后总结
解析器模式采用了“编译原理”来解释句子,其中涉及四种角色:解析器接口、终结符、非终结符、上下文,还涉及到一些概念:文法、句子,语法树等。
思考题:
除了纸上说的那些场景,检测一段文字中是否包含敏感字符,能否用解析器模式呢?
参考文档:
https://blog.csdn.net/d303577562/article/details/119040804
网友评论