А. Григорьев - О чём не пишут в книгах по Delphi

Тут можно читать онлайн А. Григорьев - О чём не пишут в книгах по Delphi - бесплатно ознакомительный отрывок. Жанр: comp-programming, издательство БХВ-Петербург, год 2008. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    О чём не пишут в книгах по Delphi
  • Автор:
  • Жанр:
  • Издательство:
    БХВ-Петербург
  • Год:
    2008
  • Город:
    СПб
  • ISBN:
    978-5-9775-019003
  • Рейтинг:
    4.25/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

А. Григорьев - О чём не пишут в книгах по Delphi краткое содержание

О чём не пишут в книгах по Delphi - описание и краткое содержание, автор А. Григорьев, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Рассмотрены малоосвещённые вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные механизмы их работы, особенности для протоколов TCP и UDP и др. Большое внимание уделено разбору ситуаций возникновения ошибок и получения неверных результатов в "простом и правильном" коде. Отдельно рассмотрены особенности работы с целыми, вещественными и строковыми типами данных, а также приведены примеры неверных результатов, связанных с ошибками компилятора, VCL и др. Для каждой из таких ситуаций предложены методы решения проблемы. Подробно рассмотрен синтаксический анализ в Delphi на примере арифметических выражений. Многочисленные примеры составлены с учётом различных версий: от Delphi 3 до Delphi 2007. Прилагаемый компакт-диск содержит примеры из книги.

Для программистов

О чём не пишут в книгах по Delphi - читать онлайн бесплатно ознакомительный отрывок

О чём не пишут в книгах по Delphi - читать книгу онлайн бесплатно (ознакомительный отрывок), автор А. Григорьев
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Сама по себе задача преобразования строки в вещественное число достаточно сложна, и чтобы не отвлекаться на ее решение, мы воспользуемся функцией StrToFloatиз модуля SysUtils. Когда функция Numberвыделит из строки последовательность символов, являющуюся числом, эта последовательность передается функции StrToFloat, и преобразованием занимается она. Здесь следует учесть два момента. Во-первых, в нашей грамматике разделителем целой и дробной части является точка, a StrToFloatиспользует системные настройки, т.е. разделителем может быть и запятая. Чтобы обойти эту проблему, слегка изменим синтаксис и будем сравнивать аргумент функции IsSeparatorне с символом ".", а с DecimalSeparator(таким образом, наш калькулятор тоже станет чувствителен к системным настройкам). Во-вторых, не всякое выражение, соответствующее нашей грамматике, будет допустимым числом с точки зрения StrToFloat, т.к. эта функция учитывает диапазон типа Extended. Например, синтаксически верное выражение "2е5000" даст исключение EConvertError, т.к. данное число выходит за пределы этого диапазона. Но пока мы остаемся в рамках типа Extended, мы вынуждены мириться с этим.

Новые функции приведены в листинге 4.3.

Листинг 4.3. Реализация простейшего калькулятора

// Выделение из строки подстроки, соответствующей

// определению , и вычисление этого числа

// S — строка, из которой выделяется подстрока

// Р — номер позиции в строке, с которой должно

// начинаться число. После завершения работы функции

// этот параметр содержит номер первого после числа

function Number(const S: string; var P: Integer): Extended;

var

InitPos: Integer;

begin

// InitPos нам понадобится для выделения подстроки,

// которая будет передана в StrToFloat

InitPos := Р;

if (Р <= Length(S)) and IsSign(S[P]) then Inc(P);

if (P > Length(S)) or not IsDigit(S[P]) then

raise ESyntaxError.Create(

'Ожидается цифра в позиции ' + IntToStr(Р));

repeat

Inc(P);

until (P > Length(S)) or not IsDigit(S[P]);

if (P <= Length(S)) and IsSeparator(S[P]) then begin

Inc(P);

if (P > Length(S)) or not IsDigit(S[P]) then

raise ESyntaxError.Create(

'Ожидается цифра в позиции ' + IntToStr(Р));

repeat

Inc(P);

until (P > Length(S)) or not IsDigit(S[P]);

end;

if (P <= Length(S)) and IsExponent(S[P]) then

begin

Inc(P);

if Р > Length(S) then

raise ESyntaxError.Create('Неожиданный конец строки');

if IsSign(S[P]) then Inc(P);

if (P > Length(S)) or not IsDigit(S[P]) then

