Нормально ли, что некоторые выражения C, разрешенные в его грамматике, не разрешены при компиляции на практике?

#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 (операторы присваивания).