В тексте сканера OSS у Вирта есть, мягко говоря, не самый образцовый кусок. Вот он:
## Код:
```
PROCEDURE comment;
BEGIN R.ReadChar(ch);
  LOOP
    LOOP
      WHILE ch = "(" DO
        R.ReadChar(ch);
        IF ch = "*" THEN comment END
      END;
      IF ch = "*" THEN R.ReadChar(ch); EXIT END;
      IF R.eot THEN EXIT END;
      R.ReadChar(ch)
    END;
    IF ch = ")" THEN R.ReadChar(ch); EXIT END;
    IF R.eot THEN Mark("комментарий не завершен"); EXIT END
  END
END comment;
```
(Это вариант с CD для BB, из которого выброшен IF, увеличивающий номер строки, т. к. этого куска нет и у Вирта)
Критиковать изощренную конструкцию из LOOPов и EXITов не вижу смысла, и так все ясно. Отмечу только, что в куске теоретически возможно чтение из файла после того, как будет истинно R.eot. На практике никакой ошибки не возникает, т. к. там оказывается 0X. Но как-то это неаккуратно.
Задача переписать этот кусок "как надо" - отличный этюд для программирования. Маленький, относительно трудный (Вирт – не решил), и не надуманный, а 100% взятый из практики.

Предлагаю всем, кто считает, что может профессионально писать надежные  и понятные программы, решить этот этюд. Приверженцам идей Дейкстры - доказать делом свою приверженность. Любителям Дракона - проверить его [не]пригодность для решения этой задачи. Особенно интересными были бы результаты от любителей Дейкстры и Дракона одновременно (Илья, привет!).

Свой вариант решения прилагаю в виде архива. Он запаролен, чтобы никак не повлиять на  другие решения. Потом будет интересно их сравнить.