You are looking at historical revision 4895 of this page. It may differ significantly from its current revision.

Introduction

This small extension provides parsing expression grammar pattern matching with the help of the ftl egg. The parsing expressions are implemented as meta interfaces that can be constructed and combined programmatically. Data to match is consumed from arbitrary lookahead input interfaces.

Requirements

ftl

This extension supports static linking.

Interfaces

Mark input (mi)

An arbitrary lookahead input stream. The concrete implementations mi=list, mi=vector, mi=reverse-vector, mi=string, mi=reverse-string are available and operate on list stacks of their respective associated datatypes and their subranges.

A new implementation of the interface is created as

(mi-interface read empty? mark restore forget)

and the following methods are supported:

((%mi-read mi) in) => (values) | (values obj in)

Reads the next token from the input. If there is no more input, nothing is returned, otherwise the token and the new input are returned.

((%mi-empty? mi) in) => #t | #f

Returns whether the given input has no more tokens to read.

((%mi-mark mi) in) => in

Returns an input to use for further reading if a future reset to the current position may be necessary.

((%mi-restore mi) in) => in

Returns the input reset to the last position stored by the mark method.

((%mi-forget mi) in) => in

Returns the input with the last position stored by the mark method removed.

Matcher (m)

Represents a parsing expression that can be applied to any mark input.

A new implementation of this interface is created as

(m-interface match-%mi)

and the following basic operation is supported:

(((%m-match-%mi m) mi) in) => (values obj | #f in)

Compares the start of the given mark input to some pattern and returns the matching object and the advanced mark input in case of success or #f and the mark input restored to its former position.

To be able to create recursive patterns, the following special operations are supported:

(m-proxy) => <m-interface>

Creates a proxy matcher interface with no stored procedure.

(m-implement! tgt-m src-m)

Fixes a proxy matcher by copying the stored procedure from another matcher interface. Signals an error if the target interface is not a proxy or if the source interface is a proxy as well.

Most likely you will not have to create your own implementations of the matcher interface by hand but will rather use one of the generator procedures below.

Matcher constants and generators

m=anything

Matcher that matches any single token from the input.

((m=wildcard-anything->%a a)
 #!optional (min-repeat 0) (max-repeat #f) dst) => <m-interface>

Creates a matcher that matches a sequence of arbitrary tokens from the input that is at least min-repeat long and at most max-repeat long. If max-repeat is #f, any remaining input is eaten up. The matched tokens are collected using the given accumulator interface.

((m=item/%t t) f) => <m-interface>

Creates a matcher that matches a single element satisfying the given test.

((m=not-item/%t t) f) => <m-interface>

Creates a matcher that matches a single element not satisfying the given test.

((m=wildcard-item/%t->%a t a)
 f #!optional (min-repeat 1) (max-repeat #f) dst) => <m-interface>

Creates a matcher that matches a sequence of tokens matching the given test that is at least min-repeat long and at most max-repeat long. If max-repeat is #f, any remaining input is eaten up. The matched tokens are collected using the given accumulator interface.

((m=wildcard-not-item/%t->%a t a)
 f #!optional (min-repeat 1) (max-repeat #f) dst) => <m-interface>

Creates a matcher that matches a sequence of tokens not matching the given test that is at least min-repeat long and at most max-repeat long. If max-repeat is #f, any remaining input is eaten up. The matched tokens are collected using the given accumulator interface.