Interpreter języka Pascal w Delphi

Artur

Witam

Artykuł ten zostal napisany przez zespół w składzie:

Artur Mościcki</li> Kamil Mościcki</li> Igor Kruk</li> Adam Miler</li> </ul>

Ze względu na ograniczenia 4programmers kody źródłowe i exeka można ściagnąć z http://sourceforge.net/projects/iaa-pascal/

Nie będę tu tłumaczył każdej linii kodu - bo jest tego ze 4000 :)

Program rozbija wpisany tekst na leksemy, sprawdza poprawność i wykonuje. Wszelkie błędy są zgłaszane

Zakres funkcjonalny:

  • deklaracja zmiennych globalnych
  • mozliwe typy zmiennych: integer, double
  • operacje wejscia | wyjscia (read | readln, write | writeln)
  • operacje arytmetyczne: dodawanie, odejmowanie, mnozenie, dzielenie, potegowanie
  • operacja przypisania :=
  • operacje porownania < | > | = | <> | <= | >=
  • nawiasy ( )
  • komentarz { }
  • separatory ; | .
  • operacje warunkowe if ... then
  • mozna zagniezdzac instrukcje if ... then
  • petla for ... to ... do
  • mozna uzywac petli zagniezdzonych
  • poczatek/koniec bloku begin | end
  • mozna wykonywac dowolne wyrazenia arytmetyczne z nawiasami
  • w operacjach arytmetycznych mozna uzywac nastepujacych funkcji matematycznych: sin, cos, tan cotan, arcsin,
    arccos, arctan, ln, exp, sqrt
  • mozna stosowac wciecia
  • nie wazna jest liczba bialych znakow oddzielajacych poszczegolne slowa/wyrazenia
  • moze wystepowac kilka instrukcji w jednej linii
  • read | readln | write | writeln realizuje pojedyncza operacjewejscia/wyjscia ? nie mozna uzywac operatorow konkatenacji wewnatrz operacji wejscia/wyjscia
  • nie mozna uzywac operatorow logicznych AND, OR, NOT
  • w instrukcji if ... then nie moze byc nawiasow i warunkow zlozonych
  • miedzy slowami kluczowymi for i to, oraz to i do nie moze byc zlozonych przypisan
  • nie mozna stosowac zmiennych sterujacych petla po lewej stronie znaku przypisania wewnatrz bloku wykonywalnego petli

15 komentarzy

Adam.Pilorz: Wiesz w której linii ma pokazać błąd to jest kwestia umowy - ja miałem ochotę by pokazywał w 11 - nio ale gdzieś zrobiłem (+1) za dużo:). Pewnie, że w Pasclau lub w Delphi nie musi być średnika przez end. Nio ale my założylismy że u nas musi być:) - bo inaczej pokazuje błąd :)

Artur: Ale przecież Turbo Pascal albo Delphi w owym przykładzie również pokazałby błąd w 12 linijce, tylko trochę inaczej by go nazwał. Bo dopiero tam jest błąd (rozpoczęcie nowej instrukcji). Nie każda instrukcja musi mieć średnik na końcu, bo jest to separator instrukcji, nie jej zakończenie. Na przykład jak masz begin i:=1 end; to przed end wcale nie musi być średnika. No ale to takie OT trochę :)

migajek - drobne niedociągnięie zapomniałem w programie zrobić -1 i dlatego wyszło że to jest linia 12 - ale ogólnie pokazuje dobrze w której linii jest błąd - jak widać nie wszystkie możliwości zostały sprawdzone :) - zachęcam do testowania

Deti - sorki myslałem że DetoX to ktoś inny - w każdym razie dzięki za kod - ułatwiło mi to tworzenia działań matematycznych

No bo przeca tam pokazują, jak wyświetlane są błędy :)

Ladne, ladne :) Tylko IMO srednika brakuje w lini 11 w przykladzie z rysunku 1 ;)
Deti/Artur : jaki kod? :P

Tak.. to ja się podpisałem ;)

Chcieć to nam się nie chciało :) po prostu musieliśmy to napisać, natomiast jeśli chodzi o ten kod, który Deti pokazałeś to ja nie mam innego pomysłu na takie coś - otóż jeśli którakolwiek z funkcji zmieni ok na false to oznacza to ze wystąpił jakiś błąd składniowy i reszta funkcji nie jest wykonywana - ale fakt dałoby się dużo ładniej to napisać - ale nie było już czasu :) trzeba było zaliczyć semestr :) Deti dzięki za umieszczenie kodu na 4programmers (bo chyba nie jest to Twój kod - bo ktoś sie podpisał w module)

Z zewnatrz rzeczywiscie ladne, ale w srodku wyglada dosyc srednio, "szacuneczek" jedynie za to, ze chcialo sie wam tyle pisac, kiedys bawilem sie w podobna rzecz, tyle, ze nie byl to interpretator a kompilator (w sumie niewielka roznica): http://4programmers.net/file.php?id=1881, tyle, ze poszedlem troche na latwizne i skorzystalem z regexp.

ładnie, ładnie .. chociaż wnętrze kodu pozostawia wiele do zyczenia .. oto fragment:

  if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_program;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_poczatek_programu;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_var;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_deklaracje_zmiennych;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_begin_i_end;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_sredniki_po_end;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).deklaruj_zmienne;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_ilosc_begin_i_end;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_if;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_ilosc_if_then;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_petle;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_ilosc_for_to;
    if (Form2.MDIChildren[0] as TForm1).ok=true then
       (Form2.MDIChildren[0] as TForm1).sprawdz_ilosc_for_do;

I BTW: fajnie, że ktoś wykorzystał mój kodzik :]]

Ogólnie, to zamiast pisać, że wolno, że mało wydajnie to bym raczej napisał: szacuneczek... no ale cóż...

Wiem, że wydajność nie jest najlepsza, to jest tylko przykład interpretera - wiele kwestii można by było zrobić inaczej - ale grunt, że działa:) i że można sobie pooglądać kod źródlowy i samemu cos na tej podstwie pokombinować:)

1 sekunda na taki program:

program licz;

var
  a, i, czas: integer;
begin
  a := 0;
  for i := 1 to 20 do
    a := a+1;

  writeln(a);
end.

Naprawde niezle ;P

Niezle, jeszcze tylko sprawdze wydajnosc, ale widze ze na matme bedzei w sam raz :D