~snowball-yiddish-dev/snowball-yiddish/trunk

« back to all changes in this revision

Viewing changes to website/p/snowman.html

  • Committer: martinporter
  • Date: 2001-10-19 11:36:36 UTC
  • Revision ID: svn-v4:633ccae0-01f4-0310-8c99-d3591da6f01f:trunk:60
initialĀ upload

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
<HTML>
 
3
<HEAD>
 
4
<TITLE>Snowball Manual</TITLE></HEAD>
 
5
<BODY BGCOLOR=WHITE>
 
6
<TABLE WIDTH=75% ALIGN=CENTER COLS=1>
 
7
<H1 ALIGN=CENTER>Snowball Manual</H1>
 
8
<TR><TD BGCOLOR="#FCFCe0">
 
9
<BR>&nbsp;<H2>Links to resources</H2>
 
10
<DL><DD><TABLE CELLPADDING=0>
 
11
<TR><TD><A HREF="../q/use.html">          Using Snowball</A>
 
12
<TR><TD><A HREF="../porter/stemmer.html"> Porter stemmer - a case study</A>
 
13
</TABLE></DL>
 
14
</TR>
 
15
 
 
16
<TR><TD>
 
17
<BR><BR>
 
18
 
 
19
<BR>&nbsp;<H2>Snowball definition</H2>
 
20
 
 
21
Snowball is a small string-handling language, and its name was chosen as a
 
22
tribute to SNOBOL (Farber 1964, Griswold 1968), with which it shares the
 
23
concept of string patterns delivering signals that are used to control the
 
24
flow of the program.
 
25
 
 
26
<BR>&nbsp;<H2>Data types</H2>
 
27
 
 
28
The basic data types handled by Snowball are strings of characters, signed
 
29
integers, and boolean truth values, or more simply <I>strings</I>, <I>integers</I>
 
30
and <I>booleans</I>. At present Snowball's characters are 8-bit ASCII, which is
 
31
sufficient for presenting the algorithms, but at some point Unicode
 
32
characters will need to be supported.
 
33
 
 
34
<BR>&nbsp;<H2>Names</H2>
 
35
 
 
36
A name in Snowball is a letter followed by zero or more letters, digits
 
37
and underlines. A name can be of type <I>string</I>, <I>integer</I>, <I>boolean</I>,
 
38
<I>routine</I>, <I>external</I> or <I>grouping</I>. All names must be declared. A
 
39
declaration has the form
 
40
<BR><PRE>
 
41
    Ts ( ... )
 
42
</PRE>
 
43
where symbol &nbsp;<TT>T</TT>&nbsp; is one of &nbsp;<TT>string</TT>, &nbsp;<TT>integer</TT>&nbsp; etc, and the region in
 
44
brackets contains a list of names separated by whitespace. For example,
 
45
<BR><PRE>
 
46
    integers ( p1 p2 )
 
47
    booleans ( Y_found )
 
48
 
 
49
    routines (
 
50
       shortv
 
51
       R1 R2
 
52
       Step_1a Step_1b Step_1c Step_2 Step_3 Step_4 Step_5a Step_5b
 
53
    )
 
54
 
 
55
    externals ( stem )
 
56
 
 
57
    groupings ( v v_WXY v_LSZ )
 
58
</PRE>
 
59
<TT>p1</TT>&nbsp; and &nbsp;<TT>p2</TT>&nbsp; are integers, &nbsp;<TT>Y_found</TT>&nbsp; is boolean, and so on. Snowball is quite
 
60
strict about the declarations, so all the names go in the same name space,
 
61
no name may be declared twice, all used names must be declared, no two
 
62
routine definitions can have the same name, etc. Names declared and
 
63
subsequently not used are merely reported in a warning message. A name may
 
64
not be one of the reserved words of Snowball.
 
65
 
 
66
<BR>&nbsp;<H2>Literals</H2>
 
67
 
 
68
A literal integer is a digit sequence, and is always interpreted as
 
69
decimal. A literal string is written between single quotes, for example,
 
70
<BR><PRE>
 
71
    'aeiouy'
 
72
</PRE>
 
73
A string may be preceded by the word &nbsp;<TT>hex</TT>, in which case the contents are
 
74
interpreted as being written out in hexadecimal notation, e.g.
 
75
<BR><PRE>
 
76
    hex '0D0A'  /* carriage return, line feed */
 
77
</PRE>
 
78
Equivalently
 
79
<BR><PRE>
 
80
    hex '0d0a'   /* lower case also allowed */
 
81
    hex '0D 0A'  /* spaces ignored */
 
82
</PRE>
 
83
But &nbsp;<TT>hex 'd0a'</TT>&nbsp; would be an error: the number of enclosed symbols must be
 
84
even.
 
85
<BR><BR>
 
86
Strings may include special <I>string macro</I> sequences, to handle unusual
 
87
character combinations.
 
88
<BR><BR>
 
89
String macros may be defined in the form &nbsp;<TT>stringdef m 'S'</TT>, where &nbsp;<TT>'S'</TT>&nbsp; is a
 
90
string, and &nbsp;<TT>m</TT>&nbsp; a sequence of one or more printing characters terminating
 
91
with whitespace.
 
92
<BR><BR>
 
93
Two special <I>insert characters</I> are defined by the directive
 
94
<TT>stringescapes AB</TT>, where &nbsp;<TT>A</TT>&nbsp; and &nbsp;<TT>B</TT>&nbsp; are printing characters, and &nbsp;<TT>A</TT>&nbsp; is not
 
95
single quote. (<TT>B</TT>&nbsp; may equal &nbsp;<TT>A</TT>, but then &nbsp;<TT>A</TT>&nbsp; itself can never be escaped.) For
 
96
example,
 
97
<BR><PRE>
 
98
    stringescapes []
 
99
</PRE>
 
100
A subsequent occurrence of the same directive redefines the insert
 
101
characters.
 
102
<BR><BR>
 
103
Thereafter, &nbsp;<TT>[m]</TT>&nbsp; inside a string causes &nbsp;<TT>S</TT>&nbsp; to be substituted in place of &nbsp;<TT>m</TT>.
 
104
<BR><BR>
 
