Терминальные и нетерминальные символы
В настоящее время я читаю о шаблоне интерпретатора, и там говорится что-то о терминальных и нетерминальных символах. Поэтому я пошел в Википедию и прочитал об этом. Но я до сих пор не понимаю, что такое терминальный и нетерминальный символ. Можете ли вы дать мне несколько примеров с программированием. Я не хочу, чтобы страница википедии была скопирована... Я хочу примеры из реального мира.
1 ответ
Каждый язык - будь то человеческий язык, компьютерный язык или научная нотация - состоит из символов. Эти символы являются наименьшими значимыми единицами языка, например, человеческие языки имеют слова и знаки препинания; математика имеет числа и операторы; У Java есть идентификаторы, литералы и символы. Эти фундаментальные символы являются терминалами, наименьшими частями, на которые вы можете разбить операторы.
Эти терминалы связаны друг с другом, чтобы делать заявления, и языки имеют особые способы, которыми вы можете связать нетерминалы вместе, чтобы передать значение, например, в математике, вы можете объединить число, операнд и другое число (например, 5
+
2
) для выполнения операции, и в Java вы можете объединить идентификатор, символ знака равенства, литерал числа и символ точки с запятой (например, size
=
50
;
) сделать заявление о назначении. Эти разрешенные способы объединения терминалов называются нетерминалами. Нетерминалы могут быть комбинациями терминалов, других нетерминалов или обоих.
Таким образом, терминалы - это символы языка, а нетерминалы - это комбинации этих терминалов для создания выражений и операторов. Например, простой язык программирования может иметь такие терминалы, как if
, else
, while
, +
, -
, (
, )
, ++
, --
, '\n'
, 3.14159
и многое другое. Эти терминалы могут быть объединены в нетерминалы, такие как:
- Оператор присваивания
- Если заявление
- Пока цикл
- Объявление переменной
- и так далее
Шаблон интерпретатора заключается в том, что он принимает эти терминальные и нетерминальные символы и определяет их как классы или типы данных, которые соответствуют структуре языка. Таким образом, для терминальных символов, таких как числа или идентификаторы, они могут быть определены как
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();
}
}
Итак, вы можете видеть, что терминалы представляют собой значения, такие как числа, идентификаторы и строки, а нетерминалы представляют выражения и операторы, рекурсивно созданные из этих терминалов. Я не очень хорош в объяснении теории, но надеюсь, что приведенные здесь практические примеры помогут вам понять.