Next: Builtin functions, Previous: Macro processing, Up: Top [Contents][Index]
| • Activation of patterns: | ||
| • Pattern parts: | ||
| • Pattern parts working together: |
In this part the use and working of patterns is explained.
A pattern is a collection of pattern parts with associated programs. The programs are used to perform certain data transactions after a certain pattern part is detected.
Patterns do not function on their own, but are linked to macros when defining a macro. Unlike macros, patterns have a global scope and are not restricted to a macro set.
Patterns are mostly used for collecting arguments of macros. However, because of their flexibility they can also be used for other purposes such as argument substitution in the definition string or perform parser functions for e.g. infix notations.
Next: Pattern parts, Up: Patterns [Contents][Index]
Patterns are not permanently active. They are active from a certain point and end at another:
As a consequence of the linking to macros, at any one time only one pattern can be active. This does of course not exclude the nested use of macros and their associated patterns.
Next: Pattern parts working together, Previous: Activation of patterns, Up: Patterns [Contents][Index]
Pattern parts make up a pattern and are detected in the same way as macros. However they do not replace a piece of text, but start a small program to do the necessary work.
Pattern parts are detected in the same way as macros, but have more possibilities. Whereas a macro name has only the possibility for character or byte sets for a position, pattern parts have also the possibilities to:
?.
+.
*.
~.
A set of characters is defined like in macro names with default square brackets. An example of all letters in ASCII code for a single position:
[a-zA-Z]
The set notation also has to be used for the other mentioned possibilities. The special character to define one of the possibilities is placed directly behind the set. For example to have zero or one character of a set of all letters:
[a-zA-Z]?
As can be seen from the previous examples, the - is the default to indicate
a range of characters in a set.
Instead of the direct indication of a character, also the ASCII number
can be used to define a character. The default character @ is used to indicate
that the following hexadecimal number defines an ASCII character.
For example:
@41
is the letter A.
A standard pattern part is triggered in the same way as a macro: all characters should be in the input to match.
An example: a pattern part defined as [a-z] will be triggered with an input of
Hello at the e, l, l and o.
A pattern part can also be set to depend on the previous pattern part using an append pattern part function. The matching of the appended pattern part will only start if the previous pattern part triggered, just as if the two pattern parts are one. For example:
First pattern part
el
Appended pattern part
[a-z]
With input
Hello
Will trigger the first pattern part at the end of Hel
and trigger the appended pattern part at the following l.
Together with the pattern part a small forth like program is defined. This program will need to do the necessary work for the pattern part. It is executed when the pattern part is triggered by a match in the input.
All the available instructions for the programs can be found in Programs for patterns and macros.
Previous: Pattern parts, Up: Patterns [Contents][Index]
The pattern parts together form a pattern that can do something useful. The selection of the parts is therefore
an important aspect of having a proper working pattern. To illustrate this a similar pattern to
the default 0 pattern for argument collection is used as an example.
The following example is a pattern for collecting arguments with a similar syntax as the argument collection of m4.
It is however more simple, in that leading spaces in arguments are not excluded and that the argument characters
"(" and ")" can not be nested.
The example uses a 0_pattern macro linked to the pattern function to define a pattern that
is similar to the default pattern 0, but uses the:
(" instead of ":" as the start character of argument collection.
," instead of ";" as the separator character of the arguments.
)" instead of the newline as the stop character of argument collection.
This example is using the pattern 0 for argument collection. The new pattern will be named 1.
The complete pattern is defined by:
0_pattern:1;[@00-@27@29-@ff]~;argpos =0 ifthen abort 0_pattern:1;[,)];end 0_pattern:1;[(,];begin 0_pattern:1;);stop
The first line:
0_pattern:1;[@00-@27@29-@ff]~;argpos =0 ifthen abort
defines a pattern part consisting of a single character, whereby every character except the "(" (@28) will match.
It will test if a macro has arguments by checking if the first character is a "(" or not.
It is triggered only once (the "~" is used). Thus if the character in the input is not "(" the
pattern part matches and the program is executed.
The program checks if it is executed at the first position: argpos =0 ifthen. If it is executed at the
first position, then the first character in the input is not "(", no arguments follow and the collection
of arguments is aborted by: abort.
If the first character is "(", then the program will be executed later than the first position and the
abort will not be executed.
The second line:
0_pattern:1;[,)];end
defines a pattern part consisting of a single character, whereby this character is either a "," or a ")".
If the input matches, then this is the end of an argument. The argument is then put on the stack by: end.
The third line:
0_pattern:1;[(,];begin
defines a pattern part consisting of a single character, whereby this character is either a "(" or a ",".
If the input matches, then this is the begin of an argument. The argument start position is stored by: begin.
The last line:
0_pattern:1;);stop
defines a pattern part consisting of a single character, whereby this character a ")".
If the input matches, then this is means the end the argument collection. The argument collection
is stopped by: stop. After this the macro has collected all arguments and continues.
It can be seen that different pattern parts are triggered at the same time by the same input. The order of the definition of the pattern parts therefore plays an important role.
Every pattern part that matches will trigger the related program. Thus multiple pattern parts can trigger their programs at the same position. The order in which these programs execute can have a big influence on the result, therefore the order of execution is:
Pattern parts are triggered in order of definition.
In the example above the "," executes both the end and begin.
This character is the separator between arguments. The previous argument should first be put on the stack by
the end and the next argument can then be started by the begin.Thus the pattern part with the
end is defined before the pattern part with begin. In a similar way the argument collection
should put the last argument on the stack before it stops.
The issue of priority can also be overcome by a different pattern definition:
0_pattern:1;[@00-@27@29-@ff]~;argpos =0 ifthen abort 0_pattern:1;,;end begin 0_pattern:1;(;begin 0_pattern:1;);end stop
However for more complex patterns the priority still plays a role.
Previous: Pattern parts, Up: Patterns [Contents][Index]