105
Immediately after the stringescapes directive, &nbsp;<TT>[']</TT>&nbsp; will substitute &nbsp;<TT>'</TT>&nbsp; and
 
106
<TT>[[]</TT>&nbsp; will substitute &nbsp;<TT>[</TT>, although macros &nbsp;<TT>'</TT>&nbsp; and &nbsp;<TT>[</TT>&nbsp; may subsequently be
 
107
redefined. A further feature is that &nbsp;<TT>[<I>W</I>]</TT>&nbsp; inside a string, where &nbsp;<TT><I>W</I></TT>&nbsp; is a
 
108
sequence of whitespace characters including one or more newlines, is
 
109
ignored. This enables long strings to be written over a number of lines.
 
110
<BR><BR>
 
111
For example,
 
112
<BR><PRE>
 
113
    stringescapes []
 
114
 
 
115
    /* special Spanish characters (in ISO Latin) */
 
116
 
 
117
    stringdef a'   hex 'A0'  // a-acute
 
118
    stringdef e'   hex '82'  // e-acute
 
119
    stringdef i'   hex 'A1'  // i-acute
 
120
    stringdef o'   hex 'A2'  // o-acute
 
121
    stringdef u'   hex 'A3'  // u-acute
 
122
    stringdef u"   hex '81'  // u-diaeresis
 
123
    stringdef n~   hex 'A4'  // n-tilde
 
124
 
 
125
    /* and in the next string we define all the characters in Spanish
 
126
       used to represent vowels
 
127
    */
 
128
 
 
129
    define v 'aeiou[a'][e'][i'][o'][u'][u"]'
 
130
</PRE>
 
131
<BR>&nbsp;<H2>Routines</H2>
 
132
 
 
133
A routine definition has the form
 
134
<BR><PRE>
 
135
    define R as C
 
136
</PRE>
 
137
where &nbsp;<TT>R</TT>&nbsp; is the routine name and &nbsp;<TT>C</TT>&nbsp; is a command, or bracketed group of
 
138
commands. So a routine is defined as a sequence of zero or more commands.
 
139
Snowball routines do not (at present) take parameters. For example,
 
140
<BR><PRE>
 
141
    define Step_5b as (      // this defines Step_5b
 
142
        ['l']                // three commands here: [, 'l' and ]
 
143
        R2 'l'               // two commands, R2 and 'l'
 
144
        delete               // delete is one command
 
145
    )
 
146
 
 
147
    define R1 as $p1 <= cursor
 
148
        /* R1 is defined as the single command "$p1 <= cursor" */
 
149
</PRE>
 
150
A routine is called simply by using its name, &nbsp;<TT>R</TT>, as a command.
 
151
 
 
152
<BR>&nbsp;<H2>Commands and signals</H2>
 
153
 
 
154
The flow of control in Snowball is arranged by the implicit use of
 
155
<I>signals</I>, rather than the explicit use of constructs like the &nbsp;<TT>if</TT>,
 
156
<TT>then</TT>, &nbsp;<TT>break</TT>&nbsp; of C. The scheme is designed for handling strings, but is
 
157
perhaps easier to introduce using integers. Suppose &nbsp;<TT>x</TT>, &nbsp;<TT>y</TT>, &nbsp;<TT>z</TT>&nbsp; ... are
 
158
integers. The command
 
159
<BR><PRE>
 
160
    $x = 1
 
161
</PRE>
 
162
sets &nbsp;<TT>x</TT>&nbsp; to 1. The command
 
163
<BR><PRE>
 
164
    $x > 0
 
165
</PRE>
 
166
tests if &nbsp;<TT>x</TT>&nbsp; is greater than zero. Both commands give a signal <B><I>t</I></B> or <B><I>f</I></B>,
 
167
(<I>true</I> or <I>false</I>), but while the second command gives <B><I>t</I></B> if &nbsp;<TT>x</TT>&nbsp; is greater
 
168
than zero and <B><I>f</I></B> otherwise, the first command always gives <B><I>t</I></B>. In Snowball,
 
169
every command gives a <B><I>t</I></B> or <B><I>f</I></B> signal. A sequence of commands can be turned
 
170
into as a single command by putting them in a list surrounded by round
 
171
brackets:
 
172
<BR><PRE>
 
173
    ( C<SUB>1</SUB> C<SUB>2</SUB> C<SUB>3</SUB> ... C<SUB>i</SUB> C<SUB>i+1</SUB> ... )
 
174
</PRE>
 
175
When this is obeyed, &nbsp;<TT>C<SUB>i+1</SUB></TT>&nbsp; will be obeyed if each of the preceding &nbsp;<TT>C<SUB>1</SUB></TT>&nbsp; ...
 
176
<TT>C<SUB>i</SUB></TT>&nbsp; give <B><I>t</I></B>, but as soon as a &nbsp;<TT>C<SUB>i</SUB></TT>&nbsp; gives <B><I>f</I></B>, the subsequent &nbsp;<TT>C<SUB>i+1</SUB> C<SUB>i+2</SUB></TT>&nbsp; ...
 
177
are ignored, and the whole sequence gives signal <B><I>f</I></B>. If all the &nbsp;<TT>C<SUB>i</SUB></TT>&nbsp; give <B><I>t</I></B>,
 
178
however, the bracketed command sequence also gives <B><I>t</I></B>. So,
 
179
<BR><PRE>
 
180
    $x > 0  $y = 1
 
181
</PRE>
 
182
sets &nbsp;<TT>y</TT>&nbsp; to 1 if &nbsp;<TT>x</TT>&nbsp; is greater than zero. If &nbsp;<TT>x</TT>&nbsp; is less than or equal to zero
 
183
the two commands give <B><I>f</I></B>.
 
184
<BR><BR>
 
185
If &nbsp;<TT>C<SUB>1</SUB></TT>&nbsp; and &nbsp;<TT>C<SUB>2</SUB></TT>&nbsp; are commands, we can build up the larger commands,
 
186
<DL><DD><DL>
 
187
    <DT><TT>C<SUB>1</SUB> or C<SUB>2</SUB></TT>
 
188
        <DD>- Do &nbsp;<TT>C<SUB>1</SUB></TT>. If it gives <B><I>t</I></B> ignore &nbsp;<TT>C<SUB>2</SUB></TT>, otherwise do &nbsp;<TT>C<SUB>2</SUB></TT>. The resulting
 
189
        signal is <B><I>t</I></B> if and only &nbsp;<TT>C<SUB>1</SUB></TT>&nbsp; or &nbsp;<TT>C<SUB>2</SUB></TT>&nbsp; gave <B><I>t</I></B>.
 
190
    <DT><TT>C<SUB>1</SUB> and C<SUB>2</SUB></TT>
 
191
        <DD>- Do &nbsp;<TT>C<SUB>1</SUB></TT>. If it gives <B><I>f</I></B> ignore &nbsp;<TT>C<SUB>2</SUB></TT>, otherwise do &nbsp;<TT>C<SUB>2</SUB></TT>. The resulting
 
192
        signal is <B><I>t</I></B> if and only &nbsp;<TT>C<SUB>1</SUB></TT>&nbsp; and &nbsp;<TT>C<SUB>2</SUB></TT>&nbsp; gave <B><I>t</I></B>.
 
193
    <DT><TT>not C</TT>
 
194
        <DD>- Do &nbsp;<TT>C</TT>. The resulting signal is <B><I>t</I></B> if &nbsp;<TT>C</TT>&nbsp; gave <B><I>f</I></B>, otherwise <B><I>f</I></B>.
 
195
    <DT><TT>try C</TT>
 
196
        <DD>- Do &nbsp;<TT>C</TT>. The resulting signal is <B><I>t</I></B> whatever the signal of &nbsp;<TT>C</TT>.
 
197
    <DT><TT>fail C</TT>
 
198
        <DD>- Do &nbsp;<TT>C</TT>. The resulting signal is <B><I>f</I></B> whatever the signal of &nbsp;<TT>C</TT>.
 
199
</DL></DL>
 
200
So for example,
 
201
<DL><DD><DL>
 
202
    <DT><TT>($x > 0  $y = 1) or ($y = 0)</TT>
 
203
        <DD>- sets &nbsp;<TT>y</TT>&nbsp; to 1 if &nbsp;<TT>x</TT>&nbsp; is greater than zero, otherwise to zero.
 
204
 
 
205
    <DT><TT>try( ($x > 0) and ($z > 0) $y = 1)</TT>
 
206
        <DD>- sets &nbsp;<TT>y</TT>&nbsp; to 1 if both &nbsp;<TT>x</TT>&nbsp; and &nbsp;<TT>z</TT>&nbsp; are greater than 0, and gives <B><I>t</I></B>.
 
207
</DL></DL>
 
208
This last example is the same as
 
209
<BR><PRE>
 
210
    try($x > 0  $z > 0  $y = 1)
 
211
</PRE>
 
212
so that &nbsp;<TT>and</TT>&nbsp; seems unnecessary here. But we will see that &nbsp;<TT>and</TT>&nbsp; has a
 
213
particular significance in string commands.
 
214
<BR><BR>
 
215
When a &#8216;monadic&#8217; construct like &nbsp;<TT>not</TT>, &nbsp;<TT>try</TT>&nbsp; or &nbsp;<TT>fail</TT>&nbsp; is not followed by a
 
216
round bracket, the construct applies to the shortest following valid command.
 
217
So for example
 
218
<BR><PRE>
 
219
    try not $x < 1 $z > 0
 
220
</PRE>
 
221
would mean
 
222
<BR><PRE>
 
223
    try ( not ( $x < 1 ) ) $z > 0
 
224
</PRE>
 
225
because &nbsp;<TT>$x < 1</TT>&nbsp; is the shortest valid command following &nbsp;<TT>not</TT>, and then
 
226
<TT>not $x < 1</TT>&nbsp; is the shortest valid command following &nbsp;<TT>try</TT>.
 
227
<BR><BR>
 
228
The &#8216;diadic&#8217; constructs like &nbsp;<TT>and</TT>&nbsp; and &nbsp;<TT>or</TT>&nbsp; must sit in a bracketed list
 
229
of commands anyway, for example,
 
230
<BR><PRE>
 
231
    ( C<SUB>1</SUB> C<SUB>2</SUB> and C<SUB>3</SUB> C<SUB>4</SUB> or C<SUB>5</SUB> )
 
232
</PRE>
 
233
And then in this case &nbsp;<TT>C<SUB>2</SUB></TT>&nbsp; and &nbsp;<TT>C<SUB>3</SUB></TT>&nbsp; are connected by the &nbsp;<TT>and</TT>; &nbsp;<TT>C<SUB>4</SUB></TT>&nbsp; and &nbsp;<TT>C<SUB>5</SUB></TT>&nbsp; are
 
234
connected by the &nbsp;<TT>or</TT>. So
 
235
<BR><PRE>
 
236
    $x > 0  not $y > 0 or not $z > 0  $t > 0
 
237
</PRE>
 
238
means
 
239
<BR><PRE>
 
240
    $x > 0  ((not ($y > 0)) or (not ($z > 0)))  $t > 0
 
241
</PRE>
 
242
<TT>and</TT>&nbsp; and &nbsp;<TT>or</TT>&nbsp; are equally binding, and bind from left to right,
 
243
so &nbsp;<TT>C<SUB>1</SUB> or C<SUB>2</SUB> and C<SUB>3</SUB></TT>&nbsp; means &nbsp;<TT>(C<SUB>1</SUB> or C<SUB>2</SUB>) and C<SUB>3</SUB></TT>&nbsp; etc.
 
244
 
 
245
<BR>&nbsp;<H2>AEs and integer commands</H2>
 
246
 
 
247
An AE (arithmetic expression) consists of integer names and literal
 
248
numbers connected by diadic &nbsp;<TT>+</TT>, &nbsp;<TT>-</TT>, &nbsp;<TT>*</TT>&nbsp; and &nbsp;<TT>/</TT>, and monadic &nbsp;<TT>-</TT>, with the same
 
249
binding powers and semantics as C. An integer command has the form
 
250
<BR><PRE>
 
251
    $X <I>op</I> AE
 
252
</PRE>
 
253
where &nbsp;<TT>X</TT>&nbsp; is an integer name and <I>op</I> is one of the six tests &nbsp;<TT>==</TT>, &nbsp;<TT>!=</TT>, &nbsp;<TT>>=</TT>, &nbsp;<TT>></TT>,
 
254
<TT><=</TT>, &nbsp;<TT><</TT>, or five assignments &nbsp;<TT>=</TT>, &nbsp;<TT>+=</TT>, &nbsp;<TT>-=</TT>, &nbsp;<TT>*=</TT>, &nbsp;<TT>/=</TT>. Again, the meanings are the
 
255
same as in C.
 
256
<BR><BR>
 
257
As well as integer names and literal numbers, the following may be used in
 
258
AEs:
 
259
<DL><DD><TABLE CELLPADDING=0>
 
260
<TR><TD><TT>minint</TT>&nbsp;   <TD></TD><TD>  - the smallest negative number
 
261
<TR><TD><TT>maxint</TT>&nbsp;   <TD></TD><TD>  - the largest positive number
 
262
<TR><TD><TT>sizeof s</TT>&nbsp; <TD></TD><TD>  - the number of characters in &nbsp;<TT>s</TT>, where &nbsp;<TT>s</TT>&nbsp; is the name of a string
 
263
<TR><TD><TT>cursor</TT>&nbsp;   <TD></TD><TD>  - the current value of the string <I>cursor</I>
 
264
<TR><TD><TT>limit</TT>&nbsp;    <TD></TD><TD>  - the current value of the string <I>limit</I>
 
265
<TR><TD><TT>size</TT>&nbsp;     <TD></TD><TD>  - the size of the string, in characters
 
266
</TABLE></DL>
 
267
The <I>cursor</I> and <I>limit</I> concepts are explained below.
 
268
<BR><BR>
 
269
Examples of integer commands are,
 
270
<BR><PRE>
 
271
    $p1 <= cursor  // signal is f if the cursor is before position p1
 
272
    $p1 = limit    // set p1 to the string limit
 
273
</PRE>
 
274
 
 
275
<BR>&nbsp;<H2>String commands</H2>
 
276
 
 
277
If &nbsp;<TT>s</TT>&nbsp; is a string name, a string command has the form
 
278
<BR><PRE>
 
279
    $s C
 
280
</PRE>
 
281
where &nbsp;<TT>C</TT>&nbsp; is a command that operate on the string. Strings can be processed
 
282
left-to-right or right-to-left, but we will describe only the
 
283
left-to-right case for now. The string has a <I>cursor</I>, which we will
 
284
denote by <B><I>c</I></B>, and a limit point, or <I>limit</I>, which we will denote by <B><I>l</I></B>. <B><I>c</I></B>
 
285
advances towards <B><I>l</I></B> in the course of a string command, but the various
 
286
constructs &nbsp;<TT>and</TT>, &nbsp;<TT>or</TT>, &nbsp;<TT>not</TT>&nbsp; etc have side-effects which keep moving it
 
287
backwards. Initially <B><I>c</I></B> is at the start and <B><I>l</I></B> the end of the string. For
 
288
example,
 
289
<BR><PRE>
 
290
        'a|n|i|m|a|d|v|e|r|s|i|o|n'
 
291
        |                         |
 
292
        c                         l
 
293
</PRE>
 
294
<B><I>c</I></B>, and <B><I>l</I></B>, mark the boundaries between characters, and not
 
295
characters themselves. The characters between <B><I>c</I></B> and <B><I>l</I></B> will be denoted by
 
296
<B><I>c:l</I></B>.
 
297
<BR><BR>
 
298
If &nbsp;<TT>C</TT>&nbsp; gives <B><I>t</I></B>, the cursor <B><I>c</I></B> will have a new, well-defined value. But if &nbsp;<TT>C</TT>
 
299
gives <B><I>f</I></B>, <B><I>c</I></B> is undefined. Its later value will in fact be determined by the
 
300
outer context of commands in which &nbsp;<TT>C</TT>&nbsp; came to be obeyed, not by &nbsp;<TT>C</TT>&nbsp; itself.
 
301
<BR><BR>
 
302
Here is a list of the commands that can be used to operate on strings.
 
303
 
 
304
&nbsp;<H4>a) Setting a value</H4>
 
305
 
 
306
 
 
307
<DL>
 
308
<DT><TT>= S</TT>
 
309
    <DD>where &nbsp;<TT>S</TT>&nbsp; is the name of a string or a literal string. <B><I>c:l</I></B> is set equal
 
310
    to &nbsp;<TT>S</TT>, and <B><I>l</I></B> is adjusted to point to the end of the copied string. The
 
311
    signal is <B><I>t</I></B>. For example,
 
312
<BR><PRE>
 
313
        $x = 'animadversion'    /* literal string */
 
314
        $y = x                  /* string name */
 
315
</PRE>
 
316
</DL>
 
317
 
 
318
&nbsp;<H4>b) Basic tests</H4>
 
319
 
 
320
<DL>
 
321
<DT><TT>S</TT>
 
322
    <DD>here and below, &nbsp;<TT>S</TT>&nbsp; is the name of a string or a literal string. If <B><I>c:l</I></B>
 
323
    begins with the substring &nbsp;<TT>S</TT>, <B><I>c</I></B> is repositioned to the end of this
 
324
    substring, and the signal is <B><I>t</I></B>. Otherwise the signal is <B><I>f</I></B>. For example,
 
325
<BR><PRE>
 
326
        $x 'anim'   /* gives t, assuming the string is 'animadversion' */
 
327
        $x ('anim' 'ad' 'vers')
 
328
                    /* ditto */
 
329
 
 
330
        $t = 'anim'
 
331
        $x t        /* ditto */
 
332
</PRE>
 
333
<DT><TT>C<SUB>1</SUB> or C<SUB>2</SUB></TT>
 
334
    <DD>This is like the case for integers described above, but the extra
 
335
    touch is that if &nbsp;<TT>C<SUB>1</SUB></TT>&nbsp; gives <B><I>f</I></B>, <B><I>c</I></B> is set back to its old position after
 
336
    &nbsp;<TT>C<SUB>1</SUB></TT>&nbsp; has given <B><I>f</I></B> and before &nbsp;<TT>C<SUB>2</SUB></TT>&nbsp; is tried, so that the test takes place on
 
337
    the same point in the string. So we have
 
338
<BR><PRE>
 
339
        $x ('anim'  /* signal t */
 
340
            'ation' /* signal f */
 
341
           ) or
 
342
           ( 'an'   /* signal t - from the beginning */
 
343
           )
 
344
</PRE>
 
345
<DT><TT>true</TT>, &nbsp;<TT>false</TT>
 
346
    <DD><TT>true</TT>&nbsp; is a dummy command that generates signal <B><I>t</I></B>. &nbsp;<TT>false</TT>&nbsp; generates
 
347
    signal <B><I>f</I></B>. They are sometimes useful for emphasis,
 
348
<BR><PRE>
 
349
        define start_off as true       // nothing to do
 
350
        define exception_list as false // put in among(...) list later
 
351
 
 
352
</PRE>
 
353
        &nbsp;<TT>true</TT>&nbsp;      is equivalent to     &nbsp;<TT>()</TT>
 
354
<DT><TT>C<SUB>1</SUB> and C<SUB>2</SUB></TT>
 
355
    <DD>And similarly <B><I>c</I></B> is set back to its old position after &nbsp;<TT>C<SUB>1</SUB></TT>&nbsp; has given <B><I>t</I></B>
 
356
    and before &nbsp;<TT>C<SUB>2</SUB></TT>&nbsp; is tried. So,
 
357
<BR><PRE>
 
358
        $x 'anim' and 'an'   /* signal t */
 
359
        $x ('anim'  'an')    /* signal f, since 'an' and 'ad' mis-match */
 
360
</PRE>
 
361
<DT><TT>not C</TT>
 
362
<DT><TT>try C</TT>
 
363
    <DD>These are like the integer tests, with the added feature that <B><I>c</I></B> is set
 
364
    back to its old position after an <B><I>f</I></B> signal is turned into <B><I>t</I></B>. So,
 
365
<BR><PRE>
 
366
        $x (not 'animation' not 'immersion')
 
367
            /* both tests are done at the start of the string */
 
368
 
 
369
        $x (try 'animus' try 'an'
 
370
            'imad')
 
371
            /* - gives t */
 
372
</PRE>
 
373
<DL><DD><TABLE CELLPADDING=0>
 
374
<TR><TD>        &nbsp;<TT>try C</TT>&nbsp;     <TD></TD><TD> is equivalent to <TD></TD><TD>    &nbsp;<TT>C or true</TT>
 
375
</TABLE></DL>
 
376
<DT><TT>test C</TT>
 
377
    <DD>This does command &nbsp;<TT>C</TT>&nbsp; but without advancing <B><I>c</I></B>. Its signal is the same as
 
378
    the signal of &nbsp;<TT>C</TT>, but following signal <B><I>t</I></B>, <B><I>c</I></B> is set back to its old
 
379
    value.
 
380
<DL><DD><TABLE CELLPADDING=0>
 
381
<TR><TD>        &nbsp;<TT>test C</TT>&nbsp;       <TD></TD><TD>  is equivalent to   <TD></TD><TD>  &nbsp;<TT>not not C</TT>
 
382
<TR><TD>        &nbsp;<TT>test C<SUB>1</SUB> C<SUB>2</SUB></TT>&nbsp; <TD></TD><TD>  is equivalent to   <TD></TD><TD>  &nbsp;<TT>C<SUB>1</SUB> and C<SUB>2</SUB></TT>
 
383
</TABLE></DL>
 
384
<DT><TT>fail C</TT>
 
385
    <DD>This does &nbsp;<TT>C</TT>&nbsp; and gives signal <B><I>f</I></B>. It is equivalent to &nbsp;<TT>C false</TT>. Like
 
386
    &nbsp;<TT>false</TT>&nbsp; it is useful, but only rarely.
 
387
 
 
388
<DT><TT>do C</TT>
 
389
    <DD>This does &nbsp;<TT>C</TT>, puts <B><I>c</I></B> back to its old value and gives signal <B><I>t</I></B>. It is
 
390
    very useful as a way of suppressing the side effect of <B><I>f</I></B> signals and
 
391
    cursor movement.
 
392
<DL><DD><TABLE CELLPADDING=0>
 
393
<TR><TD>        &nbsp;<TT>do C</TT>&nbsp;     <TD></TD><TD>  is equivalent to   <TD></TD><TD>  &nbsp;<TT>try test C</TT>
 
394
<TR><TD>                     <TD></TD><TD>  or                 <TD></TD><TD>  &nbsp;<TT>test try C</TT>
 
395
</TABLE></DL>
 
396
<DT><TT>goto C</TT>
 
397
    <DD><B><I>c</I></B> is moved right until obeying &nbsp;<TT>C</TT>&nbsp; gives <B><I>t</I></B>. But if <B><I>c</I></B> cannot be moved
 
398
    right because it is at <B><I>l</I></B> the signal is <B><I>f</I></B>. <B><I>c</I></B> is set back to the position
 
399
    it had before the last obeying of &nbsp;<TT>C</TT>, so the effect is to leave <B><I>c</I></B> before
 
400
    the pattern which matched against &nbsp;<TT>C</TT>.
 
401
<BR><PRE>
 
402
        $x goto 'ad'         /* positions c after 'anim' */
 
403
        $x goto 'ax'         /* signal f */
 
404
</PRE>
 
405
<DT><TT>gopast C</TT>
 
406
    <DD>Like goto, but <B><I>c</I></B> is not set back, so the effect is to leave <B><I>c</I></B> after
 
407
    the pattern which matched against &nbsp;<TT>C</TT>.
 
408
<BR><PRE>
 
409
        $x gopast 'ad'       /* positions c after 'animad' */
 
410
</PRE>
 
411
<DT><TT>repeat C</TT>
 
412
    <DD><TT>C</TT>&nbsp; is repeated until it gives <B><I>f</I></B>. When this happens <B><I>c</I></B> is set back to the
 
413
    position it had before the last repetition of &nbsp;<TT>C</TT>, and &nbsp;<TT>repeat C</TT>&nbsp; gives
 
414
    signal <B><I>t</I></B>. For example,
 
415
<BR><PRE>
 
416
        $x repeat gopast 'a' /* position c after the last 'a' */
 
417
</PRE>
 
418
<DT><TT>loop AE C</TT>
 
419
    <DD>This is like &nbsp;<TT>C C ... C</TT>&nbsp; written out AE times, where AE is an arithmetic
 
420
    expression. For example,
 
421
<BR><PRE>
 
422
        $x loop 2 gopast ('a' or 'e' or 'i' or 'o' or 'u')
 
423
            /* position c after the second vowel */
 
424
</PRE>
 
425
    The equivalent expression in C has the shape,
 
426
<BR><PRE>
 
427
        {    int i;
 
428
             int limit = AE;
 
429
             for (i = 0; i < limit; i++) C;
 
430
        }
 
431
</PRE>
 
432
<DT><TT>atleast AE C</TT>
 
433
    <DD>This is equivalent to &nbsp;<TT>loop AE C repeat C</TT>.
 
434
 
 
435
<DT><TT>hop AE</TT>
 
436
    <DD>moves <B><I>c</I></B> AE character positions towards <B><I>l</I></B>, but if AE is negative, or if
 
437
    there are less than AE characters between <B><I>c</I></B> and <B><I>l</I></B> the signal is <B><I>f</I></B>.
 
438
    For example,
 
439
<BR><PRE>
 
440
        test hop 3
 
441
</PRE>
 
442
    tests that <B><I>c:l</I></B> contains more than 2 characters.
 
443
 
 
444
<DT><TT>next</TT>
 
445
    <DD>is equivalent to &nbsp;<TT>hop 1</TT>.
 
446
</DL>
 
447
 
 
448
&nbsp;<H4>c) Moving text about</H4>
 
