Паскаль - проверки правильности расстановки открывающих и закрывающих скобок в выражении -- пример кода

Условие задачи:

На вход программе подаётся последовательность символов, заканчивающаяся точкой (точка - признак конца и в последовательность не входит).
Проверить: правильно ли в данной последовательности расставлены круглые скобки (то есть справа от каждой открывающей есть соответствующая закрывающая, а слева от каждой закрывающей есть
соответствующая открывающая). Например, в последовательности
00(0) скобки расставлены правильно а в последовательности (0)) неправильно.
Вывести на экран в качестве ответа YES или NO.

Пример решения, в котором последовательность вводится единой строкой:


Program BracketsTesting;
var // секция объявления переменных
   i,
   bracketsDif, // счётчик разницы между открытыми и закрытыми скобками
   len: Integer;
   
   my_sequence:  String; // сюда считаем последовательность символов
   stop_symb: char; 
begin // тело программы

   stop_symb := '.'; // точка как признак конца последовательности
   bracketsDif := 0; // условно "правильное" состояние расстановки скобок
   
   Writeln('Введите последовательность: ');
   Readln(my_sequence);  // считываем последовательность введённую пользователем
   
   len := length(my_sequence); // определяем длину последовательности
   for i:=1 to len do // обходим последовательность поcимвольно
   begin
    {сначала проверим - не пора ли уже прервать цикл}
    

    if ((my_sequence[i] = stop_symb) // если встретили точку
      OR (bracketsDif < 0)) then  // или число закрывающих скобок превысило число открывающих
        break; // выходим из текущего цикла
    
    {если цикл прерывать пока рано проверим, что за очередной символ
       в последовательности мы встретили и отреагируем, если это скобка}
    
    if (my_sequence[i] = '(') then // еслли это открывающая скобка
       bracketsDif :=  bracketsDif + 1 // увеличим разницу
    else if (my_sequence[i] = ')') then // если это закрывающая скобка
       bracketsDif :=  bracketsDif - 1 // уменьшим разницу

   end; // конец цикла перебора символов последовательности
   
   if (bracketsDif = 0) then
     Writeln ('YES') // скобки в порядке
   else 
      Writeln ('NO'); // что-то не то
   
end.

Пояснения

Немного поясним ситуацию с таким вот моментом:

"если мы встретили точку или число закрывающих превысило число открывающих, то выходим из цикла"
а если число открывающих превысит (bracketsDif >0), тогда что происходит?

Дело в том, что ситуция превышения числа открывающих скобок нормальна, так как для этих скобок могут быть встречены закрывающие в ходе дальнейшего перебора символов последовательности, например, для фрагмента:

((ab+

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

((ab+в)+n)

- и тут всё ок (YES).

С другой стороны предположим, что последовательность начинается так:

)fsdg

- тут как не открывай/закрывай скобки в дальнейшем ситуацию уже не спасти, как и, например, тут:

(fdsg)g)fsdg

-- также шансов "исправить" ситуацию уже нельзя.

Таким образом если скобка закрывается, после того как все необходимые скобки итак закрыты (или скобок вообще ещё не встречалось), то мы можем говорить о том что расстановка не корректна (NO).