Sometimes data is in fixed fields. The patTab, patRTab, patLen, patPos, and patRPos functions make it easy to split out the fields in a fixed field string. PatTab and patRTab work from the left and right end of the string and take a number as their argument. They succeed by matching forward to the specified tab position. For example:
p = patPos(10) + patTab(15);
PatPos(10) matches the null string if it is in position 10. So at match time, the matcher works its way forward to position 10, then patTab(15) matches text from the current position (10) forward to position 15. This pattern is equivalent to patPos(10)+patLen(5). Another example:
p = patPos(0) + patRTab(0);
This example matches the entire string, from 0 characters from the start to 0 characters from the end. the patRem() function takes no argument and is shorthand for patRTab(0); it means the remainder of the string. Pattern matching can also be anchored to the beginning of the string like this:
patMatch( "now is the time", patLen(15) + patRPos(0), NULL, ANCHOR );
The above pattern uses NULL rather than a replacement value, and ANCHOR as an option. Both are uppercase, as shown. NULL means that no replacement is done. ANCHOR means that the match is anchored to the beginning of the string. The default value is UNANCHORED.
Patterns can be built up like this, but this is not recursive:
p = "a" | "b"; // matches one character
p = p + p; // two characters
p = p + p; // four characters
Pat Match( "babb", patPos(0) + p + patRPos(0) );
p = "<" + expr(p) + "*" + expr(p) + ">" | "x";
Pat Match( "<<x*<x*x>>*x>", patPos(0) + p + patRPos(0) );
Remember, expr() is the procrastination function; when the pattern is assigned to the variable p, expr() delays evaluating its argument (p) until later. In the next statement, patMatch performs the pattern match operation, and each time it encounters expr(), it looks for the current value of the argument. In this example, the value does not change during the match). So, if p is defined in terms of itself, how can this possibly work?
p consists of two alternatives. The right hand choice is easy: a single letter x. The left side is harder: <p*p> . Each p could be a single letter x, since that is one of the choices p could match, or it could be <p*p>. The last few example have used patPos(0) + ... + patRPos(0) to make sure the pattern matches the entire source text. Sometimes this is what you want, and sometimes you would rather the pattern match a subtext. If you are experimenting with these examples by changing the source text, you probably want to match the entire string to easily tell what was matched. The result from Pat Match is 0 or 1.
x = Expr(x) + "a" | "b"; // + binds tighter than |
If the pattern is used in FULLSCAN mode, it eventually uses up all memory as it expands. By default, the patMatch function does not use FULLSCAN, and makes some assumptions that allow the recursion to stop and the match to succeed. The pattern matches either a “b”, or anything the pattern matches followed by an “a”.
rc = Pat Match( "baaaaa", x );