NAPA Compiler
V4.50
Author: Yves Leduc, yves.leduc.be@gmail.com
Main Page
Data Structures
Files
File List
Globals
Loading...
Searching...
No Matches
C:/Simulate/Napados/Source/mp.c
Go to the documentation of this file.
1
/* *** METAPHONE AND LEVENSHTEIN ALGORITHMS TO DOCUMENT SOME OF THE ERRORS DETECTED BY NAPA ************************************* */
2
3
#undef EXTERN
4
#define EXTERN extern
5
6
#include "
./napa.h
"
7
#include "
./proto.h
"
8
9
10
/* ****************************************************************************************************************************** */
11
12
/* Metaphone catches errors on natural language, Damerau_Levenshtein completes the test for more artificial symbols. */
13
14
/* The Metaphone algorithm was developed by Lawrence Phillips. Like the Soundex algorithm, it compares words that sound alike */
15
/* but are spelled differently. Metaphone was designed to overcome difficulties encountered with Soundex. */
16
17
/* The Levenshtein distance between two strings is given by the minimum number of operations needed to transform one string into */
18
/* the other, where an operation is an insertion, deletion, or substitution of a single character. The Damerau_Levenshtein */
19
/* distance is an improvement of the Levenshtein distance by considering transposition. This implementation was written by */
20
/* Gary A. Parker and originally published in the June/July, 1991 (vol. 5 nr. 4) issue of C Gazette. As published, this code was */
21
/* explicitly placed in the public domain by the author. */
22
/* */
23
/* Simplified and modified by Yves Leduc to match with NAPA simulator. */
24
25
26
27
/* *** In this file: ************************************************************************************************************ */
28
29
/* long damerau_levenshtein(char*, char*) */
30
/* long damerau_levenshtein_strcmp(char *word1, char *word2) */
31
32
/* void metaphone(const char *word_in, char *word_out) */
33
/* long metaphone_strcmp(const char *word1, const char *word2) */
34
35
/* void process_array_error(const char *tok) */
36
/* void process_instruction_error(const char *instr) */
37
/* void process_node_error(const char *tok) */
38
/* void process_node_kind_error(const char *nod) */
39
/* void process_record_error(const char *tok) */
40
/* void process_variable_error(sconst char *tok) */
41
42
43
/* *** MACROS USED IN THIS FILE ************************************************************************************************* */
44
45
#define METAPHONE_MAX 10
/* NAPA node and variable names could be long! */
46
47
#define METAPHONE_VOWEL(x) (vsvfn[(x) - 'A'] & 1)
/* AEIOU */
48
#define METAPHONE_SAME(x) (vsvfn[(x) - 'A'] & 2)
/* FJLMNR */
49
#define METAPHONE_VARSON(x) (vsvfn[(x) - 'A'] & 4)
/* CGPST */
50
#define METAPHONE_FRONTV(x) (vsvfn[(x) - 'A'] & 8)
/* EIY */
51
#define METAPHONE_NOGHF(x) (vsvfn[(x) - 'A'] & 16)
/* BDH */
52
53
54
/* ****************************************************************************************************************************** */
55
56
void
process_instruction_error
(
const
char
*instr) {
57
char
tok1[51][
STRLENGTH
];
/* 51 strings of STRLENGTH characters */
58
char
tok2[
STRLENGTH
];
59
char
*s = (
char
*) NULL;
60
long
i, n;
61
n = 0L;
62
(void) strcpy(tok1[n++],
"alias"
);
63
(void) strcpy(tok1[n++],
"array"
);
64
(void) strcpy(tok1[n++],
"assert"
);
65
(void) strcpy(tok1[n++],
"call"
);
66
(void) strcpy(tok1[n++],
"cell"
);
/* in cell interface */
67
(void) strcpy(tok1[n++],
"command_line"
);
68
(void) strcpy(tok1[n++],
"comment"
);
69
(void) strcpy(tok1[n++],
"data"
);
70
(void) strcpy(tok1[n++],
"debug"
);
71
(void) strcpy(tok1[n++],
"decimate"
);
72
(void) strcpy(tok1[n++],
"declare"
);
73
(void) strcpy(tok1[n++],
"directive"
);
74
(void) strcpy(tok1[n++],
"drop"
);
75
(void) strcpy(tok1[n++],
"dump"
);
76
(void) strcpy(tok1[n++],
"dvar"
);
77
(void) strcpy(tok1[n++],
"error"
);
78
(void) strcpy(tok1[n++],
"event"
);
79
(void) strcpy(tok1[n++],
"export"
);
80
(void) strcpy(tok1[n++],
"format"
);
81
(void) strcpy(tok1[n++],
"fs"
);
82
(void) strcpy(tok1[n++],
"ganging"
);
83
(void) strcpy(tok1[n++],
"gateway"
);
84
(void) strcpy(tok1[n++],
"header"
);
85
(void) strcpy(tok1[n++],
"init"
);
86
(void) strcpy(tok1[n++],
"inject"
);
87
(void) strcpy(tok1[n++],
"input"
);
88
(void) strcpy(tok1[n++],
"interface"
);
89
(void) strcpy(tok1[n++],
"interlude"
);
90
(void) strcpy(tok1[n++],
"interpolate"
);
91
(void) strcpy(tok1[n++],
"ivar"
);
92
(void) strcpy(tok1[n++],
"load"
);
93
(void) strcpy(tok1[n++],
"napa_version"
);
94
(void) strcpy(tok1[n++],
"node"
);
95
(void) strcpy(tok1[n++],
"nominal"
);
96
(void) strcpy(tok1[n++],
"opcode"
);
97
(void) strcpy(tok1[n++],
"output"
);
98
(void) strcpy(tok1[n++],
"ping"
);
99
(void) strcpy(tok1[n++],
"post"
);
100
(void) strcpy(tok1[n++],
"random_seed"
);
101
(void) strcpy(tok1[n++],
"restart"
);
102
(void) strcpy(tok1[n++],
"string"
);
103
(void) strcpy(tok1[n++],
"stuck"
);
104
(void) strcpy(tok1[n++],
"synchronize"
);
105
(void) strcpy(tok1[n++],
"terminate"
);
106
(void) strcpy(tok1[n++],
"title"
);
107
(void) strcpy(tok1[n++],
"tool"
);
108
(void) strcpy(tok1[n++],
"ts"
);
109
(void) strcpy(tok1[n++],
"update"
);
110
(void) strcpy(tok1[n++],
"warning"
);
111
(void) strcpy(tok2, instr);
112
s = tok2;
113
s =
upper_to_lower
(s);
114
(void) fprintf(
STDERR
,
"\n"
);
115
for
(i = 0L; i < n; i++) {
116
if
(0 == strcmp(tok1[i], tok2)) {
117
(void) fprintf(
STDERR
,
" ? <%s>\n"
, tok1[i]);
118
return
;
119
}
120
}
121
for
(i = 0L; i < n; i++) {
122
if
((0 ==
metaphone_strcmp
(instr, tok1[i])) || (0 ==
damerau_levenshtein_strcmp
(instr, tok1[i]))) {
123
(void) fprintf(
STDERR
,
" ? <%s>\n"
, tok1[i]);
124
}
125
}
126
return
;
127
}
128
129
130
/* ****************************************************************************************************************************** */
131
132
void
process_node_kind_error
(
const
char
*kind) {
133
char
tok1[100][
STRLENGTH
];
/* 100 strings of STRLENGTH characters */
134
char
tok2[
STRLENGTH
];
135
char
*s = (
char
*) NULL;
136
long
i, n;
137
n = 0L;
138
(void) strcpy(tok1[n++],
"adc"
);
139
(void) strcpy(tok1[n++],
"algebra"
);
140
(void) strcpy(tok1[n++],
"alu"
);
141
(void) strcpy(tok1[n++],
"and"
);
142
(void) strcpy(tok1[n++],
"average"
);
143
(void) strcpy(tok1[n++],
"bshift"
);
144
(void) strcpy(tok1[n++],
"btoi"
);
145
(void) strcpy(tok1[n++],
"buffer"
);
146
(void) strcpy(tok1[n++],
"bwand"
);
147
(void) strcpy(tok1[n++],
"bwbuffer"
);
148
(void) strcpy(tok1[n++],
"bwinv"
);
149
(void) strcpy(tok1[n++],
"bwnand"
);
150
(void) strcpy(tok1[n++],
"bwnor"
);
151
(void) strcpy(tok1[n++],
"bwnot"
);
152
(void) strcpy(tok1[n++],
"bwor"
);
153
(void) strcpy(tok1[n++],
"bwxnor"
);
154
(void) strcpy(tok1[n++],
"bwxor"
);
155
(void) strcpy(tok1[n++],
"cell"
);
156
(void) strcpy(tok1[n++],
"change"
);
157
(void) strcpy(tok1[n++],
"clip"
);
158
(void) strcpy(tok1[n++],
"clock"
);
159
(void) strcpy(tok1[n++],
"comp"
);
160
(void) strcpy(tok1[n++],
"const"
);
161
(void) strcpy(tok1[n++],
"copy"
);
162
(void) strcpy(tok1[n++],
"cosine"
);
163
(void) strcpy(tok1[n++],
"dac"
);
164
(void) strcpy(tok1[n++],
"dalgebra"
);
165
(void) strcpy(tok1[n++],
"dc"
);
166
(void) strcpy(tok1[n++],
"delay"
);
167
(void) strcpy(tok1[n++],
"differentiator"
);
168
(void) strcpy(tok1[n++],
"div"
);
169
(void) strcpy(tok1[n++],
"dtoi"
);
170
(void) strcpy(tok1[n++],
"dtool"
);
171
(void) strcpy(tok1[n++],
"duser"
);
172
(void) strcpy(tok1[n++],
"equal"
);
173
(void) strcpy(tok1[n++],
"fzand"
);
174
(void) strcpy(tok1[n++],
"fzbuffer"
);
175
(void) strcpy(tok1[n++],
"fzinv"
);
176
(void) strcpy(tok1[n++],
"fznand"
);
177
(void) strcpy(tok1[n++],
"fznor"
);
178
(void) strcpy(tok1[n++],
"fznot"
);
179
(void) strcpy(tok1[n++],
"fzor"
);
180
(void) strcpy(tok1[n++],
"fzxnor"
);
181
(void) strcpy(tok1[n++],
"fzxor"
);
182
(void) strcpy(tok1[n++],
"gain"
);
183
(void) strcpy(tok1[n++],
"generator"
);
184
(void) strcpy(tok1[n++],
"hold"
);
185
(void) strcpy(tok1[n++],
"ialgebra"
);
186
(void) strcpy(tok1[n++],
"integrator"
);
187
(void) strcpy(tok1[n++],
"inv"
);
188
(void) strcpy(tok1[n++],
"itob"
);
189
(void) strcpy(tok1[n++],
"itod"
);
190
(void) strcpy(tok1[n++],
"itool"
);
191
(void) strcpy(tok1[n++],
"iuser"
);
192
(void) strcpy(tok1[n++],
"latch"
);
193
(void) strcpy(tok1[n++],
"lshift"
);
194
(void) strcpy(tok1[n++],
"max"
);
195
(void) strcpy(tok1[n++],
"merge"
);
196
(void) strcpy(tok1[n++],
"min"
);
197
(void) strcpy(tok1[n++],
"mod"
);
198
(void) strcpy(tok1[n++],
"muller"
);
199
(void) strcpy(tok1[n++],
"mux"
);
200
(void) strcpy(tok1[n++],
"nand"
);
201
(void) strcpy(tok1[n++],
"noise"
);
202
(void) strcpy(tok1[n++],
"nor"
);
203
(void) strcpy(tok1[n++],
"not"
);
204
(void) strcpy(tok1[n++],
"offset"
);
205
(void) strcpy(tok1[n++],
"or"
);
206
(void) strcpy(tok1[n++],
"osc"
);
207
(void) strcpy(tok1[n++],
"poly"
);
208
(void) strcpy(tok1[n++],
"prod"
);
209
(void) strcpy(tok1[n++],
"quant"
);
210
(void) strcpy(tok1[n++],
"ram"
);
211
(void) strcpy(tok1[n++],
"ram2"
);
212
(void) strcpy(tok1[n++],
"rect"
);
213
(void) strcpy(tok1[n++],
"register"
);
214
(void) strcpy(tok1[n++],
"relay"
);
215
(void) strcpy(tok1[n++],
"rip"
);
216
(void) strcpy(tok1[n++],
"rom"
);
217
(void) strcpy(tok1[n++],
"rom2"
);
218
(void) strcpy(tok1[n++],
"rshift"
);
219
(void) strcpy(tok1[n++],
"rshift1"
);
220
(void) strcpy(tok1[n++],
"rshift2"
);
221
(void) strcpy(tok1[n++],
"sign"
);
222
(void) strcpy(tok1[n++],
"sine"
);
223
(void) strcpy(tok1[n++],
"square"
);
224
(void) strcpy(tok1[n++],
"step"
);
225
(void) strcpy(tok1[n++],
"sub"
);
226
(void) strcpy(tok1[n++],
"sum"
);
227
(void) strcpy(tok1[n++],
"test"
);
228
(void) strcpy(tok1[n++],
"toggle"
);
229
(void) strcpy(tok1[n++],
"track"
);
230
(void) strcpy(tok1[n++],
"triangle"
);
231
(void) strcpy(tok1[n++],
"trig"
);
232
(void) strcpy(tok1[n++],
"uadc"
);
233
(void) strcpy(tok1[n++],
"udac"
);
234
(void) strcpy(tok1[n++],
"wsum"
);
235
(void) strcpy(tok1[n++],
"xnor"
);
236
(void) strcpy(tok1[n++],
"xor"
);
237
(void) strcpy(tok1[n++],
"zero"
);
238
(void) fprintf(
STDERR
,
"\n"
);
239
(void) strcpy(tok2, kind);
240
s = tok2;
241
s =
upper_to_lower
(s);
242
for
(i = 0L; i < n; i++) {
243
if
(0 == strcmp(tok1[i], tok2)) {
244
(void) fprintf(
STDERR
,
" ? <%s>\n"
, tok1[i]);
245
return
;
246
}
247
}
248
for
(i = 0L; i < n; i++) {
249
if
((0 ==
metaphone_strcmp
(kind, tok1[i])) || (0 ==
damerau_levenshtein_strcmp
(kind, tok1[i]))) {
250
(void) fprintf(
STDERR
,
" ? <%s>\n"
, tok1[i]);
251
}
252
}
253
return
;
254
}
255
256
257
/* ****************************************************************************************************************************** */
258
259
void
process_node_error
(
const
char
*tok1) {
260
long
n;
261
int
flag;
262
char
tok2[
STRLENGTH
];
263
char
tok3[
STRLENGTH
];
264
char
*s = (
char
*) NULL;
265
char
*t = (
char
*) NULL;
266
(void) strcpy(tok2, tok1);
267
s = tok2;
268
s =
upper_to_lower
(s);
269
for
(n = 0L; n <
Num_Nodes
; n++) {
270
if
(!
Node_List
[n].aliased) {
271
(void) strcpy(tok3,
Node_List
[n].name1);
272
t = tok3;
273
t =
upper_to_lower
(t);
274
if
(0 == strcmp(tok2, tok3)) {
275
(void) fprintf(
STDERR
,
"\n node? <%s>\n"
,
Node_List
[n].name1);
276
return
;
277
}
278
}
else
{
279
(void) strcpy(tok3,
Node_List
[n].name2);
280
t = tok3;
281
t =
upper_to_lower
(t);
282
if
(0 == strcmp(tok2, tok3)) {
283
(void) fprintf(
STDERR
,
"\n node? <%s>\n"
,
Node_List
[n].name2);
284
return
;
285
}
286
(void) strcpy(tok3,
Node_List
[n].name1);
287
t = tok3;
288
t =
upper_to_lower
(t);
289
if
(0 == strcmp(tok2, tok3)) {
290
(void) fprintf(
STDERR
,
"\n node? <%s>\n"
,
Node_List
[n].name1);
291
return
;
292
}
293
}
294
}
295
flag =
false
;
296
for
(n = 0L; n <
Num_Nodes
; n++) {
297
if
(!
Node_List
[n].aliased) {
298
(void) strcpy(tok3,
Node_List
[n].name1);
299
t = tok3;
300
t =
upper_to_lower
(t);
301
if
((0 ==
metaphone_strcmp
(tok2, tok3)) || (0 ==
damerau_levenshtein_strcmp
(tok2, tok3))) {
302
(void) fprintf(
STDERR
,
"\n node? <%s>"
,
Node_List
[n].name1);
303
flag =
true
;
304
}
305
}
else
{
306
(void) strcpy(tok3,
Node_List
[n].name2);
307
t = tok3;
308
t =
upper_to_lower
(t);
309
if
((0 ==
metaphone_strcmp
(tok2, tok3)) || (0 ==
damerau_levenshtein_strcmp
(tok2, tok3))) {
310
(void) fprintf(
STDERR
,
"\n node? <%s>"
,
Node_List
[n].name2);
311
flag =
true
;
312
}
313
(void) strcpy(tok3,
Node_List
[n].name1);
314
t = tok3;
315
t =
upper_to_lower
(t);
316
if
((0 ==
metaphone_strcmp
(tok2, tok3)) || (0 ==
damerau_levenshtein_strcmp
(tok2, tok3))) {
317
(void) fprintf(
STDERR
,
"\n node? <%s>"
,
Node_List
[n].name1);
318
flag =
true
;
319
}
320
}
321
}
322
if
(flag) {
323
(void) fprintf(
STDERR
,
"\n"
);
324
}
325
return
;
326
}
327
328
329
/* ****************************************************************************************************************************** */
330
331
void
process_variable_error
(
const
char
*tok1) {
332
long
v;
333
int
flag;
334
char
tok2[
STRLENGTH
];
335
char
tok3[
STRLENGTH
];
336
char
*s = (
char
*) NULL;
337
char
*t = (
char
*) NULL;
338
(void) strcpy(tok2, tok1);
339
s = tok2;
340
s =
upper_to_lower
(s);
341
for
(v = 0L; v <
Num_Vars
; v++) {
342
if
(!
Var_List
[v].aliased) {
343
(void) strcpy(tok3,
Var_List
[v].name1);
344
t = tok3;
345
t =
upper_to_lower
(t);
346
if
(0 == strcmp(tok2, tok3)) {
347
(void) fprintf(
STDERR
,
"\n variable? <%s>\n"
,
Var_List
[v].name1);
348
return
;
349
}
350
}
else
{
351
(void) strcpy(tok3,
Var_List
[v].name2);
352
t = tok3;
353
t =
upper_to_lower
(t);
354
if
(0 == strcmp(tok2, tok3)) {
355
(void) fprintf(
STDERR
,
"\n variable? <%s>\n"
,
Var_List
[v].name2);
356
return
;
357
}
358
(void) strcpy(tok3,
Var_List
[v].name1);
359
t = tok3;
360
t =
upper_to_lower
(t);
361
if
(0 == strcmp(tok2, tok3)) {
362
(void) fprintf(
STDERR
,
"\n variable? <%s>\n"
,
Var_List
[v].name1);
363
return
;
364
}
365
}
366
}
367
flag =
false
;
368
for
(v = 0L; v <
Num_Vars
; v++) {
369
if
(!
Var_List
[v].aliased) {
370
(void) strcpy(tok3,
Var_List
[v].name1);
371
t = tok3;
372
t =
upper_to_lower
(t);
373
if
((0 ==
metaphone_strcmp
(tok2, tok3)) || (0 ==
damerau_levenshtein_strcmp
(tok2, tok3))) {
374
(void) fprintf(
STDERR
,
"\n variable? <%s>"
,
Var_List
[v].name1);
375
flag =
true
;
376
}
377
}
else
{
378
(void) strcpy(tok3,
Var_List
[v].name2);
379
t = tok3;
380
t =
upper_to_lower
(t);
381
if
((0 ==
metaphone_strcmp
(tok2, tok3)) || (0 ==
damerau_levenshtein_strcmp
(tok2, tok3))) {
382
(void) fprintf(
STDERR
,
"\n variable? <%s>"
,
Var_List
[v].name2);
383
flag =
true
;
384
}
385
(void) strcpy(tok3,
Var_List
[v].name1);
386
t = tok3;
387
t =
upper_to_lower
(t);
388
if
((0 ==
metaphone_strcmp
(tok2, tok3)) || (0 ==
damerau_levenshtein_strcmp
(tok2, tok3))) {
389
(void) fprintf(
STDERR
,
"\n variable? <%s>"
,
Var_List
[v].name1);
390
flag =
true
;
391
}
392
}
393
}
394
if
(flag) {
395
(void) fprintf(
STDERR
,
"\n"
);
396
}
397
return
;
398
}
399
400
401
/* ****************************************************************************************************************************** */
402
403
void
process_record_error
(
const
char
*tok1) {
404
long
r;
405
int
flag;
406
char
tok2[
STRLENGTH
];
407
char
tok3[
STRLENGTH
];
408
char
*s = (
char
*) NULL;
409
char
*t = (
char
*) NULL;
410
(void) strcpy(tok2, tok1);
411
s = tok2;
412
s =
upper_to_lower
(s);
413
for
(r = 0L; r <
Num_Records
; r++) {
414
(void) strcpy(tok3,
Record_List
[r].name);
415
t = tok3;
416
t =
upper_to_lower
(t);
417
if
(0 == strcmp(tok2, tok3)) {
418
(void) fprintf(
STDERR
,
"\n array? <%s>\n"
,
Record_List
[r].name);
419
return
;
420
}
421
}
422
flag =
false
;
423
for
(r = 0L; r <
Num_Records
; r++) {
424
(void) strcpy(tok3,
Record_List
[r].name);
425
t = tok3;
426
t =
upper_to_lower
(t);
427
if
((0 ==
metaphone_strcmp
(tok2, tok3)) || (0 ==
damerau_levenshtein_strcmp
(tok2, tok3))) {
428
(void) fprintf(
STDERR
,
"\n array? <%s>"
,
Record_List
[r].name);
429
flag =
true
;
430
}
431
}
432
if
(flag) {
433
(void) fprintf(
STDERR
,
"\n"
);
434
}
435
return
;
436
}
437
438
439
/* ****************************************************************************************************************************** */
440
441
void
process_array_error
(
const
char
*tok1) {
442
long
a;
443
int
flag;
444
char
tok2[
STRLENGTH
];
445
char
tok3[
STRLENGTH
];
446
char
*s = (
char
*) NULL;
447
char
*t = (
char
*) NULL;
448
(void) strcpy(tok2, tok1);
449
s = tok2;
450
s =
upper_to_lower
(s);
451
for
(a = 0L; a <
Num_Arrays
; a++) {
452
(void) strcpy(tok3,
Array_List
[a].name);
453
t = tok3;
454
t =
upper_to_lower
(t);
455
if
(0 == strcmp(tok2, tok3)) {
456
(void) fprintf(
STDERR
,
"\n array? <%s>\n"
,
Array_List
[a].name);
457
return
;
458
}
459
}
460
flag =
false
;
461
for
(a = 0L; a <
Num_Arrays
; a++) {
462
(void) strcpy(tok3,
Array_List
[a].name);
463
t = tok3;
464
t =
upper_to_lower
(t);
465
if
((0 ==
metaphone_strcmp
(tok2, tok3)) || (0 ==
damerau_levenshtein_strcmp
(tok2, tok3))) {
466
(void) fprintf(
STDERR
,
"\n array? <%s>"
,
Array_List
[a].name);
467
flag =
true
;
468
}
469
}
470
if
(flag) {
471
(void) fprintf(
STDERR
,
"\n"
);
472
}
473
return
;
474
}
475
476
477
/* ****************************************************************************************************************************** */
478
479
/* METAPHONE_MAX is the length of the Metaphone code. */
480
/* */
481
/* For comparing words which are not names or for some non-English names (length 4), use long code length for precise matches. */
482
483
/* This implementation was written by Gary A. Parker and originally published in the June/July, 1991 (vol. 5 nr. 4) issue of */
484
/* C Gazette. As published, this code was explicitly placed in the public domain by the author. */
485
/* */
486
/* Simplified and modified by Yves Leduc to match with NAPA simulator. */
487
488
long
metaphone_strcmp
(
const
char
*word1,
const
char
*word2) {
489
char
mword1[
METAPHONE_MAX
+ 1] = {
'\0'
};
490
char
mword2[
METAPHONE_MAX
+ 1] = {
'\0'
};
491
metaphone
(word1, mword1);
/* metaphone code of 'word1' is 'mword1' */
492
metaphone
(word2, mword2);
/* metaphone code of 'word2' is 'mword2' */
493
return
(
long
) (0 != strcmp(mword1, mword2) || (2L >
LENGTH
(word1)) || (2L >
LENGTH
(word2)));
494
}
495
496
497
void
metaphone
(
const
char
*word_in,
char
*word_out) {
498
/* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
499
const
char
vsvfn[26] = { 1, 16, 4, 16, 9, 2, 4, 16, 9, 2, 0, 2, 2, 2, 1, 4, 0, 2, 4, 4, 1, 0, 0, 0, 8, 0};
500
char
*s = (
char
*) NULL;
501
char
*s_start = (
char
*) NULL;
502
char
*s_end = (
char
*) NULL;
503
char
*ms_end = (
char
*) NULL;
504
char
word_uc[
STRLENGTH
] = {
'\0'
};
/* Word with uppercase letters */
505
int
ksflag;
/* State flag for X translation */
506
507
/* Copy word to internal buffer, dropping non-alphabetic characters */
508
/* and converting to upper case. */
509
510
for
(s = word_uc+1, s_end = word_uc+(
sizeof
(word_uc))-2; (
'\0'
!= (*word_in)) && (s < s_end); ++word_in) {
511
if
(isalpha((
int
) *word_in)) {
512
*s++ = (char) toupper((
int
) *word_in);
513
}
514
}
515
516
if
((word_uc+1) == s) {
517
*word_out =
'\0'
;
518
return
;
/* Return if zero characters */
519
}
else
{
520
s_end = s;
/* Set end of string pointer */
521
}
522
523
/* Pad with '\0', front and rear */
524
525
*s++ =
'\0'
;
526
*s =
'\0'
;
527
s = word_uc;
528
*s++ =
'\0'
;
529
530
/* Check for PN, KN, GN, WR, WH, and X at start */
531
532
switch
(*s) {
533
case
'P'
:
534
case
'K'
:
535
case
'G'
:
536
if
(
'N'
== *(s+1)) {
537
*s++ =
'\0'
;
538
}
539
break
;
540
541
case
'A'
:
542
if
(
'E'
== *(s+1)) {
543
*s++ =
'\0'
;
544
}
545
break
;
546
547
case
'W'
:
548
if
(
'R'
== *(s+1)) {
549
*s++ =
'\0'
;
550
}
else
if
(
'H'
== *(s+1)) {
551
*(s+1) = *s;
552
*s++ =
'\0'
;
553
}
554
break
;
555
556
case
'X'
:
557
*s =
'S'
;
558
break
;
559
560
default
:
561
break
;
562
}
563
564
/* Now loop through string, stopping at the end of the string or when computed Metaphone code is METAPHONE_MAX characters long. */
565
566
ksflag =
false
;
/* State flag for KStranslation */
567
568
for
(ms_end = (word_out +
METAPHONE_MAX
), s_start = s; (s <= s_end) && (word_out < ms_end); ++s) {
569
570
if
(ksflag) {
571
ksflag =
false
;
572
*word_out++ = *s;
573
574
}
else
{
/* Drop duplicates except for CC */
575
576
if
((*(s-1) == *s) && (
'C'
!= *s)) {
577
continue
;
578
}
579
580
/* Check for F J L M N R or first letter vowel */
581
582
if
(
METAPHONE_SAME
(*s) || ((s == s_start) &&
METAPHONE_VOWEL
(*s))) {
583
*word_out++ = *s;
584
}
else
{
585
switch
(*s) {
586
case
'B'
:
587
if
((s < s_end) || (
'M'
!= *(s-1))) {
588
*word_out++ = *s;
589
}
590
break
;
591
case
'C'
:
592
if
((
'S'
!= *(s-1)) || (!
METAPHONE_FRONTV
(*(s+1)))) {
593
if
((
'I'
== *(s+1)) && (
'A'
== *(s+2))) {
594
*word_out++ =
'X'
;
595
}
else
if
(
METAPHONE_FRONTV
(*(s+1))) {
596
*word_out++ =
'S'
;
597
}
else
if
(
'H'
== *(s+1)) {
598
if
(((s == s_start) && (!
METAPHONE_VOWEL
(*(s+2)))) || (
'S'
== *(s-1))) {
599
*word_out++ =
'K'
;
600
}
else
{
601
*word_out++ =
'X'
;
602
}
603
}
else
{
604
*word_out++ =
'K'
;
605
}
606
}
607
break
;
608
609
case
'D'
:
610
if
((
'G'
== *(s+1)) &&
METAPHONE_FRONTV
(*(s+2))) {
611
*word_out++ =
'J'
;
612
}
else
{
613
*word_out++ =
'T'
;
614
}
615
break
;
616
617
case
'G'
:
618
if
(((
'H'
!= *(s+1)) ||
METAPHONE_VOWEL
(*(s+2))) && ((
'N'
!= *(s+1)) || (((s+1) < s_end) &&
619
((
'E'
!= *(s+2)) || (
'D'
!= *(s+3))))) && ((
'D'
!= *(s-1)) || (!
METAPHONE_FRONTV
(*(s+1))))) {
620
if
(
METAPHONE_FRONTV
(*(s+1)) && (
'G'
!= *(s+2))) {
621
*word_out++ =
'J'
;
622
}
else
{
623
*word_out++ =
'K'
;
624
}
625
}
else
if
((
'H'
== *(s+1)) && (!
METAPHONE_NOGHF
(*(s-3))) && (
'H'
!= *(s-4))) {
626
*word_out++ =
'F'
;
627
}
628
break
;
629
630
case
'H'
:
631
if
(!
METAPHONE_VARSON
(*(s-1)) && (!
METAPHONE_VOWEL
(*(s-1)) ||
METAPHONE_VOWEL
(*(s+1)))) {
632
*word_out++ =
'H'
;
633
}
634
break
;
635
636
case
'K'
:
637
if
(
'C'
!= *(s-1)) {
638
*word_out++ =
'K'
;
639
}
640
break
;
641
642
case
'P'
:
643
if
(
'H'
== *(s+1)) {
644
*word_out++ =
'F'
;
645
}
else
{
646
*word_out++ =
'P'
;
647
}
648
break
;
649
650
case
'Q'
:
651
*word_out++ =
'K'
;
652
break
;
653
654
case
'S'
:
655
if
((
'H'
== *(s+1)) || ((
'I'
== *(s+1)) && ((
'O'
== *(s+2)) || (
'A'
== *(s+2))))) {
656
*word_out++ =
'X'
;
657
}
else
{
658
*word_out++ =
'S'
;
659
}
660
break
;
661
662
case
'T'
:
663
if
((
'I'
== *(s+1)) && ((
'O'
== *(s+2)) || (
'A'
== *(s+2)))) {
664
*word_out++ =
'X'
;
665
}
else
if
(
'H'
== *(s+1)) {
666
*word_out++ =
'O'
;
667
}
else
if
((
'C'
!= *(s+1)) || (
'H'
!= *(s+2))) {
668
*word_out++ =
'T'
;
669
}
670
break
;
671
672
case
'V'
:
673
*word_out++ =
'F'
;
674
break
;
675
676
case
'W'
:
677
case
'Y'
:
678
if
(
METAPHONE_VOWEL
(*(s+1))) {
679
*word_out++ = *s;
680
}
681
break
;
682
683
case
'X'
:
684
if
(s == s_start) {
685
*word_out++ =
'S'
;
686
}
else
{
687
*word_out++ =
'K'
;
688
ksflag =
true
;
689
}
690
break
;
691
692
case
'Z'
:
693
*word_out++ =
'S'
;
694
break
;
695
default
:
696
break
;
697
}
698
}
699
}
700
}
701
*word_out =
'\0'
;
/* terminate the output string by '\0' */
702
return
;
703
}
704
705
706
/* ****************************************************************************************************************************** */
707
708
/* Pragmatic comparison to tolerate some dyslexia */
709
710
long
damerau_levenshtein_strcmp
(
const
char
*word1,
const
char
*word2) {
711
return
(
long
) ((2L <
damerau_levenshtein
(word1, word2)) || (
LENGTH
(word1) < 3L) || (
LENGTH
(word2) < 3L));
712
}
713
714
715
/* Function 'damerau_levenshtein(str1, str2)' computes the Damerau_Levenshtein distance */
716
717
long
damerau_levenshtein
(
const
char
*s,
const
char
*t) {
718
long
m[256][256];
/* matrix[][] */
719
long
ls, lt;
/* length of s, t */
720
long
i, i1, j, j1;
/* iterates through s, t */
721
long
a, b, c, cost;
/* cost */
722
char
si, tj;
/* character of s, t */
723
ls =
MIN
(
LENGTH
(s), 255L);
724
lt =
MIN
(
LENGTH
(t), 255L);
725
if
((0L == ls) || (0L == lt)) {
726
return
MAX
(ls, lt);
727
}
728
for
(i = 0L; i <= ls; i++) {
729
m[i][0] = i;
730
}
731
for
(j = 0L; j <= lt; j++) {
732
m[0][j] = j;
733
}
734
for
(i = 1L; i <= ls; i++) {
735
i1 = i - 1L;
736
si = s[i1];
737
for
(j = 1L; j <= lt; j++) {
738
j1 = j - 1L;
739
tj = t[j1];
740
cost = (si == tj) ? 0L : 1L;
741
/* Levenshtein */
742
m[i][j] = m[i1][j ] + 1L;
/* deletion */
743
a = m[i ][j1] + 1L;
/* insertion */
744
b = m[i1][j1] + cost;
/* substitution */
745
m[i][j] =
MIN
(a, m[i][j]);
746
m[i][j] =
MIN
(b, m[i][j]);
747
/* Damerau */
748
if
((1L < i) && (1L < j) && ((s[i] == t[j1])) && (s[i1] == t[j])) {
749
c = m[i-2L][j-2L] + cost;
/* transposition */
750
m[i][j] =
MIN
(c, m[i][j]);
751
}
752
}
753
}
754
return
m[ls][lt];
755
}
756
757
758
/* ****************************************************************************************************************************** */
759
/* end of file */
process_node_kind_error
void process_node_kind_error(const char *kind)
Definition
mp.c:132
METAPHONE_SAME
#define METAPHONE_SAME(x)
Definition
mp.c:48
process_instruction_error
void process_instruction_error(const char *instr)
Definition
mp.c:56
METAPHONE_FRONTV
#define METAPHONE_FRONTV(x)
Definition
mp.c:50
metaphone_strcmp
long metaphone_strcmp(const char *word1, const char *word2)
Definition
mp.c:488
metaphone
void metaphone(const char *word_in, char *word_out)
Definition
mp.c:497
METAPHONE_VARSON
#define METAPHONE_VARSON(x)
Definition
mp.c:49
damerau_levenshtein
long damerau_levenshtein(const char *s, const char *t)
Definition
mp.c:717
METAPHONE_VOWEL
#define METAPHONE_VOWEL(x)
Definition
mp.c:47
METAPHONE_NOGHF
#define METAPHONE_NOGHF(x)
Definition
mp.c:51
process_array_error
void process_array_error(const char *tok1)
Definition
mp.c:441
process_record_error
void process_record_error(const char *tok1)
Definition
mp.c:403
process_node_error
void process_node_error(const char *tok1)
Definition
mp.c:259
METAPHONE_MAX
#define METAPHONE_MAX
Definition
mp.c:45
process_variable_error
void process_variable_error(const char *tok1)
Definition
mp.c:331
damerau_levenshtein_strcmp
long damerau_levenshtein_strcmp(const char *word1, const char *word2)
Definition
mp.c:710
napa.h
Var_List
EXTERN VAR_TYPE Var_List[2047L]
Definition
napa.h:970
Record_List
EXTERN RECORD_TYPE Record_List[127L]
Definition
napa.h:965
Num_Vars
EXTERN long Num_Vars
Definition
napa.h:836
Array_List
EXTERN ARRAY_TYPE Array_List[63L]
Definition
napa.h:950
LENGTH
#define LENGTH(s)
Definition
napa.h:397
Num_Records
EXTERN long Num_Records
Definition
napa.h:828
Num_Arrays
EXTERN long Num_Arrays
Definition
napa.h:800
STDERR
#define STDERR
Definition
napa.h:105
Node_List
EXTERN NODE_TYPE Node_List[4095L]
Definition
napa.h:962
Num_Nodes
EXTERN long Num_Nodes
Definition
napa.h:824
MIN
#define MIN(x, y)
Definition
napa.h:376
MAX
#define MAX(x, y)
Definition
napa.h:377
STRLENGTH
#define STRLENGTH
Definition
napa.h:217
proto.h
upper_to_lower
char * upper_to_lower(char *s)
Definition
tk.c:1775
mp.c
Generated on
for NAPA Compiler by
1.14.0