Главная » Просмотр файлов » John Harrison - Введение в функциональное программирование

John Harrison - Введение в функциональное программирование (1108517), страница 29

Файл №1108517 John Harrison - Введение в функциональное программирование (John Harrison - Введение в функциональное программирование) 29 страницаJohn Harrison - Введение в функциональное программирование (1108517) страница 292019-04-28СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 29)

выше):#parser "sin(x + y) * cos(2 * x + y)";;- : term =Fn("*",[Fn ("sin", [Fn ("+", [Var "x"; Var "y"])]);Fn ("cos", [Fn ("+", [Fn ("*", [Const "2"; Var "x"]);Var "y"])])])#install_printer "print_term";;- : unit = ()#parser "sin(x + y) * cos(2 * x + y)";;- : term = ‘sin(x + y) * cos(2 * x + y)‘9.2.5Автоматический учёт приоритетовСинтаксический анализатор, рассмотренный выше, реализует разбордвух инфиксных операций в явном виде. Однако, для большего удобства исогласованности с нашим подходом к выводу выражений, следует учесть введенную126Глава 9.

Примеры9.2. Синтаксический анализранее информацию о множестве доступных инфиксных операций. Более того,наличие даже двух различных бинарных операций заставляет прибегать кискусственным приёмам при построении грамматики и программы разбора —нетрудно представить себе, во что превратится работа, например, с дюжиной такихопераций. Таким образом, несомненна полезность автоматического порожденияиерархии анализаторов для каждой доступной операции, упорядоченных согласноих приоритетам. Решение этой задачи достаточно просто.

Прежде всего, зададимобобщённую функцию, которая принимает в качестве аргумента анализаторсинтаксической категории, которая на данном уровне приоритета считаетсяатомарным выражением, и возвращает новый анализатор, предназначенный дляразбора последовательности таких атомарных выражений, объединенных заданнойоперацией. Заметим, что того же эффекта мы можем добиться при помощи нашегонабора комбинаторов, но функция, приведенная ниже, проще и эффективнее.l e t rec binop op p a r s e r i n p u t =l e t atom1 , r e s t 1 as r e s u l t = p a r s e r i n p u t ini f not r e s t 1 = [ ] & hd r e s t 1 = Other op thenl e t atom2 , r e s t 2 = binop op p a r s e r ( t l r e s t 1 ) inFn ( op , [ atom1 ; atom2 ] ) , r e s t 2else r e s u l t ; ;Далее определим функции, которые извлекают из нашего ассоциативного спискаочередную операцию с наименьшим (равным предыдущему) приоритетом. Еслисписок был заранее сортирован по приоритетам, мы можем просто выбиратьочередной элемент по порядку следования.let findmin l = i t l i s t( fun (_, pr1 as p1 ) (_, pr2 as p2 ) −> i f pr1 <= pr2 then p1 e l s e p2 )( t l l ) ( hd l ) ; ;l e t rec d e l e t e x ( h : : t ) = i f h = x then t e l s e h : : ( d e l e t e x t ) ; ;Обобщенный анализатор множества бинарных операций с приоритетами:l e t rec p r e c e d e n c e i l i s t p a r s e r i n p u t =i f i l i s t = [ ] then p a r s e r i n p u t e l s el e t opp = f i n d m i n i l i s t inl e t i l i s t ’ = d e l e t e opp i l i s t inbinop ( f s t opp ) ( p r e c e d e n c e i l i s t ’ p a r s e r ) i n p u t ; ;Использование этого вспомогательного анализатора позволяет упростить основнойи сделать его более общим:1279.2.

Синтаксический анализГлава 9. Примерыl e t rec atom i n p u t= ( name ++ a ( Other " ( " ) ++ t e r m l i s t ++ a ( Other " ) " )>> ( fun ( ( ( name ,_) , a r g s ) ,_) −> Fn ( name , a r g s ) )| | name>> ( fun s −> Var s )| | numeral>> ( fun s −> Const s )| | a ( Other " ( " ) ++ term ++ a ( Other " ) " )>> ( snd o f s t )| | a ( Other "−" ) ++ atom>> snd ) i n p u tand term i n p u t = p r e c e d e n c e ( ! i n f i x e s ) atom i n p u tand t e r m l i s t i n p u t= ( term ++ a ( Other " , " ) ++ t e r m l i s t>> ( fun ( ( h ,_) , t ) −> h : : t )| | term>> ( fun h −> [ h ] ) ) i n p u t ; ;l e t p a r s e r = f s t o ( term ++ f i n i s h e d >> f s t ) o l e x ; ;Пример разбора выражения:#parser "2 * sin(x)^2 + 2 * sin(y)^2 - 2";;- : term =Fn("+",[Fn ("*", [Const "2"; Fn ("^", [Fn ("sin", [Var "x"]);Const "2"])]);Fn("-",[Fn ("*", [Const "2"; Fn ("^", [Fn ("sin", [Var "y"]);Const "2"])]);Const "2"])])#install_printer "print_term";;- : unit = ()#parser "2 * sin(x)^2 + 2 * sin(y)^2 - 2";;- : term = ‘2 * sin(x) ^ 2 + (2 * sin(y) ^ 2 - 2)‘9.2.6Недостатки методаНаш подход к лексическому и синтаксическому анализу не отличается особойэффективностью.

Действительно, CAML и некоторые другие реализации языка MLвключают генератор синтаксических анализаторов для LR-грамматик, аналогичныйпопулярной в Unix-среде системе YACC (Yet Another Compiler Compiler) дляязыка C. Эти генераторы не только охватывают более широкий класс грамматик,но и производят более эффективные анализаторы. Однако, мы считаем, чтопредложенный метод достаточно прозрачен, приемлем в большинстве случаеви является хорошим введением в программирование с использованием функцийвысших порядков.Небольшая доработка некоторых особенно ресурсоёмких фрагментованализатора может заметно улучшить его общую эффективность.

