Каждый язык - будь то человеческий язык, компьютерный язык или научная нотация - состоит из символов.Эти символы являются наименьшими значимыми единицами языка, например, человеческие языки имеют слова и знаки препинания;математика имеет числа и операторы;У Java есть идентификаторы, литералы и символы.Этими основными символами являются терминалы , наименьшие части, на которые можно разбить операторы.
Эти терминалы связаны друг с другом для создания операторов, и языки имеют особые способы, которыевы можете связать нетерминалы вместе, чтобы передать значение, например, в математике, вы можете объединить число, операнд и другое число (например, 5
+
2
) для выполнения операции , ив Java вы можете объединить идентификатор, символ знака равенства, числовой литерал и символ точки с запятой (например, size
=
50
;
), чтобы сделать оператор присваивания .Эти разрешенные способы объединения терминалов называются нетерминалами .Нетерминалы могут быть комбинациями терминалов, других нетерминалов или обоих.
Таким образом, терминалы являются символами языка, в то время как нетерминалы представляют собой комбинации этих терминалов для создания выражений и операторов.Например, простой язык программирования может иметь такие терминалы, как if
, else
, while
, +
, -
, (
, )
, ++
, --
, '\n'
, 3.14159
и многое другое.Эти терминалы могут быть объединены в нетерминалы, такие как:
- Оператор назначения
- Оператор If
- Цикл цикла
- Объявление переменной
- и т. Д.
Что такое шаблон интерпретатора, так это то, что он принимает эти терминальные и нетерминальные символы и определяет их как классы или типы данных, которые соответствуют структуреязык.Таким образом, для терминальных символов, таких как числа или идентификаторы, они могут быть определены как
abstract class Symbol {
abstract int evaluate();
}
class Number extends Symbol {
int value;
@Override int evaluate() {
return value;
}
}
class Identifier extends Symbol {
String name;
@Override int evaluate() {
return getIdentifierValue(name);
}
}
, а затем нетерминальные символы, например, если операторы или выражения могут быть определены как
class IfStatement extends Symbol {
Symbol condition;
Symbol ifBranch;
Symbol elseBranch;
@Override int evaluate() {
if (condition.evaluate() != 0)
return ifBranch.evaluate();
else
return elseBranch.evaluate();
}
}
class AddExpression extends Symbol {
Symbol left;
Symbol right;
@Override int evaluate() {
return left.evaluate() + right.evaluate();
}
}
Можно видеть, что терминалы представляют значения, такие как числа, идентификаторы и строки, а нетерминалы представляют выражения и операторы, построенные рекурсивно из этих терминалов.Я не очень хорош в объяснении теории, но надеюсь, что приведенные здесь практические примеры помогут вам понять.