Permalink
Browse files

Add cut? and update README.

  • Loading branch information...
1 parent 8d09e99 commit 653c1404f983cc46f48c2533fb75f0d51da87034 @Ramarren committed Jan 25, 2011
Showing with 10 additions and 9 deletions.
  1. +6 −9 README.markdown
  2. +4 −0 primitives.lisp
View
@@ -1,16 +1,15 @@
# parser-combinators
-This is an experimental implementation of [parser combinators](http://en.wikipedia.org/wiki/Parser_combinators) for Common Lisp. This is mostly inspired by Parsec, but without any optimizations. Parser combinators are, in theory, an elegant form of constructing parsers for context-free grammars.
-
-It more or less works, but was not tested for any but the simplest cases, some parts of the interface are clunky, it is quite slow in general and probably has a tendency for exponential explosions. That said, it could probably be used to parse small amounts of data, especially if applied hierarchically. Comments welcome.
-
-I have found this more convenient than regular expressions in some cases, especially where maximum performace is not required.
+This is an experimental implementation of [parser combinators](http://en.wikipedia.org/wiki/Parser_combinators) for Common Lisp. This is mostly inspired by Parsec, but with limited optimizations. Parser combinators are, in theory, an elegant form of constructing parsers for context-free grammars.
+The name of the system is `parser-combinators`, despite the name of the GitHub repository. The library is fairly lightly tested. Any comments or questions on the functionality or performance are welcome.
# Dependencies
- iterate
- alexandria
+The test suite has some additional dependencies, all of which are in [quicklisp](http://www.quicklisp.org/)
+
# Usage
Parsers combinators combine parsers. In the specific context of this library a parser is a function from `context` object to a thunk returning `parser-possibility` objects or `nil`, if there are no more possible parses. This parsers can be combined using parser combinators to create more complex parsers.
@@ -49,11 +48,9 @@ Most places which expect a parser will also accept any non-function object (a fu
`force? parser` makes a parser which is identical to its argument, but is fully executed, that is, does not perform further parsing lazily.
-`delayed? parser` creates a parser which will be constructed only when called, once. This is useful only for left-recursive parsers, which otherwhise would cause infinite recursion.
-
-`memoize? parser &optional label` creates a parser which will be memoized using label. Label makes it possible to memoize the same parser from multiple places.
+`cut? parser` discard all the results but the first, preventing backtracking.
-`curtail? parser &optional label` creates a curtailed parser. That is, recursive calls to this parser will fail if recursion depth is greater than remaining input length, since at that point success is no longer possible. This is mostly useful, together with `delayed?` modifier to handle left-recursive grammars. Obviously, this incurs a performance penalty.
+`delayed? parser` creates a parser which will be constructed only when called, once. This is useful only for left-recursive parsers, which otherwhise would cause infinite recursion.
### basic parsers
View
@@ -42,6 +42,10 @@
(when all-results
(pop all-results)))))))
+(defun cut? (parser)
+ "Parser modifier: discard all results but the first"
+ (choice1 parser (zero)))
+
(defmacro delayed? (parser)
"Parser modifier macro: parser will be built when called. This is necessary for left-recursive parsers."
`(let ((parser-cache nil))

0 comments on commit 653c140

Please sign in to comment.