{{page>courses:b6b36pjc:styles#common&noheader&nofooter}} {{page>courses:b6b36pjc:styles#ukoly&noheader&nofooter}} ===== Úkol 7 ===== V tomto bonusovém úkolu máte možnost navázat na minulý, a svůj evaluátor matematických výrazů rozšířit o podporu funkcí a o detekci chyb. ==== Formát vstupu ==== 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. ==== Detekce chyb ==== 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í {{:courses:b6b36pjc:ukoly:parser-2.zip|zde}}. ==== Příklady ==== ^ 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 | | "sin(1, 2)" | ''invalid_expression_exception'' | ''sin'' je unární funkce, není možné ji předat 2 argumenty | ==== Co odevzdat? ==== 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. ===== Rady ===== Stále platí, že operátor pro výpis do proudu (''%%<<%%'') netestujeme. ==== Kontrola chyb ==== Pokud nevíte kde s kontrolou začít, poradíme vám pár pravidel * Levá závorka musí být buďto předcházena operátorem, nebo být první token výrazu. * Pravá závorka musí být předcházena číslem a musí patřit k levé závorce. * Operátor musí následovat číslo nebo pravou závorku. * Číslo nesmí následovat číslo. * Název funkce musí být následován levou závorkou. ==== Užitečné hlavičky ==== Doporučujeme stejné hlavičky ze standardní knihovny jako v minulém úkolu.