Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Pascal_Unkn.doc
Скачиваний:
8
Добавлен:
03.11.2018
Размер:
1.63 Mб
Скачать

Многосимвольные разделители

Все это хорошо для случаев, когда комментарии ограничены одиночными символами, но как быть с такими случаями как C или стандартный Pascal, где требуются два символа? Хорошо, принцип все еще тот же самый, но мы должны совсем немного изменить наш подход. Я уверен, что вы не удивитесь узнав, что это более сложный случай.

Для много символьной ситуации проще всего перехватывать левый ограничитель в GetChar.  Мы можем "токенизировать" его прямо здесь, заменяя его одиночным символом.

Давайте условимся, что мы используем ограничители C '/*' и '*/'. Сначала мы должны возвратиться к методу 'GetCharX'. В еще одной копии вашего компилятора переименуйте GetChar в GetCharX и затем введите следующую новую процедуру GetChar:

{--------------------------------------------------------------}

{ Read New Character.  Intercept '/*' }

procedure GetChar; begin    if TempChar <> ' ' then begin       Look := TempChar;       TempChar := ' ';       end    else begin       GetCharX;       if Look = '/' then begin          Read(TempChar);          if TempChar = '*' then begin             Look := '{';             TempChar := ' ';          end;       end;    end; end;

{--------------------------------------------------------------}

Как вы можете видеть эта процедура перехватывает каждое появление '/'. Затем она исследует следующий символ в потоке. Если это символ '*', то мы нашли начало комментария и GetChar возвратит его одно-символьный заменитель. (Для простоты я использую тот же самый символ '{' как я делал для Паскаля. Если бы вы писали компилятор C, вы без сомнения захотели бы использовать какой-то другой символ, не используемый где-то еще в C. Выберите что вам нравится... даже $FF, что-нибудь  уникальное).

Если символ, следующий за '/' не '*', тогда GetChar прячет его в новой глобальной переменной TempChar и возвращает '/'.

Обратите внимание, что вы должны объявить эту новую переменную и присвоить ей значение ' '. Мне нравится делать подобные вещи с использование конструкции "типизированная константа" в Turbo Pascal:

     const TempChar: char = ' ';

Теперь нам нужна новая версия SkipComment:

{--------------------------------------------------------------}

{ Skip A Comment Field }

procedure SkipComment; begin    repeat       repeat          GetCharX;       until Look = '*';       GetCharX;    until Look = '/';    GetChar; end;

{--------------------------------------------------------------}

Обратите внимание на несколько вещей: прежде всего нет необходимости изменять функцию IsWhite и процедуру SkipWhite так как GetChar возвращает токен '{'. Если вы измените этот символ токена, тогда конечно вы также должны будете изменить символ в этих двух подпрограммах.

Во-вторых, заметьте, что SkipComment вызывает в своем цикле не GetChar а GetCharX. Это означает, что завершающий '/' не перехватывается и обрабатывается SkipComment. В-третьих, хотя работу выполняет процедура GetChar, мы все же можем работать с символами комментариев, вложенными в строки в кавычках,  вызывая GetCharX  вместо GetChar  пока мы находимся внутри строки. Наконец, заметьте, что мы можем снова обеспечить вложенные комментарии добавив одиночное утверждение в SkipComment, точно также как мы делали прежде.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]