449
 
 
450
 
 
451
We have seen in (a) that &nbsp;<TT>$x = y</TT>, when &nbsp;<TT>x</TT>&nbsp; and &nbsp;<TT>y</TT>&nbsp; are strings, sets <B><I>c:l</I></B> of &nbsp;<TT>x</TT>
 
452
to the value of &nbsp;<TT>y</TT>. Conversely
 
453
<BR><PRE>
 
454
        $x => y
 
455
</PRE>
 
456
sets the value of &nbsp;<TT>y</TT>&nbsp; to the <B><I>c:l</I></B> region of &nbsp;<TT>x</TT>.
 
457
<BR><BR>
 
458
A more delicate mechanism for pushing text around is to define a substring,
 
459
or <I>slice</I> of the string being tested. Then
 
460
 
 
461
<DL>
 
462
<DT><TT>[</TT>
 
463
    <DD>sets the left-end of the slice to <B><I>c</I></B>,
 
464
<DT><TT>]</TT>
 
465
    <DD>sets the right-end of the slice to <B><I>c</I></B>,
 
466
 
 
467
<DT><TT>-> s</TT>
 
468
    <DD>moves the slice to variable &nbsp;<TT>s</TT>,
 
469
<DT><TT><- S</TT>
 
470
    <DD>replaces the slice with variable (or literal) &nbsp;<TT>S</TT>.
 
