Definição: Dado um idioma, defina uma representação de sua gramática e defina um intérprete que usa a representação para interpretar frases no idioma.
Tipo: padrão comportamental
Diagrama de classe:
O modo de intérprete é um modo relativamente raramente usado, e eu nunca usei esse modo antes. Vamos dar uma olhada no modo de intérprete.
Estrutura do modo de intérprete
Intérprete abstrato: Declare uma interface abstrata (ou classe abstrata) à qual todas as expressões concretas devem ser implementadas. A interface é principalmente um método interpret (), chamado de uma operação de explicação. A tarefa de interpretação específica é concluída por suas várias classes de implementação, e o intérprete específico é concluído pelo TerminAlexpression, intérprete do Terminator e pelo intérprete não terminal de texpressão, respectivamente.
Expressão do terminador: implementa operações de interpretação associadas a elementos na gramática. Geralmente, existe apenas uma expressão do terminador em um padrão de intérprete, mas existem várias instâncias, correspondendo a diferentes terminadores. Metade do terminador é uma unidade de operação na gramática. Por exemplo, existe uma fórmula simples R = R1+R2, onde R1 e R2 são terminadores, e os intérpretes correspondentes que a análise R1 e R2 são terminadores.
Expressão não terminal: cada regra na gramática corresponde a uma expressão não terminal. Expressões não terminais geralmente são operadoras ou outras palavras-chave na gramática. Por exemplo, na fórmula r = r1 + r2, + é um caractere não terminal e o intérprete do Parsing + é um caráter não terminal. As expressões não terminais aumentam de acordo com a complexidade da lógica e, em princípio, cada regra gramatical corresponde a uma expressão não terminal.
Função do ambiente: a tarefa dessa função é geralmente usada para armazenar os valores específicos correspondentes a cada terminador na gramática, como R = R1+R2. Atribuímos 100 a R1 e 200 a R2. Esta informação precisa ser armazenada na função do ambiente. Em muitos casos, usamos o mapa para atuar como o papel do meio ambiente é suficiente.
exemplo
Vamos dar um exemplo de adição, subtração, multiplicação e divisão. A ideia de implementação vem do exemplo em "Java e Pattern". As funções de cada função são implementadas de acordo com as especificações mencionadas acima.
// função de contexto (ambiente), use hashmap para armazenar os valores numéricos correspondentes a variáveis da classe contexto {private mapa valuemap = new hashmap (); public void addValue (variável x, int y) {integer yi = new Integer (y); valuemap.put (x, yi); } public int LookupValue (variável x) {int i = ((integer) valuemap.get (x)). intvalue (); retornar i; }} // Função de expressão abstrata, você também pode usar interfaces para implementar a expressão de classe abstrata {public abstrate int interpret (context con); } // Classe de função de expressão do terminador constante estende a expressão {private int i; public constant (int i) {this.i = i; } public int interpret (context con) {return i; }} classe variável estende a expressão {public int interpret (context con) {// Este é um objeto variável que chama o método de interpretação retornar con.lookupValue (this); }} // Classe de função de expressão de não terminador ADD ADDENDENS EXPRESSÃO {Expressão privada esquerda, direita; endereço público (expressão esquerda, expressão direita) {this.left = esquerda; this.right = certo; } public int interpret (context con) {return left.interpret (con) + correta.interpret (con); }} classe Subtrair estende a expressão {Expressão privada esquerda, direita; public subtração (expressão esquerda, expressão direita) {this.left = esquerda; this.right = certo; } public int interpret (context con) {return left.interpret (con) - right.interpret (con); }} classe Multiply estende a expressão {Expressão privada esquerda, direita; public multiply (expressão esquerda, expressão direita) {this.left = esquerda; this.right = certo; } public int interpret (context con) {return left.interpret (con) * right.interpret (con); }} Divisão de classe estende a expressão {Expressão privada para a esquerda, direita; divisão pública (expressão esquerda, expressão à direita) {this.left = esquerda; this.right = certo; } public int interpret (context con) {try {return left.interpret (con) / right.interpret (con); } catch (arithmeticexception ae) {System.out.println ("divorc é 0!"); retornar -11111; }}} // Teste o programa, calcule (a*b)/(a-b+2) Teste de classe pública {Expressão estática privada ex; contexto estático privado Con; public static void main (string [] args) {con = new context (); // Defina variáveis e constantes variável a = new variável (); Variável b = new variable (); Constante c = nova constante (2); // atribui a variável con.addvalue (a, 5); con.addvalue (b, 7); // operação, analisamos a estrutura da frase, construímos Ex = nova divisão (nova multiplicação (a, b), novo add (novo subtração (a, b), c)); System.out.println ("O resultado da operação é:"+ex.interpret (con)); }} Vantagens e desvantagens do modo de intérprete
O intérprete é uma ferramenta de análise de sintaxe simples. Sua vantagem mais significativa é sua extensibilidade. A modificação das regras de sintaxe requer apenas a modificação dos caracteres não terminais correspondentes. Se você expandir a sintaxe, precisará adicionar apenas um caractere não terminal.
No entanto, o padrão de intérprete fará com que a classe se expanda e cada sintaxe precisa produzir uma expressão não terminal. Quando as regras de sintaxe são relativamente complexas, um grande número de arquivos de classe pode ser gerado, o que traz muitos problemas à manutenção. Ao mesmo tempo, como o método de chamada recursiva é adotado, cada expressão não terminal se importa apenas com as expressões relacionadas a si mesmo. Cada expressão precisa conhecer o resultado final e deve ser recursiva. Seja uma linguagem orientada a objetos ou uma linguagem orientada ao processo, a recursão é uma maneira não recomendada. Devido ao uso de muitos loops e recursão, a eficiência é um problema que não pode ser ignorado. Especialmente quando usado para interpretar um complexo de análise, sintaxe longa, a eficiência é insuportável.
Cenários aplicáveis para o modo de intérprete
O modo de intérprete pode ser usado nos seguintes casos:
Existe uma regra simples de sintaxe, como uma instrução SQL. Se precisarmos executar a conversão RM com base nas instruções SQL, podemos usar o padrão de intérprete para interpretar a instrução.
Alguns problemas repetitivos, como as quatro operações de adição, subtração, multiplicação e divisão, mas as fórmulas são diferentes todas as vezes. Às vezes, é a+bc*d, às vezes é um cd A*b+, etc. As fórmulas são sempre em constante mudança, mas todas estão conectadas pelos quatro caracteres não terminais de adição, subtração, multiplicação e divisão. Neste momento, podemos usar o modo de intérprete.
Coisas a serem observadas
O modo de intérprete é realmente um modo relativamente raramente usado, porque é muito problemático mantê -lo. Imagine que se um monte de intérpretes não terminais não estiver familiarizado com as regras da gramática com antecedência, ou a gramática for particularmente simples, será difícil entender sua lógica. O modo de intérprete raramente é usado no desenvolvimento real do sistema, pois pode causar problemas como eficiência, desempenho e manutenção.