Как быстро восстановить потерянные компьютерные данные. Подробное руководство по спасению информации Современный человек уже не может представить свою жизнь без компьютера. С каждым днем растет количество информации, которую мы доверяем своему электронному другу. Однако не стоит забывать, что никто не может стопроцентно гарантировать сохранность имеющихся в компьютере данных. Причин, по которым они могут быть утеряны или испорчены, существует великое множество: беспечность и ошибочные действия пользователей, аппаратные сбои, внезапное отключение электричества, деятельность вредоносных программ, нестабильная работа операционной системы, и т. д. После утраты данных многие впадают в отчаяние, полагая, что восстановить их нереально. Однако это далеко не так, более того – как показывает практика, в большинстве случаев восстановить потерянную информацию можно. Самое главное – не паниковать: одной из наиболее распространенных ошибок является то, что пользователи, обнаружив потерю или порчу данных, начинают совершать массу необдуманных действий, лишь усугубляя тем самым и без того непростую ситуацию. |
Книга предназначена для читателей, знакомых с понятием финансовых рынков, практикующих трейдеров, индивидуальных инвесторов и управляющих инвестиционными портфелями. Она является, по сути, конспективным изложением 12 книг в одной. 12 известных мастеров-практиков написали по одной главе в этот сборник с целью дать представление читателю о своих методах и техниках работы на финансовых рынках, а именно, на рынках акций, валют (FOREX), облигаций, опционов и фьючерсов. Оценив изюминку метода и возможные граничные условия, читатель может перейти к углубленному изучению работ конкретного автора. Из участников сборника, в русском переводе есть только четыре автора. Работы других, несмотря на их известность в США, практически неизвестны российскому читателю, хотя их методики поистине уникальны, а иногда и революционны. В книге приведено множество реальных примеров, позволяющих оценить эффективность предлагаемых подходов. Для финансистов, инвестиционных стратегов, технических аналитиков рынка, а также индивидуальных инвесторов, самостоятельно выходящих на финансовые рынки мира и России, чтение этой книги будет чрезвычайно полезным, а может быть и просто необходимым. |
ВВЕДЕНИЕ Эта глава - второе из тех отклонений
в сторону, которые не вписываются в основное направление этой обучающей
серии. Я упомянул в прошлый раз, что я накопил некоторые изменения, которые
должны быть внесены в структуру компилятора. Поэтому я должен был отклониться
чтобы разработать новую структуру и показать ее вам.
ТОЧКИ С ЗАПЯТОЙ Со времен появления Алгола точки
с запятой были частью почти каждого современного языка. Все мы использовали
их считая это само собой разумеющимся. Однако я полагаю, что больше ошибок
компиляции происходило из-за неправильно размещенной или отсутствующей
точки с запятой, чем в любом другом случае. И если бы мы получали один
пенни за каждое дополнительное нажатие клавиши, использованное программистами
для набора этих маленьких мошенников, мы смогли бы оплатить национальный
долг.
a=b; c=d; e=e+1; В случаях подобных этому, точка с запятой почти обязательна. Та же самая строка без точек с запятой выглядит просто "странной": a=b c= d e=e+1 Я полагаю, что это главная...
возможно единственная... причина точек с запятой: не давать программам
выглядеть странно.
СИНТАКСИЧЕСКИЙ САХАР Вся эта дисскуссия поднимает
вопрос "синтаксического сахара"... конструкций, которые добавлены к языку
не потому, что они нужны, но потому, что они заставляют программы выглядеть
правильно для программиста. В конце концов, хорошо иметь маленький простой
компилятор, но от него было бы мало пользы если бы полученный язык был
закодированным или сложным для программирования. На ум приходит язык FORTH.
Если мы можем добавить в язык возможности, которые делают программы более
легкими для чтения и понимания, и если эти возможности предохраняют программиста
от ошибок, тогда мы бы сделали это. Особенно если эти конструкции не добавляют
слишком много сложности в язык или его компилятор.
a=1+(2*b+c) b... Так как нет никакого оператора, соединяющего токен 'b' с остальной частью выражения, компилятор заключит, что выражение заканчивается на ')' а 'b' - это начало нового утверждения. Но предположим, что я просто пропустил предполагаемый оператор и в действительности хотел сказать: a=1+(2*b+c)*b... В этом случае компилятор выдаст
ошибку, хорошо, но она не будет очень осмысленной, так как он будет ожидать
знак '=' после 'b', который в действительности не должен быть там.
РАБОТА С ТОЧКАМИ С ЗАПЯТОЙ Есть два различных способа работы с точками с запятой используемые в популярных языках. В Паскале точка с запятой расценивается как разделитель операторов. Точка с запятой не требуется после последнего утверждения в блоке. Синтаксис: <block> ::= <statement> ( ';' <statement>)* <statement> ::= <assignment> | <if> | <while> ... | null (пустое утверждение важно!)
<block> ::= ( <statement> ';')* Из двух синтаксисов, синтаксис
Паскаля внешне выглядит более рациональным, но опыт показал, что он ведет
к некоторым странным трудностям. Люди так привыкают ставить точку с запятой
после каждого утверждения, что они также предпочитают ставить ее и после
последнего утверждения в блоке. Это обычно не приносит какого-либо вреда...
она просто обрабатывается как пустое утверждение. Многие программисты на
Паскале, включая вашего покорного слугу, делают точно также. Но есть
одно место, в котором вы абсолютно не можете поставить точку с запятой
- прямо перед ELSE. Это маленький подводный камень стоил мне множества
дополнительных компиляций, особенно когда ELSE добавляется к существующему
коду. Так что выбор C/Ada оказывается лучше. Очевидно, Никлаус Вирт думает
также: в его Modula-2 он отказался от Паскалевского подхода.
{--------------------------------------------------------------}
procedure Semi;
Эта процедура очень похожа на
наш старый Match. Она требует чтобы следующим токеном была точка с запятой.
Найдя его, она переходит к следующему.
{--------------------------------------------------------------}
procedure Block;
Внимательно взгляните на тонкие
изменения в операторе case. Вызов Assigment теперь ограничивается проверкой
Token. Это позволит избежать вызова Assigment когда токен является точкой
с запятой (что случается когда утверждение пустое).
{--------------------------------------------------------------}
procedure TopDecls;
Наконец нам нужен вызов для утверждения PROGRAM: {--------------------------------------------------------------}
begin
Проще некуда. Испробуйте это
с копией TINY и скажите как вам это нравится.
{--------------------------------------------------------------}
procedure Statement;
Используя эту процедуру мы можем переписать Block так: {--------------------------------------------------------------}
procedure Block;
Это, уверен, не повредило, не так ли? Теперь мы можем анализировать точки с запятой в Паскаль-подобном стиле. КОМПРОМИСС Теперь, когда мы знаем как работать
с точками с запятой, означает ли это, что я собираюсь поместить их в KISS/TINY?
И да и нет. Мне нравится дополнительный сахар и защита, которые приходят
с уверенным знанием, где заканчиваются утверждения. Но я не изменил своей
антипатии к ошибкам компиляции, связанным с точками с запятой.
{--------------------------------------------------------------}
procedure Semi;
Эта процедура будет принимать
точку с запятой всякий раз, когда вызвана, но не будет настаивать на ней.
Это означает, что когда вы решите использовать точки с запятой, компилятор
будет использовать дополнительную информацию чтобы удержаться на правильном
пути. Но если вы пропустите одну (или пропустите их всех) компилятор не
будет жаловаться. Лучший из обоих миров.
КОММЕНТАРИИ Вплоть до этого времени я тщательно
избегал темы комментариев. Вы могли бы подумать, что это будет простая
тема... в конце концов компилятор совсем не должен иметь дела с комментариями;
он просто должен игнорировать их. Чтож, иногда это так.
ОДНОСИМВОЛЬНЫЕ РАЗДЕЛИТЕЛИ Вот пример. Предположим, мы принимаем
стандарт Turbo Pascal и используем для комментариев фигурные скобки. В
этом случае мы используем односимвольные разделители, так что наш анализ
немного проще.
{--------------------------------------------------------------}
procedure SkipComment;
Ясно, что эта процедура будет
просто считывать и отбрасывать символы из входного потока, пока не найдет
правую фигурную скобку. Затем она считывает еще один символ и возвращает
его в Look.
{--------------------------------------------------------------}
procedure GetChar;
Наберите этот код и испытайте
его. Вы обнаружите, что вы действительно можете вставлять комментарии везде,
где захотите. Комментарии никогда даже не попадут в синтаксический анализатор...
каждый вызов GetChar просто возвращает любой символ, не являющийся частью
комментария.
{--------------------------------------------------------------}
function IsWhite(c: char): boolean;
Теперь мы можем работать с комментариями в процедуре SkipWhite: {--------------------------------------------------------------}
procedure SkipWhite;
Обратите внимание, что SkipWhite
написан так, что мы пропустим любую комбинацию незаполненного пространства
и комментариев в одном вызове.
{--------------------------------------------------------------}
procedure SkipComment;
Готово. Настолько утонченный обработчик комментариев, какой вам когда-либо может понадобиться. МНОГОСИМВОЛЬНЫЕ РАЗДЕЛИТЕЛИ Все это хорошо для случаев, когда
комментарии ограничены одиночными символами, но как быть с такими случаями
как C или стандартный Pascal, где требуются два символа? Хорошо, принцип
все еще тот же самый, но мы должны совсем немного изменить наш подход.
Я уверен, что вы не удивитесь узнав, что это более сложный случай.
{--------------------------------------------------------------}
procedure GetChar;
Как вы можете видеть эта процедура
перехватывает каждое появление '/'. Затем она исследует следующий символ
в потоке. Если это символ '*', то мы нашли начало комментария и GetChar
возвратит его односимвольный заменитель. (Для простоты я использую тот
же самый символ '{' как я делал для Паскаля. Если бы вы писали компилятор
C, вы без сомнения захотели бы использовать какой-то другой символ, не
используемый где-то еще в C. Выберите что вам нравится... даже $FF, что-нибудь
уникальное).
const TempChar: char = ' '; Теперь нам нужна новая версия SkipComment: {--------------------------------------------------------------}
procedure SkipComment;
Обратите внимание на несколько
вещей: прежде всего нет необходимости изменять функцию IsWhite и процедуру
SkipWhite так как GetChar возвращает токен '{'. Если вы измените этот символ
токена, тогда конечно вы также должны будете изменить символ в этих двух
подпрограммах.
ОДНОСТОРОННИЕ КОММЕНТАРИИ Пока что я показал вам как работать с любыми видами комментариев, ограниченных слева и справа. Остались только односторонние комментарии подобные используемым в ассемблере или Ada, которые завершаются концом строки. На практике этот способ проще. Единственная процедура, которая должна быть изменена - SkipComment, которая должна теперь завершаться на символе переноса строки: {--------------------------------------------------------------}
procedure SkipComment;
Если ведущий символ - одиночный, как ";" в ассемблере, тогда мы по существу все сделали. Если это двухсимвольный токен, как "--" из Ada, нам необходимо только изменить проверки в GetChar. В любом случае это более легкая проблема чем двухсторонние комментарии. ЗАКЛЮЧЕНИЕ К этому моменту у нас есть возможность
работать и с комментариями и точками с запятой, так же как и с другими
видами синтаксического сахара. Я показал вам несколько способов работы
с каждым из них, в зависимости от желаемых соглашений. Остался единственный
вопрос - какие из этих соглашений мы должны использовать в KISS/TINY?
|