Интерпретиране на низови изрази като функции

Примерите в статията ще бъдат написани на PERL само защото този език е достатъчно гъвкав и не е нужно да отклонявате вниманието от задачата към функциите за изпълнение на конкретен език.

И така, първо, относно постановката на проблема: програмата получава низов израз, съдържащ дефиницията на математическа или логическа функция с всякаква сложност. Например изразът

Тези изрази са сложни, но могат да бъдат сведени до проста форма

Операторите за сравнение също са функции, например операторът != приема стойностите на 2 променливи и връща "0" или "1". Нека [Function1] върне стойността [Value1], тогава процесът на опростяване на низове може да се извърши по следния начин:

След като изберем функцията, я заместваме в изходния ред с върнатата стойност:

Последната стойност ще бъде стойността на израза, който трябва да се намери (По-нататък ще се разглеждат само прости изрази). Въпреки това, ако използвате обработката на оригиналния низ със замяната на функцията с нейната стойност за конкретни стойности на променливите, тогава ще има сериозни загуби на производителност. Следователно е логично да се използват не самите стойности, а указатели към тях. За да направите това, ще трябва да съхранявате стойностите на самите променливи, константите и стойностите на функциите.

За тези, които не са запознати със синтаксиса на PERL, ще обясня, че ако има знак "$" преди името на променливата, тогава променливата е скаларна и може да съдържа всяка отделна стойност: низ, число, указател към обект. Ако "@", тогава това е масив от скалари, всеки елемент от масива може да бъде достъпен с помощта на името на масива, предшествано от знака "$" (т.е. елементът на масива е скалар) и индекса в квадратни скоби след името. Ако "%", тогава това е асоциативен масив, достъпът до него се извършва по същия начин като нормален, само вместоиндекс в квадратни скоби показва израз на низ в curly.

Трябва да се отбележи, че низът се анализира само веднъж при попълване на масиви, така че следващите изчисления са по-бързи.

Сега няколко думи за извикването на функция и задаването на нейните аргументи. С постоянен аргумент всичко е просто, стойността му се съхранява в масив от константи и ще се използва всеки път, когато се изчислява стойността на функцията. Стойността на променливата $A ще бъде съхранена в елемента на асоциативния масив $zn_p. Може лесно да се настрои преди всяко изчисление.

Знакът "$$" преди имената на променливите F_arg_p1 и F_arg_p2 означава, че при изчислението е необходимо да се вземат не стойностите на тези променливи (те съдържат указатели), а данните, към които те сочат. Знакът "&$" преди името F_Name_p означава, че трябва да извикате функцията, указателят към която се съхранява в променливата $F_Name_p.

Всичко, което беше описано в статията, може да се използва и за интерпретиране на сложни изрази, просто в този случай те ще бъдат представени не от една функция, а от набор от функции (логично е да напишете указатели към тях в масив и да ги извикате последователно). Със сигурност ще има читатели, които ще кажат, че изпълнението на такава задача в PERL не е необходимо или може да се реализира с помощта на стандартни езикови инструменти. Разбира се, те ще бъдат прави, но подходът, използван за решаване на проблема, ни позволява да направим аналог, например в SI (езикът поддържа всички методи, използвани в този пример)