Преобразование определения одной из функций в определение эквивалентной функции - Lisp

Узнай цену своей работы

Формулировка задачи:

Есть грамматика некоторого языка функция ::= имя_функции "(" список_параметров ")" "=>" "{" выражение "}" список_параметров ::= параметр | параметр "," список_параметров выражение ::= терм | условный_оператор условный_оператор ::= условие "?" выражение ":" выражение условие ::= терм ( "<" | "=" | ">" ) терм терм ::= параметр | целое_число Имя функции и название параметра состоят из латинских символов. Обратите внимание, что количество параметров функции и глубина вложения условных операторов не ограничены. На языке, который описывается данной грамматикой, можно определять различные функции. Ваша задача состоит в том, что бы написать на языке Лисп программу, преобразующую определение одной из таких функций (заранее неизвестно, какой) в определение эквивалентной функции на языке Лисп. Результирующая функция для каждого набора аргументов должна выдавать тот же результат, что и исходная функция - в этом смысл эквивалентности. Например, для исходной функции f( x ) => {10} определение эквивалентной функции будем таким: (defun f (x) 10) . Определение исходной функции будет передано в виде списка, для вышеприведённого примера такого: ( f \( x \) => { 10 } ) . Каждая лексема будет представлять отдельный элемент списка, так что лексическим анализом заниматься не нужно. Для простоты давайте считать, что определение исходной функции не содержит ошибок и может быть успешно преобразовано в описание Лисп-функции. Примеры входных и выходных данных >>> (tt '( func \( x \, y \) => { x > y ? -1 \: 1 } ) ) ; "func(x, y) => { x>y ? -1 : 1 }" ( defun func ( x y ) ( if ( > x y ) -1 1 ) ) >>> ( tt '( max \( x \, y \, z \) => { x > y ? x > z ? x \: z \: y > z ? y \: z } ) ); "max( x, y, z ) => { x > y ? x > z ? x : z : y > z ? y : z }" ( defun max (x y z) ( if (> x y) (if ( > x z ) x z) ( if (> y z) y z) ))

Решение задачи: «Преобразование определения одной из функций в определение эквивалентной функции»

textual
Листинг программы
(ns aeon.core
  (:require [instaparse.core :as insta]))
 
(def parser
  (insta/parser
   "function = name <'('> params <')'> <'=>'> <'{'> expr <'}'>
    name = #'\\p{Alpha}+'
    params = param | param <','> params
    param = #'\\p{Alpha}+'
    expr = term | cond
    cond = clause <'?'> expr <':'> expr
    clause = term ('<' | '=' | '>') term
    <term> = param | int
    int = #'[-]?\\d+'"
   :auto-whitespace :standard))
 
(defn transform [s]
  (let [clause (fn [x op y]
                 (case op
                   "<" `(< ~x ~y)
                   ">" `(> ~x ~y)
                   "=" `(= ~x ~y)))
        transform-map {:int read-string
                       :clause clause
                       :cond (fn [clause x y]
                               `(if ~clause ~x ~y))
                       :expr identity
                       :param read-string
                       :params vector
                       :name read-string
                       :function (fn [name args body]
                                   `(fn ~name ~((comp vec flatten) args) ~body))}]
    (->> (parser s) (insta/transform transform-map) eval)))
 
((transform "func(x, y) => {x < y ? x : y}") 2 10)
;; => 2
((transform "func(x, y) => {x > y ? 1 : -1}") 2 10)
;; => -1
((transform "func(x) => {10}") 5)
;; => 10
((transform "func(x,y,z) => {x > y ? x > z ? x : z : y > z ? y : z}") 1 7 4)
;; => 7

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4.222 из 5
Похожие ответы