Новости           

Программы

Turbo Pascal

Игры

Документация

"Странности"

FAQ

Ссылки

Благодарности

Гостевая книга

От автора

Разбор выражения 

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

                              А*В-(w+10)

         вы должны быть способны выделить операнды A,B,W и  10,  скобки  и
         операторы *,  + и -. В данном случае вам нужна процедура, которая
         возвращает каждый элемент выражения в отдельности.  Данная проце-
         дура  также  должна пропускать пробелы и табуляции и обнаруживать
         конец выражения.  Формально каждый элемент  выражения  называется
         лексемой (lcken). Следовательно, функция, которая возвращает оче-
         редную лексему выражения, называется CetToken. Для хранения выра-
         жения  нужна глобальная переменная.  Данная символьная переменная
         называется prog. Переменная prog является глобальной, так как она
         должна устанавливаться между вызовами CetToken и должна позволять
         другим функциям использовать ее. В дополнении к prog используется
         глобальная целая переменная t в качестве индекса по prog,  позво-
         ляя CetToken продвигаться по выражению по одной лексеме  за  раз.
         CetToken  предполагает,  что  prog  заканчивается символом $.  Вы
         должны убедиться и в данном случае,  что это так в виду того, что
         символ $ сигнализирует о конце выражения.
              Помимо получения  лексемы вам необходимо также знать ее тип.
         Для синтаксического разбора,  рассматриваемого  в  данной  главе,
         достаточно  трех  типов:  VARIABLE  (переменная),NUMDER (число) и
         DELIMITER (разделитель),  где тип DELIMITER используется для опе-
         раторов и скобок.  Далее показана функция CetToken с необходимыми
         глобальными переменными и функциями поддержки:

             type
               str80 = string[80];
               TType = (DELIMITER,VARIABLE,NUMBER);
             var
               token, prog: str80;
               TokType: TType;
               code, t: integer;
               result: real;

             {данная функция возвращает TRUE,  если ch является буквой
                                  алфавита}
             function IsAlpha(ch: char): boolean;
             begin
               IsAlpha:= (UpCase(ch)>='A') and (UpCase(ch)<='Z');
             end; {IsAlpha}
             {данная  функция возвращает TRUE,  если ch является
              символом новой строки,  табуляции или пробелом       }
             function IsWhite(ch: char): boolean;
             begin
               IsWhite: = (ch=' ') or (ch=chr(9)) or (ch=chr(13));
             end; {IsWhite}

             {данная функция возвращает TRUE,  если ch является
                                разделителем}

             function IsDelim(ch: char): boolean;
             begin
               if pos(ch, ' +-/*%^=()S')<>0 then IsDelim: = TRUE
             end; {IsDelim}

             {данная функция возвращает TRUE, если ch - цифра от 0 до 9}
             function IsDigit(ch: char): boolean;
             begin
               IsDigit: = (ch>='0') and (ch<='9');
             end; {IsDigit}

             {GotToken  считывает следующую лексему из входного потока}
             procedure GetToken;
             var
               temp: str80;

             begin
               token: = ''; {пустая строка }
               while(IsWhite(prog[t])) do t:=t+1; {пропустить
                            предшествующие пробелы}

               if prog[t]='S' then token: = 'S';
               if pos(prog[t], '+-*/%^=()')<>0 then
               begin
                TokType: = DELIMITER;
                token: = prog[t]; {является оператором }
                t: = t+1;
               end else if IsAlpha(prog[t]) then
               begin
                While(not IsDelim(prog[t])) do
                begin
                  token: = concat(token, prog[t]); { построить лексемы }
                  t: = t+1;
                end;
                TokType: = VARIABLE;
               end
               else if IsDigit(prog[t]) then
               begin
                while(not IsDelim[t])) do
                begin
                  token: = concat(token,prog[t]); { построить число }
                  t: = t+1;
                  TokType: = NUMBER;
                end;
               end;
            end;{GetToken}

              Прежде, чем данная процедура может быть  использована,  гло-
         бальная  переменная t должна быть установлена в 1.  Помните,  что
         эта переменная используется для индексирования  по  строке  prog,
         которая содержит входное выражение. При входе в CetToken процеду-
         ра проверяет,  не равен ли очередной символ $,  который указывает
         на конец строки выражения. Предваряющие пробелы пропускаются. Хо-
         тя пробелы могут быть добавлены в  выражение  для  читабельности,
         при синтаксическом разборе они игнорируются.
              После пропуска пробелов prog(t) указывает на число, перемен-
         ную,  оператор или $, если хвостовые пробелы завершают выражение.
         Если следующий символ является оператором, то этот символ возвра-
         щается  как  строка в глобальной переменной token и тип DELIMITER
         помещается в TokType. Если этот следующий символ является буквой,
         то считается, что это переменная; символ возвращается, как строка
         в token; TokType принимает значение VARIABLE. Если следующий сим-
         вол  является  числом,  то  целое число возвращается как строка в
         token с типом NUMBER. Наконец, если следующий символ отсутствует,
         вы можете считать, что это найден конец выражения, и token прини-
         мает значение $.
              Чтобы сохранить  логическую ясность данной функции,  опреде-
         ленное количество проверок на ошибки опущено и сделан ряд допуще-
         ний. Например, некоторые неопознанные символы отбрасываются. Кро-
         ме того,  в данной версии переменные могут быть любой  длины,  но
         первым символом должна быть буква.  Однако, вы легко можете моди-
         фицировать CelToken, чтобы допустить применение символьных строк,
         чисел с плавающей запятой или чего-либо еще.
              Для того,  чтобы понять,  как работает CetToken, рассмотрим,
         что она возвращает на каждом шаге для выражения А+100-(В*С)/2.

             Лексема  Тип лексемы

               A      VARIABLE  переменная
               +      DELIMITER ограничитель
              100     NUMBER    число
               -      DELIMITER ограничитель
               (      DELIMITER ограничитель
               B      VARIABLE  переменная
               *      DELIMITER ограничитель
               C      VARIABLE  переменная

               )      DELIMITER ограничитель
               /      DELIMITER ограничитель
               2      NUMBER    число
               $      $

(с)Все права защищены

По всем интересующим вопросампрошу писать на электронный адрес

    Rambler's Top100 PROext: Top 1000
    Rambler's Top100 Яндекс цитирования
Hosted by uCoz