defining a custom notation

The predefined notation in myPatterns can be overridden very easily with a custom notation for a particular class.

For example, let us define the usual mathematical notation for the following simple type of complex numbers.

public class Complex {
    double re, im;
    public Complex(double r, double i) { re = r; im = i; }
}
The usual notation for complex numbers is "a + bi" for a complex number with an imaginary part, and simply "a" for complex numbers whith a no imaginary part. However, in myPatterns, all notations must start with an open parenthesis (one of "([{") and end with the corresponding closing parenthesis (")]}"). Thus, the implemented notation will be in fact "(a + bi)" and "(a)", respectively.

Defining this notation for Complex objects is simply done by declaring that the Complex class implements the Notation interface, and by implementing an appropriate matches() method:

public boolean matches(String pat, ParsePosition pos, Subst sub) {
    return
        Matchbox.matchChar('(', pat, pos)
        && Matchbox.matchData(this.re, pat, pos, sub)
        && (pat.charAt(pos.getIndex()) == '+'
            && Matchbox.matchChar('+', pat, pos)
            && Matchbox.matchData(this.im, pat, pos, sub)
            && Matchbox.matchChar('i', pat, pos)
            || pat.charAt(pos.getIndex()) == ')' && this.im == 0)
        && Matchbox.matchChar(')', pat, pos);
}
This method matches in fact a sub-pattern at a given offset (represented as a ParsePosition) with the current Complex. The third argument is the substitution already accumulated while matching the portion of the pattern that appears before the current sub-pattern (i.e. between the beginning of the pattern and the given offset). This substitution must simply be passed to all the worker functions that require it. There are predefined worker function for matching a character (matchChar()), a token (matchToken()), and a sub-data (matchData()). If the match is successful, the method must update the parse position, reflecting the sub-pattern that has been consumed, and return true. If the match is unsuccessful, the method must return false.

Using this notation, the following calls to match():

System.out.println(Matchbox.match(new Complex(2, 3), "(%x+%yi)"));
System.out.println(Matchbox.match(new Complex(2, 0), "(%x+%yi)"));
System.out.println(Matchbox.match(new Complex(2, 0), "(%x)"));
System.out.println(Matchbox.match(new Complex(1, 2), "(1.0+%yi)"));
print the following substitutions:
{ x:2.0 y:3.0 }
{ x:2.0 y:0.0 }
{ x:2.0 }
{ y:2.0 }

Next: Parsed notations