Подумайте, является ли x
в объявлении int x;
выражением.
Раньше я думал, что это точно не так, но грамматика здесь называет имя переменной id-выражением.
Тогда можно было бы утверждать, что выражением является только выражение, а не ??-expression
. Но тогда в 1 + 2
не совпадают ни 1
, ни 2
, потому что это additive-expression
и multiplicative-expression
соответственно, а не expression
s. Но здравый смысл подсказывает, что их тоже следует называть выражениями.
Мы могли бы решить, что любое ??-expression
(включая expression
) является выражением, но тогда имя переменной в объявлении также совпадает.
Мы могли бы определить выражение как любое ??-expression
, кроме id-expression
, но это кажется довольно произвольным.
Каково правильное грамматическое определение выражения и является ли имя переменной в ее объявлении выражением или нет?
Грамматика представляет собой иерархию понятий. Любое id-выражение является выражением, но не любое выражение является id-выражением. Любое аддитивное-выражение также является выражением, но не любое выражение является аддитивным-выражением.
В чем проблема id-expression
быть выражением? Как говорится на связанной странице, это ограниченная форма primary-expression
. Таким образом, «выражение» в объявлении должно быть очень конкретным типом выражения.
@nielsen Это вызывает некоторые непонятные вопросы. Если это выражение, имеет ли оно категорию значения? (в своем собственном объявлении) Тип?
@н.м. Я бы сказал, что грамматика — это набор правил раскрытия плюс начальный термин. "Любое аддитивное-выражение также является выражением" Я так не думаю. Да, expression
может в некоторых случаях расширяться до additive-expression
, но это расширение не происходит для 1
в случае 1 + 2
, потому что левая часть +
является непосредственно additive-expression
.
Грамматика может интерпретироваться как набор правил расширения, набор правил сокращения или набор определений. Если мы хотим ответить на такие вопросы, как «является ли id-выражение выражением», мы интерпретируем его как набор определений. Если интерпретировать грамматику как набор правил, то такие вопросы не имеют смысла. «Выражение» (не «выражение») — это уникальный символ в наборе правил, не более того.
Что означает вопрос «является x
выражением»?
Когда мы говорим о конкретных вхождениях выражений и идентификаторов в конкретной программе, мы должны учитывать ее дерево синтаксического анализа. Подстрока программы является expression
, если некоторое вхождение expression
узла в ее дереве разбора расширяется до этой подстроки.
Таким образом, x
в объявлении int x;
не является выражением, потому что в дереве синтаксического анализа (любой допустимой программы, содержащей expression
в качестве объявления) нет int x;
, которое расширяется до этого вхождения x
. Существует узел id-expression
, но этот конкретный узел id-expression
не является расширением узла expression
, он является частью расширения узла declaration
.
Когда речь идет о выражениях и идентификаторах по отдельности, то «является» означает «расширяется до/сжимается в соответствии с некоторым правилом грамматики». Таким образом, взятое изолированно, x
является выражением. Это означает, что мы можем построить программу, где x
— выражение в соответствии с приведенным выше определением.
Эти определения являются чисто синтаксическими и как таковые действительны для любого языка и грамматики. Однако стандарт С++ неофициально утверждает, что
Выражение — это последовательность операторов и операндов, определяющая вычисление
и в нескольких местах говорит о подвыражениях как о выражениях сами по себе. Таким образом, термин «выражение» в стандарте не совпадает с элементом грамматики expression
.
Однако это не непреодолимая проблема. Грамматика — это только инструмент. Стандарт мог бы определить грамматику по-другому:
expression:
expression = expression
expression + expression
expression * expression
...
( expression )
id-expression
и устранить двусмысленность в английском тексте. Если мы хотим, чтобы понятие выражения близко соответствовало элементу грамматики, нам, вероятно, следует мысленно рассмотреть грамматику, представленную таким образом.
В качестве альтернативы, как вы предлагаете, мы можем рассмотреть расширение любого ??-expression
«выражения», но заменить некоторые вхождения id-expression
новым символом. Эти два подхода кажутся эквивалентными.
Примечание: эта версия ответа полностью переписана. Предыдущая версия была результатом недоразумения.
Я убежден, что это не так. Попробую найти более яркий пример...
Хорошо, учтите следующее: в int x;
x
является (среди прочего) идентификатором . Но есть еще правило namespace-name -> идентификатор. Применяя вашу логику, x
в int x;
(или любой идентификатор в любом месте) является именем пространства имен (исключительно потому, что такое правило существует, хотя здесь оно не используется). Это то же самое, что сказать, что любой additive-expression
является expression
, потому что правило expression -> additive-expression
существует.
@HolyBlackCat Я понимаю, что вы имеете в виду, позвольте мне исправить свой ответ.
@HolyBlackCat В итоге я полностью переписал его.
Ага, значит, вы выбрали вариант «только expression
— это выражение». Но тогда в 1 + 2
ни 1
, ни 2
не являются выражениями.
После просмотра ссылок, предоставленных @LanguageLawyer (1 , 2), я пришел к выводу, что id-expression
— это неправильное название и не всегда выражение (например, это не выражение в декларации).
Тогда исходная подстрока является выражением, если вызывается хотя бы один из ее родителей в дереве синтаксического анализа:
expression
или*-expression
1 но не id-expression
, и этот родитель расширяется именно до этой подстроки и ничего больше.
Это то же самое определение @n.m. предложено, за исключением того, что я также разрешаю узлы «*-expression
, а не id-expression
».
1*
— это подстановочный знак для любой строки.
Я бы сказал, что это выражение, если оно является id-выражением, если оно не является декларатором. id-выражения «в изоляции» неоднозначны — они могут быть выражениями или деклараторами, в зависимости от контекста.
@ChrisDodd Это определение не отвергает все id-expressions
(оно допускает те, которые также являются некоторыми другими *-expression
s).
по крайней мере один из его родителей в дереве синтаксического анализа вызывается: expression
Это делает id-expression
в RHS члена класса доступом к выражению.
@LanguageLawyer Часть «и этот родитель расширяется именно до этой подстроки и ничего более» должна исключать это, я думаю.
Не уверен, подходит ли
language-lawyer
или нет. Я ищу разумное, но точное определение, которому я могу научить других, но я не хочу, чтобы в итоге «1
и2
в1 + 2
на самом деле не были выражениями», потому что это противоречит здравому смыслу.