algorytm.org

Implementacja w Ada

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Odwrotna Notacja Polska - Implementacja w Ada
Ocena użytkownikóww: *****  / 2
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 26 lipca 2005 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

ONP.adb:
--
-- Odwrotna Notacja Polska
-- www.algorytm.org (c) 2006
-- Tomasz Lubiński
--
--

with Text_IO;
use Text_IO;

procedure ONP is

   Stack_pointer: Integer range 0..1000 := 0;
   Stack: array (1 .. 1000) of Character;
   
   procedure concat(dst : in out String; src : in String; ptr : in out Integer) is
   begin
      for i in src'Range loop
        ptr := ptr + 1;
        dst(ptr) := src(i);
      end loop;
   end;
   
   -- returns true if stack is empty, false otherwise
   function stackIsEmpty return boolean is
   begin
      return (Stack_pointer = 0);
   end;
   
   -- gets character from stack
   function stackPop return character is
   begin
      if Stack_pointer > 0 then
         Stack_pointer := Stack_pointer - 1;
         return Stack(Stack_pointer + 1);
      end if;
      return ' ';
   end;
   
   -- pushes character on stack
   procedure stackPush(c: Character) is
   begin
      Stack_pointer := Stack_pointer + 1;
      Stack(Stack_pointer) := c;
   end;   

   -- gets all operators until bracket from stack
   function getFromStackUntilBracket return String is
      result : String(1..1000);
      ptr    : Integer := 0;
      c      : Character;
   begin
      if not stackIsEmpty then
         c := stackPop;
         ptr :=  ptr + 1;
         result(ptr) := ' ';
         while c /= '(' loop
            ptr := ptr + 1;
            result(ptr) := ' ';
            ptr := ptr + 1;
            result(ptr) := c;
            if stackIsEmpty then
               exit;
            end if;
            c := stackPop;
          end loop;
      end if;
      return result(1..ptr);
   end;

   -- gets all operators with priority less or equal to oeprator from stack
   function getFromStack(operator: Character) return String is
      result : String(1..1000);
      ptr    : Integer := 0;
      c      : Character;
   begin
      if not stackIsEmpty then
         c := stackPop;
         while (((operator = '+' or operator = '-') and c /= '(') or
                ((operator = '/' or operator = '*') and (c = '/' or c = '*'))) loop
            ptr := ptr + 1;
            result(ptr) := ' ';
            ptr := ptr + 1;
            result(ptr) := c;
            if stackIsEmpty then
               exit;
            end if;
            c := stackPop;
         end loop;
         stackPush(c);
      end if;
     
      stackPush(operator);
      return result(1..ptr);
   end;

   -- gets all from stack
   function getAllFromStack return String is
      result : String(1..1000);
      ptr    : Integer := 0;
      c      : Character;
   begin   
      while not stackIsEmpty loop
         c := stackPop;
         ptr := ptr + 1;
         result(ptr) := ' ';
         ptr := ptr + 1;
         result(ptr) := c;
      end loop;
      return result(1..ptr);
   end;


   statement: String := "(2+4)*3";
   sign     : boolean := true; --indicates that - is a number sign (not operator minus)
   result   : String (1..1000);
   ptr      : Integer := 0;
   
begin

   -- process all characters
   for i in statement'range loop
      if statement(i) = '(' then
         stackPush('(');
         sign := true;
         concat(result, " ", ptr);                               
      elsif statement(i) = ')' then
         concat(result, " " & getFromStackUntilBracket, ptr);
         sign := false;
      elsif (statement(i) = '+' or
             statement(i) = '-' or
             statement(i) = '*' or
             statement(i) = '/') and (sign = false) then
         concat(result, " " & getFromStack(statement(i)), ptr);             
         sign := true;
      else
         if sign and then
            statement(i) = '-' then
         concat(result, " ", ptr);                               
         end if;
         concat(result, ""&statement(i), ptr);                      
         sign := false;
      end if;
   end loop;
   
   concat(result, getAllFromStack, ptr);                               
   Put_Line(statement & " ONP: " & result(1..ptr));
 
end;
Dodaj komentarz