471
</DL>
 
472
For example
 
473
<BR><PRE>
 
474
        /* assume x holds 'animadversion' */
 
475
        $x ( [         // '[animadversion' - [ set as indicated
 
476
             loop 2 gopast 'a'
 
477
                       // '[anima|dversion' - c is marked by '|'
 
478
             ]         // '[anima]dversion' - ] set as indicated
 
479
             -> y      // y is 'anima'
 
480
           )
 
481
</PRE>
 
482
For any string, the slice ends should be assumed to be unset until they are
 
483
set with the two commands &nbsp;<TT>[</TT>, &nbsp;<TT>]</TT>. Thereafter the slice ends will retain
 
484
the same values until altered.
 
485
 
 
486
<DL>
 
487
<DT><TT>delete</TT>
 
488
    <DD>is equivalent to &nbsp;<TT><- ''</TT>
 
489
</DL>
 
490
 
 
491
This next example deletes all vowels in x,
 
492
<BR><PRE>
 
493
        define vowel ('a' or 'e' or 'i' or 'o' or 'u')
 
494
        ....
 
495
        $ x repeat ( gopast([vowel]) delete )
 
496
</PRE>
 
497
As this example shows, the slice markers &nbsp;<TT>[</TT>&nbsp; and &nbsp;<TT>]</TT>&nbsp; often appear as
 
