Classes

To avoid having to write out lists of alternatives over and over, tadpole allows you to define classes:

class ab = 'a' 'b';

A class can be used as both a matcher and a replacer simply using its name:

class ab = 'a' 'b';
class bc = 'b' 'c';
rule classes = ab@i -> bc@i;

This behaves in much the same way as an alternative construct listing all the symbols in the class, including interacting with bindings.

You can also combine classes, for example to create a consonant class from multiple more specific ones:

class stop = 'p' 't' 'k';
class nasal = 'm' 'n';
class cons = stop | nasal | 'r'; 

Combining classes in this way will preserve the order of symbols, but any duplicates are removed.

Classes not just reduce the amount of code needed, but also simplify working with longer symbols and segmentation.

Segmentation

There is a complication when working with symbol matchers: 'a' 'b' is not equal to 'ab'. In some situations, this can be sidestepped using the previously mentioned string constructs, but sometimes you need more control.

By default, tadpole segments the input into symbols based on unicode characters. This can sometimes lead to unexpected results, for example with accented characters becoming two symbols.

To control segmentation and use it to your advantage, tadpole offers several methods. The simplest is to use classes to define all the symbols in the language, and then segment based on these symbols.

class cls = 'a' 'b' 'c' 'k' 'ck';
segmentation class all;

This will segment back into 'b' 'a' 'ck'. Input segmentation generates all possible ways of dividing the input into valid symbols and chooses the one with the least symbols. If multiple segmentations with the same number of symbols are possible, the result is not specified and may not be what you want but should be consistent.

Having a symbol 'ck' means that the string "c" will not match this word, because strings can’t split symbols.

You can also specify a list of classes to use for segmentation while ignoring others:

segmentation class vow cons;

Note that the segmentation directive captures the state of class definitions at the point it is called, so you should always call it after defining all the classes you need.

In most cases, segmentation class all; after defining your classes is sufficient to segment inputs in a useful way.

If a rule could create an unwanted segmentation, for example by inserting a symbol you’d want merged with another, you can rerun segmentation at any point by running:

segmentation rebuild;

Finally, to reset the segmentation settings to default, use

segmentation clear;