raise ESyntaxError.Create(

'Ожидается цифра в позиции ' + IntToStr(Р));

repeat

Inc(P);

until (P > Length(S)) or not IsDigit(S[P]);

end;

Result := StrToFloat(Copy(S, InitPos, P - InitPos));

end;

// Проверка символа на соответствие

function IsOperator(Ch: Char): Boolean;

begin

Result := Ch in ['+', '-', '*', '/'];

end;

// Проверка строки на соответствие

// и вычисление выражения

function Expr(const S: string): Extended;

var

P: Integer;

OpSymb: Char;

begin

P := 1;

Result := Number(S, P);

while (P <= Length(S)) and IsOperator(S[P]) do

begin

OpSymb := S[P];

Inc(P);

case OpSymb of

'+': Result := Result + Number(S, P);

'-': Result := Result - Number(S, P);

'*': Result := Result * Number(S, P);

'/': Result := Result / Number(S, P);

end;

end;

if P <= Length(S) then

raise ESyntaxError.Create(

'Heкорректный символ в позиции ' + IntToStr(Р));

end;

Код приведен практически без комментариев, т.к. он очень простой, и все моменты, заслуживающие упоминания, мы уже разобрали в тексте. На прилагаемом компакт-диске находится программа SimpleCalcSample, которая демонстрирует работу нашего калькулятора. Калькулятор выполняет действия над числами слева направо, без учета приоритета операций, т.е. вычисление выражения "2+2*2" даст 8.

Грамматика выражения является простой для разбора, т.к. разбор выражения идет слева направо, и для соотнесения очередной части строки с тем или иным нетерминальным символом на любом этапе анализа достаточно знать только следующий символ. Такие грамматики называются LR(1)-грамматиками (в более общем случае требуется не один символ, а одна лексема). Класс этих грамматик был исследован Кнутом.

Грамматика Паскаля не относится к классу LR(1)-грамматик из-за уже упоминавшейся проблемы отнесения elseк тому или иному if. Чтобы решить эту проблему, приходится вводить два нетерминальных символа — завершенной формы оператора ifelse) и незавершенной (без else). Таким образом, встретив в тексте программы лексему if, синтаксический анализатор не может сразу отнести ее к одному из этих символов, пока не продвинется вперед и не натолкнется на наличие или отсутствие else. А поскольку оператор ifможет быть оператором в циклах for, whileили в операторе with, для них также приходится вводить завершенную и незавершенную форму. Именно из-за этой проблемы Вирт (разработчик Паскаля) отказался от идеи составного оператора и модифицировал синтаксис в своем новом языке Оберон таким образом, чтобы проблема elseне возникала.

Другое достоинство нашей простой грамматики — ее однозначность. Любая синтаксически верная строка не допускает неоднозначной трактовки. Неоднозначность могла бы возникнуть, например), если бы какая-то операция обозначалась символом "." (точка). Тогда было бы непонятно, должно ли выражение "1.5" трактоваться как число "одна целая пять десятых" или как выполнение операции над числами 1 и 5. Этот пример выглядит несколько надуманным, но неоднозначные грамматики, тем не менее, иногда встречаются на практике. Например, если запятая служит для отделения дробной части числа от целой и для разделения значений в списке параметров функций, то выражение f(1,5)может, с одной стороны, трактоваться как вызов функции fс одним аргументом 1.5, а с другой — как вызов ее с двумя аргументами 1 и 5. Правила решения неоднозначных ситуаций не описываются в виде БНФ, их приходится объяснять "на словах", что затрудняет разбор соответствующих выражений. Другой пример неоднозначной грамматики — грамматика языков C/C++. В них оператор инкремента, записывающийся как "++",имеет две формы записи — префиксную (перед увеличиваемой переменной) и постфиксную (после переменной). Кроме того, этот оператор возвращает значение, поэтому его можно использовать в выражениях. Синтаксически допустимо, например, выражение а+++b, но грамматика не дает ответа, следует ли это трактовать как (а++)+bили как а+(++b). Кроме того, т.к. существует операция "унарный плюс", возможно и третье толкование — а+(+(+b)).

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


А. Григорьев читать все книги автора по порядку

А. Григорьев - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




О чём не пишут в книгах по Delphi отзывы


Отзывы читателей о книге О чём не пишут в книгах по Delphi, автор: А. Григорьев. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x