Conversation
|
@krickert If you think this PR is ready for review, please put it out of draft. I'll review once ready. Think we can make some progress, as M6 vote seems to pass and will be processed soon, so we can add on top of that. |
|
Yes, I do think they're ready for review. Thank you! Let me know about anything you'd like to see changed. |
rzo1
left a comment
There was a problem hiding this comment.
Little time, so here is a GPT 5.6-sol review instead for now
Request changes. Three behavior changes need preservation or an explicit compatibility decision.
Validation across the combined stack: 1,856 targeted tests, zero failures, one skipped.
| if (matcher.matches()) { | ||
| return matcher.group(1); | ||
| int separator = outcome.lastIndexOf('-'); | ||
| if (separator > 0 && isWordChars(outcome, separator + 1)) { |
There was a problem hiding this comment.
The previous regex rejected line terminators in the type prefix. person\u2028-start now produces a type instead of null. Please preserve that rejection.
| * @return {@code true} for exactly that shape. | ||
| */ | ||
| private static boolean isCapPeriod(String token) { | ||
| return token.length() == 2 && isCapPeriodStart(token.charAt(0)) && token.charAt(1) == '.'; |
There was a problem hiding this comment.
A.\n previously produced cp; this now produces ic. The original $ anchor accepts a final line terminator. Please preserve the feature behavior.
| int i = 0; | ||
| while (i < text.length()) { | ||
| int cp = Character.codePointAt(text, i); | ||
| if (cp >= LOWER_CODE_POINT && cp <= UPPER_CODE_POINT) { |
There was a problem hiding this comment.
The original regex also matches literal hyphens. a-b previously normalized to a b, but now remains a-b. Please preserve this behavior or explicitly document and test the compatibility change.
|
So some of the "corrections" are preserving regex, not doing the intent. They would create an intentional bug in the code. The purpose of the ticket is to "de-regex" because regex overmatches and does unpredictable behavior / is slow (haha holding off on doing a regex rant here). If the regex is bugged, we're going to cover it in this ticket. We won't preserve bugs :) I'm going to be methodical about this one, and I am in favor of writing a ton of unit tests to ensure the behavior of our code does what it is intended to do, but not to preserve the behavior if it's buggy. This is a great opportunity to harden edge cases that have gone unnoticed. I'm going to take advantage of that. Please feel free to point out any edge cases I may want to try and they will be covered. I'm looking forward to this because we'll have deterministic behavior. I've even seen differences on regex matching between JDK versions. It hurts my eyes :) |
|
Go for adding tests . |
|
This is soooo regex - Tests are finding more bugs - that existed in both regex and our code. Fixing all of the regex domain ones and improving the test coverage. |
|
Poor sol - in one of the other branches your sol review suggested a regex fallback - I'm not going to do that. Fallbacks are weaksauce and by definition cause issues that go against the purpose of these tickets (and it's also a nasty habit most LLMs do to make their code pass where it should fail loudly). Instead I'll back up the decision with heavier testing. If regex is needed for that feature, we should be explicit and make it a separate feature and call out that it's a regex feature. I found one instance where we do accept patterns, I'll include a one-sentence brief as to how it is limited to the JDK char sets. |
|
The emoji change touches default langdetect features. I'll trigger the eval build before we merge. Still working on it though - almost ready to merge. |
|
Here are some additional comments. Def. needs an eval build for the compat changes (langdetect via Blocking
MinorStringUtil / DownloadUtil
AD readers
ConlluStream / ParserTool
Runtime / featuregen / emoji
Process
Sibling PRs (#1276–#1282, all draft)
|
|
Follow-up: the pre-existing issues found during review are now filed.
|
694d650 to
fece12a
Compare
…in DefaultLemmatizerContextGenerator
…in DefaultPOSContextGenerator Add pinning tests for the accept and reject sides of both predicates.
…entenceStream replaceGuillemetPunctuation replicates replaceAll of the »\s+ punct patterns: every run of ASCII whitespace between » and the punctuation character is removed. parsePunctuationLine replicates matches() of the ^(=*)(\W+)$ pattern: the line consists of leading equals signs followed by one or more non-word characters, where a word character is an ASCII letter, digit, or underscore. A line of only equals signs matches, with the last equals sign as lexeme.
Adds StringUtil.isAsciiWhitespace, splitOnAsciiWhitespace, containsAsciiUpperCase, and containsAsciiDigit and removes the copies from the AD streams, the English TokenSampleStream, DownloadUtil, and the POS and lemmatizer context generators. NameFinderME.extractNameType delegates to BioCodec. Cases the new tests found first: the TokenSampleStream split returned one empty token for a whitespace-only line where the original split returned none, and matchHyphenatedToken accepted a single hyphen. BrownCluster.splitTabs now removes all trailing empty fields, as String.split does. Each helper has a test, parameterized where the inputs are a table, with the reject side and the edge cases: empty input, leading and trailing separators, non-ASCII spaces and digits, and supplementary-plane characters. Helpers only called from instance methods are no longer static; the block comments on the helpers are now Javadoc that states the behavior.
… quirks Scans now do what the code meant instead of what the regular expression would accept: - EmojiCharSequenceNormalizer replaces only supplementary-plane code points. BMP characters, hyphens and unpaired surrogates are kept. - ParserTool separates brackets on Unicode whitespace in one pass, so brackets that follow each other are all spaced and no space is doubled. - The FeatureGeneratorUtil capital-period feature needs one capital and one period; a trailing line break no longer qualifies. - BioCodec rejects a line terminator at any position of an outcome type. - DownloadUtil accepts a checksum file with leading Unicode whitespace and treats a blank file as missing. - The AD streams split on the toolkit whitespace definition, drop empty underscore parts and judge punctuation lines by code point. - ConlluStream fails a malformed multiword token id with an InvalidFormatException instead of skipping it. StringUtil adds isAsciiLetter, isAsciiDigit, endOfAsciiDigits, isLineTerminator and indexOfLineTerminator, shared by BioCodec, ADSentenceSampleStream and ConlluStream here and needed by the related OPENNLP-1929 to OPENNLP-1935 branches. isAsciiWhitespace and splitOnAsciiWhitespace are removed; callers use the Unicode-aware StringUtil.isWhitespace and WhitespaceTokenizer. The manual documents the bracket handling of the parser tool, the CoNLL-U multiword id and language code rules, the AD reader rules and the emoji normalizer in the language detector chapter. Tests cover the accept and reject side of each scan, the Unicode plane boundaries and Unicode whitespace separators.
…cans Index pages with CRLF line endings and uppercase anchors, href values with entities or percent escapes returned as written, and checksum files with CR or CRLF line endings, an uppercase hash, or a path after the hash. Outcomes with a line terminator at either end for the BIO codec, multiword token ids with digits from other scripts, trailing whitespace or an overflowing right side for CoNLL-U, paragraph keys followed by digits from other scripts for the AD reader, CR and CRLF lexicon lines for Brown clusters, and unpaired surrogates at either end plus combining marks after a supplementary run for the emoji normalizer.
StringUtil: contract-only Javadoc, a shared null message and offset check, isAsciiLowerCase next to isAsciiLetter, and indexOfLineTerminator returns -1 when there is no terminator, with the Pattern definition and the wider UnicodeWhitespace line break set named. EmojiCharSequenceNormalizer: readResolve, a shorter class Javadoc, no allocation when the text has no supplementary code point, one codePointAt per step, and a CJK Extension B case in the test. The serialver default equals the written value on main and here, so the UID is unchanged. The English TokenSampleStream splits on Unicode White_Space with a fixed definition instead of the shared WhitespaceTokenizer, and the Javadoc and tests state the changed behavior, quote state reset included. DownloadUtil: the hash is the first field of a Unicode whitespace split, a blank checksum file is an IOException that names the file, the anchor scan ends at an unclosed anchor, and case is ignored via regionMatches. ConlluStream: a MultiwordRange record, constants for the separator and messages, leading zeros rejected, an empty node id test, and the manual states what earlier releases did with malformed ids. ParserTool returns a line without brackets unchanged. The name finder validators call BioCodec directly. Feature generator tests are parameterized with boundary cases, and the manuals for the parser tool and the language detector are corrected.
…nder LEGACY CompatibilityMode in opennlp-api selects, for the classes that corrected their output in 3.0.0, between the corrected output and the output of the 1.x/2.x releases, built like WhitespaceMode and independent of it. Under LEGACY the EmojiCharSequenceNormalizer replaces hyphens, code points from U+D83C to U+10FC00 and unpaired surrogates in that range, as the old pattern did, so language detector models trained with an earlier release keep their n-grams until they are retrained. A test compares the legacy output with the old pattern on all code points. The manual describes the property in a new section.
fece12a to
1ecab10
Compare
# Conflicts: # opennlp-core/opennlp-formats/src/main/java/opennlp/tools/formats/conllu/ConlluStream.java # opennlp-core/opennlp-formats/src/test/java/opennlp/tools/formats/conllu/ConlluStreamTest.java
# Conflicts: # opennlp-core/opennlp-formats/src/test/java/opennlp/tools/formats/ad/ADNameSampleStreamTest.java
|
@krickert and team: I am confused here. |
Replaces the patterns in the POS tagger and lemmatizer context generators, BioCodec, BrownCluster and TokenPatternFeatureGenerator with character scans and adds the shared ASCII and line terminator helpers to StringUtil. The output of every site is unchanged. The type extraction of NameFinderME moves to BioCodec. Split out of apache#1275; the changes that alter output follow in separate parts.
The AD corpus readers no longer use regular expressions. This includes the reader changes split out of OPENNLP-1928 (apache#1275): ADNameSampleStream, ADPOSSampleStream, ADSentenceSampleStream and ADSentenceStream replace their tag, whitespace, underline, hyphen, alphanumeric, metadata and punctuation patterns with character scans over the StringUtil helpers. ADSentenceStream.SentenceParser reads node, leaf and bizarre-leaf lines and the fallback check with cursor scans, ADSentenceStream recognizes the sentence, title, box, paragraph and text tags by name, and the package-private ADMetadata reads the text id, the paragraph id and the source for ADNameSampleStream and ADSentenceSampleStream. The scans follow the format, not the accidents of the old patterns: an AD tree line without a tag keeps its full lexeme, the first lexeme character is no longer lost, paren-in-group node tails and quoted-bracket tags are read, and whitespace follows the Unicode definition. Hyphenated words are preserved by default; the ADTokenSampleStreamFactory option and the CLI chapter describe the switch. A leaf without a functional tag in ADChunkSampleStream is tagged with its lexeme, as the POS reader does. The corpora chapter states the reader contract. On the real corpora the output is unchanged: all AD streams over Bosque_CF_8.0 and FlorestaVirgem_CF_3.0 are byte-identical to the previous readers, and the ArvoresDeitadasEval training data hashes are the same. Squashed from the review rounds of apache#1276 for the rebase onto apache#1311.
Replaces the patterns in the POS tagger and lemmatizer context generators, BioCodec, BrownCluster and TokenPatternFeatureGenerator with character scans and adds the shared ASCII and line terminator helpers to StringUtil. The output of every site is unchanged. The type extraction of NameFinderME moves to BioCodec. Split out of apache#1275; the changes that alter output follow in separate parts.
The AD corpus readers no longer use regular expressions. This includes the reader changes split out of OPENNLP-1928 (apache#1275): ADNameSampleStream, ADPOSSampleStream, ADSentenceSampleStream and ADSentenceStream replace their tag, whitespace, underline, hyphen, alphanumeric, metadata and punctuation patterns with character scans over the StringUtil helpers. ADSentenceStream.SentenceParser reads node, leaf and bizarre-leaf lines and the fallback check with cursor scans, ADSentenceStream recognizes the sentence, title, box, paragraph and text tags by name, and the package-private ADMetadata reads the text id, the paragraph id and the source for ADNameSampleStream and ADSentenceSampleStream. The scans follow the format, not the accidents of the old patterns: an AD tree line without a tag keeps its full lexeme, the first lexeme character is no longer lost, paren-in-group node tails and quoted-bracket tags are read, and whitespace follows the Unicode definition. Hyphenated words are preserved by default; the ADTokenSampleStreamFactory option and the CLI chapter describe the switch. A leaf without a functional tag in ADChunkSampleStream is tagged with its lexeme, as the POS reader does. The corpora chapter states the reader contract. On the real corpora the output is unchanged: all AD streams over Bosque_CF_8.0 and FlorestaVirgem_CF_3.0 are byte-identical to the previous readers, and the ArvoresDeitadasEval training data hashes are the same. Squashed from the review rounds of apache#1276 for the rebase onto apache#1311.
…racter scans (#1311) * OPENNLP-1928: Replace trivial regular expressions with character scans Replaces the patterns in the POS tagger and lemmatizer context generators, BioCodec, BrownCluster and TokenPatternFeatureGenerator with character scans and adds the shared ASCII and line terminator helpers to StringUtil. The output of every site is unchanged. The type extraction of NameFinderME moves to BioCodec. Split out of #1275; the changes that alter output follow in separate parts. * OPENNLP-1928: Split Brown cluster lines with StringUtil.split * OPENNLP-1928: Check StringUtil arguments with requireNonNullArg instead of a message constant --------- Co-authored-by: Kristian Rickert <kristian@apache.org>
The AD corpus readers no longer use regular expressions. This includes the reader changes split out of OPENNLP-1928 (apache#1275): ADNameSampleStream, ADPOSSampleStream, ADSentenceSampleStream and ADSentenceStream replace their tag, whitespace, underline, hyphen, alphanumeric, metadata and punctuation patterns with character scans over the StringUtil helpers. ADSentenceStream.SentenceParser reads node, leaf and bizarre-leaf lines and the fallback check with cursor scans, ADSentenceStream recognizes the sentence, title, box, paragraph and text tags by name, and the package-private ADMetadata reads the text id, the paragraph id and the source for ADNameSampleStream and ADSentenceSampleStream. The scans follow the format, not the accidents of the old patterns: an AD tree line without a tag keeps its full lexeme, the first lexeme character is no longer lost, paren-in-group node tails and quoted-bracket tags are read, and whitespace follows the Unicode definition. Hyphenated words are preserved by default; the ADTokenSampleStreamFactory option and the CLI chapter describe the switch. A leaf without a functional tag in ADChunkSampleStream is tagged with its lexeme, as the POS reader does. The corpora chapter states the reader contract. On the real corpora the output is unchanged: all AD streams over Bosque_CF_8.0 and FlorestaVirgem_CF_3.0 are byte-identical to the previous readers, and the ArvoresDeitadasEval training data hashes are the same. Squashed from the review rounds of apache#1276 for the rebase onto apache#1311.
The AD corpus readers no longer use regular expressions. This includes the reader changes split out of OPENNLP-1928 (apache#1275): ADNameSampleStream, ADPOSSampleStream, ADSentenceSampleStream and ADSentenceStream replace their tag, whitespace, underline, hyphen, alphanumeric, metadata and punctuation patterns with character scans over the StringUtil helpers. ADSentenceStream.SentenceParser reads node, leaf and bizarre-leaf lines and the fallback check with cursor scans, ADSentenceStream recognizes the sentence, title, box, paragraph and text tags by name, and the package-private ADMetadata reads the text id, the paragraph id and the source for ADNameSampleStream and ADSentenceSampleStream. The scans follow the format, not the accidents of the old patterns: an AD tree line without a tag keeps its full lexeme, the first lexeme character is no longer lost, paren-in-group node tails and quoted-bracket tags are read, and whitespace follows the Unicode definition. The corpora chapter states the reader contract. On the real corpora the output is unchanged: all AD streams over Bosque_CF_8.0 and FlorestaVirgem_CF_3.0 are byte-identical to the previous readers, and the ArvoresDeitadasEval training data hashes are the same. Squashed from the review rounds of apache#1276 for the rebase onto current main.
The AD corpus readers no longer use regular expressions. This includes the reader changes split out of OPENNLP-1928 (apache#1275): ADNameSampleStream, ADPOSSampleStream, ADSentenceSampleStream and ADSentenceStream replace their tag, whitespace, underline, hyphen, alphanumeric, metadata and punctuation patterns with character scans over the StringUtil helpers. ADSentenceStream.SentenceParser reads node, leaf and bizarre-leaf lines and the fallback check with cursor scans, ADSentenceStream recognizes the sentence, title, box, paragraph and text tags by name, and the package-private ADMetadata reads the text id, the paragraph id and the source for ADNameSampleStream and ADSentenceSampleStream. The scans follow the format, not the accidents of the old patterns: an AD tree line without a tag keeps its full lexeme, the first lexeme character is no longer lost, paren-in-group node tails and quoted-bracket tags are read, and whitespace follows the Unicode definition. The corpora chapter states the reader contract. On the real corpora the sentence samples are unchanged: the verifyTrainingData hashes of ArvoresDeitadasEval stay the same for Bosque_CF_8.0 and FlorestaVirgem_CF_3.0. The tree, name, POS and chunk streams differ in 2 Bosque and 86 Floresta samples, all from the reader bug fixes above: tag fragments such as .vp and <ARGOpp no longer appear as lexemes, and the first character or the whole lexeme of a tag-less tree line is no longer lost (P: reads DP, CJT: reads CJT, and the =H==( and =H===( lines contribute ( again). Squashed from the review rounds of apache#1276 for the rebase onto current main.
The AD corpus readers no longer use regular expressions. This includes the reader changes split out of OPENNLP-1928 (apache#1275): ADNameSampleStream, ADPOSSampleStream, ADSentenceSampleStream and ADSentenceStream replace their tag, whitespace, underline, hyphen, alphanumeric, metadata and punctuation patterns with character scans over the StringUtil helpers. ADSentenceStream.SentenceParser reads node, leaf and bizarre-leaf lines and the fallback check with cursor scans, ADSentenceStream recognizes the sentence, title, box, paragraph and text tags by name, and the package-private ADMetadata reads the text id, the paragraph id and the source for ADNameSampleStream and ADSentenceSampleStream. The scans follow the format, not the accidents of the old patterns: an AD tree line without a tag keeps its full lexeme, the first lexeme character is no longer lost, paren-in-group node tails and quoted-bracket tags are read, and whitespace follows the Unicode definition. The corpora chapter states the reader contract. On the real corpora the sentence samples are unchanged: the verifyTrainingData hashes of ArvoresDeitadasEval stay the same for Bosque_CF_8.0 and FlorestaVirgem_CF_3.0. The tree, name, POS and chunk streams differ in 2 Bosque and 86 Floresta samples, all from the reader bug fixes above: tag fragments such as .vp and <ARGOpp no longer appear as lexemes, and the first character or the whole lexeme of a tag-less tree line is no longer lost (P: reads DP, CJT: reads CJT, and the =H==( and =H===( lines contribute ( again). Squashed from the review rounds of apache#1276 for the rebase onto current main.
…h cursor scans (#1276) * OPENNLP-1930: Parse Arvores Deitadas markup with cursor scans The AD corpus readers no longer use regular expressions. This includes the reader changes split out of OPENNLP-1928 (#1275): ADNameSampleStream, ADPOSSampleStream, ADSentenceSampleStream and ADSentenceStream replace their tag, whitespace, underline, hyphen, alphanumeric, metadata and punctuation patterns with character scans over the StringUtil helpers. ADSentenceStream.SentenceParser reads node, leaf and bizarre-leaf lines and the fallback check with cursor scans, ADSentenceStream recognizes the sentence, title, box, paragraph and text tags by name, and the package-private ADMetadata reads the text id, the paragraph id and the source for ADNameSampleStream and ADSentenceSampleStream. The scans follow the format, not the accidents of the old patterns: an AD tree line without a tag keeps its full lexeme, the first lexeme character is no longer lost, paren-in-group node tails and quoted-bracket tags are read, and whitespace follows the Unicode definition. The corpora chapter states the reader contract. On the real corpora the sentence samples are unchanged: the verifyTrainingData hashes of ArvoresDeitadasEval stay the same for Bosque_CF_8.0 and FlorestaVirgem_CF_3.0. The tree, name, POS and chunk streams differ in 2 Bosque and 86 Floresta samples, all from the reader bug fixes above: tag fragments such as .vp and <ARGOpp no longer appear as lexemes, and the first character or the whole lexeme of a tag-less tree line is no longer lost (P: reads DP, CJT: reads CJT, and the =H==( and =H===( lines contribute ( again). Squashed from the review rounds of #1276 for the rebase onto current main. * OPENNLP-1930: Close the detokenizer dictionary stream after loading DetokenizerSampleStreamFactory.createDetokenizer left the dictionary FileInputStream open, so JUnit TempDir cleanup failed on Windows for ADHyphenatedTokenTest: 'detokenizer.xml: The process cannot access the file because it is being used by another process' (27 errors, Windows jobs of run 35343354338). The dictionary reads the stream fully in its constructor, so close it there. * OPENNLP-1930: Restore the metadata reject rows and pin U+2029 The review asked to put back the dropped reject cases 'CF_1001 p=2' and 'CF 1001 p=2' (the text id follows the leading letters and hyphens directly). Also pin U+2029, which the corpora chapter documents as read like U+2028. * OPENNLP-1930: End a quoted lemma at the first matching quote at a field boundary The leaf scans searched backward from the end of the line, so a lemma extended to the last quote after which the rest still parsed, the greedy behavior of the replaced patterns: =H:n("x" M S)<tab>a') b produced lemma 'x" M S)<tab>a', no morphology, and lexeme 'b'. Now the first matching quote followed by whitespace, a secondary tag, or a closing bracket closes the field, giving lemma 'x', morphology 'M S', and lexeme 'a') b'. Later quotes are not tried, so a line that does not parse after that quote becomes a fallback leaf. Quotes inside a word remain part of the lemma, and the square bracket after some Floresta time and measurement lemmas is accepted. Red: 7 assertion failures over 247 parser cases. Passing: 500 focused AD cases. No parsed field changed for the 920,203 quoted tree-line candidates in Bosque and FlorestaVirgem. The manual documents the lemma boundary rule. * OPENNLP-1930: Update the Bosque chunker perceptron score for the corrected reader Eval build 81 of eval-tests-configurable failed one assertion on this branch: ArvoresDeitadasEval.evalPortugueseChunkerPerceptron expected 0.9631066789979492 and got 0.963736197429554. The other 14 Arvores Deitadas runs, among them the GIS, QN and naive Bayes chunker runs, passed at their expected values. The change comes from 2 Bosque node lines with tags joined by a stray separator, =====P.vp and ========N<ARGOpp. The old reader lost the first character of a tag-less tree line and put .vp and <ARGOpp into 2 sentences as words of an NP chunk. The reader on this branch reads them as tag-less lines with markup and adds no token. A dump of every Bosque chunk sample from main and from this branch (4212 samples each) shows no other difference than these 3 tokens. ADChunkSampleStreamTest.testNodeLineWithStraySeparatorAddsNoToken records that reading. Red on main: expected [que, teria, de, .] but was [que, .vp, teria, <ARGOpp, de, .]. Passes on this branch. The perceptron value is updated to the one the build got. Local runs with the same Bosque file (md5 b69a3b82c385741cd876d166878b52e8) reproduce 0.9631066789979492 on main and 0.963736197429554 on this branch.
Replaces the regular expressions of sixteen small sites with character scans and adds the helpers they share to
StringUtil. Most sites give the same output as before; the ones that do not are listed below with the old and the new result. Where the two differ, the scan follows what the code was meant to do, and a test pins each corrected case.Behavior changes
EmojiCharSequenceNormalizer (deprecated, part of the default language detector chain). Only supplementary-plane code points, U+10000 and above, are replaced by a space now. The old pattern was parsed as the range U+D83C to U+10FC00 plus a literal hyphen, so it also blanked the hyphen, the BMP characters from U+D83C to U+FFFF (fullwidth and halfwidth forms, CJK compatibility ideographs, Arabic presentation forms, the private use area, U+FE0F, and unpaired surrogates from U+D83C to U+DFFF), and it kept U+10FC01 to U+10FFFF. Output differs for U+002D, U+D83C to U+FFFF, and U+10FC01 to U+10FFFF. A run of supplementary code points still becomes one space, so CJK Extension B ideographs are still removed. Text without a supplementary code point is returned as it is.
readResolvereturns the singleton. TheserialVersionUIDequals theserialverdefault before and after the change, so it stays. The factory Javadoc and the manual row say what changed and that models trained with an earlier release were built with the old output. Those models keep working without retraining under a new process-wide switch,-Dopennlp.compat.mode=LEGACY(opennlp.tools.util.CompatibilityModein opennlp-api, built likeWhitespaceModeand independent of it): underLEGACYthe normalizer produces the 1.x/2.x output, verified against the old pattern on every code point;CURRENTis the default. The introduction chapter documents the property; #1281 uses the same switch for its surrogate rule.TokenSampleStream (English). Tokens are split on runs of Unicode White_Space with a fixed definition (
StringUtil.splitOnUnicodeWhitespace), independent of the whitespace mode; before,split("\\s+")split on ASCII whitespace only. A leading space no longer yields an empty first token with the span (0,0). A line without a token resets the open-quote state. A token holding a letter or digit of any script is a word; before,[A-Za-z0-9]made non-ASCII words attach to the previous token as punctuation. All four are tested.FeatureGeneratorUtil. The
cpclass needs one capital and one period and no other character.A.\nwascpand isicnow; the trailing terminator is only reachable through U+0085 in legacy mode. No other token changes class (all code points compared), so no POS or lemmatizer eval build is needed.ParserTool. Brackets that follow each other are each separated:
a))bgivesa ) ) b, before it gavea ) )b. A line without a bracket is returned unchanged. Whitespace follows the toolkit whitespace mode, as the tokenizer that runs next does.ConlluStream. A multiword token id must be two runs of ASCII digits without a leading zero, joined by one hyphen, with the end not smaller than the start. Any other id fails the read with an
InvalidFormatExceptionnaming the id. Before,3-threwArrayIndexOutOfBoundsException,-4and3--4threwNumberFormatException, and4-3and1-2-3were read without an error.DownloadUtil. A blank checksum file is an
IOExceptionsaying so; before, the model was rejected with "Expected: null". The hash is the first field of a Unicode whitespace split.AD readers (
ADNameSampleStream,ADPOSSampleStream,ADSentenceStream,ADSentenceSampleStream). A leading_in a multiword name no longer yields an empty token; tags, contractions, and NER markup are separated by any whitespace of the toolkit whitespace mode, not only ASCII space; a line of non-ASCII letters is not a punctuation leaf. The training samples change for corpora with such lines. Moving these changes into #1276, which rewrites the same code, is an open decision (see below).Rewrites without a change in output
BioCodec.extractNameType(the old regex and the scan agree on every input tried),DownloadUtilindex page links,BrownClusterlexicon lines, thetext_xxlanguage code ofConlluStream, and the capital and digit features of the POS tagger and lemmatizer context generators, which stay ASCII-only because trained models depend on them.CompatibilityMode
New in opennlp-api:
CompatibilityModewithLEGACYandCURRENT, resolved fromopennlp.compat.modeat startup, overridable withsetActiveandreset, one warning per process underLEGACY, scheduled for removal in 4.0 like the whitespace switch.StringUtil
New helpers:
isAsciiLetter,isAsciiLowerCase,isAsciiDigit,endOfAsciiDigits,isLineTerminator,indexOfLineTerminator(returns -1 when there is none).isLineTerminatoris the setjava.util.regex.Patternuses; it is narrower thanUnicodeWhitespace.lineBreakCodePointSet, which also includes vertical tab and form feed.isLineTerminatoris used by the glob matcher of #1278 as well.Manual
The emoji row of the language detector chapter, the bracket paragraph of the parser tool section, a CoNLL-U section in the corpora chapter, and the AD reader paragraph.
Before merge
ArvoresDeitadasEval(AD readers, tokenizer training input).TokenSampleStream.Open decisions for the reviewers
Verification
opennlp-runtime 2718, opennlp-formats 520, opennlp-cli 60, opennlp-tools 624 tests with checkstyle, offline,
-Dopennlp.forkCount=1. No newjava.util.regeximport, no JDK whitespace predicate.