Как разобрать оператор if / else с помощью yacc - PullRequest
0 голосов
/ 07 апреля 2019

Я пытаюсь создать файл .y для разработки базового языка программирования, в котором значения терминалов просто true и false.Однако у меня возникла проблема с определением правила для оператора 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 из 'ifstatement' не имеет объявленного типа ifstatement: IF выражение COLON выражение {if ($ 2 == true) {$$ = $ 4;}}

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

1 Ответ

3 голосов
/ 08 апреля 2019

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

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

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

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

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

...