![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 78 Pomógł: 9 Dołączył: 2.02.2011 Skąd: undefined Ostrzeżenie: (0%) ![]() ![]() |
Witam.
Chciałem sobie zrobić prosty kalkulator który będzie pobierał od użytkownika wyrażenie arytmetyczne i zwracał jego wynik. Np: Podaję: Kod (10+9)/(11*8) Otrzymuję Kod 0.215909090 Myślałem nad wykorzystaniem do tego wyrażeń regularnych, ale pojawia się pewien problem. Otóż nie bardzo wiem jak wymusić na kwantyfikatorach, aby dzielił mi wyrażenie tylko względem najwyższego znaku tzn. powyższe wyrażenie powinno mi podzielić na: Kod l=(10+9); r=(11*8); sign=/; oczywiście powyższe wyrażenia mogą wyglądać także inaczej. Np można używać na nich prostych funkcji: Kod sin(10+4)/cos(8-11) l=sin(10+4); sign=/; r=cos(8-11); Do tej pory używałem wyrażenia regularnego: Kod /^(?<l>[[:print:]]+)(?<sign>[\*\/\-\+]{1})(?<r>[[:print:]]+)/ Każdą ze stron wyrażenia arytmetycznego będę rozpoznawał rekurencyjnie, i do analizy funkcji mam już wyrażenie regularne Jak można by to najrozsądniej rozwiązać? Ten post edytował shinuexx 27.11.2011, 14:10:33 |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat Czyli analizuję ciąg od początku, sprawdzam co mam a potem czego oczekuję następnie. Jeśli tak nie jest to błąd a jeśli jest to następny znak? Mógłbyś już nawet na etapie wykrywania tokenów wywalać pewne błędy składni, np. ")" nie może się pojawić jeżeli nie ma poprzedzającego go "(", ale generalnie darowałbym sobie na tym etapie takie coś. Nie możesz przewidzieć wszystkich w tym miejscu, w dodatku "zabrudziłbyś" kod tokenizera.1. Odczytujesz wszystkie tokeny, nie bacząc na ich poprawność względem gramatyki języka (tutaj: wyrażeń matematycznych). 2. Na podstawie odczytanych tokenów próbujesz utworzyć AST. Na tym etapie wyłapujesz błędy składni. EDIT: Nie analizowałem całości ale kilka błędów już rzuciło mi się w oczy: 1. "-" (minus) to nie tylko operator odejmowania (operator dwuargumentowy), ale i operator wskazujący na wartość przeciwną (ujemną) następującego po nim wyrażenia (operator jednoargumentowy), np.: $a = -$b; 2. W przypadku gdy będziesz miał zapis 2 + invalidFunction(6) w chwili obecnej parser potraktuje invalidFunction jako... zmienną. Nie muszę chyba tłumaczyć, że jest to bzdura. EDIT: Na prawdę polecam poświęcić ze dwie godz nad wynikami wyszukiwania c / java / php math parser (język jest tutaj bez znaczenia) - jest tego sporo Ten post edytował Crozin 29.11.2011, 00:45:21 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 14.10.2025 - 02:54 |