Cluster & Nosok
Я тут небольшой интерпретатор для какого-то эзотерического языка написал, там только вложенные скобки используются. И вот выдаёт синтаксическую ошибку на, казалось бы, вполне правильном запросе. Поможешь разобраться?
Конечно, давай глянем на парсер и на ввод, который его сбивает с толку.
Понял, кидай фрагмент, который разбирает скобки, и строку, которая вызывает проблему. Просмотрю AST, чтобы понять, в чём дело. Да, скинь код парсера и проблемный ввод — посмотрю, где баланс стека нарушается.
Вот суть моего парсера – он просто перебирает строку, добавляя в стек при каждом открывающем скобочка и извлекая при каждом закрывающем. Он выдаёт ошибку, если пытается извлечь из пустого стека или доходит до конца строки с непарными скобками.
Вот пример строки, которая вызывает проблему:
```
((()())())()
```
Когда я запускаю `parse` на этой строке, он сообщает об ошибке на 11-й позиции – считает скобки сбалансированными, а парсер видит лишний `()` в конце, который не учтён. Похоже, нужно покопаться в логике AST.
Твоя логика цикла хорошая, но сообщение об ошибке вводящее в заблуждение. Эти "лишние скобки в конце" не проблема – они сбалансированы. На самом деле, проблема в том, что ты используешь один целочисленный счётчик для стека. Это нормально для сопоставления, но ты печатаешь индекс, где происходит переполнение стека. Индекс 11 указывает на предпоследний символ, потому что ты ещё внутри цикла, когда ошибка возвращается. Если ты хочешь сообщить точное положение непарной закрывающей скобки, тебе нужно возвращать `i+1` или отслеживать индекс до уменьшения. Короче говоря, подкорректируй расчёт индекса ошибки, и ты увидишь, как он правильно указывает на непарную скобку в позиции 10, а не 11. И ещё, проверь, нет ли в строке ввода скрытых символов новой строки или возврата каретки, которые могут сдвигать индексы.
Похоже на обычную ошибку, связанную с неправильным сдвигом индекса; просто сдвинь отчет на один или захвати индекс до уменьшения. И еще проверь, нет ли случайных переносов строки или возвратов каретки, если ты читаешь из файла. Как только разберёшься с этим, счетчика стека вполне хватит, чтобы доказать, что всё сбалансировано. Что ещё вызывает проблемы у парсера?
Да, это обычный баг с нумерацией с нуля. Счетчик работает, но если хочешь более надежный парсер, нужна настоящая стековая структура для отслеживания позиций – тогда сможешь указывать на ошибку точно по символу. И еще убедись, что ты не игнорируешь молчаливым образом любые символы, кроме скобок – сейчас они просто пропускаются, и это нормально для чистого языка со скобками, но странно будет, если потом добавишь другие токены. Если когда-нибудь захочешь расширить это, замени int на слайс индексов. Тогда сможешь доставать точный индекс соответствующей открывающей скобки и предоставить пользователю полный трейс. И будь аккуратен с UTF-8 – твой цикл в порядке, но если перейдешь на чтение побайтово, сломается на многобайтовых последовательностях. Всё, больше сюрпризов с текущей логикой не должно быть.
Got it—switching to a slice of indices is the clean way to trace errors. Will keep an eye on UTF‑8 if I ever move to a byte stream. Thanks for the heads‑up.