mittens 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/lib/mittens/version.rb +1 -1
- data/vendor/snowball/.github/workflows/ci.yml +43 -3
- data/vendor/snowball/.github/workflows/coverage.yml +8 -5
- data/vendor/snowball/GNUmakefile +46 -16
- data/vendor/snowball/NEWS +437 -13
- data/vendor/snowball/README.rst +4 -4
- data/vendor/snowball/algorithms/earlymodernenglish.sbl +301 -0
- data/vendor/snowball/algorithms/french.sbl +1 -1
- data/vendor/snowball/algorithms/ukrainian.sbl +1251 -0
- data/vendor/snowball/compiler/analyser.c +460 -156
- data/vendor/snowball/compiler/driver.c +41 -36
- data/vendor/snowball/compiler/generator.c +24 -1
- data/vendor/snowball/compiler/generator_ada.c +46 -45
- data/vendor/snowball/compiler/generator_c.c +1094 -187
- data/vendor/snowball/compiler/generator_csharp.c +34 -11
- data/vendor/snowball/compiler/generator_dart.c +39 -11
- data/vendor/snowball/compiler/generator_go.c +6 -6
- data/vendor/snowball/compiler/generator_java.c +29 -8
- data/vendor/snowball/compiler/generator_js.c +65 -38
- data/vendor/snowball/compiler/generator_pascal.c +69 -26
- data/vendor/snowball/compiler/generator_php.c +33 -12
- data/vendor/snowball/compiler/generator_python.c +23 -4
- data/vendor/snowball/compiler/generator_rust.c +37 -13
- data/vendor/snowball/compiler/generator_zig.c +6 -6
- data/vendor/snowball/compiler/header.h +85 -14
- data/vendor/snowball/compiler/space.c +67 -38
- data/vendor/snowball/compiler/tokeniser.c +28 -16
- data/vendor/snowball/csharp/Snowball/AssemblyInfo.cs +2 -2
- data/vendor/snowball/csharp/Snowball/Stemmer.cs +1 -4
- data/vendor/snowball/cxx/generate_algorithms.pl +5 -4
- data/vendor/snowball/cxx/{utilities.cxx → snowball_runtime.cxx} +1 -1
- data/vendor/snowball/cxx/stemmer.h +4 -0
- data/vendor/snowball/cxx/stemwords.cxx +36 -6
- data/vendor/snowball/dart/lib/src/snowball.dart +2 -2
- data/vendor/snowball/dart/pubspec.yaml +1 -1
- data/vendor/snowball/doc/libstemmer_c_README +3 -0
- data/vendor/snowball/doc/libstemmer_php_README +1 -1
- data/vendor/snowball/doc/libstemmer_python_README +8 -6
- data/vendor/snowball/examples/stemwords.c +4 -14
- data/vendor/snowball/go/env.go +16 -4
- data/vendor/snowball/include/libstemmer.h +0 -3
- data/vendor/snowball/java/org/tartarus/snowball/SnowballProgram.java +4 -4
- data/vendor/snowball/javascript/base-stemmer.js +27 -40
- data/vendor/snowball/javascript/stemwords.js +34 -10
- data/vendor/snowball/libstemmer/libstemmer_c.in +5 -5
- data/vendor/snowball/libstemmer/mkmodules.pl +5 -3
- data/vendor/snowball/libstemmer/modules.txt +4 -2
- data/vendor/snowball/pascal/SnowballProgram.pas +2 -2
- data/vendor/snowball/php/base-stemmer.php +2 -2
- data/vendor/snowball/python/setup.py +5 -1
- data/vendor/snowball/python/snowballstemmer/basestemmer.py +1 -2
- data/vendor/snowball/runtime/api.c +14 -3
- data/vendor/snowball/runtime/api.h +13 -9
- data/vendor/snowball/runtime/{utilities.c → snowball_runtime.c} +115 -181
- data/vendor/snowball/runtime/snowball_runtime.h +35 -24
- data/vendor/snowball/rust/src/snowball/snowball_env.rs +1 -1
- data/vendor/snowball/tests/compilertest +3 -3
- data/vendor/snowball/tests/runtime/among.sbl +96 -2
- data/vendor/snowball/tests/runtime/attachinsert.sbl +4 -0
- data/vendor/snowball/tests/runtime/debug.out +7 -0
- data/vendor/snowball/tests/runtime/debug.sbl +9 -0
- data/vendor/snowball/tests/runtime/integertests.sbl +22 -0
- data/vendor/snowball/tests/runtime/marklimit.sbl +30 -0
- data/vendor/snowball/tests/runtime/naming.sbl +20 -0
- data/vendor/snowball/tests/runtime/reverse.sbl +11 -0
- data/vendor/snowball/tests/stemtest.c +2 -5
- data/vendor/snowball/tests/syntax/aeslicefrom.sbl +7 -0
- data/vendor/snowball/tests/syntax/canon.sbl +14 -0
- data/vendor/snowball/tests/syntax/canon.syntax +36 -0
- data/vendor/snowball/tests/syntax/inline.syntax +4 -4
- data/vendor/snowball/tests/syntax/localvar.sbl +38 -0
- data/vendor/snowball/tests/syntax/localvar.stderr +3 -0
- data/vendor/snowball/tests/syntax/localvar.syntax +76 -0
- data/vendor/snowball/tests/syntax/unused.sbl +5 -1
- data/vendor/snowball/tests/syntax/unused.stderr +3 -1
- data/vendor/snowball/zig/env.zig +24 -4
- metadata +14 -4
|
@@ -22,24 +22,27 @@ extern byte * get_input(const char * filename) {
|
|
|
22
22
|
fprintf(stderr, "%s: Read error\n", filename);
|
|
23
23
|
exit(1);
|
|
24
24
|
}
|
|
25
|
+
SET_SIZE(u, size);
|
|
25
26
|
} else {
|
|
26
27
|
// Unseekable stream, e.g. piped stdin.
|
|
27
28
|
size = 0;
|
|
28
29
|
u = create_s(INITIAL_INPUT_BUFFER_SIZE);
|
|
29
30
|
while (true) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
size_t s = CAPACITY(u) - size;
|
|
32
|
+
size_t r = fread(u + size, 1, s, input);
|
|
33
|
+
size += (int)r;
|
|
34
|
+
SET_SIZE(u, size);
|
|
35
|
+
if (r < s) {
|
|
36
|
+
if (ferror(input)) {
|
|
37
|
+
fprintf(stderr, "%s: Read error\n", filename);
|
|
38
|
+
exit(1);
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
35
41
|
}
|
|
36
|
-
size
|
|
37
|
-
if (r < s) break;
|
|
38
|
-
u = increase_capacity_s(u, size);
|
|
42
|
+
u = reserve_s(u, size * 2);
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
45
|
if (input != stdin) fclose(input);
|
|
42
|
-
SET_SIZE(u, size);
|
|
43
46
|
return u;
|
|
44
47
|
}
|
|
45
48
|
|
|
@@ -171,12 +174,12 @@ static int read_literal_string(struct tokeniser * t, int c) {
|
|
|
171
174
|
error1(t, "character values exceed 0x01ffff");
|
|
172
175
|
}
|
|
173
176
|
/* Ensure there's enough space for a max length
|
|
174
|
-
* UTF-8 sequence
|
|
177
|
+
* UTF-8 sequence and then encode the character
|
|
178
|
+
* directly into that space. */
|
|
175
179
|
int b_size = SIZE(t->b);
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
SET_SIZE(t->b, b_size + put_utf8(codepoint, t->b + b_size));
|
|
180
|
+
t->b = reserve_b(t->b, b_size + 4);
|
|
181
|
+
SET_SIZE(t->b, b_size + put_utf8(codepoint,
|
|
182
|
+
t->b + b_size));
|
|
180
183
|
} else {
|
|
181
184
|
if (t->encoding == ENC_SINGLEBYTE) {
|
|
182
185
|
/* Only ISO-8859-1 is handled this way - for
|
|
@@ -533,7 +536,7 @@ extern int read_token(struct tokeniser * t) {
|
|
|
533
536
|
for (r = t->includes; r; r = r->next) {
|
|
534
537
|
byte * s = copy_s(r->s);
|
|
535
538
|
s = add_sz_to_s(s, file);
|
|
536
|
-
s
|
|
539
|
+
s = ensure_nul_s(s);
|
|
537
540
|
if (file_owned > 0) {
|
|
538
541
|
free(file);
|
|
539
542
|
} else {
|
|
@@ -546,7 +549,7 @@ extern int read_token(struct tokeniser * t) {
|
|
|
546
549
|
}
|
|
547
550
|
}
|
|
548
551
|
if (u == NULL) {
|
|
549
|
-
error(t, "Can't get '", (byte *)file, strlen(file), "'");
|
|
552
|
+
error(t, "Can't get '", (byte *)file, (int)strlen(file), "'");
|
|
550
553
|
exit(1);
|
|
551
554
|
}
|
|
552
555
|
memmove(q, t, sizeof(struct input));
|
|
@@ -587,6 +590,15 @@ extern int peek_token(struct tokeniser * t) {
|
|
|
587
590
|
return token;
|
|
588
591
|
}
|
|
589
592
|
|
|
593
|
+
extern void push_token(struct tokeniser * t, int token) {
|
|
594
|
+
if (t->token_held) {
|
|
595
|
+
error1(t, "push_token() called but token already held");
|
|
596
|
+
exit(1);
|
|
597
|
+
}
|
|
598
|
+
t->token = token;
|
|
599
|
+
t->token_held = true;
|
|
600
|
+
}
|
|
601
|
+
|
|
590
602
|
extern const char * name_of_token(int code) {
|
|
591
603
|
for (int i = 0; i < NUM_ALPHA_TOKENS; i++) {
|
|
592
604
|
if (alpha_tokens[i].code == code)
|
|
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|
|
32
32
|
// You can specify all the values or you can default the Build and Revision Numbers
|
|
33
33
|
// by using the '*' as shown below:
|
|
34
34
|
// [assembly: AssemblyVersion("1.0.*")]
|
|
35
|
-
[assembly: AssemblyVersion(/*SNOWBALL_VERSION*/"3.
|
|
36
|
-
[assembly: AssemblyFileVersion(/*SNOWBALL_VERSION*/"3.
|
|
35
|
+
[assembly: AssemblyVersion(/*SNOWBALL_VERSION*/"3.2.0.0")]
|
|
36
|
+
[assembly: AssemblyFileVersion(/*SNOWBALL_VERSION*/"3.2.0.0")]
|
|
@@ -26,6 +26,11 @@ sub add_name {
|
|
|
26
26
|
open my $out, '>', $outname or die "Can't open output file '$outname': $!\n";
|
|
27
27
|
|
|
28
28
|
print $out <<END;
|
|
29
|
+
// $outname: Snowball stemmer factory
|
|
30
|
+
//
|
|
31
|
+
// This file is generated by $0 from a list of module names.
|
|
32
|
+
// Do not edit manually.
|
|
33
|
+
|
|
29
34
|
#include "stemmer.h"
|
|
30
35
|
END
|
|
31
36
|
|
|
@@ -45,10 +50,6 @@ END
|
|
|
45
50
|
close $in;
|
|
46
51
|
|
|
47
52
|
print $out <<END;
|
|
48
|
-
// $outname: Snowball stemmer factory
|
|
49
|
-
//
|
|
50
|
-
// This file is generated by $0 from a list of module names.
|
|
51
|
-
// Do not edit manually.
|
|
52
53
|
|
|
53
54
|
#include <string.h>
|
|
54
55
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#define SNOWBALL_RUNTIME_THROW_EXCEPTIONS
|
|
2
|
-
#include "../runtime/
|
|
2
|
+
#include "../runtime/snowball_runtime.c"
|
|
@@ -4,7 +4,11 @@ namespace Snowball {
|
|
|
4
4
|
|
|
5
5
|
class Stemmer {
|
|
6
6
|
public:
|
|
7
|
+
#ifdef SNOWBALL_WIDE
|
|
8
|
+
virtual std::wstring operator()(const std::wstring& word) = 0;
|
|
9
|
+
#else
|
|
7
10
|
virtual std::string operator()(const std::string& word) = 0;
|
|
11
|
+
#endif
|
|
8
12
|
};
|
|
9
13
|
|
|
10
14
|
Stemmer* make_stemmer(const char* language);
|
|
@@ -14,10 +14,13 @@
|
|
|
14
14
|
const char * progname;
|
|
15
15
|
static int pretty = 1;
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
template<typename Char>
|
|
18
|
+
void
|
|
19
|
+
stem_file(Snowball::Stemmer& stemmer,
|
|
20
|
+
std::basic_istream<Char>& f_in,
|
|
21
|
+
std::basic_ostream<Char>& f_out)
|
|
19
22
|
{
|
|
20
|
-
std::
|
|
23
|
+
std::basic_string<Char> word;
|
|
21
24
|
|
|
22
25
|
while (true) {
|
|
23
26
|
int ch = f_in.get();
|
|
@@ -28,8 +31,12 @@ stem_file(Snowball::Stemmer& stemmer, std::istream& f_in, std::ostream& f_out)
|
|
|
28
31
|
word.clear();
|
|
29
32
|
int inlen = 0;
|
|
30
33
|
while (ch != '\n' && ch >= 0) {
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
if (sizeof(Char) == 1) {
|
|
35
|
+
/* Update count of utf-8 characters. */
|
|
36
|
+
if (ch < 0x80 || ch > 0xBF) inlen += 1;
|
|
37
|
+
} else {
|
|
38
|
+
inlen += 1;
|
|
39
|
+
}
|
|
33
40
|
/* force lower case: */
|
|
34
41
|
if (ch < 128) ch = tolower(ch);
|
|
35
42
|
|
|
@@ -71,7 +78,7 @@ stem_file(Snowball::Stemmer& stemmer, std::istream& f_in, std::ostream& f_out)
|
|
|
71
78
|
static void
|
|
72
79
|
usage(int n)
|
|
73
80
|
{
|
|
74
|
-
printf("usage: %s [-l <language>] [-i <input file>] [-o <output file>] [-
|
|
81
|
+
printf("usage: %s [-l <language>] [-i <input file>] [-o <output file>] [-p[2]] [-h]\n"
|
|
75
82
|
"\n"
|
|
76
83
|
"The input file consists of a list of words to be stemmed, one per\n"
|
|
77
84
|
"line. Words should be in lower case, but (for English) A-Z letters\n"
|
|
@@ -147,6 +154,7 @@ try {
|
|
|
147
154
|
exit(1);
|
|
148
155
|
}
|
|
149
156
|
|
|
157
|
+
#ifndef SNOWBALL_WIDE
|
|
150
158
|
/* prepare the files */
|
|
151
159
|
std::ifstream f_in;
|
|
152
160
|
if (in) {
|
|
@@ -167,6 +175,28 @@ try {
|
|
|
167
175
|
|
|
168
176
|
/* do the stemming process: */
|
|
169
177
|
stem_file(*stemmer, in ? f_in : std::cin, out ? f_out : std::cout);
|
|
178
|
+
#else
|
|
179
|
+
/* prepare the files */
|
|
180
|
+
std::wifstream f_in;
|
|
181
|
+
f_in.open(in ? in : "/dev/stdin");
|
|
182
|
+
if (!f_in.is_open()) {
|
|
183
|
+
fprintf(stderr, "file %s not found\n", in);
|
|
184
|
+
exit(1);
|
|
185
|
+
}
|
|
186
|
+
std::wofstream f_out;
|
|
187
|
+
f_out.open(out ? out : "/dev/stdout");
|
|
188
|
+
if (!f_out.is_open()) {
|
|
189
|
+
fprintf(stderr, "file %s cannot be opened\n", out);
|
|
190
|
+
exit(1);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
std::locale c_utf8("C.UTF8");
|
|
194
|
+
f_in.imbue(c_utf8);
|
|
195
|
+
f_out.imbue(c_utf8);
|
|
196
|
+
|
|
197
|
+
/* do the stemming process: */
|
|
198
|
+
stem_file(*stemmer, f_in, f_out);
|
|
199
|
+
#endif
|
|
170
200
|
|
|
171
201
|
return 0;
|
|
172
202
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: snowball
|
|
2
2
|
description: This package provides stemmers generated from Snowball algorithms.
|
|
3
|
-
version: 3.
|
|
3
|
+
version: 3.2.0 # SNOWBALL_VERSION
|
|
4
4
|
repository: https://github.com/snowballstem/snowball
|
|
5
5
|
issue_tracker: https://github.com/snowballstem/snowball/issues
|
|
6
6
|
topics:
|
|
@@ -6,6 +6,9 @@ available for download from:
|
|
|
6
6
|
|
|
7
7
|
https://snowballstem.org/download.html
|
|
8
8
|
|
|
9
|
+
We aim to keep libstemmer compatible with ISO C90. We have CI tests which
|
|
10
|
+
build using modern compilers set to C90 mode, but if you hit compatibility
|
|
11
|
+
problems please report them.
|
|
9
12
|
|
|
10
13
|
What is Stemming?
|
|
11
14
|
-----------------
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
Snowball stemming library collection for Python
|
|
2
2
|
===============================================
|
|
3
3
|
|
|
4
|
-
Python
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Python >= 3.3 is supported, though the oldest version we currently test in CI
|
|
5
|
+
is Python 3.8.
|
|
6
|
+
|
|
7
|
+
We no longer support Python 2 as the Python developers stopped supporting it at
|
|
8
|
+
the start of 2020. Snowball 2.1.0 was the last release to officially support
|
|
9
|
+
Python 2; Snowball 3.0.1 was the last release which had the code to support
|
|
10
|
+
Python 2, but we were no longer testing it.
|
|
9
11
|
|
|
10
12
|
What is Stemming?
|
|
11
13
|
-----------------
|
|
@@ -69,7 +71,7 @@ Snowball's ``libstemmer_c`` and should provide results 100% compatible to
|
|
|
69
71
|
**snowballstemmer**.
|
|
70
72
|
|
|
71
73
|
**PyStemmer** is faster because it wraps generated C versions of the stemmers;
|
|
72
|
-
**snowballstemmer** uses
|
|
74
|
+
**snowballstemmer** uses generated Python code and is slower, but offers a pure
|
|
73
75
|
Python solution.
|
|
74
76
|
|
|
75
77
|
If PyStemmer is installed, ``snowballstemmer.stemmer`` returns a ``PyStemmer``
|
|
@@ -2,16 +2,15 @@
|
|
|
2
2
|
* line interface for stemming using any of the algorithms provided.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
#ifdef _MSC_VER
|
|
6
|
+
# define _CRT_SECURE_NO_WARNINGS // Suppress stupid warning about fopen().
|
|
7
|
+
#endif
|
|
8
|
+
|
|
5
9
|
#include <stdio.h>
|
|
6
10
|
#include <stdlib.h> /* for malloc, free */
|
|
7
11
|
#include <string.h> /* for memmove */
|
|
8
12
|
#include <ctype.h> /* for isupper, tolower */
|
|
9
13
|
|
|
10
|
-
#ifdef __cplusplus
|
|
11
|
-
// Support compiling as C++ to test code generated by `snowball -c++`.
|
|
12
|
-
# include <exception>
|
|
13
|
-
#endif
|
|
14
|
-
|
|
15
14
|
#include "libstemmer.h"
|
|
16
15
|
|
|
17
16
|
const char * progname;
|
|
@@ -119,9 +118,6 @@ usage(int n)
|
|
|
119
118
|
|
|
120
119
|
int
|
|
121
120
|
main(int argc, char * argv[])
|
|
122
|
-
#ifdef __cplusplus
|
|
123
|
-
try
|
|
124
|
-
#endif
|
|
125
121
|
{
|
|
126
122
|
const char * in = NULL;
|
|
127
123
|
const char * out = NULL;
|
|
@@ -211,9 +207,3 @@ try
|
|
|
211
207
|
|
|
212
208
|
return 0;
|
|
213
209
|
}
|
|
214
|
-
#ifdef __cplusplus
|
|
215
|
-
catch (const std::exception& e) {
|
|
216
|
-
fprintf(stderr, "Exception: %s\n", e.what());
|
|
217
|
-
exit(1);
|
|
218
|
-
}
|
|
219
|
-
#endif
|
data/vendor/snowball/go/env.go
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
package snowball
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
"
|
|
4
|
+
"fmt"
|
|
5
5
|
"strings"
|
|
6
6
|
"unicode/utf8"
|
|
7
7
|
)
|
|
@@ -38,7 +38,7 @@ func (env *Env) SetCurrent(s string) {
|
|
|
38
38
|
env.Limit = len(s)
|
|
39
39
|
env.LimitBackward = 0
|
|
40
40
|
env.Bra = 0
|
|
41
|
-
env.Ket =
|
|
41
|
+
env.Ket = 0
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
func (env *Env) ReplaceS(bra, ket int, s string) int32 {
|
|
@@ -463,8 +463,20 @@ func (env *Env) FindAmongB(amongs []*Among, ctx interface{}) int32 {
|
|
|
463
463
|
}
|
|
464
464
|
}
|
|
465
465
|
|
|
466
|
-
func (env *Env) Debug(
|
|
467
|
-
|
|
466
|
+
func (env *Env) Debug(n, line int) {
|
|
467
|
+
length := len(env.current)
|
|
468
|
+
fmt.Printf("%3d (line %4d): [%d]'", n, line, length)
|
|
469
|
+
for i := 0; i <= length; i++ {
|
|
470
|
+
if env.LimitBackward == i { fmt.Print("{") }
|
|
471
|
+
if env.Bra == i { fmt.Print("[") }
|
|
472
|
+
if env.Cursor == i { fmt.Print("|") }
|
|
473
|
+
if env.Ket == i { fmt.Print("]") }
|
|
474
|
+
if env.Limit == i { fmt.Print("}") }
|
|
475
|
+
if (i < length) {
|
|
476
|
+
if env.current[i] == 0 { fmt.Print("#") } else { fmt.Print(env.current[i : i + 1]) }
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
fmt.Println("'")
|
|
468
480
|
}
|
|
469
481
|
|
|
470
482
|
func (env *Env) Clone() *Env {
|
|
@@ -7,9 +7,6 @@ extern "C" {
|
|
|
7
7
|
struct sb_stemmer;
|
|
8
8
|
typedef unsigned char sb_symbol;
|
|
9
9
|
|
|
10
|
-
/* FIXME - should be able to get a version number for each stemming
|
|
11
|
-
* algorithm (which will be incremented each time the output changes). */
|
|
12
|
-
|
|
13
10
|
/** Returns an array of the names of the available stemming algorithms.
|
|
14
11
|
* Note that these are the canonical names - aliases (ie, other names for
|
|
15
12
|
* the same algorithm) will not be included in the list.
|
|
@@ -12,8 +12,8 @@ public class SnowballProgram {
|
|
|
12
12
|
cursor = 0;
|
|
13
13
|
length = limit = 0;
|
|
14
14
|
limit_backward = 0;
|
|
15
|
-
bra =
|
|
16
|
-
ket =
|
|
15
|
+
bra = 0;
|
|
16
|
+
ket = 0;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -42,8 +42,8 @@ public class SnowballProgram {
|
|
|
42
42
|
cursor = 0;
|
|
43
43
|
this.length = limit = length;
|
|
44
44
|
limit_backward = 0;
|
|
45
|
-
bra =
|
|
46
|
-
ket =
|
|
45
|
+
bra = 0;
|
|
46
|
+
ket = 0;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
@@ -20,8 +20,8 @@ export default class BaseStemmer {
|
|
|
20
20
|
this.c = 0;
|
|
21
21
|
this.limit = this.current.length;
|
|
22
22
|
this.limit_backward = 0;
|
|
23
|
-
this.bra =
|
|
24
|
-
this.ket =
|
|
23
|
+
this.bra = 0;
|
|
24
|
+
this.ket = 0;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -228,7 +228,7 @@ export default class BaseStemmer {
|
|
|
228
228
|
|
|
229
229
|
/**
|
|
230
230
|
* @param {Array<Array<string|number>>} v
|
|
231
|
-
* @param {
|
|
231
|
+
* @param {function(): boolean} [call_among_func]
|
|
232
232
|
* @return {number}
|
|
233
233
|
*/
|
|
234
234
|
find_among(v, call_among_func) {
|
|
@@ -250,15 +250,13 @@ export default class BaseStemmer {
|
|
|
250
250
|
let common = common_i < common_j ? common_i : common_j; // smaller
|
|
251
251
|
// w[0]: string, w[1]: result, w[2]: substring_i (optional), w[3]: function (optional)
|
|
252
252
|
const w = v[k];
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
for (i2 = common; i2 < w[0].length; i2++) {
|
|
253
|
+
const s = /**@type{string}*/ (w[0]);
|
|
254
|
+
for (let i2 = common; i2 < s.length; i2++) {
|
|
256
255
|
if (c + common === l) {
|
|
257
256
|
diff = -1;
|
|
258
257
|
break;
|
|
259
258
|
}
|
|
260
|
-
|
|
261
|
-
diff = this.current.charCodeAt(c + common) - w[0].charCodeAt(i2);
|
|
259
|
+
diff = this.current.charCodeAt(c + common) - s.charCodeAt(i2);
|
|
262
260
|
if (diff !== 0) break;
|
|
263
261
|
common++;
|
|
264
262
|
}
|
|
@@ -283,33 +281,28 @@ export default class BaseStemmer {
|
|
|
283
281
|
}
|
|
284
282
|
while (true) {
|
|
285
283
|
const w = v[i];
|
|
286
|
-
|
|
287
|
-
if (common_i >=
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
if (w.length < 4) return w[1];
|
|
292
|
-
// @ts-expect-error: w[3] always number.
|
|
293
|
-
this.af = w[3];
|
|
284
|
+
const len = /**@type {string}*/ (w[0]).length;
|
|
285
|
+
if (common_i >= len) {
|
|
286
|
+
this.c = c + len;
|
|
287
|
+
if (w.length < 4) return /**@type {number}*/ (w[1]);
|
|
288
|
+
this.af = /**@type {number}*/ (w[3]);
|
|
294
289
|
// @ts-expect-error: call_among_func never null here.
|
|
295
290
|
if (call_among_func.call(this)) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
// @ts-expect-error: w[3] always number.
|
|
299
|
-
return w[1];
|
|
291
|
+
this.c = c + len;
|
|
292
|
+
return /**@type {number}*/ (w[1]);
|
|
300
293
|
}
|
|
301
294
|
}
|
|
302
295
|
// Tests for undefined (if w.length < 2) or 0.
|
|
303
296
|
if (!w[2]) return 0;
|
|
304
|
-
|
|
305
|
-
i -= w[2];
|
|
297
|
+
i -= /**@type {number}*/ (w[2]);
|
|
306
298
|
}
|
|
307
299
|
}
|
|
308
300
|
|
|
309
301
|
// find_among_b is for backwards processing. Same comments apply
|
|
310
302
|
/**
|
|
311
303
|
* @param {Array<Array<string|number>>} v
|
|
312
|
-
* @param {
|
|
304
|
+
* @param {function(): boolean} [call_among_func]
|
|
305
|
+
* @return {number}
|
|
313
306
|
*/
|
|
314
307
|
find_among_b(v, call_among_func) {
|
|
315
308
|
/** @protected */
|
|
@@ -329,15 +322,13 @@ export default class BaseStemmer {
|
|
|
329
322
|
let diff = 0;
|
|
330
323
|
let common = common_i < common_j ? common_i : common_j;
|
|
331
324
|
const w = v[k];
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
for (i2 = w[0].length - 1 - common; i2 >= 0; i2--) {
|
|
325
|
+
const s = /**@type{string}*/ (w[0]);
|
|
326
|
+
for (let i2 = s.length - 1 - common; i2 >= 0; i2--) {
|
|
335
327
|
if (c - common === lb) {
|
|
336
328
|
diff = -1;
|
|
337
329
|
break;
|
|
338
330
|
}
|
|
339
|
-
|
|
340
|
-
diff = this.current.charCodeAt(c - 1 - common) - w[0].charCodeAt(i2);
|
|
331
|
+
diff = this.current.charCodeAt(c - 1 - common) - s.charCodeAt(i2);
|
|
341
332
|
if (diff !== 0) break;
|
|
342
333
|
common++;
|
|
343
334
|
}
|
|
@@ -357,24 +348,20 @@ export default class BaseStemmer {
|
|
|
357
348
|
}
|
|
358
349
|
while (true) {
|
|
359
350
|
const w = v[i];
|
|
360
|
-
|
|
361
|
-
if (common_i >=
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
// @ts-expect-error: w[3] always number.
|
|
366
|
-
this.af = w[3];
|
|
351
|
+
const len = /**@type {string}*/ (w[0]).length;
|
|
352
|
+
if (common_i >= len) {
|
|
353
|
+
this.c = c - len;
|
|
354
|
+
if (w.length < 4) return /**@type {number}*/ (w[1]);
|
|
355
|
+
this.af = /**@type {number}*/ (w[3]);
|
|
367
356
|
// @ts-expect-error: call_among_func never null here.
|
|
368
357
|
if (call_among_func.call(this)) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
return w[1];
|
|
358
|
+
this.c = c - len;
|
|
359
|
+
return /**@type {number}*/ (w[1]);
|
|
372
360
|
}
|
|
373
361
|
}
|
|
374
362
|
// Tests for undefined (if w.length < 2) or 0.
|
|
375
363
|
if (!w[2]) return 0;
|
|
376
|
-
|
|
377
|
-
i -= w[2];
|
|
364
|
+
i -= /**@type {number}*/ (w[2]);
|
|
378
365
|
}
|
|
379
366
|
}
|
|
380
367
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
1
2
|
import fs from 'node:fs';
|
|
2
3
|
import process from 'node:process';
|
|
3
4
|
import readline from 'node:readline';
|
|
@@ -19,8 +20,9 @@ The output file consists of the stemmed words, one per line.
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
{
|
|
22
|
-
let input
|
|
23
|
-
let output
|
|
23
|
+
let input;
|
|
24
|
+
let output;
|
|
25
|
+
/**@type {BufferEncoding}*/
|
|
24
26
|
let encoding = 'utf8';
|
|
25
27
|
let language = 'English';
|
|
26
28
|
let usage_error = false;
|
|
@@ -45,7 +47,7 @@ The output file consists of the stemmed words, one per line.
|
|
|
45
47
|
usage_error = true;
|
|
46
48
|
break;
|
|
47
49
|
}
|
|
48
|
-
language = argv.shift();
|
|
50
|
+
language = /**@type {string}*/ (argv.shift());
|
|
49
51
|
break;
|
|
50
52
|
case "-i":
|
|
51
53
|
if (argv.length === 0)
|
|
@@ -69,7 +71,16 @@ The output file consists of the stemmed words, one per line.
|
|
|
69
71
|
usage_error = true;
|
|
70
72
|
break;
|
|
71
73
|
}
|
|
72
|
-
|
|
74
|
+
{
|
|
75
|
+
const enc = /**@type {string}*/ (argv.shift());
|
|
76
|
+
if (!Buffer.isEncoding(enc))
|
|
77
|
+
{
|
|
78
|
+
console.log('Unknown character encoding: ' + enc + '\n');
|
|
79
|
+
usage_error = true;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
encoding = enc;
|
|
83
|
+
}
|
|
73
84
|
break;
|
|
74
85
|
default:
|
|
75
86
|
console.log('Unknown command line option: ' + arg + '\n');
|
|
@@ -85,13 +96,13 @@ The output file consists of the stemmed words, one per line.
|
|
|
85
96
|
|
|
86
97
|
const stemmer = await create(language);
|
|
87
98
|
let istream, ostream;
|
|
88
|
-
if (input !==
|
|
99
|
+
if (input !== undefined) {
|
|
89
100
|
istream = fs.createReadStream(input, encoding);
|
|
90
101
|
} else {
|
|
91
102
|
istream = process.stdin;
|
|
92
103
|
if (istream.setEncoding) istream.setEncoding(encoding);
|
|
93
104
|
}
|
|
94
|
-
if (output !==
|
|
105
|
+
if (output !== undefined) {
|
|
95
106
|
ostream = fs.createWriteStream(output, encoding);
|
|
96
107
|
} else {
|
|
97
108
|
ostream = process.stdout;
|
|
@@ -101,8 +112,17 @@ The output file consists of the stemmed words, one per line.
|
|
|
101
112
|
stemming(stemmer, istream, ostream);
|
|
102
113
|
}
|
|
103
114
|
|
|
104
|
-
|
|
105
|
-
|
|
115
|
+
/**
|
|
116
|
+
* @typedef {object} Stemmer
|
|
117
|
+
* @property {function(string): string} stemWord
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @param {Stemmer} stemmer
|
|
122
|
+
* @param {NodeJS.ReadableStream} input
|
|
123
|
+
* @param {NodeJS.WritableStream} output
|
|
124
|
+
*/
|
|
125
|
+
function stemming(stemmer, input, output) {
|
|
106
126
|
const lines = readline.createInterface({
|
|
107
127
|
input: input,
|
|
108
128
|
terminal: false
|
|
@@ -112,13 +132,16 @@ function stemming (stemmer, input, output) {
|
|
|
112
132
|
});
|
|
113
133
|
}
|
|
114
134
|
|
|
115
|
-
|
|
135
|
+
/**
|
|
136
|
+
* @param {string} name
|
|
137
|
+
* @return {Promise<Stemmer>} name
|
|
138
|
+
*/
|
|
139
|
+
async function create(name) {
|
|
116
140
|
const lc_name = name.toLowerCase();
|
|
117
141
|
if (/\W/.test(lc_name) || lc_name === 'base') {
|
|
118
142
|
console.log('Unknown stemming language: ' + name + '\n');
|
|
119
143
|
usage();
|
|
120
144
|
process.exit(1);
|
|
121
|
-
return;
|
|
122
145
|
}
|
|
123
146
|
const filename = `../js_out/${lc_name}-stemmer.js`;
|
|
124
147
|
try {
|
|
@@ -127,5 +150,6 @@ async function create (name) {
|
|
|
127
150
|
return new stemmerModule.default();
|
|
128
151
|
} catch (error) {
|
|
129
152
|
console.error(error);
|
|
153
|
+
process.exit(1);
|
|
130
154
|
}
|
|
131
155
|
}
|