Существует ли более точный синтаксис для спецификаторов объявлений для языка программирования C? - PullRequest
1 голос
/ 06 апреля 2020

Расширяя синтаксис «объявлений-спецификаторов» из стандарта C, я получаю синтаксис, который допускает множество комбинаций спецификаторов, которые семантически нелогичны. Кто-нибудь написал более точный синтаксис, который позволяет меньше противоречивых комбинаций? Похоже, что неупорядоченная природа синтаксиса (предположительно предназначена для того, чтобы программист не был обременен необходимостью запоминать порядок спецификаторов) усложняет задачу. Было бы полезно, если бы существовала некоторая нотация для указания «любой из выбора спецификаторов, но допускается только одно вхождение каждого из выбора» (это не очень хорошо сформулировано). Или я лаю не на том дереве? если, например, есть хороший лаконичный набор правил semanti c, которые указывают, какие комбинации (не) разрешены вместе. Из моей интерпретации стандарта C синтаксис:

спецификаторы объявления: (спецификатор класса хранения | спецификатор типа | спецификатор типа | спецификатор функции | спецификатор выравнивания) +

спецификатор класса хранения: 'typedef' | 'extern' | 'stati c' | '_Thread_local' | 'auto' | 'register'

спецификатор типа: 'void' | 'char '|' short '|' int '|' long '|' float '|' double '|' подписано '|' unsigned '|' _Bool '|' _Complex '| '_Atomi c' '(' имя-типа ')' | спецификатор структуры или объединения | спецификатор enum | typedef-name

квалификатор типа: 'const' | 'restrict' | 'volatile' | '_Atomi c'

спецификатор функции: 'inline' | '_Noreturn'

спецификатор выравнивания: '_Alignas' '(' имя-типа | константа-выражение ')'

Ответы [ 2 ]

1 голос
/ 06 апреля 2020

В определении языка есть отдельные ограничения , которые определяют, какие комбинации спецификаторов объявлений являются допустимыми; это не указано в самой грамматике. Например:

6.7.2 Спецификаторы типа
...
Ограничения

2 По крайней мере один спецификатор типа должен быть указывается в спецификаторах объявлений в каждом объявлении и в списке спецификаторов-определителей в каждом объявлении структуры и имени типа. Каждый список спецификаторов типов должен представлять собой один из следующих мультимножеств (разделенных запятыми, если на элемент приходится более одного мультимножества); спецификаторы типа могут встречаться в любом порядке, возможно, смешанные с другими спецификаторами объявления.

- void
- char
- подписанный символ
- неподписанный символ
- короткий, подписанный короткий , short int или подписанное short int
- неподписанное короткое или unsigned short int
- int, подписанное или подписанное int
- unsigned или unsigned int
- long, подписанное long, long int или со знаком long int
- без знака long или без знака long int
- long long, со знаком long long, long long int или со знаком long long int
- unsigned long long или без знака long long int
- float
- double
- long double
- _Bool
- float _Complex
- double _Complex
- long double _Complex
- atomi c спецификатор типа
- спецификатор структуры или объединения
- спецификатор перечисления
- имя определения типа

C 2011 Онлайн-черновик

пока все что наверное * 104 8 * может быть закодировано в грамматике, это будет громоздко. Я думаю, что создание отдельного ограничения делает жизнь немного проще (а также облегчает введение новых комбинаций или устаревших).

0 голосов
/ 06 апреля 2020

Стандарт C не предусматривает никаких правил относительно порядка реализации описателей объявлений, спецификаторов классов хранения, спецификаторов типов, спецификаторов типов данных или спецификаторов выравнивания внутри объявления определенного объекта.

Вы можете смешивать их произвольно.

Цитата из ISO / IEC 9899: 2018, раздел 6.7.2 / 2

"По крайней мере один спецификатор типа должен быть указан в спецификаторы объявлений в каждом объявлении и в списке спецификаторов-спецификаторов в каждом объявлении структуры и имени типа. Каждый список спецификаторов типов должен представлять собой один из следующих мультимножеств (разделенных запятыми, если в элементе содержится более одного мультимножества); спецификаторы типа могут встречаться в любом порядке, возможно, смешанными с другими спецификаторами объявления . "

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

Кстати, есть еще одна вещь, которую следует учитывать, хотя она синтаксически верна пока . Указатель класса хранения устарел куда-либо, кроме первой позиции.

Цитата из ISO / IEC 9899: 2011, Раздел 6.11.5 - Спецификаторы класса хранения:

"Размещение спецификатора класса хранения, отличного от начала спецификаторов объявления в объявлении, является устаревшей функцией."

Таким образом,

static const long long int a;

можно записать как:

static long int const long a;

или

static long const long int a;

или

static int const long long a;

Но чтобы ваш код читался и ясно для будущих читателей, вы должны использовать общее соглашение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...