498
pairs in a bracketed style, which makes for easy reading of the Snowball
 
499
scripts. But it must be remembered that, unusually in a computer
 
500
programming language, they are not true brackets.
 
501
<BR><BR>
 
502
More simply, text can be inserted at <B><I>c</I></B>.
 
503
<DL>
 
504
<DT><TT>insert S</TT>
 
505
    <DD>insert variable or literal &nbsp;<TT>S</TT>&nbsp; before <B><I>c</I></B>, moving <B><I>c</I></B> to the right of the
 
506
    insert. &nbsp;<TT><+</TT>&nbsp; is a synonym for &nbsp;<TT>insert</TT>.
 
507
 
 
508
<DT><TT>attach S</TT>
 
509
    <DD>the same, but leave <B><I>c</I></B> at the left of the insert.
 
510
</DL>
 
511
 
 
512
&nbsp;<H4>d) Marks</H4>
 
513
 
 
514
 
 
515
The cursor, <B><I>c</I></B>, (and the limit, <B><I>l</I></B>) can be thought of as having a numeric
 
516
value, from zero upwards:
 
517
<BR><PRE>
 
518
         | a | n | i | m | a | d | v | e | r | s | i | o | n |
 
519
         0   1   2   3   4   5   6   7   8   9  10  11  12  13
 
520
</PRE>
 
521
It is these numeric values of <B><I>c</I></B> and <B><I>l</I></B> which are accessible through
 
522
<TT>cursor</TT>&nbsp; and &nbsp;<TT>limit</TT>&nbsp; in arithmetic expressions.
 
523
<DL>
 
524
<DT><TT>setmark X</TT>
 
525
    <DD>sets &nbsp;<TT>X</TT>&nbsp; to the current value of <B><I>c</I></B>, where &nbsp;<TT>X</TT>&nbsp; is an integer variable.
 
526
 
 
527
<DT><TT>tomark AE</TT>
 
528
    <DD>moves <B><I>c</I></B> forward to the position given by AE,
 
529
 
 
530
<DT><TT>atmark AE</TT>
 
531
    <DD>tests if <B><I>c</I></B> is at position AE (<B><I>t</I></B> or <B><I>f</I></B> signal).
 
532
</DL>
 
533
In the case of &nbsp;<TT>tomark AE</TT>, a similar fail condition occurs as with &nbsp;<TT>hop AE</TT>.
 
534
If <B><I>c</I></B> is already beyond AE, or if position <B><I>l</I></B> is before position AE, the
 
535
signal is <B><I>f</I></B>.
 
536
<BR><BR>
 
537
In the stemming algorithms, certain regions of the word are defined by
 
538
setting marks, and later the failure condition of &nbsp;<TT>tomark</TT>&nbsp; is used to see if
 
539
<B><I>c</I></B> is inside a particular region.
 
540
<BR><BR>
 
541
Two other commands put <B><I>c</I></B> at <B><I>l</I></B>, and test if <B><I>c</I></B> is at <B><I>l</I></B>,
 
542
<DL>
 
543
<DT><TT>tolimit</TT>
 
544
    <DD>moves <B><I>c</I></B> forward to <B><I>l</I></B> (signal <B><I>t</I></B> always),
 
545
 
 
546
<DT><TT>atlimit</TT>
 
547
    <DD>tests if <B><I>c</I></B> is at <B><I>l</I></B> (<B><I>t</I></B> or <B><I>f</I></B> signal).
 
548
</DL>
 
549
 
 
550
&nbsp;<H4>e) Changing <B><I>l</I></B></H4>
 
551
 
 
552
 
 
553
In this account of string commands we see <B><I>c</I></B> moving right towards <B><I>l</I></B>, while
 
554
<B><I>l</I></B> stays fixed at the end. In fact <B><I>l</I></B> can be reset to a new position between
 
555
<B><I>c</I></B> and its old position, to act as a shorter barrier for the movement of <B><I>c</I></B>.
 
556
 
 
557
<DL>
 
558
<DT><TT>setlimit C<SUB>1</SUB> for C<SUB>2</SUB></TT>
 
559
    <DD><TT>C<SUB>1</SUB></TT>&nbsp; is obeyed, and if it gives <B><I>f</I></B> the final value of <B><I>c</I></B> becomes the new
 
560
    position of <B><I>l</I></B>. <B><I>c</I></B> is then set back to its old value before &nbsp;<TT>C<SUB>1</SUB></TT>&nbsp; was
 
561
    obeyed, and &nbsp;<TT>C<SUB>2</SUB></TT>&nbsp; is obeyed. Finally <B><I>l</I></B> is set back to its old position.
 
