1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/fawdlstty-Facc

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
chapter_2.md 5.2 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 30.11.2024 13:48 224b242

Глава 2: Грамматика языка программирования

Код, состоящий из символов

Код состоит из различных символов. Например, следующий код:

static void Main (string [] args) {
    Console.WriteLine ("Hello World!");
}

Сначала идёт ключевое слово static, состоящее из шести символов, которое обозначает статичность. Затем идёт ключевое слово void, состоящее из четырёх символов, которое представляет тип возвращаемого значения функции. Далее идут необязательные символы, такие как перенос строки и отступы табуляции.

Прежде всего, мы должны чётко понимать, что код на языке программирования — это строка, состоящая из разных символов.

Комбинации различных операторов

Рассмотрим предыдущий код:

static void Main (string [] args) {
    Console.WriteLine("Hello World!");
    Console.WriteLine("Hello World!");
    Console.WriteLine("Hello World!");
}

Это простой код, не так ли? Теперь давайте проанализируем его. Отличие этого кода от предыдущего заключается в том, что фраза «Hello World!» выводится три раза. На основе этого мы можем смело предположить, что в функции может быть от нуля до N строк кода (это очевидно).

Теперь определим структуру функции. Сначала идёт заголовок функции, который мы называем func_begin. Затем идут операторы, которые мы называем stmt. Наконец, идёт конец функции, который мы называем func_end.

Мы можем описать эту структуру с помощью специальной грамматики:

func_stmt ::= func_begin stmt* func_end

Проще говоря, структура функции (func_stmt) состоит из трёх частей: заголовка функции (func_begin), тела функции (состоит из операторов stmt, звёздочка означает повторение от нуля до бесконечности раз) и конца функции (func_end).

Эта грамматика позволяет нам сопоставить обе части кода, независимо от того, сколько выражений содержится в функции Main.

Терминальные и нетерминальные символы

Вкратце, терминальные символы — это символы или строки в коде. Нетерминальные символы — это определения структур.

Например, мы хотим разобрать следующее выражение:

1+2*3-4/5

Оно состоит из девяти частей, каждая из которых является символом. Мы можем представить его как:

expr ::= num op num op num op num op num

Упростим его:

expr ::= num (op num)+

Здесь op и num объединяются четыре раза, поэтому мы объединяем их и требуем, чтобы они повторялись хотя бы один раз.

Затем мы определяем num и op:

num ::= [0-9]+
op ::= '+' | '-' | '*' | '/'

Как видите, при определении грамматики языка мы используем символ ::= для соединения двух частей. Левая часть определяет нетерминальный символ, а правая часть может быть терминальным символом или комбинацией нетерминальных символов.

Мы можем рассматривать строку кода как корень дерева, где нетерминальные символы являются узлами ствола, а терминальные символы — листьями. Определение грамматики — это определение того, какие типы дочерних узлов могут иметь узлы ствола. Когда мы определяем грамматику, мы берём строку кода и сопоставляем её с корнем дерева, пока не достигнем всех листьев. В результате получается дерево, называемое абстрактным синтаксическим деревом (AST).

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/fawdlstty-Facc.git
git@api.gitlife.ru:oschina-mirror/fawdlstty-Facc.git
oschina-mirror
fawdlstty-Facc
fawdlstty-Facc
main