In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "what is the interpreter pattern of the design pattern series". Interested friends may wish to take a look at it. The method introduced in this paper is simple, fast and practical. Next, let the editor take you to learn "what is the interpreter pattern of the design pattern series"?
Schema definition
Define a language for the parsing object, define the grammatical representation of the language, and then design a parser to interpret the sentences in the language. In other words, analyze the instances in the application by compiling the language. This pattern implements an interface for grammar expression processing, which interprets a particular context.
The concepts of grammar and sentence mentioned here are the same as those described in the compilation principle. "grammar" refers to the grammatical rules of the language, and "sentence" is the element of the language set. For example, there are many sentences in Chinese. "I am Chinese" is one of them. A grammar tree can be used to describe sentences in the language intuitively.
The structure and implementation of pattern
Interpreter pattern is often used in compiling or analyzing simple language. in order to master its structure and implementation, we must first understand the related concepts of "grammar, sentence, syntax tree" in the principle of compilation.
Grammar
Grammar is a formal rule used to describe the grammatical structure of a language. There are no rules. For example, some people think that the principle of perfect love is "mutual attraction, single-mindedness, and no love experience". Although the last rule is more stringent, everything must have rules, and so does language. whether it is machine language or natural language, it has its own grammar rules. For example, the grammar of "sentence" in Chinese is as follows.
< sentence >:: = < subject > < predicate > < object >
< subject >:: = < pronoun > | < noun >
< predicate >:: = < verb >
< object >:: = < pronoun > | < noun >
< pronoun > you | me | him
< noun > 7 college students I Xiaoxia I English
< verb >:: = Yes | study
Note: the symbol "::" here means "defined as". The non-Terminator is enclosed by "<" and ">", and what is not enclosed is the Terminator.
Sentence
A sentence is the basic unit of a language and an element in a language set. It is composed of terminators and can be deduced from grammar. For example, the above grammar can deduce "I am a college student", so it is a sentence.
Syntax tree
Syntax tree is a kind of tree representation of sentence structure, which represents the derivation of sentences, and it is helpful to understand the level of sentence grammatical structure. The following picture shows the syntax tree of "I am a college student".
The structure of the interpreter pattern is similar to that of the combination pattern, but it contains more elements than the combination pattern, and the combination pattern is an object structure pattern, while the interpreter pattern is a behavior-like pattern.
The realization of pattern
The key to the implementation of the interpreter pattern is to define grammar rules, design Terminator and non-Terminator classes, draw a structure diagram, and build a syntax tree if necessary. The code structure is as follows:
Package com.niuh.designpattern.interpreter.v1; / *
* interpreter mode *
* / public class InterpreterPattern {} / / Abstract expression class interface AbstractExpression {public Object interpret (String info); / / interpretation method} / / Terminator expression class class TerminalExpression implements AbstractExpression {public Object interpret (String info) {/ / handling of a pair of Terminator expressions return null;}} / / non-Terminator expression class class NonterminalExpression implements AbstractExpression {private AbstractExpression exp1; private AbstractExpression exp2 Public Object interpret (String info) {/ / processing of Terminator expressions return null;}} / / Environment class class Context {private AbstractExpression exp; public Context () {/ / data initialization} public void operation (String info) {/ / call the interpretation method of the related expression class}}
Problem solved
Build an interpreter to interpret sentences for some fixed grammars.
Pattern composition
Example illustration
An overview of examples
Use interpreter mode to design a reader program for Beijing bus card.
Explanation: if the Beijing bus card reader can judge the identity of passengers, if it is "Haidian District" or "Chaoyang District", "old people", "women" and "children" can take the bus for free, and other people can deduct 2 yuan at a time.
Analysis: this example is more suitable for the design of "interpreter pattern". First of all, the grammar rules are designed as follows.
:: = Haidian District | Chaoyang District:: = elderly | Women | Children
Then, according to the grammar rules, follow the steps below to design the class diagram of the bus card reader program.
Use steps
Step 1: define an abstract expression (Expression) interface that contains the interpretation method interpret (String info).
/ / abstract expression class interface Expression {public boolean interpret (String info);}
Step 2: define a Terminator expression (Terminal Expression) class, which uses the Set class to save cities or people that meet the conditions, and implements the interpretation method interpret (Stringinfo) in the abstract expression interface to determine whether the parsed string is a Terminator in the collection.
Class TerminalExpression implements Expression {private Set set = new HashSet (); public Terminal_Expression (String [] data) {for (int I = 0; I < data.length; I +) {set.add (data [I]);}} public boolean interpret (String info) {if (set.contains (info)) {return true;} return false }}
Step 3: define a non-Terminator expression (AndExpressicm) class, which is also a subclass of the abstract expression, which contains the Terminator expression object of the city satisfying the condition and the Terminator expression object of the person who meets the condition, and implements the interpret (String info) method to determine whether the analyzed string is a qualified person in the city that meets the condition.
Class AndExpression implements Expression {private Expression city = null; private Expression person = null; public And_Expression (Expression city, Expression person) {this.city = city; this.person = person;} public boolean interpret (String info) {String s [] = info.split; return city.interpret (s [0]) & & person.interpret (s [1]);}}
Step 4: define an Context class that contains the data needed by the interpreter, initializes the Terminator expression, and defines a method freeRide (String info) that calls the interpretation method of the expression object to interpret the parsed string.
Class Context {private String [] citys = {"Haidian District", "Chaoyang District"}; private String [] persons = {"elderly", "women", "children"}; private Expression cityPerson; public Context () {Expression city = new Terminal_Expression (citys); Expression person = new Terminal_Expression (persons); cityPerson = new And_Expression (city, person) } public void freeRide (String info) {boolean ok = cityPerson.interpret (info); if (ok) {System.out.println ("you are" + info + ", your ride is free!) ;} else {System.out.println (info + ", you are not a free person, 2 yuan will be deducted for this ride!") ;}
Step 5: client test
Public class InterpreterPattern {public static void main (String [] args) {Context bus = new Context (); bus.freeRide ("the elderly in Haidian District"); bus.freeRide ("Young people in Haidian District"); bus.freeRide ("Women in Chaoyang District"); bus.freeRide ("Children in Chaoyang District"); bus.freeRide ("Young people in Nanjing");}}
Output result
You are an old man in Haidian District, your ride is free this time!
Young people in Haidian District, you are not free of charge, the fare for this ride is 2 yuan!
You are a woman in Chaoyang District, your ride is free this time!
You are a child in Chaoyang District, your ride is free!
Young people in Nanjing, you are not a free person, this ride deducts 2 yuan!
Advantages
Interpreter pattern is a kind of behavioral pattern, and its main advantages are as follows.
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
Good expansibility. Because classes are used to represent the grammar rules of a language in the interpreter pattern, grammar can be changed or extended through mechanisms such as inheritance.
It's easy to achieve. Each expression node class in the syntax tree is similar, so it is easier to implement its grammar.
Shortcoming
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
The execution efficiency is low. Interpreter mode usually uses a large number of loops and recursive calls, when the sentence to be interpreted is complex, its running speed is very slow, and the debugging process of the code is also troublesome.
Will cause the class to expand. Each rule in the interpreter pattern needs to define at least one class. When there are many grammar rules, the number of classes will increase sharply, making it difficult for the system to manage and maintain.
Few scenarios can be applied. In software development, there are very few application examples that need to define language grammars, so this pattern is rarely used.
Application scenario
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
When the grammar of the language is relatively simple, and execution efficiency is not the key issue.
When the problem is repeated and can be expressed in a simple language.
When a language requires interpretation and execution, and sentences in the language can be represented as an abstract syntax tree, such as XML document interpretation.
Extension of the pattern
In project development, if you want to analyze and evaluate data expressions, you no longer need to use the interpreter pattern to design. Java provides the following powerful mathematical formula parsers: Expression4J, MESP (Math Expression String Parser) and Jep, which can interpret some complex grammars, powerful and easy to use.
Now take Jep as an example to show you how to use the toolkit. Jep is the abbreviation of Java expression parser, or Java expression Analyzer. It is a Java library used to transform and evaluate mathematical expressions. Through this library, users can enter an arbitrary formula in the form of a string and then quickly calculate the result. And Jep supports user-defined variables, constants, and functions, which include many commonly used mathematical functions and constants.
Configure the dependency package before using it:
Jep jep 2.24
Let's look at a case study:
Package com.niuh.designpattern.interpreter.v3; import org.nfunk.jep.JEP; / *
* JepDemo *
* / public class JepDemo {public static void main (String [] args) {JEP jep = new JEP (); / / A mathematical expression String exp = "((aqb) * (Centra)) / b"; / / assign values to variables jep.addVariable ("a", 10); jep.addVariable ("b", 10); jep.addVariable ("c", 10) Try {/ / execute jep.parse_Expression (exp); Object result = jep.getValueAsObject (); System.out.println ("calculation result:" + result);} catch (Throwable e) {System.out.println ("An error occured:" + e.getMessage ());}
The running result of the program is as follows:
Calculation result: 2.0
Application in source code
Analysis on the Application of interpreter pattern in SpelExpressionParser
Class diagram analysis
In the following class diagram, Expression is an interface that is equivalent to a non-Terminator expression in our interpreter pattern, while ExpressionParser is equivalent to a Terminator expression. Different Parser objects are returned depending on the Expression object.
Partial source code analysis
Expression interface
/ / abstract non-Terminator expression public interface Expression {Object getValue () throws EvaluationException; Object getValue (Object rootObject) throws EvaluationException;}
SpelExpression class
/ / specific non-terminal expression public class SpelExpression implements Expression {@ Override public Object getValue () throws EvaluationException {Object result; if (this.compiledAst! = null) {try {TypedValue contextRoot = evaluationContext = = null? Null: evaluationContext.getRootObject (); return this.compiledAst.getValue (contextRoot = = null? Null: contextRoot.getValue (), evaluationContext);} catch (Throwable ex) {/ / If running in mixed mode, revert to interpreted if (this.configuration.getCompilerMode () = = SpelCompilerMode.MIXED) {this.interpretedCount = 0; this.compiledAst = null;} else {/ / Running in SpelCompilerMode.immediate mode-propagate exception to caller throw new SpelEvaluationException (ex, SpelMessage.EXCEPTION_RUNNING_COMPILED_EXPRESSION) }} ExpressionState expressionState = new ExpressionState (getEvaluationContext (), this.configuration); result = this.ast.getValue (expressionState); checkCompile (expressionState); return result;}}
CompositeStringExpression
/ / specific non-Terminator expression public class CompositeStringExpression implements Expression {@ Override public String getValue () throws EvaluationException {StringBuilder sb = new StringBuilder (); for (Expression expression: this.expressions) {String value = expression.getValue (String.class); if (value! = null) {sb.append (value);}} return sb.toString ();}}
ExpressionParser interface
Public interface ExpressionParser {/ / parse expression Expression parse_Expression (String expressionString) throws ParseException; Expression parse_Expression (String expressionString, ParserContext context) throws ParseException;}
TemplateAwareExpressionParser class
Public abstract class TemplateAwareExpressionParser implements ExpressionParser {@ Override public Expression parse_Expression (String expressionString) throws ParseException {return parse_Expression (expressionString, NON_TEMPLATE_PARSER_CONTEXT);} / / return different Expression objects @ Override public Expression parse_Expression (String expressionString, ParserContext context) throws ParseException {if (context = = null) {context = NON_TEMPLATE_PARSER_CONTEXT;} if (context.isTemplate ()) {return parseTemplate (expressionString, context) } else {return doParse_Expression (expressionString, context);}} private Expression parseTemplate (String expressionString, ParserContext context) throws ParseException {if (expressionString.length () = = 0) {return new Literal_Expression ("");} Expression [] expressions = parseExpressions (expressionString, context); if (expressions.length = = 1) {return expressions [0];} else {return new CompositeString_Expression (expressionString, expressions) }} / / abstract, subclass to implement protected abstract Expression doParse_Expression (String expressionString, ParserContext context) throws ParseException;}
SpelExpressionParser class
Public class SpelExpressionParser extends TemplateAwareExpressionParser {@ Override protected SpelExpression doParse_Expression (String expressionString, ParserContext context) throws ParseException {/ / An InternalSpelExpressionParser is returned here, return new InternalSpelExpressionParser (this.configuration) .doParse_Expression (expressionString, context);}}
InternalSpelExpressionParser class
Class InternalSpelExpressionParser extends TemplateAwareExpressionParser {@ Override protected SpelExpression doParse_Expression (String expressionString, ParserContext context) throws ParseException {try {this.expressionString = expressionString; Tokenizer tokenizer = new Tokenizer (expressionString); tokenizer.process (); this.tokenStream = tokenizer.getTokens (); this.tokenStreamLength = this.tokenStream.size (); this.tokenStreamPointer = 0; this.constructedNodes.clear (); SpelNodeImpl ast = eat_Expression () If (moreTokens ()) {throw new SpelParseException (peekToken (). StartPos, SpelMessage.MORE_INPUT, toString (nextToken ();} Assert.isTrue (this.constructedNodes.isEmpty ()); return new Spel_Expression (expressionString, ast, this.configuration);} catch (InternalParseException ex) {throw ex.getCause () At this point, I believe you have a deeper understanding of "what is the interpreter pattern of the design pattern series". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.