Определение: Учитывая язык, определите представление его грамматики и определите интерпретатора, который использует представление для интерпретации предложений на языке.
Тип: поведенческий паттерн
Классовая диаграмма:
Режим интерпретатора является относительно редко используемым режимом, и я никогда раньше не использовал этот режим. Давайте посмотрим на режим интерпретатора.
Структура режима интерпретатора
Аннотация переводчика: объявить абстрактный интерфейс (или абстрактный класс), к которому должны реализованы все конкретные выражения. Интерфейс является в основном методом интерпретации (), называемый операцией объяснения. Конкретная задача интерпретации выполняется по различным классам реализации, а конкретный интерпретатор завершается с помощью Terminator Interprerer Terminalexpression и непонминальной интерпретаторной невозможны соответственно.
Выражение терминатора: реализует операции интерпретации, связанные с элементами в грамматике. Обычно в шаблоне интерпретатора существует только одна экспрессия терминатора, но есть несколько экземпляров, соответствующих различным терминаторам. Половина терминатора является операционной единицей в грамматике. Например, существует простая формула R = R1+R2, где R1 и R2 являются терминаторами, и соответствующие переводчики, которые анализируют R1 и R2, являются терминаторами.
Неподошное выражение: каждое правило в грамматике соответствует некомминальной экспрессии. Неподмешные выражения, как правило, являются операторами или другими ключевыми словами в грамматике. Например, в формуле r = r1 + r2, + некомминальный символ, а интерпретатор диапазона +-не концевой символ. Непосмертные выражения увеличиваются в зависимости от сложности логики, и в принципе каждое правило грамматики соответствует неледуковому выражению.
Роль окружающей среды: задача этой роли обычно используется для хранения конкретных значений, соответствующих каждому терминатору в грамматике, таких как R = R1+R2. Мы назначаем 100 по R1 и 200 до R2. Эта информация должна храниться в роли окружающей среды. Во многих случаях мы используем карту, чтобы действовать в качестве роли окружающей среды.
пример
Давайте приведем пример сложения, вычитания, умножения и деления. Идея реализации исходит из примера в «Java и Pattern». Функции каждой роли реализованы в соответствии со спецификациями, упомянутыми выше.
// Роль контекста (среда), используйте HashMap для хранения численных значений, соответствующих переменным, класс, {частная карта ValueMap = new HashMap (); public void AddValue (переменная x, int y) {integer yi = new Integer (y); valuemap.put (x, yi); } public int lookupValue (переменная x) {int i = ((integer) valueMap.get (x)). intvalue (); вернуть я; }} // Роль абстрактного выражения, вы также можете использовать интерфейсы для реализации абстрактного выражения класса {public abstract int интерпретация (Context con); } // Терминаторная выражение роли Константа Constant расширяет выражение {private int i; public Constant (int i) {this.i = i; } public int интерпретация (контекст con) {return i; }} переменная класса Extends Expression {public int rotport (context con) {// Это объект переменной, который называет метод интерпретации return con.lookupvalue (this); }} // Неудовлетворительное выражение выражения класс роли add Extends выражение {частное выражение влево, справа; Общественный адрес (выражение слева, выражение справа) {this.left = слева; this.right = верно; } public int интерпретация (контекст con) {return left.interpret (con) + right.interpret (con); }} класс вычитается расширяет выражение {частное выражение влево, справа; публичное вычитание (выражение влево, выражение справа) {this.left = слева; this.right = верно; } public int интерпретация (контекст con) {return left.interpret (con) - right.interpret (con); }} класс умножает выражение выражения {частное выражение влево, справа; публичный умножение (выражение влево, выражение справа) {this.left = слева; this.right = верно; } public int интерпретация (контекст con) {return left.interpret (con) * right.interpret (con); }} разделение класса расширяет выражение {частное выражение влево, справа; Публичное разделение (выражение слева, выражение справа) {this.left = слева; this.right = верно; } public int интерпретация (context con) {try {return left.interpret (con) / right.interpret (con); } catch (arithmeticexception ae) {system.out.println ("divorc is 0!"); возврат -11111; }}} // Проверка программы, рассчитывать (a*b)/(a-b+2) Общедоступный тест класса {частное статическое выражение Ex; частный статический контекст Con; public static void main (String [] args) {con = new Context (); // Установить переменные и константы переменная a = new variable (); Переменная b = new переменная (); Постоянная c = новая константа (2); // назначить переменную con.addvalue (a, 5); con.addvalue (b, 7); // Работа мы сами анализируем структуру предложения, построить ex = новое разделение (новое умножение (a, b), новое добавление (новое вычитание (a, b), c)); System.out.println («Результат работы:»+ex.Interpret (con)); }} Преимущества и недостатки режима интерпретатора
Интерпретатор - это простой инструмент анализа синтаксиса. Его наиболее значительным преимуществом является его расширяемость. Изменение синтаксических правил требует только изменения соответствующих некомминальных символов. Если вы расширяете синтаксис, вам нужно только добавить некомминальный символ.
Тем не менее, шаблон интерпретатора приведет к расширению класса, и каждый синтаксис должен произвести не концевое выражение. Когда правила синтаксиса являются относительно сложными, может быть сгенерировано большое количество файлов класса, что доставляет много проблем для технического обслуживания. В то же время, поскольку принят метод рекурсивного вызова, каждое не концевое выражение заботится только о выражениях, связанных с самим собой. Каждое выражение должно знать конечный результат и должно быть рекурсивным. Будь то объектно-ориентированный язык или ориентированный на процесс язык, рекурсия не рекомендуется. Из -за использования большого количества петель и рекурсии эффективность является проблемой, которую нельзя игнорировать. Особенно, когда используется для интерпретации комплекса диапазона, длительного синтаксиса, эффективность невыносима.
Применимые сценарии для режима интерпретатора
Режим интерпретатора может использоваться в следующих случаях:
Существует простое синтаксическое правило, такое как утверждение SQL. Если нам нужно выполнить преобразование RM на основе операторов SQL, мы можем использовать шаблон интерпретатора для интерпретации оператора.
Некоторые повторяющиеся проблемы, такие как четыре операции добавления, вычитания, умножения и деления, но формулы каждый раз различаются. Иногда это A+BC*D, иногда это CD*B+CD и т. Д. Формулы постоянно меняются, но все они связаны с четырьмя некомнатными символами добавления, вычитания, умножения и деления. В настоящее время мы можем использовать режим интерпретатора.
Что следует отметить
Режим интерпретатора действительно является относительно редко используемым режимом, потому что он слишком хлопотно для его поддержания. Представьте, что если куча неподотничных переводчиков не знакомы с правилами грамматики заранее, или грамматика особенно проста, будет трудно понять ее логику. Режим интерпретатора редко используется в реальной разработке системы, потому что он может вызвать такие проблемы, как эффективность, производительность и обслуживание.