562
    The signal is <B><I>f</I></B> if either &nbsp;<TT>C<SUB>1</SUB></TT>&nbsp; or &nbsp;<TT>C<SUB>2</SUB></TT>&nbsp; gives <B><I>f</I></B>, otherwise <B><I>t</I></B>.
 
563
    For example,
 
564
<BR><PRE>
 
565
    $x ( setlimit goto 's'  // 'animadver}sion' new l as marked '}'
 
566
         for                // below, '|' marks c after each goto
 
567
         ( goto 'a' and     // '|animadver}sion'
 
568
           goto 'e' and     // 'animadv|er}sion'
 
569
           goto 'i' and     // 'an|imadver}sion'
 
570
         )
 
571
       )
 
572
</PRE>
 
573
    This checks that x has characters &#8216;a&#8217;, &#8216;e&#8217; and &#8216;i&#8217; before the first
 
574
    &#8216;s&#8217;.
 
575
</DL>
 
576
 
 
577
&nbsp;<H4>f) Backward processing</H4>
 
578
 
 
579
String commands have been described with <B><I>c</I></B> to the left of <B><I>l</I></B> and moving
 
580
right. But the process can be reversed.
 
581
 
 
582
<DL>
 
583
<DT><TT>backwards C</TT>
 
584
    <DD><B><I>c</I></B> and <B><I>l</I></B> are swapped over, and <B><I>c</I></B> moves left towards <B><I>l</I></B>. &nbsp;<TT>C</TT>&nbsp; is obeyed, the
 
585
    signal given by &nbsp;<TT>C</TT>&nbsp; becomes the signal of &nbsp;<TT>backwards C</TT>, and <B><I>c</I></B> and <B><I>l</I></B> are
 
586
    swapped back to their old values (except that <B><I>l</I></B> may have been adjusted
 
587
    because of deletions and insertions). &nbsp;<TT>C</TT>&nbsp; cannot contain another
 
588
    &nbsp;<TT>backwards</TT>&nbsp; command.
 
589
 
 
590
<DT><TT>reverse C</TT>
 
591
    <DD>A similar idea, but here <B><I>c</I></B> simply moves left instead of moving right,
 
592
    with the beginning of the string as the limit, <B><I>l</I></B>. &nbsp;<TT>C</TT>&nbsp; can contain other
 
593
    &nbsp;<TT>reverse</TT>&nbsp; commands, but it cannot contain commands to do deletions or
 
594
    insertions - it must be used for testing only. (Without this
 
595
    restriction Snowball's semantics would become very untidy.)
 
596
</DL>
 
597
 
 
598
Forward and backward processing are entirely symmetric, except that forward
 
599
processing is the default direction, and literals strings are always
 
600
written out forwards, even when they are being tested backwards. So the
 
601
following are equivalent,
 
602
<BR><PRE>
 
603
    $x (
 
604
        'ani' 'mad' 'version' atlimit
 
605
    )
 
606
 
 
607
    $x backwards (
 
608
        'version' 'mad' 'ani' atlimit
 
609
    )
 
610
</PRE>
 
611
If a routine is defined for backwards mode processing, it must be included
 
612
inside a &nbsp;<TT>backwardmode(...)</TT>&nbsp; declaration.
 
613
 
 
614
&nbsp;<H4>g) &nbsp;<TT>substring among</TT></H4>
 
615
 
 
616
The use of &nbsp;<TT>substring among</TT>&nbsp; is central to the implementation of the
 
617
stemming algorithms. It is like a case switch on strings. In its simpler
 
618
form,
 
619
<BR><PRE>
 
620
        substring among('S<SUB>1</SUB>' 'S<SUB>2</SUB>' 'S<SUB>3</SUB>' ...)
 
621
</PRE>
 
622
searches for the longest matching substring &nbsp;<TT>'S<SUB>1</SUB>'</TT>&nbsp; or &nbsp;<TT>'S<SUB>2</SUB>'</TT>&nbsp; or &nbsp;<TT>'S<SUB>3</SUB>'</TT>&nbsp; ... from
 
623
position <B><I>c</I></B>. (The &nbsp;<TT>'S<SUB>i</SUB>'</TT>&nbsp; must all be different.) So this has the same
 
624
semantics as
 
625
<BR><PRE>
 
626
        ('S<SUB>1</SUB>' or 'S<SUB>2</SUB>' or 'S<SUB>3</SUB>' ...)
 
627
</PRE>
 
628
- so long as the &nbsp;<TT>'S<SUB>i</SUB>'</TT>&nbsp; are written out in decreasing order of length.
 
629
<BR><BR>
 
630
<TT>substring</TT>&nbsp; may be omitted, in which case it is attached to its following
 
631
<TT>among</TT>, so
 
632
<BR><PRE>
 
633
    among(...)
 
634
</PRE>
 
635
without a preceding &nbsp;<TT>substring</TT>&nbsp; is equivalent to
 
636
<BR><PRE>
 
637
    (substring among(...))
 
638
</PRE>
 
639
<TT>substring</TT>&nbsp; may also be detached from its &nbsp;<TT>among</TT>, although it must
 
640
precede it textually in the same routine in which the &nbsp;<TT>among</TT>&nbsp; appears.
 
641
The general form of &nbsp;<TT>substring ... among</TT>&nbsp; is,
 
642
<BR><PRE>
 
643
    substring
 
644
    ...
 
645
    among( 'S<SUB>11</SUB>' 'S<SUB>12</SUB>' ... (C<SUB>1</SUB>)
 
646
           'S<SUB>21</SUB>' 'S<SUB>22</SUB>' ... (C<SUB>2</SUB>)
 
647
           ...
 
648
 
 
649
           'S<SUB>n1</SUB>' 'S<SUB>n2</SUB>' ... (C<SUB>n</SUB>)
 
650
         )
 
651
</PRE>
 
652
Obeying &nbsp;<TT>substring</TT>&nbsp; searches for a longest match among the &nbsp;<TT>'S<SUB>ij</SUB>'</TT>. The
 
653
signal from &nbsp;<TT>substring</TT>&nbsp; is <B><I>t</I></B> if a match is found, otherwise <B><I>f</I></B>. When the
 
654
<TT>among</TT>&nbsp; comes to be obeyed, the &nbsp;<TT>C<SUB>i</SUB></TT>&nbsp; corresponding to the matched &nbsp;<TT>'S<SUB>ij</SUB>'</TT>&nbsp; is
 
655
obeyed, and its signal becomes the signal of the &nbsp;<TT>among</TT>&nbsp; command.
 
656
<BR><BR>
 
657
<TT>substring/among</TT>&nbsp; pairs must match up textually inside each routine
 
658
definition. But there is no problem with an &nbsp;<TT>among</TT>&nbsp; containing other
 
659
<TT>substring/among</TT>&nbsp; pairs, and &nbsp;<TT>substring</TT>&nbsp; is optional before &nbsp;<TT>among</TT>&nbsp; anyway.
 
660
The essential constraint is that two &nbsp;<TT>substring</TT>s must be separated by an
 
661
<TT>among</TT>, and each &nbsp;<TT>substring</TT>&nbsp; must be followed by an &nbsp;<TT>among</TT>.
 
662
<BR><BR>
 
663
The effect of obeying &nbsp;<TT>substring</TT>&nbsp; when the preceding &nbsp;<TT>among</TT>&nbsp; is not obeyed
 
664
is undefined. This would happen for example here,
 
665
<BR><PRE>
 
666
    try($x != 617 substring)
 
667
    among(...) // among is bypassed in the exceptional case where x == 617
 
668
</PRE>
 
669
The significance of separating the &nbsp;<TT>substring</TT>&nbsp; from the &nbsp;<TT>among</TT>&nbsp; is to allow
 
670
them to work in different contexts. For example,
 
671
<BR><PRE>
 
672
    setlimit tomark L for substring
 
673
 
 
674
    among( 'S<SUB>11</SUB>' 'S<SUB>12</SUB>' ... (C<SUB>1</SUB>)
 
675
           ...
 
676
 
 
677
           'S<SUB>n1</SUB>' 'S<SUB>n2</SUB>' ... (C<SUB>n</SUB>)
 
678
         )
 
