May 26, 2023

Пишем интерпретатор на PascalABC.NET. Лексический анализатор. Часть 4. Проверка ошибок

Данный текст - продолжение https://teletype.in/@pascalabcnet/Lex3

Программа на языке программирования может содержать так называемые лексические ошибки. Это ошибки, связанные с неправильным распознаванием лексем. Программа на языке программирования может содержать так называемые лексические ошибки. Это ошибки, связанные с неправильным распознаванием лексем. Например, в программе может быть использован символ, с которого не начинается ни одна лексема.

Как должен вести себя лексический анализатор при возникновении ошибки? Он должен возвращать место ошибки и строку, в которой произошла ошибка. Сделать это просто - бросить исключение соответствующего типа и сохранить в нем тип ошибки и ее позицию. Код, который перехватит это исключение, должен визуализировать место ошибки чтобы её было удобно исправить.

Покажем, как выглядит реакция на ошибки в нашем лексическом анализаторе.

Ошибка 1. Неизвестный символ

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

Ошибка 2. Неверный символ в середине лексемы

Эта ошибка возникает при разборе двухсимвольных лексем && и || - когда после считывания первого символа этой лексемы второй символ - неправильный.

При возникновении ошибочных ситуаций лексер кидает исключение - оно перехватывается основной программой, которая и выводит ошибку как показано на скриншотах. Центральной здесь является процедура OutputError, которая описана в модуле Common:

procedure OutputError(prefix: string; e: BaseCompilerException; 
  lines: array of string);
begin
  var line := lines[e.Pos.Line-1];
  Println(line);
  Println(' '*(e.Pos.Col-1) + '^');
  Println(prefix + ' ' + e.Pos.ToString + ': ' + e.Message);
end;

На этом мы завершаем рассмотрение лексического анализатора, построенного с нуля своими руками.