Вожусь с парсером для Си компилятора. Обнаруживаю кое-что неожиданное в языке. Как вы думаете, как должен парсер интерпретировать конструкцию вида:
Всё зависит от смысла bar. Если bar определён как переменная:
Но представим, что bar определено как тип:
Однако и это ещё не всё. Может оказаться, что bar определено как агрегатный тип, то есть массив или структура:
А вы говорите: контекстно свободные грамматики. Свобода нам только снится. 😀
Нет вопросов! - воскликнет наивный читатель. 😀 В языке Би действительно это всегда было вычисление выражения bar, взятого в скобки. Однако Си не так прост.foo = (bar)
Всё зависит от смысла bar. Если bar определён как переменная:
то это действительно будет вычисление значения bar и присваивание в foo. Или даже как массив int bar[] или как функция int bar(). То же самое, но уже не значение а адрес. Всё ожидаемо.int bar;
Но представим, что bar определено как тип:
Тогда конструкция превращается в приведение типа, и парсер должен ожидать дальше некое значение, например:typedef int bar;
foo = (bar) 42;
Однако и это ещё не всё. Может оказаться, что bar определено как агрегатный тип, то есть массив или структура:
Тогда конструкция превращается в составной литерал, и парсер должен ожидать дальше фигурные скобки со списком значений:typedef int bar[];
foo = (bar) { 42, 56, 72 };А вы говорите: контекстно свободные грамматики. Свобода нам только снится. 😀

no subject
Date: 2025-05-11 20:08 (UTC)Ну да в реале-то си не то чтобы так уж КС. Местами.
no subject
Date: 2025-05-12 03:00 (UTC)no subject
Date: 2025-05-11 21:17 (UTC)ident_sy("foo") = oparen_sy ident_sy("bar") cparen_syили
ident_sy("foo") = oparen_sy type_sy("bar") cparen_syили
ident_sy("foo") = oparen_sy aggrtype_sy("bar") cparen_syА уж как под руководством парсера, таким образом, НЯП, контекстно-свободного, по ходу дела модифицируется сканер - это отдельный вопрос.
no subject
Date: 2025-05-12 00:18 (UTC)// Get type from symbol table. switch (sym_type(yytext)) { case TOKEN_TYPEDEF_NAME: // Previously defined typedef return TOKEN_TYPEDEF_NAME; case TOKEN_ENUMERATION_CONSTANT: // Previously defined enum return TOKEN_ENUMERATION_CONSTANT; default: // Includes undefined names return TOKEN_IDENTIFIER; }Наверное тут же он должен отличать простой тип от составного, но у меня пока не отличает.no subject
Date: 2025-05-12 03:36 (UTC)