679
</PRE>
 
680
Here the test for the longest &nbsp;<TT>'S<SUB>ij</SUB>'</TT>&nbsp; is constrained to the region between <B><I>c</I></B>
 
681
and the mark point given by integer &nbsp;<TT>L</TT>. But the commands &nbsp;<TT>C<SUB>i</SUB></TT>&nbsp; operate outside
 
682
this limit. Another example is
 
683
<BR><PRE>
 
684
    reverse substring
 
685
 
 
686
    among( 'S<SUB>11</SUB>' 'S<SUB>12</SUB>' ... (C<SUB>1</SUB>)
 
687
           ...
 
688
 
 
689
           'S<SUB>n1</SUB>' 'S<SUB>n2</SUB>' ... (C<SUB>n</SUB>)
 
690
         )
 
691
</PRE>
 
692
The substring test is in the opposite direction in the string to the
 
693
direction of the commands &nbsp;<TT>C<SUB>i</SUB></TT>.
 
694
<BR><BR>
 
695
The last &nbsp;<TT>(C<SUB>n</SUB>)</TT>&nbsp; may be omitted, in which case &nbsp;<TT>(true)</TT>&nbsp; is assumed.
 
696
<BR><BR>
 
697
Another possible abbreviation is that when &nbsp;<TT>substring</TT>&nbsp; is omitted, a
 
698
construct such as
 
699
<BR><PRE>
 
700
    among( 'S<SUB>11</SUB>' 'S<SUB>12</SUB>' ... (C C<SUB>1</SUB>)
 
701
           'S<SUB>21</SUB>' 'S<SUB>22</SUB>' ... (C C<SUB>2</SUB>)
 
702
           ...
 
703
           'S<SUB>n1</SUB>' 'S<SUB>n2</SUB>' ... (C C<SUB>n</SUB>)
 
704
         )
 
705
</PRE>
 
706
can be written
 
707
<BR><PRE>
 
708
    among( (C)
 
709
           'S<SUB>11</SUB>' 'S<SUB>12</SUB>' ... (C<SUB>1</SUB>)
 
710
           'S<SUB>21</SUB>' 'S<SUB>22</SUB>' ... (C<SUB>2</SUB>)
 
711
           ...
 
712
           'S<SUB>n1</SUB>' 'S<SUB>n2</SUB>' ... (C<SUB>n</SUB>)
 
713
         )
 
714
</PRE>
 
715
and this is just equivalent to
 
716
<BR><PRE>
 
717
    substring C
 
718
    among( 'S<SUB>11</SUB>' 'S<SUB>12</SUB>' ... (C<SUB>1</SUB>)
 
719
           'S<SUB>21</SUB>' 'S<SUB>22</SUB>' ... (C<SUB>2</SUB>)
 
720
           ...
 
721
           'S<SUB>n1</SUB>' 'S<SUB>n2</SUB>' ... (C<SUB>n</SUB>)
 
722
         )
 
723
</PRE>
 
724
<BR>&nbsp;<H2>Booleans</H2>
 
725
 
 
726
<TT>set B</TT>&nbsp; and &nbsp;<TT>unset B</TT>&nbsp; set &nbsp;<TT>B</TT>&nbsp; to true and false respectively, where &nbsp;<TT>B</TT>&nbsp; is a
 
727
boolean name. &nbsp;<TT>B</TT>&nbsp; as a command gives a signal <B><I>t</I></B> if it is set true, <B><I>f</I></B>
 
728
otherwise. For example,
 
729
<BR><PRE>
 
730
    booleans ( Y_found )   // declare the boolean
 
731
 
 
732
    ....
 
733
 
 
734
    unset Y_found          // unset it
 
735
    do ( ['y'] <-'Y' set Y_found )
 
736
       /* if c:l begins 'y' replace it by 'Y' and set Y_found */
 
737
 
 
738
    do repeat(goto (v ['y']) <-'Y' set Y_found)
 
739
       /* repeatedy move down the string looking for v 'y' and
 
740
          replacing 'y' with 'Y'. Whenever the replacement takes
 
741
          place set Y_found. v is a test for a vowel, defined as
 
742
          a grouping (see below). */
 
743
 
 
744
 
 
745
    /* Y_found means there are some letters Y in the string.
 
746
       Later we can use this to trigger a conversion back to
 
747
       lower case y. */
 
748
 
 
749
    ....
 
