From fc63a2350d4dccc960d62bc58d736285c52da510 Mon Sep 17 00:00:00 2001 From: upstream Date: Fri, 2 Oct 2026 15:56:23 +0200 Subject: [PATCH] Upstream spencermountain/compromise state of the touched files before a2f78f6e79 --- src/2-two/postTagger/model/numbers/numbers.js | 88 +++++++++++++++++++ .../numbers/numbers/parse/toNumber/data.js | 87 ++++++++++++++++++ tests/three/numbers/number-parse.test.js | 47 ++++++++++ 3 files changed, 222 insertions(+) create mode 100644 src/2-two/postTagger/model/numbers/numbers.js create mode 100644 src/3-three/numbers/numbers/parse/toNumber/data.js create mode 100644 tests/three/numbers/number-parse.test.js diff --git a/src/2-two/postTagger/model/numbers/numbers.js b/src/2-two/postTagger/model/numbers/numbers.js new file mode 100644 index 0000000..7cd2094 --- /dev/null +++ b/src/2-two/postTagger/model/numbers/numbers.js @@ -0,0 +1,88 @@ +export default [ + // ==== Ambiguous numbers ==== + // one [second] + { match: `#Cardinal [second]`, group: 0, tag: 'Unit', reason: 'one-second' }, + // with [a] hundred jobs + { + match: '!once? [(a|an)] hundred', + group: 0, + tag: 'Value', + reason: 'a-hundred', + }, + // with [a] thousand jobs + { + match: '!once? [(a|an)] thousand', + group: 0, + tag: 'Value', + reason: 'a-thousand', + }, + // with [a] million jobs + { + match: '!once? [(a|an)] million', + group: 0, + tag: 'Value', + reason: 'a-million', + }, + // with [a] billion jobs + { + match: '!once? [(a|an)] billion', + group: 0, + tag: 'Value', + reason: 'a-billion', + }, + // with [a] trillion jobs + { + match: '!once? [(a|an)] trillion', + group: 0, + tag: 'Value', + reason: 'a-trillion', + }, + // ==== PhoneNumber ==== + // 1 800 555-1234 + { match: '(1|+1) #Value #PhoneNumber', tag: 'PhoneNumber', reason: 'country-code' }, + // (454) 232-9873 + { match: '#NumericValue #PhoneNumber', tag: 'PhoneNumber', reason: 'area-code' }, + + // ==== Currency ==== + // chinese yuan + { match: '#Demonym #Currency', tag: 'Currency', reason: 'demonym-curr' }, + // ten [bucks] + { match: '#Value [(buck|bucks|grand)]', group: 0, tag: 'Currency', reason: 'value-bucks' }, + // ==== Money ==== + // [5] dollars + { match: '[#Value+] #Currency', group: 0, tag: 'Money', reason: 'value-curr' }, + + // ==== Ordinal ==== + // [second] dog + { match: '[second] #Noun', group: 0, tag: 'Ordinal', reason: 'second-noun' }, + + // ==== Units ==== + // 5 [dollars] + { match: '#Value+ [#Currency]', group: 0, tag: 'Unit', reason: 'curr-unit' }, + // 5 [feet] + { match: '#Value [(foot|feet)]', group: 0, tag: 'Unit', reason: 'foot-unit' }, + // 500 fifth [ave] + { match: '#Value [#Abbreviation]', group: 0, tag: 'Unit', reason: 'value-abbr' }, + // 5 [k] + { match: '#Value [k]', group: 0, tag: 'Unit', reason: 'value-k' }, + // kilometers an hour + { match: '#Unit an hour', tag: 'Unit', reason: 'unit-an-hour' }, + + // ==== Magnitudes ==== + // minus 7 + { match: '(minus|negative) #Value', tag: 'Value', reason: 'minus-value' }, + // seven point five + { match: '#Value (point|decimal) #Value', tag: 'Value', reason: 'decimal-point' }, + // a [half] second + { match: '#Determiner [(half|quarter)] #Ordinal', group: 0, tag: 'Value', reason: 'half-ord' }, + // thousand and two + { match: `#Multiple+ and #Value`, tag: 'Value', reason: 'mag-and-value' }, + // 5 miles [per hour] + { match: '#Value #Unit [(per|an) (hr|hour|sec|second|min|minute)]', group: 0, tag: 'Unit', reason: 'unit-per-dur' }, + // 5 [square] miles + { match: '#Value [(square|cubic)] #Unit', group: 0, tag: 'Unit', reason: 'square-miles' }, + // twelve percent + { match: '#Cardinal percent', tag: '#Percent #Unit', reason: 'value-percent' }, + // 5 [gb] + { match: '#Value [(gb|pa|ft|foot|feet|m)]', group: 0, tag: 'Unit', reason: 'ambig-unit' }, +] diff --git a/src/3-three/numbers/numbers/parse/toNumber/data.js b/src/3-three/numbers/numbers/parse/toNumber/data.js new file mode 100644 index 0000000..b592aa2 --- /dev/null +++ b/src/3-three/numbers/numbers/parse/toNumber/data.js @@ -0,0 +1,87 @@ +export default { + ones: { + zeroth: 0, + first: 1, + second: 2, + third: 3, + fourth: 4, + fifth: 5, + sixth: 6, + seventh: 7, + eighth: 8, + ninth: 9, + zero: 0, + one: 1, + two: 2, + three: 3, + four: 4, + five: 5, + six: 6, + seven: 7, + eight: 8, + nine: 9, + }, + teens: { + tenth: 10, + eleventh: 11, + twelfth: 12, + thirteenth: 13, + fourteenth: 14, + fifteenth: 15, + sixteenth: 16, + seventeenth: 17, + eighteenth: 18, + nineteenth: 19, + ten: 10, + eleven: 11, + twelve: 12, + thirteen: 13, + fourteen: 14, + fifteen: 15, + sixteen: 16, + seventeen: 17, + eighteen: 18, + nineteen: 19, + }, + tens: { + twentieth: 20, + thirtieth: 30, + fortieth: 40, + fourtieth: 40, + fiftieth: 50, + sixtieth: 60, + seventieth: 70, + eightieth: 80, + ninetieth: 90, + twenty: 20, + thirty: 30, + forty: 40, + fourty: 40, + fifty: 50, + sixty: 60, + seventy: 70, + eighty: 80, + ninety: 90, + }, + multiples: { + hundredth: 100, + thousandth: 1000, + millionth: 1e6, + billionth: 1e9, + trillionth: 1e12, + quadrillionth: 1e15, + quintillionth: 1e18, + sextillionth: 1e21, + septillionth: 1e24, + hundred: 100, + thousand: 1000, + million: 1e6, + billion: 1e9, + trillion: 1e12, + quadrillion: 1e15, + quintillion: 1e18, + sextillion: 1e21, + septillion: 1e24, + grand: 1000, + }, +} diff --git a/tests/three/numbers/number-parse.test.js b/tests/three/numbers/number-parse.test.js new file mode 100644 index 0000000..1b9625c --- /dev/null +++ b/tests/three/numbers/number-parse.test.js @@ -0,0 +1,47 @@ +import test from 'tape' +import nlp from '../_lib.js' +const here = '[three/number-parse] ' + +test('parse numbers', function (t) { + const arr = [ + ['seven hundred', 700], + ['a hundred and seventy', 170], + ['9 hundred', 900], + ['9 hundred and 2', 902], + ['9 hundred and twenty', 920], + ['hundred and seventy', 170], + ['hundred and seventy two', 172], + ['hundred and seventy two thousand', 172000], + ['seven hundred and twenty', 720], + ['three twenty', 320], + ['hundred and three', 103], + + //dropped-hundred + ['seven twenty', 720], + ['two twenty', 220], + ['eight fifty', 850], + ['two fifty', 250], + ['two fifty five', 255], + + ['two and a half', 2.5], + ['fifty and a half', 50.5], + // ['two fifty and three quarters', 250.75], + ['twenty two percent', 22], + ['two hundred and twenty percent', 220], + ['220 percent', 220], + ['$220', 220], + + // false-positives + ['seven and twenty', 7], + ['three three', 3], + ['four two zero', 4], + // ['three twentieth', null], + // ['third twenty', null], + // ['seventy hundred', null], + ] + arr.forEach(function (a) { + const num = nlp(a[0]).values().get()[0] + t.equal(num, a[1], here + a[0]) + }) + t.end() +})