Так, при128Глава 9. Примеры9.2. Синтаксический анализналичии в одной синтаксической категории нескольких продукций с общимпрефиксом, следует избегать его многократного анализа, который может оказатьсянетривиальным. Примером подобной ситуации служат правила вывода для термов:term −→ name(termlist)|name| ···Мы намеренно поместили в ходе реализации более длинное правило первым, таккак в противном случае успешное чтение имени приведёт в дальнейшем к отказупри попытке разбора списка аргументов.

Однако, возникающее при этом повторноесканирование избыточно. В данном случае цена избыточности невелика, посколькуповторному анализу подвергается лишь одна лексема, но потенциальные накладныерасходы при разборе termlist могут оказаться более существенными:let . . .and t e r m l i s t i n p u t= ( term ++ a ( Other " , " ) ++ t e r m l i s t>> ( fun ( ( h ,_) , t ) −> h : : t )| | term>> ( fun h −> [ h ] ) ) i n p u t ; ;В отличие от предыдущего примера, здесь повторному сканированию вслучае возврата подвергается целый терм, который может быть сколь угодносложным.

Существуют различные способы избежать этого. Например, мы можемпреобразовать правила вывода так, чтобы выбор одного из них происходил уже послетого, как прочитан начальный терм. Комбинатор many позволяет легко устранитьявную рекурсию:let . . .and t e r m l i s t i n p u t= term ++ many ( a ( Other " , " ) ++ term >> snd )>> ( fun ( h , t ) −> h : : t ) i n p u t ; ;Таким образом, итоговая реализация анализатора имеет вид:1299.2. Синтаксический анализГлава 9.

Примерыl e t rec atom i n p u t= ( name ++ a ( Other " ( " ) ++ t e r m l i s t ++ a ( Other " ) " )>> ( fun ( ( ( name ,_) , a r g s ) ,_) −> Fn ( name , a r g s ) )| | name>> ( fun s −> Var s )| | numeral>> ( fun s −> Const s )| | a ( Other " ( " ) ++ term ++ a ( Other " ) " )>> ( snd o f s t )| | a ( Other "−" ) ++ atom>> snd ) i n p u tand term i n p u t = p r e c e d e n c e ( ! i n f i x e s ) atom i n p u tand t e r m l i s t i n p u t= ( term ++ many ( a ( Other " , " ) ++ term >> snd )>> ( fun ( h , t ) −> h : : t ) ) i n p u t ; ;Общим недостатком нашего подхода и метода рекурсивного спуска в целомявляются проблемы с разбором леворекурсивных грамматик. Правило выводанекоторой синтаксической категории называется леворекурсивным, если его праваячасть начинается с этой же категории.

Например, если бы мы попытались определитьв нашей грамматике левоассоциативную операцию сложения, это можно было бывыразить так:term −→ term + mulexp|mulexpПрямое отображение этих правил вывода на язык ML приведет к зацикливанию,поскольку функция term будет вызываться для одного и того же подвыраженияснова и снова. Существуют различные, причём не слишком универсальные, способырешения проблемы. Например, мы можем реализовать в явном виде цикл вместорекурсии, применение которой в данном контексте не имеет под собой особыхоснований.

Для этого воспользуемся стандартными комбинаторами наподобие many,чтобы получить список деревьев разбора подвыражений вида mulexp, после чегопостроим по этому списку результирующее левоассоциативное дерево.В заключение отметим, что наша обработка ошибок разбора не отличаетсяособой элегантностью. При возникновении любого затруднения мы порождаемисключение Noparse, обработка которого представляет собой возврат. Такоеповедение, однако, не всегда подходит для типичных грамматик. В лучшем случае,оно приведёт к интенсивному повторному сканированию, но может вызвать ипоследовательность возвратов вплоть до корня дерева разбора. Например, встретивв ходе анализа подвыражение 5 + мы ожидаем, что вслед за символом + следуеточередной терм. Если он не был найден, следует выдать пользователю внятноесообщение об ошибке вместо простой генерации Noparse и, возможно, последующихбезуспешных попыток разобрать выражение другим путём.130Глава 9.

Примеры9.39.3. Точная арифметика вещественных чиселТочная арифметика вещественных чиселМашинная реализация вещественной арифметики обычно используетприближённое представление чисел в формате с плавающей точкой. В общемслучае, мы можем оперировать вещественными числами (либо вручную, либо припомощи компьютера) лишь в том случае, когда они имеют то или иное конечноепредставление. Возникает вопрос, уместно ли говорить о ‘существовании’ чисел,которые не представимы в конечной форме. Например, Кронекер признавал целыеи рациональные числа, поскольку их можно задать точно, а также алгебраическиечисла3 , представимые многочленами, корнями которых они являются. Однако, онотвергал трансцендентные числа, как не имеющие конечного представления.Говорят, что когда Кронекеру попалось на глаза известное доказательствотрансцендентности числа π Lindemann (1882), он якобы отозвался о нем так:«интересно, если не принимать во внимание того, что числа π не существует».Учитывая современные достижения, мы можем сказать, что конечноепредставление в принципе возможно для гораздо большего количества чисел,чем те, существование которых признавалось Кронекером.

Характеристики

Тип файла
PDF-файл
Размер
1,38 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6382
Авторов
на СтудИзбе
308
Средний доход
с одного платного файла
Обучение Подробнее