Состав • типы, • примитивы, • комбинаторы первого порядка, • комбинаторы высшего порядка. • Свойство замыкания (композиционность). • Возможность эффективной реализации. Принципы комбинаторных библиотек E. Кирпичев. Элементы функциональных языков. Практика функционального программирования №3.
Recursive Programming Techniques. Addison-Wesley, 1975. • Ph. Wadler. How to Replace Failure by a List of Successes. A method for exception handling, backtracking, and pattern matching in lazy functional languages // 1985 • G. Hutton. Higher-order functions for parsing // Journal of functional programming. 1992/2 • J. Fokker. Functional Parsers // 1995
A type Parser[A] = String => (A, String) Нет композиции функций, не обязательно парсить всю строку Может закончиться неудачей type Parser[A] = String => Option[(A, String)]
type Input = Reader[Elem] sealed abstract class ParseResult[+T] case class Success[+T](result: T, override val next: Input) extends ParseResult[T] sealed abstract class NoSuccess(val msg: String, override val next: Input) extends ParseResult[Nothing] case class Failure(override val msg: String, override val next: Input) extends NoSuccess(msg, next) case class Error(override val msg: String, override val next: Input) extends NoSuccess(msg, next) ... abstract class Parser[+T] extends (Input => ParseResult[T]) { ... } case class ~[+a, +b](_1: a, _2: b) { override def toString = "("+ _1 +"~"+ _2 +")" } } package scala.util.parsing.input abstract class Reader[+T] { def first: T def rest: Reader[T] } Stream annotated with coordinates Controlling backtracking Deconstructing sequencing
учить новый инструмент. • Исполняемая грамматика - всегда актуальный код. • Краткость + богатая выразительность: LL(*) и больше (в том числе, контекстные грамматики). • Можно делать fusion синтаксического разбора и чего-нибудь еще. • Модульность