您的位置 首页 java

动手写一个根据解释器模式实现语法解析功能(Java版)

模式的定义与特点

解释器(Interpreter)模式的定义:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。解释器模式是一种类行为型模式,其主要优点如下。

  1. 扩展性好。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。
  2. 容易实现。在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。

解释器模式的主要缺点如下。

  1. 执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。
  2. 会引起类膨胀。解释器模式中的每条规则至少需要定义一个类,当包含的文法规则很多时,类的个数将急剧增加,导致系统难以管理与维护。
  3. 可应用的场景比较少。在 软件开发 中,需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。

模式的结构

  1. 抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
  2. 终结符表达式(Terminal Expression)角色:是抽象表达式的子类,用来实现文法中与 终结符 相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
  3. 非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
  4. 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
  5. 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

模式的应用场景

  1. 当语言的文法较为简单,且执行效率不是关键问题时。
  2. 当问题重复出现,且可以用一种简单的语言来进行表达时。
  3. 当一个语言需要解释执行,并且语言中的句子可以表示为一个抽象语法树的时候,如 XML 文档解释。

示例

 /**
 * @descript 抽象表达式接口
 * @author 79197
 *
 */interface  Expression Interface {
//解释方法 interpet method
public boolean interpetMethod(String analyzedobject);
}  
 /**
 * @descript 这是一个终结符类,
 * 作用一是定义文法(规则或者说是终结符)集合,
 * 二是实现解释器方法,解释器的作用是判断被分析的 字符串 是否在定义的集合(文法,规则,终结符)中
 *  This is Terminal class
 *  The first function is to  define  the rule set
 *  The second function is to implement the interpretation class
 *  The function of interpretation is judge whether the analyzed string is in the defined set
 * @author 79197
 *
 */public class TerminalExperssion implements ExpressionInterface{

 private  Set<String> setregulationdata = new HashSet<String>();

//初始化数据
public TerminalExperssion(List<String> data) {
data.forEach(i -> setregulationdata.add(i));
}
//实现解释器方法,判断被分析对象是否在终结符集合中
public boolean interpetMethod(String analyzedobject) {
//System.out.println("终结符集合:"+setregulationdata.size());
//System.out.println("是否在终结符集全中:"+setregulationdata.contains(analyzedobject));
if(setregulationdata.contains(analyzedobject))
return true;
else
return false;
}

}  
 /**
 * @descript 这是一个非终结符类
 *  作用一是聚合解释器表达式
 *  作用二是判断字符器是否满足解释器所表达的对象
 * @author 79197
 *
 */public class UnTerminalExperssion implements ExpressionInterface{

ExpressionInterface obj1=null;
ExpressionInterface obj2=null;
ExpressionInterface obj3=null;
//聚合抽象表达式类
public UnTerminalExperssion(ExpressionInterface obj1,ExpressionInterface obj2,ExpressionInterface obj3) {
this.obj1=obj1;
this.obj2=obj2;
this.obj3=obj3;
}
//实现解释器方法,作用是判断被分析对象是否满足终结符类所有定义的终结符
public boolean interpetMethod(String analyzedobject) {
String[] analyzedobjectTempStrings=analyzedobject.split(" ");
//System.out.println(analyzedobjectTempStrings[0]+""+analyzedobjectTempStrings[1]+""+analyzedobjectTempStrings[2]);
return obj1.interpetMethod(analyzedobjectTempStrings[0]) 
&& obj2.interpetMethod(analyzedobjectTempStrings[1]) 
&& obj3.interpetMethod(analyzedobjectTempStrings[2]);
}

}  
 /**
 * @descript环境类
 * 作用一聚合抽象表达式类
 *  作用二是初始化终结符所定义的集合
 *  作用三是初始化非终结符对象
 *  作用四是封闭解释器解析结果
 * @author 79197
 */public class Context {
//终结符集合
List<String> subjectObj=new ArrayList<String>();
List<String> systemObj=new ArrayList<>();
List<String> predicativeObj=new ArrayList<>();
//聚合解释器表达式
ExpressionInterface unTerminal;

public Context() {
//初始化主语
subjectObj.add("I");
subjectObj.add("Me");
subjectObj.add("We");
subjectObj.add("Use");
ExpressionInterface subjectset=new TerminalExperssion(subjectObj);
//初始化系动语
systemObj.add("is");
systemObj.add("am");
systemObj.add("are");
systemObj.add("was");
ExpressionInterface systemset=new TerminalExperssion(systemObj);
//初始化表语
predicativeObj.add("chinese");
ExpressionInterface predicatetiveset=new TerminalExperssion(predicativeObj);

unTerminal=new UnTerminalExperssion(subjectset,systemset,predicatetiveset);
}

public  void  ClosedInterpretationMethod(String analyzedobject) {
//System.out.println("是否满足终结符条件:"+unTerminal.interpetMethod(analyzedobject));
if(unTerminal.interpetMethod(analyzedobject)) {
System.out.println("这是一个主系表结构");
}else {
System.out.println("这种结构还未定义");
}

}
}  

测试类

 public class InterpretModeTestMan {

public  static  void main(String[] args) {

String obj1="I am chinese";
String obj2="I succeeded,but the structure is undefined";

Context objContext=new Context();
objContext.ClosedInterpretationMethod(obj1);
objContext.ClosedInterpretationMethod(obj2);
}

}  

文章来源:智云一二三科技

文章标题:动手写一个根据解释器模式实现语法解析功能(Java版)

文章地址:https://www.zhihuclub.com/185205.shtml

关于作者: 智云科技

热门文章

网站地图