Как разбирать операторы if/else с помощью yacc

Я пытаюсь создать файл .y для разработки базового языка программирования, где терминальные значения просто истинны и ложны. Однако у меня возникла проблема с определением правила для оператора if. Синтаксис оператора if похож на;

a=TRUE
if TRUE: print(a)

и мой BNF похож;

statement : assignment | ifstatement | print
ifstatement : IF expression COLON statement                {if ($2==true){$$ = $4;}}

где IF — токен ключевого слова if и COLON для ':'. Но когда я компилирую свои файлы, я получаю следующую ошибку:

$4 of ‘ifstatement’ has no declared type ifstatement : IF expression COLON statement {if ($2==true){$$ = $4;}}

Итак, мой вопрос: какое может быть правило, которое я должен использовать для операторов if else, отличных от {если($2==истина){$$ = $4;}}?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
2 117
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема, на которую жалуется бизон, заключается в том, что вы присваиваете $$, что является семантическим значением ifstatement, но вы не сказали бизону, каков тип ifstatement. Как и в C, если у вас есть переменная, вам нужно объявить ее тип.

Это предполагает, что вы сказали bison, что не все грамматические символы имеют один и тот же тип. Другими словами, у вас есть объявление %union, в котором указаны имена тегов для всех типов, которые вы используете. Затем вам нужно объявить типы всех токенов и нетерминалов, которые имеют значения, используя объявления %token и %type.

Ваше действие if ($2==true){$$ = $4;} требует, чтобы $$ (ifexpression), $2 (expression) и $4 (statement) были объявлены типы. Если bison жалуется только на один из них, то вы знаете, как объявлять типы, потому что два других уже объявлены. В противном случае, если у вас много таких ошибок, то вам следует просмотреть файл соответствующий раздел в руководстве по зубру. Вы также можете прочитать всю главу о семантические значения.

Однако ничто из вышеперечисленного не решает реальной проблемы с этим действием, связанной с вашим подходом к интерпретации программного кода. Ожидается, что оператор if будет оценивать свою ветвь true только в том случае, если условие действительно истинно. Но обратите внимание, что значение $4 уже было вычислено до того, как ваше действие было выполнено, независимо от того, выполняется ли условие. Все, что делает действие, — это перенаправляет уже вычисленное значение statement в значение ifstatement. Также обратите внимание, что $$ ничего не присваивается, если условие равно false. Таким образом, его значение равно значению $4 или оно не инициализировано, и в последнем случае попытка использовать его значение приведет к неопределенному поведению.

Вот почему любой нетривиальный язык не может быть оценен во время синтаксического анализа. Условные блоки могут быть оценены только после того, как условный оператор был проанализирован, поэтому их оценку необходимо отложить. И повторяющиеся блоки — например, операторы for и while — должны оцениваться много раз, хотя они анализируются только один раз.

Другие вопросы по теме