V tomto úkolu navážete na minulý, a svůj evaluátor matematických výrazů rozšíříte o podporu funkcí a o detekci chyb.
Vstup již může obsahovat víceméně arbitrární znaky a vaším úkolem je ho nejenom vyhodnotit, ale i detekovat chyby. Stále platí, že čísla používají dekadický zápis, operátory jsou stejné jako minule a funkce jsou definovány jako sekvence alfanumerických znaků, začínající písmenem a následována levou závorkou (“(”). Funkce jsou podporovány pouze tři, sin, cos, log.
Předpokládejte, že argumenty pro sin a cos jsou v radiánech.
Hlášení chyb probíhá pomocí výjimek. V expr.hpp je předdefinovaná rodina výjimek, domain_exception, unknown_function_exception, invalid_expression_exception a jejich společný předek, math_exception.
Jak název napovídá, unknown_function_exception slouží k hlášení výrazů ve kterých se vyskytuje neznámá funkce a domain_exception slouží k hlášení špatného vstupu do funkcí, které mají omezený definiční obor (v našem případě log). invalid_expression_exception pak slouží k hlášení všech ostatních chyb.
Potřebné hlavičkové soubory a testy jsou ke stažení zde.
| Vstup | Výsledek/Výjimka | Poznámka |
|---|---|---|
| “1 + 2” | 3 | — |
| “(1)” | 1 | — |
| “)(” | invalid_expression_exception | — |
| “2 % 3” | invalid_expression_exception | modulo není podporováno |
| “sin 2” | invalid_expression_exception | sin není následován ( |
| “log log(1)” | invalid_expression_exception | první log není následován ( |
| “sin(1)” | 0.841… | — |
| “f1(2)” | unknown_function_exception | f1 je následováno (, ale není to známá funkce |
| “3 33” | invalid_expression_exception | chybí operátor mezi čísly |
| “3 33 +” | invalid_expression_exception | operátor je až za čísly |
| “2sin(2)” | invalid_expression_exception | implicitní násobení nepodporujeme |
| “log(-1)” | invalid_expression_exception | unární mínus nepodporujeme |
| “log(0-1)” | domain_exception | log je definován pouze pro x > 0 |
Všechny soubory, které implementují vaší část úlohy, specificky pokud jste přidali další .hpp soubory, pak je nezapomeňte též odevzdat. Naopak ale neodevzdávejte expr.hpp, ani žádné testovací soubory.
Stále platí, že operátor pro výpis do proudu (<<) netestujeme.
Ke kontrole výrazů vám poradíme pár jednoduchých pravidel
Doporučujeme stejné hlavičky ze standardní knihovny jako v minulém úkolu.