#c #syntax #compilation #grammar
#c #синтаксис #Сборник #грамматика
Вопрос:
Я изучал грамматику C: http://www.quut.com/c/ANSI-C-grammar-y-1999.html#unary-expression
Есть это правило
assignment_expression
: conditional_expression
| unary_expression assignment_operator assignment_expression
;
И
unary_expression
: postfix_expression
| INC_OP unary_expression
| DEC_OP unary_expression
| unary_operator cast_expression
| SIZEOF unary_expression
| SIZEOF '(' type_name ')'
;
Итак, почему мы не можем сделать что-то вроде:
v = 3<4 ? 10 : 2;
поскольку v является unary_expression?
Комментарии:
1. Формальная грамматика не определяет язык полностью. Существует небольшой набор дополнительных требований, написанных на английском языке.
2. Вы правы. Эти правила позволяют
v =
. Но посмотрите Примечание в начале файла: «Я хочу, чтобы эта версия была как можно ближе к стандартной грамматике C 1999 года .. «, что указывает на то, что это может быть неподходящий анализатор для языка C.
Ответ №1:
Да, это нормально. Язык C определяется несколькими уровнями правил. Грубо говоря, в качестве введения:
- Отдельные символы собираются в токены предварительной обработки в соответствии с лексическими правилами C.
- Грамматика определяет, какие последовательности токенов предварительной обработки разрешены, а также то, как они интерпретируются (структурированы в виде дерева).
- Ограничения, указанные в стандарте C, добавляют семантические правила, которые грамматика не может указать. Например, ограничение на оператор присваивания заключается в том, что он должен иметь изменяемое значение lvalue в качестве левого операнда.
- Дополнительные правила в стандарте C определяют семантику и дополнительные требования.
Ответ №2:
Грамматика языка — это только одна часть определения языка. Существуют дополнительные семантические правила и ограничения, которые определяют, что синтаксис сам по себе не может. Например, сам по себе синтаксис не может указывать, что переменные и функции должны быть объявлены перед использованием, или что операнд унарного *
оператора должен иметь тип указателя и т.д.
Для выражений присваивания существует ограничение, заключающееся в том, что целью присваивания должно быть изменяемое значение lvalue, которое является выражением, указывающим область памяти таким образом, что содержимое этой области может быть прочитано или обновлено. Если v
это имя переменной, то оно также служит значением lvalue.
Однако, семантические правила
оператора гласят, что результат v
— это не lvalue-выражение, и как таковое не может быть предметом уступки.
Главу и стих, посвященные всему этому, см. в онлайн-проекте C 2011, разделы 6.3.2.1 (значения Lvalues, массивы и обозначения функций), 6.5.3 (Унарные операторы) и 6.5.16 (операторы присваивания).