mrbounce Opublikowano 22 Maja 2004 Zgłoś Opublikowano 22 Maja 2004 witam szukam programu w c/c++ (kod) realizujacego odwrotna notacje polska ze stosem - potrzebuje to do "pisanego przeze mnie" kompilatora (flex, bison, itd.) - mam taki przedmiot :?, a ze wzgledu brak czasu i kilka innych powodow ;), zwracam sie do forumowiczow. wszystkie inne dodatki, materialy zwiazane z pisaniem wlasnego kompilatora, beda mile widziane :) . za wszelka pomoc z gory dziekuje. pozdrawiam Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
bartolomeo_1 Opublikowano 22 Maja 2004 Zgłoś Opublikowano 22 Maja 2004 prezenetacja odwrotnej notacji polskiej ze stosem, na przykładzie kalkulatora. mam nadzieję, że pomoże. kod znalazłem kiedyś w internecie, nie był podpisany, więc jak go ktoś pozna, to prosze nie pisać mi maili, że pogwałciłem jego prawa autorskie ;) /* Program Kalkulator */#include <conio.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <stdlib.h>/* priorytety operator˘w i nawiasu */char priorytety [5] = "(+*/-";/* elementy stosu */struct stos{ char info [20]; /* 20 - maksymalna dugo† zapami©tywanej informacji */ struct stos *nast; /* wska«nik do nastepnego elementu */};/* usuwanie elementu ze stosu *//* zwracany jest adres poczĄtku stosu */struct stos *usun_element (struct stos *st){ if (st != NULL) { struct stos *tmpst = st -> nast; /* zapami©tanie wska«nika */ /* do nast©pnego elementu */ free (st); /* zwolnienie pami©ci */ return tmpst; /* przepisanie wska«nika */ } else return NULL;}/* podanie zawartoci pola "info" g˘rnego elementu stosu */char *podaj_element (struct stos *st){ if (st != NULL) return st -> info; else return "";}/* wstawienie elementu na stos *//* zwracany jest adres poczĄtku stosu */struct stos *wstaw_element (struct stos *st,char *str){ struct stos *tmpst = malloc (sizeof (struct stos)); /* allokacja pami©ci */ strcpy (tmpst -> info,str); /* kopiowanie pola "info" */ tmpst -> nast = st; /* wstawienie */ return tmpst; /* na stos */}/* sprawdzanie priotytet˘w operator˘w */int sprawdz_priorytet (char op,struct stos *st){ int pr_o = 0, pr_st = 0; /* przypadek gdy stos jest pusty */ if (st == NULL) return 1; /* wyznaczenie priorytetu operatora op */ while (priorytety [pr_o] != op) pr_o++; /* wyznaczenie priorytetu operatora na wierzchoku stosu */ while (priorytety [pr_st] != st -> info [0]) pr_st++; return pr_o >= pr_st;}/* wywietlenie komunikatu o b©dzie */void blad (int nr,int pozycja){ printf ("BĄd w pozycji:%in",pozycja); switch (nr) { case 0: printf ("BĄd podczas analizy skadniowejn"); break; case 1: printf ("Niespodziewany operatorn"); break; case 2: printf ("Niespodziewany nawiasn"); break; case 3: printf ("Niedozwolona kombinacja )(n"); break; case 4: printf ("Niedozwolona kombinacja ()n"); break; case 5: printf ("Kopoty z nawiasamin"); break; } exit (nr);}/* sprawdzenie poprawnoci wyraľenia */void kontrola_bledow (char *wyrazenie){ int i; int lewy_n = 0, prawy_n = 0; /* czy pierwszy jest operator */ if (wyrazenie [0] == '+' || wyrazenie [0] == '*' || wyrazenie [0] == '/') blad (1,1); /* czy ostatni jest operator */ if (wyrazenie [strlen (wyrazenie) - 1] == '+' || wyrazenie [strlen (wyrazenie) - 1] == '*' || wyrazenie [strlen (wyrazenie) - 1] == '/' || wyrazenie [strlen (wyrazenie) - 1] == '-') blad (1,strlen (wyrazenie)); /* og˘lna kontrola wyraľenia */ for (i = 0; i < strlen (wyrazenie) - 1; i++) { /* czy nie ma sytuacji liczba ( */ if ((isdigit (wyrazenie [i]) && wyrazenie [i+1] == '(')) blad (2,i + 1); /* czy nie ma sytuacji )( */ if (wyrazenie [i] == ')' && wyrazenie [i+1] == '(') blad (3,i + 1); /* czy nie ma sytuacji () */ if (wyrazenie [i] == '(' && wyrazenie [i+1] == ')') blad (4,i + 1); } /* kontrola iloci nawias˘w */ for (i = 0; i < strlen (wyrazenie); i++) { if (wyrazenie [i] == '(') lewy_n++; if (wyrazenie [i] == ')') prawy_n++; } if (lewy_n != prawy_n) blad (5,0);}/* zamiana formuu z postaci wrostkowej (normalnej) *//* na posta† w ONP Odwrotnej Notacji Polskiej */char *zmiana_formuly (char *wyrazenie){ char wyrazenieONP [512] = ""; /* wyraľenie w notacji ONP */ char oper [2] = " "; /* zmienna pomocnicza przy obsudze operator˘w */ struct stos *glowa = NULL; /* wska«nik na wierzchoek stosu */ int i = 0,j; /* g˘wna p©tla */ while (i < strlen (wyrazenie)) switch (wyrazenie [i]) { /* lewy nawias po prostu wrzucamy na stos */ case '(': glowa = wstaw_element (glowa,"("); i++; break; /* prawy nawias - wrzucamy wszystko do wyraľenia w ONP */ /* aľ do napotkania na stosie lewego nawiasu */ case ')': while (strcmp (podaj_element (glowa),"(")) { strcat (wyrazenieONP,podaj_element (glowa)); strcat (wyrazenieONP," "); /* spacja oddzielajĄca */ glowa = usun_element (glowa); } /* do usuni©cia pozosta nawias */ glowa = usun_element (glowa); i++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* dozwolony jest przecinek */ case '.': /* wyodr©bnienie liczby i jej kopiowanie do wyrazenia ONP */ j = strlen (wyrazenieONP); while ((isdigit (wyrazenie [i]) || wyrazenie [i] == '.') && i < strlen (wyrazenie)) { wyrazenieONP [j] = wyrazenie [i]; i++; j++; } strcat (wyrazenieONP," "); /* liczb© oddzielamy spacjĄ */ break; case '-': /* sprawdzenie czy - nie stoi na poczĄtku wyraľenia */ /* lub przed nawiasem, w˘wczas dodajemy do wyraľenia */ /* w ONP 0 czyli zamieniamy np. -1 na 0-1 */ if (i == 0 || wyrazenie [i - 1] == '(') strcat (wyrazenieONP,"0 "); /* dalej post©pujemy jak ze zwykym operatorem "+" */ /* czyli faktycznie zamieniamy odejmowanie na dodawanie */ if (sprawdz_priorytet ('+',glowa)) glowa = wstaw_element (glowa,"+"); else { /* przestawienie operator˘w stosownie do ich priorytet˘w */ while (!sprawdz_priorytet ('+',glowa)) { strcat (wyrazenieONP,podaj_element (glowa)); strcat (wyrazenieONP," "); glowa = usun_element (glowa); } /* na stos odkadamy "+" */ glowa = wstaw_element (glowa,"+"); } /* charakterystyczne jest to, ľe przy obsudze */ /* "-" nie przesun©limy i o jeden a dalej badamy */ /* formu© jako zwyky minus - brak instrukcji break!! */ case '+': case '*': case '/': oper [0] = wyrazenie [i]; /* ciĄg znak˘w oper to "+","-" lub "/" */ /* napotkany operator ma wyľszy priorytet niľ */ /* ten kt˘ry leľy na wierzchoku stosu */ if (sprawdz_priorytet (wyrazenie [i],glowa)) { glowa = wstaw_element (glowa,oper); i++; } else { /* przestawienie operator˘w stosownie do ich priorytet˘w */ while (!sprawdz_priorytet (wyrazenie [i],glowa)) { strcat (wyrazenieONP,podaj_element (glowa)); strcat (wyrazenieONP," "); glowa = usun_element (glowa); } /* na stos dokadamy napotkany operator */ glowa = wstaw_element (glowa,oper); i++; } break; default: blad (0,i+1); } /* ze stosu "zrzucamy" operatory i dopisujemy */ /* je na koniec wyraľenia ONP */ while (glowa != NULL) { strcat (wyrazenieONP,podaj_element (glowa)); strcat (wyrazenieONP," "); glowa = usun_element (glowa); } /* zwracamy warto† funnkcji */ return wyrazenieONP;}/* oblicznie wartoci operacji dla poszczeg˘lnych operator˘w */double oblicz_wartosc (char oper,double pom1,double pom2){ switch (oper) { case '+': return pom1 + pom2; case '*': return pom1 * pom2; case '/': return pom1 / pom2; } return 0; /* ta instukcja nie powinna zosta† wykonana! */ /* wstawiona, eliminuje ostrzeľenie kompilatora */}/* oblicznie wartoci formuy zapisanej w ONP */double wartosc_wyrazenia (char *wyrazenie){ int i = 0,j; char str1 [40] = ""; char str2 [40] = ""; struct stos *glowa = NULL; double wartosc; /* gowna p©tla */ while (i < strlen (wyrazenie)) { switch (wyrazenie [i]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* dozwolony jest przecinek */ case '.': /* wyodr©bnienie liczby i jej kopiowanie do str1 */ j = 0; while ((isdigit (wyrazenie [i]) || wyrazenie [i] == '.') && i < strlen (wyrazenie)) { str1 [j] = wyrazenie [i]; i++; j++; } str1 [j] = 0; /* zaanaczenie koäca skopiowanej liczby */ glowa = wstaw_element (glowa,str1); /* wstawienie na stos */ break; case '-': strcpy (str1,podaj_element (glowa)); glowa = usun_element (glowa); /* zdj©cie liczby ze stosu */ strcpy (str2,"-"); /* negujemy liczb© poprzez */ strcat (str2,str1); /* dodanie minusa na poczĄtku */ glowa = wstaw_element (glowa,str2); /* liczba na stos */ i++; break; case '+': case '*': case '/': strcpy (str2,podaj_element (glowa)); /* zdejmujemy dwie liczby */ glowa = usun_element (glowa); /* ze stosu, wykonujemy */ strcpy (str1,podaj_element (glowa)); /* operacj© i wynik */ glowa = usun_element (glowa); /* odkadamy na stos */ wartosc = oblicz_wartosc (wyrazenie [i],atof (str1),atof (str2)); gcvt (wartosc,5,str1); glowa = wstaw_element (glowa,str1); i++; break; default: i++; /* b©dĄ to spacje - po prostu je omijamy */ } } /* wynik - warto† wyraľenia znajduje si© na stosie */ strcpy (str1,podaj_element (glowa)); glowa = usun_element (glowa); return atof (str1);}/* g˘wny program */void main (){ char wyrazenie [512]; char wyrazenieONP [512] = ""; clrscr (); printf ("Podaj wyraľenie:n"); scanf ("%255s",wyrazenie); kontrola_bledow (wyrazenie); strcpy (wyrazenieONP,zmiana_formuly (wyrazenie)); printf ("Wyraľenie w odwrotnej notacji polskiej: n%s",wyrazenieONP); printf ("nWartosc wyraľenia %f",wartosc_wyrazenia (wyrazenieONP)); getch ();} Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
dzi Opublikowano 24 Maja 2004 Zgłoś Opublikowano 24 Maja 2004 Jesli nie musisz uzywac stosu to dla mnie bylo latwiej zrobic to tzw "trojkami". Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mrbounce Opublikowano 27 Maja 2004 Zgłoś Opublikowano 27 Maja 2004 dzieki za odpowiedzi :), juz sobie troche poradzilem (wystarczy to zrobic w bison-ie) Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
dzi Opublikowano 27 Maja 2004 Zgłoś Opublikowano 27 Maja 2004 dzieki za odpowiedzi :), juz sobie troche poradzilem (wystarczy to zrobic w bison-ie)Hehe, no w sumie tak, pytanie jak :D Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...