750
 
 
751
    do (Y_found repeat(goto (['Y']) <- 'y')
 
752
</PRE>
 
753
<BR>&nbsp;<H2>Groupings</H2>
 
754
 
 
755
A grouping brings characters together and enables them to be looked for
 
756
with a single test.
 
757
<BR><BR>
 
758
If &nbsp;<TT>G</TT>&nbsp; is declared as a grouping, it can be defined by
 
759
<BR><PRE>
 
760
    define G G<SUB>1</SUB> <I>op</I> G<SUB>2</SUB> <I>op</I> G<SUB>3</SUB> ...
 
761
</PRE>
 
762
where <I>op</I> is &nbsp;<TT>+</TT>&nbsp; or &nbsp;<TT>-</TT>, and &nbsp;<TT>G<SUB>1</SUB></TT>, &nbsp;<TT>G<SUB>2</SUB></TT>, &nbsp;<TT>G<SUB>3</SUB></TT>&nbsp; are literal strings, or groupings that
 
763
have already been defined. (There can be zero or more of these additional
 
764
<I>op</I> components). For example,
 
765
<BR><PRE>
 
766
    define capital_letter  'ABDEFGHIJKLMNOPQRSTUVWXYZ'
 
767
    define small_letter    'abdefghijklmnopqrstuvwxyz'
 
768
    define letter          capital_letter + small_letter
 
769
    define vowel           'aeiou' + 'AEIOU'
 
770
    define consonant       letter - vowel
 
771
    define digit           '0123456789'
 
772
    define alphanumeric    letter + digit
 
773
</PRE>
 
774
Once &nbsp;<TT>G</TT>&nbsp; is defined, it can be used as a command, and is equivalent to a test
 
775
<BR><PRE>
 
776
    'ch1' or 'ch2' or ...
 
777
</PRE>
 
778
where &nbsp;<TT>ch1</TT>, &nbsp;<TT>ch2</TT>&nbsp; ... list all the characters in the grouping.
 
779
<BR><BR>
 
780
<TT>non G</TT>&nbsp; is the converse test, and matches any character except the
 
781
characters of &nbsp;<TT>G</TT>. Note that &nbsp;<TT>non G</TT>&nbsp; is not the same as &nbsp;<TT>not G</TT>, in fact
 
782
<BR><PRE>
 
783
    non G    is equivalent to     (not G next)
 
784
</PRE>
 
785
<TT>non</TT>&nbsp; may be optionally followed by hyphen, so one may write
 
786
<BR><PRE>
 
787
    non-vowel
 
788
    non-digit
 
789
</PRE>
 
790
etc.
 
791
 
 
792
<BR>&nbsp;<H2>A Snowball program</H2>
 
793
 
 
794
 
 
795
A complete program consists of a sequence of declarations followed by a
 
796
sequence of definitions of groupings and routines. Routines which are
 
797
implicitly defined as operating on <B><I>c:l</I></B> from right to left must be included
 
798
in a &nbsp;<TT>backwardmode(...)</TT>&nbsp; declaration.
 
799
<BR><BR>
 
800
A Snowball program is called up via a simple
 
801
<A HREF="../q/use.html">API</A>
 
802
through its defined
 
803
externals. For example,
 
804
<BR><PRE>
 
805
    externals ( stem1 stem2 )
 
806
    ....
 
807
    define stem1 as ( ... /* stem1 commands */ )
 
808
    define stem2 as ( ... /* stem2 commands */ )
 
809
</PRE>
 
810
The API also allows a current string to be defined, and this becomes the
 
811
<B><I>c:l</I></B> string for the external routine to work on. Its final value is the
 
812
result handed back through the API.
 
813
<BR><BR>
 
814
The strings, integers and booleans are accessible from any point in the
 
815
program, and exist throughout the running of the Snowball program. They are
 
816
therefore like static declarations in C.
 
817
 
 
818
<BR>&nbsp;<H2>Comments, and other whitespace fillers</H2>
 
819
 
 
820
At a deeper level, a program is a sequence of <I>tokens</I>, interspersed with
 
821
whitespace. Names, reserved words, literal numbers and strings are all
 
822
tokens. Various symbols, made up of non-alphanumerics, are also tokens.
 
823
<BR><BR>
 
824
A name, reserved word or number is terminated by the first character that
 
825
cannot form part of it. A symbol is recognised as the longest sequence of
 
826
characters that forms a valid symbol. So &nbsp;<TT>+=-</TT>&nbsp; is two symbols, &nbsp;<TT>+=</TT>&nbsp; and
 
827
<TT>-</TT>, because &nbsp;<TT>+=</TT>&nbsp; is a valid symbol in the language while &nbsp;<TT>+=-</TT>&nbsp; is not.
 
828
Whitespace separates tokens but is otherwise ignored. This of course is
 
829
like C.
 
830
<BR><BR>
 
831
Anywhere that whitespace can occur, there may also occur:
 
832
<BR><BR>
 
833
(a) Comments, in the usual multi-line &nbsp;<TT>/* .... */</TT>&nbsp; or single line
 
834
<TT>// ...</TT>&nbsp; format.
 
835
<BR><BR>
 
836
(b) Get directives. These are like &nbsp;<TT>#include</TT>&nbsp; commands in C, and have the form
 
837
<TT>get 'S'</TT>, where &nbsp;<TT>'S'</TT>&nbsp; is a literal string. For example,
 
838
<BR><PRE>
 
839
    get '/home/martin/snowball/main-hdr' // include the file contents
 
840
</PRE>
 
841
(c) &nbsp;<TT>stringescapes XY</TT>&nbsp; where &nbsp;<TT>X</TT>&nbsp; and &nbsp;<TT>Y</TT>&nbsp; are any two printing characters.
 
842
<BR><BR>
 
843
(d) &nbsp;<TT>stringdef m 'S'</TT>&nbsp; where &nbsp;<TT>m</TT>&nbsp; is sequence of characters not including
 
844
whitespace and terminated with whitespace, and &nbsp;<TT>'S'</TT>&nbsp; is a literal string.
 
845
<BR><BR>
 
846
 
 
847
This completes the definition of Snowball.
 
848
 
 
849
<BR><BR>
 
850
 
 
851
 
 
852
 
 
853
</TR>
 
854
 
 
855
<TR><TD BGCOLOR="#e0e0FC">
 
856
<BR>&nbsp;<H2>Snowball syntax</H2>
 
857
<FONT SIZE=-1><PRE>
 
858
<DL><DD>
 
859
 
 
860
<BR>&nbsp;<H2>Appendix 1 - Snowball syntax</H2>
 
861
 
 
862
<TT>||</TT>&nbsp; is used for alternatives, &nbsp;<TT>[<I>X</I>]</TT>&nbsp; means that <I>X</I> is optional, and &nbsp;<TT>[<I>X</I>]*</TT>
 
863
means that <I>X</I> is repreated zero or more times. meta-symbols are defined on
 
864
the left. &nbsp;<TT>&lt;char></TT>&nbsp; means any character.
 
865
<BR><BR>
 
866
The definition of literal strings does not allow for the escaping
 
867
conventions. The command &nbsp;<TT>?</TT>&nbsp; is a debugging aid.
 
868
<BR><BR>
 
869
 
 
870
<FONT SIZE=-1><PRE>
 
871
&lt;letter>        ::= a || b || ... || z || A || B || ... || Z
 
872
&lt;digit>         ::= 0 || 1 || ... || 9
 
873
&lt;name>          ::= &lt;letter> [ &lt;letter> || &lt;digit> || _ ]*
 
874
&lt;s_name>        ::= &lt;name>
 
875
&lt;i_name>        ::= &lt;name>
 
876
&lt;b_name>        ::= &lt;name>
 
877
&lt;r_name>        ::= &lt;name>
 
878
&lt;g_name>        ::= &lt;name>
 
879
&lt;hexdigit>      ::= &lt;digit> || a || b || c || d || e || f ||
 
880
                               A || B || C || D || E || F
 
881
&lt;literal string>::= '[&lt;char>]*' || hex '[&lt;hexdigit>]*'
 
882
&lt;number>        ::= &lt;digit> [ &lt;digit> ]*
 
883
 
 
884
S               ::= &lt;s_name> || &lt;literal string>
 
885
G               ::= &lt;g_name> || &lt;literal string>
 
886
 
 
887
&lt;declaration>   ::= strings ( [&lt;s_name>]* ) ||
 
888
                    integers ( [&lt;i_name>]* ) ||
 
889
                    booleans ( [&lt;b_name>]* ) ||
 
890
                    routines ( [&lt;r_name>]* ) ||
 
891
                    externals ( [&lt;r_name>]* ) ||
 
892
                    groupings ( [&lt;g_name>]* )
 
893
 
 
894
&lt;r_definition>  ::= define &lt;r_name> as C
 
895
&lt;g_definition>  ::= G || &lt;g_definition> + G || &lt;g_definition> - G
 
896
 
 
897
AE              ::= (AE) ||
 
898
                    AE + AE || AE - AE || AE * AE || AE / AE || - AE ||
 
899
                    maxint || minint || cursor || limit || size ||
 
900
                    sizeof &lt;s_name> || &lt;i_name> || &lt;integer>
 
901
 
 
902
&lt;i_command>     ::= $ &lt;i_name> = AE ||
 
903
                    $ &lt;i_name> += AE || $ &lt;i_name> -= AE ||
 
904
                    $ &lt;i_name> *= AE || $ &lt;i_name> /= AE ||
 
905
                    $ &lt;i_name> == AE || $ &lt;i_name> != AE ||
 
906
                    $ &lt;i_name> > AE || $ &lt;i_name> >= AE ||
 
907
                    $ &lt;i_name> &lt; AE || $ &lt;i_name> &lt;= AE ||
 
908
 
 
909
&lt;s_command>     ::= $ &lt;s_name> C
 
910
 
 
911
C               ::= ( [C]* ) ||
 
912
                    &lt;i_command> || &lt;s_command> || C or C || C and C ||
 
913
                    not C || test C || try C || do C || fail C ||
 
914
                    goto C || gopast C || repeat C || loop AE C ||
 
915
                    atleast AE C || S || = S || insert S || attach S ||
 
916
                    &lt;- S || delete ||  hop AE || next ||
 
917
                    => &lt;s_name> || [ || ] || -> &lt;s_name> ||
 
918
                    setmark &lt;i_name> || tomark AE || atmark AE ||
 
919
                    tolimit || atlimit || setlimit C for C ||
 
920
                    backwards C || reverse C ||
 
921
                    substring || among ( [&lt;literal string> || (C)]* ) ||
 
922
                    set &lt;b_name> || unset &lt;b_name> || &lt;b_name> ||
 
923
                    &lt;r_name> || &lt;g_name> || non [-] &lt;g_name> ||
 
924
                    true || false || ?
 
925
 
 
926
P              ::=  [P]* || &lt;declaration> ||
 
927
                    &lt;r_definition> || &lt;g_definition> ||
 
928
                    backwardmode ( P )
 
929
 
 
930
&lt;program>      ::=  P
 
931
 
 
932
 
 
933
 
 
934
synonyms:      &lt;+ for insert
 
935
</PRE></FONT>
 
936
 
 
937
 
 
938
</DL>
 
939
</PRE></FONT>
 
940
</TR>
 
941
 
 
942
 
 
943
</TABLE>
 
944
</BODY>
 
945
</HTML>