Они принадлежат обоим мирам:
Синтаксис опишет, какие операторы являются примитивными типами (int
, float
) и являются ключевыми словами (return
, for
, while
). Таким образом, синтаксис решает, какие «слова» вы можете использовать в языке программирования. Под словом «я» подразумевается каждый возможный токен: =
- это токен, void
- это токен, varName12345
- это токен, который считается идентификатором, 12.4
- это токен, рассматриваемый как float и так далее. .
Семантика опишет, как эти токены могут быть объединены вместе в вашем языке.
Например, у вас будет семантика while
:
WHILE ::= 'while' '(' CONDITION ')' '{' STATEMENTS '}'
CONDITION ::= CONDITION '&&' CONDITION | CONDITION '||' CONDITION | ...
STATEMENTS ::= STATEMENT ';' STATEMENTS | empty_rule
и так далее. Это грамматика языка, которая точно описывает его структуру. Таким образом, он сможет решить, является ли программа правильной в соответствии с семантикой языка.
Тогда есть третий аспект семантики, а именно «что означает эта конструкция?». Вы можете видеть это как соответствие между, например, циклом for
и тем, как он должен быть переведен на язык нижнего уровня, который необходимо выполнить.
Этот третий аспект будет определять правильность вашей программы в отношении разрешенных операций. Обычно вы можете заставить компилятор отклонять многие программы, которые не имеют смысла (потому что они нарушают семантику), но чтобы иметь возможность находить много разных ошибок, вам нужно будет представить новый инструмент: средство проверки типов, которое также будет проверять это всякий раз, когда вы делаете операции они правильные в соответствии с типами.
Например, ваша грамматика может разрешить делать varName = 12.4
, но средство проверки типов будет использовать объявление varName
, чтобы понять, можете ли вы присвоить ему число с плавающей запятой. (конечно же, речь идет о статической проверке типов)