CA4 Project - Functional Specification

Parse::Combinator, a combinator parser for Perl

Dave Madden 97304531
12 January 2001


Introduction
As a perl programmer, I have often used perl in problems involving text-handling. Perl has developed a good reputation over time in this regard, because it allows for very quick and easy development, and has what is generally considered to be the best regular expression engine currently in widespread use.

However, despite this, perl's native functionality is lacking. Regular expressions simply are not powerful enough to deal with complex grammars. Parsing emails (RFC822) is incredibly convoluted using regular expressions. There are several parsing modules (libraries) available for perl, such as Parse-RecDescent, libparse, Parse-Yapp, and Parse-Vipar. Most of these are unfortunately underutilizing by the perl community. This might be partly to do with the fact that they do not give perl an edge over other tools and languages - Yapp, ParseLex, and Parse-Vipar, for example, are very like existing UNIX tools such as Yacc, Bison and Lex. This means that they make it possible to do Yacc and Lex like tasks in Perl, but do not make it especially easy to allow the use of this functionality as an integral part of the language. RecDescent is powerful, but again, uses its own "little language" rather than perl functions.

Advantages offered by combinator parsing
A combinator parser offers the possibility of a more integrated parsing process. As Daan Leijen puts it, "Combinator parsers are written and used within the same programming language as the rest of the program. There is no gap between the grammar formalism (Yacc) and the actual programming language used (C). Users learn just one language!". Parsers are manipulable as part of the language. For example, if you were building a file viewer, that needs to parse several types of text, and apply common functionality to them, you could construct a custom-parser dynamically within the program, and pass it around within the language.
In addition, new combinators can be created. This allows the use of entirely new ways of constructing grammars. See the glossary.

Scope of this document
This document describes the basic architecture, aims and functionality of the combinator parser project.

Overview of the project
Glossery
In order to better explain the architecture of the project, the glossary provides brief descriptions of some of the main elements of the project.

Project objectives
These are the project objectives:
  1. To formulate and implement a way of using the functional methodolgy within Perl, a non-functional language.
  2. To produce the fundamental parts of the combinator parser architecure, and package these in one or more perl modules.
  3. To provide additional functionality on top of the core combinator parser itself, to make it easier to use, more flexible, and to provide common functionality pre-written.
The combinator parser's structure is to be topologically and semantically based on [E]BNF. This requires the combinators to offer recursion, sequencing etc. Objective 3 might explicitly provide a BNF-like grammar if it is found that perl programmers aren't satisfied with using the combinators directly. (This would be less powerful than using the combinators directly.) Exactly how Objective 3 is dealt with will depend largely on programmer feed-back.

Project constraints
There are two major constraints:
  1. Perl is not a functional language. This means that applying a functional methodology will be difficult, and not always practical.
  2. Time. A module requires significant amounts of usage and testing by programmers to refine its API and internals. Time is the main limitation on this, as in most projects.
System architecture
There are three tiers to the architecture, corresponding to the three Project Objectives:
  1. Tier 1: Functional programming functionality. This will involve both using appropriate coding techniques, and implementing perl functions to mimic the functionality of common functional language functions, as needed. It will involve finding and exploiting ways of using perl's features to act like functional features. e.g. Using perl arrays (or array refs, or objects containing arrays) as sequences.
  2. Tier 2: Combinator parser core. This consists of several sub-parts:
  3. Tier 3: Additional Functionality. Exactly what this includes will depend on the feed-back I get from other perl programmers. It will certainly include general parsers. i.e. high level parsers build using combinators, other general parsers, and basic parsers. These general parsers will include a library of common patterns. It will also include additional ways of using Tier 2 functionality, through alternative BNF-style notation and/or suitable general parsers and combinators.
-------------------------------------------------------------
| General parser / combinator library | Additional notation |	Tier 3
-------------------------------------------------------------
| 			Basic Parsers		  	    |	Tier 2
-------------------------------------------------------------
| Primitive Parsers		| Basic combinators	    |
-------------------------------------------------------------
| Functional methodology functionality			    |	Tier 1
-------------------------------------------------------------


Schedule
January:
Functional Specification
Simple prototype. This will be a single module, containing primitive and basic parsers, and basic combinators. The functional elements will be dealt with in an ad hoc manner. (Prototypes of Tier 1 and Tier 2)

February:
Abstract out functional elements (Tier 1) into seperate functions and/or a seperate module as needed. Document clearly how all functional aspects are being dealt with. This might be a minor job, initially.
Re-code Tier 2 as a seperate module (or modules).
Write some general parsers (part of Tier 3).
Write initial documentation.
Find out more about CPAN packaging.
Start getting feed-back from perl coders.

March:
Initial prototype of Tier 3 functionality.
Get more feed-back.

April (after exams):
Do a re-code. Some code will be retained from before if suitable. Any major new unforseen elements will be introduced / dealt with at this point.

May:
Debug, test, get more feedback, modify Tier 3 based on this. Tier 1 and 2 should require much less modification at this point.
Documentation, packaging.

References
Academic papers:
The main papers upon which this project is significantly based are about implementing combinator parsers in actual functional languages such as Gofer, Miranda(tm) and Haskell.

Graham Hutton. (1992)
Higher-order functions for parsing.
Journal of Functional Programming 2: 232-343.
http://www.cs.nott.ac.uk/Department/Staff/gmh/parsing.ps

Graham Hutton and Erik Meijer. (1993)
Functional Pearls - Monadic Parsing in Haskell.
http://www.cs.nott.ac.uk/~gmh//pearl.ps

Graham Hutton and Erik Meijer. (1996)
Monadic Parser Combinators.
Technical report NOTTCS-TR-96-4. Department of Computer Science, University of Nottingham.
http://www.cs.nott.ac.uk/Department/Staff/gmh/monparsing.ps.

Comparitive implementations:
One of the implementations I examined was Parsec, a combinator parser for Haskell, by Daan Leijan
Parsec: http://www.cs.uu.nl/~daan

Functional programming:
"Functional Programming : Practice and Theory" (Bruce J. MacLennan, ISBN 0-201-13744-5)
Functional programming: http://cm.bell-labs.com/cm/cs/who/wadler/topics/monads.html
Haskell: www.haskell.org
Haskell: "Haskell: The Craft of Functional Programming" (Simon Thompson, ISBN 0-201-34275-8)

Additional topics:
Perl: www.perl.org
Perl modules: www.cpan.org