Overview
Comment: | [core][fr] tests suggestions for JS, suggestions update |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | fr | core |
Files: | files | file ages | folders |
SHA3-256: |
fb8de11c89bac99c911f9fa9836a2fa9 |
User & Date: | olr on 2021-01-21 18:04:41 |
Other Links: | manifest | tags |
Context
2021-01-21
| ||
21:12 | [build] nnbsp in py2js() also check-in: b217bc2731 user: olr tags: trunk, build | |
18:04 | [core][fr] tests suggestions for JS, suggestions update check-in: fb8de11c89 user: olr tags: trunk, fr, core | |
10:30 | [fr] ajustements (tests) check-in: 8e7a1e20da user: olr tags: trunk, fr | |
Changes
Modified gc_core/js/tests.js from [5a6c382af8] to [9717be7ff0].
︙ | ︙ | |||
19 20 21 22 23 24 25 | this.spfTests = spfTests; this._aRuleTested = new Set(); } * testParse (bDebug=false) { const t0 = Date.now(); let sURL; | | | > > > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | this.spfTests = spfTests; this._aRuleTested = new Set(); } * testParse (bDebug=false) { const t0 = Date.now(); let sURL; if (typeof(process) !== 'undefined') { sURL = (this.spfTests !== "") ? this.spfTests : "./"+this.gce.lang+"/tests_data.json"; } else { sURL = (this.spfTests !== "") ? this.spfTests : "resource://grammalecte/"+this.gce.lang+"/tests_data.json"; } const aData = JSON.parse(helpers.loadFile(sURL)).aData; let nInvalid = 0; let nTotal = 0; let sErrorText; let sExpectedSuggs; let sExpectedErrors; let nTestWithExpectedError = 0; let nTestWithExpectedErrorAndSugg = 0; let nUnexpectedErrors = 0; let sTextToCheck; let sFoundErrors; let sFoundSuggs; let sListErr; let sLineNum; let i = 1; let sUntestedRules = ""; let bShowUntested = false; let zOption = /^__([a-zA-Z0-9]+)__ /; let sOption; |
︙ | ︙ | |||
53 54 55 56 57 58 59 | sOption = false; m = zOption.exec(sLine); if (m) { sLine = sLine.slice(sLine.indexOf(" ")+1); sOption = m[1]; } if (sLine.includes("->>")) { | | < | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < < < < < < < < < < < < | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | sOption = false; m = zOption.exec(sLine); if (m) { sLine = sLine.slice(sLine.indexOf(" ")+1); sOption = m[1]; } if (sLine.includes("->>")) { [sErrorText, sExpectedSuggs] = this._splitTestLine(sLine); nTestWithExpectedErrorAndSugg += 1 } else { sErrorText = sLine.trim(); sExpectedSuggs = ""; } sExpectedErrors = this._getExpectedErrors(sErrorText); if (sExpectedErrors.trim() != "") { nTestWithExpectedError += 1; } sTextToCheck = sErrorText.replace(/\{\{/g, "").replace(/\}\}/g, ""); [sFoundErrors, sListErr, sFoundSuggs] = this._getFoundErrors(sTextToCheck, bDebug, sOption); if (sExpectedErrors !== sFoundErrors) { yield "\n" + i.toString() + "\n# Line num: " + sLineNum + "\n> to check: " + sTextToCheck + "\n expected: " + sExpectedErrors + "\n found: " + sFoundErrors + "\n errors: \n" + sListErr; nInvalid = nInvalid + 1; } else if (sExpectedSuggs) { if (!this._checkSuggestions(sExpectedSuggs, sFoundSuggs)) { yield "\n# Line num: " + sLineNum + "\n> to check: " + sTextToCheck + "\n expected: " + sExpectedSuggs + "\n found: " + sFoundSuggs + "\n errors: \n" + sListErr; nUnexpectedErrors += 1; } } nTotal = nTotal + 1; } i = i + 1; if (i % 1000 === 0) { yield i.toString(); } } yield "Tests with expected errors: " + nTestWithExpectedError + " and suggestions: " + nTestWithExpectedErrorAndSugg + " > " + nTestWithExpectedErrorAndSugg/nTestWithExpectedError*100 + " %"; if (nUnexpectedErrors) { yield "Unexpected errors: " + nUnexpectedErrors; } yield* this._showUntestedRules() } catch (e) { console.error(e); } const t1 = Date.now(); yield "Tests parse finished in " + ((t1-t0)/1000).toString() + " s\nTotal errors: " + nInvalid.toString() + " / " + nTotal.toString(); } * _showUntestedRules () { let i = 0; for (let [sOpt, sLineId, sRuleId] of this.gce.listRules()) { if (sOpt !== "@@@@" && !this._aRuleTested.has(sLineId) && !/^[0-9]+[sp]$|^[pd]_/.test(sRuleId)) { sUntestedRules += sLineId + "/" + sRuleId + ", "; i += 1; } } if (i > 0) { yield sUntestedRules + "\n[" + i.toString() + " untested rules]"; } } _splitTestLine (sLine) { let [sText, sSugg] = sLine.split("->>"); sSugg = sSugg.trim().replace(/ /g, " "); if (sSugg.startsWith('"') && sSugg.endsWith('"')) { sSugg = sSugg.slice(1,-1); } return [sText.trim(), sSugg]; } _getFoundErrors (sLine, bDebug, sOption) { try { let aErrs = []; if (sOption) { this.gce.setOption(sOption, true); aErrs = this.gce.parse(sLine, "FR", bDebug); this.gce.setOption(sOption, false); } else { aErrs = this.gce.parse(sLine, "FR", bDebug); } let sRes = " ".repeat(sLine.length); let sListErr = ""; let lAllSugg = []; for (let oErr of aErrs.sort( (a,b) => a["nStart"] - b["nStart"] )) { sRes = sRes.slice(0, oErr["nStart"]) + "~".repeat(oErr["nEnd"] - oErr["nStart"]) + sRes.slice(oErr["nEnd"]); sListErr += " * {" + oErr['sLineId'] + " / " + oErr['sRuleId'] + "} at " + oErr['nStart'] + ":" + oErr['nEnd'] + "\n"; lAllSugg.push(oErr["aSuggestions"].join("|")); this._aRuleTested.add(oErr["sLineId"]); } return [sRes, sListErr, lAllSugg.join("|||")]; } catch (e) { console.error(e); } return [" ".repeat(sLine.length), "", ""]; } _getExpectedErrors (sLine) { try { let sRes = " ".repeat(sLine.length); let z = /\{\{.+?\}\}/g; let m; |
︙ | ︙ | |||
128 129 130 131 132 133 134 | } catch (e) { console.error(e); } return " ".repeat(sLine.length); } | | | | | < < < | < | | | | < < < < > | | < < | < | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | } catch (e) { console.error(e); } return " ".repeat(sLine.length); } _checkSuggestions (sAllExceptedSuggs, sAllFoundSuggs) { let lAllExpectedSuggs = sAllExceptedSuggs.split("|||"); let lAllFoundSuggs = sAllFoundSuggs.split("|||"); if (lAllExpectedSuggs.length != lAllFoundSuggs.length) { return false; } for (let i = 0; i < lAllExpectedSuggs.length; i++) { let aExpectedSuggs = new Set(lAllExpectedSuggs[i].split("|")); let aFoundSuggs = new Set(lAllFoundSuggs[i].split("|")); if (aExpectedSuggs.size !== aFoundSuggs.size || ![...aExpectedSuggs].every(value => aFoundSuggs.has(value))) { return false; } } return true; } } if (typeof(exports) !== 'undefined') { exports.TestGrammarChecking = TestGrammarChecking; } |
Modified gc_core/py/lang_core/tests_core.py from [f2f8ff9a94] to [335b223b65].
︙ | ︙ | |||
108 109 110 111 112 113 114 | if not self._checkSuggestions(sExceptedSuggs, sFoundSuggs): print("\n# Line num: " + sLineNum + \ "\n> to check: " + _fuckBackslashUTF8(sTextToCheck) + \ "\n expected: " + sExceptedSuggs + \ "\n found: " + sFoundSuggs + \ "\n errors: \n" + sListErr) nUnexpectedErrors += 1 | | | > > | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | if not self._checkSuggestions(sExceptedSuggs, sFoundSuggs): print("\n# Line num: " + sLineNum + \ "\n> to check: " + _fuckBackslashUTF8(sTextToCheck) + \ "\n expected: " + sExceptedSuggs + \ "\n found: " + sFoundSuggs + \ "\n errors: \n" + sListErr) nUnexpectedErrors += 1 print("Tests with expected errors:", nTestWithExpectedError, " and suggestions:", nTestWithExpectedErrorAndSugg, "> {:.4} %".format(nTestWithExpectedErrorAndSugg/nTestWithExpectedError*100)) if nUnexpectedErrors: print("Unexpected errors:", nUnexpectedErrors) self._showUntestedRules() def _showUntestedRules (self): aUntestedRules = set() for _, sOpt, sLineId, sRuleId in gc_engine.listRules(): sRuleId = sRuleId.rstrip("0123456789") if sOpt != "@@@@" and sRuleId not in self._aTestedRules and not re.search("^[0-9]+[sp]$|^[pd]_", sRuleId): aUntestedRules.add(f"{sLineId}/{sRuleId}") if aUntestedRules: print() |
︙ | ︙ | |||
165 166 167 168 169 170 171 | sRes = " " * len(sLine) for i, m in enumerate(self._zError.finditer(sLine)): nStart = m.start() - (4 * i) nEnd = m.end() - (4 * (i+1)) sRes = sRes[:nStart] + "~" * (nEnd - nStart) + sRes[nEnd:-4] return sRes | | | | | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | sRes = " " * len(sLine) for i, m in enumerate(self._zError.finditer(sLine)): nStart = m.start() - (4 * i) nEnd = m.end() - (4 * (i+1)) sRes = sRes[:nStart] + "~" * (nEnd - nStart) + sRes[nEnd:-4] return sRes def _checkSuggestions (self, sAllExceptedSuggs, sAllFoundSuggs): lAllExpectedSuggs = sAllExceptedSuggs.split("|||") lAllFoundSuggs = sAllFoundSuggs.split("|||") if len(lAllExpectedSuggs) != len(lAllFoundSuggs): return False for sExceptedSuggs, sFoundSuggs in zip(lAllExpectedSuggs, lAllFoundSuggs): if set(sExceptedSuggs.split("|")) != set(sFoundSuggs.split("|")): return False return True |
︙ | ︙ |
Modified gc_lang/fr/modules-js/gce_suggestions.js from [916bb2d5db] to [807177b0cf].
︙ | ︙ | |||
77 78 79 80 81 82 83 | } return Array.from(aSugg).join("|"); } return ""; } function joinVerbAndSuffix (sFlex, sSfx) { | | | | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | } return Array.from(aSugg).join("|"); } return ""; } function joinVerbAndSuffix (sFlex, sSfx) { if (/^-t-/i.test(sSfx) && /[td]$/i.test(sFlex)) { return sFlex + sSfx.slice(2); } if (/[eac]$/i.test(sFlex)) { if (/^-(?:en|y)$/i.test(sSfx)) { return sFlex + "s" + sSfx; } if (/^-(?:ie?l|elle|on)$/i.test(sSfx)) { return sFlex + "-t" + sSfx; } } return sFlex + sSfx; } function suggVerbPpas (sFlex, sWhat=null) { |
︙ | ︙ | |||
160 161 162 163 164 165 166 | function suggVerbFrom (sStem, sFlex, sWho="") { "conjugate <sStem> according to <sFlex> (and eventually <sWho>)" let aSugg = new Set(); for (let sMorph of gc_engine.oSpellChecker.getMorph(sFlex)) { let lTenses = [ ...sMorph.matchAll(/:(?:Y|I[pqsf]|S[pq]|K|P|Q)/g) ]; if (sWho) { | | | | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | function suggVerbFrom (sStem, sFlex, sWho="") { "conjugate <sStem> according to <sFlex> (and eventually <sWho>)" let aSugg = new Set(); for (let sMorph of gc_engine.oSpellChecker.getMorph(sFlex)) { let lTenses = [ ...sMorph.matchAll(/:(?:Y|I[pqsf]|S[pq]|K|P|Q)/g) ]; if (sWho) { for (let [sTense, ] of lTenses) { if (conj.hasConj(sStem, sTense, sWho)) { aSugg.add(conj.getConj(sStem, sTense, sWho)); } } } else { for (let [sTense, ] of lTenses) { for (let sWho of [ ...sMorph.matchAll(/:[123][sp]/g) ]) { if (conj.hasConj(sStem, sTense, sWho)) { aSugg.add(conj.getConj(sStem, sTense, sWho)); } } } } |
︙ | ︙ | |||
221 222 223 224 225 226 227 | } const _dQuiEst = new Map ([ ["je", ":1s"], ["j’", ":1s"], ["tu", ":2s"], ["il", ":3s"], ["on", ":3s"], ["elle", ":3s"], ["iel", ":3s"], ["nous", ":1p"], ["vous", ":2p"], ["ils", ":3p"], ["elles", ":3p"], ["iels", ":3p"] ]); | < < | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | } const _dQuiEst = new Map ([ ["je", ":1s"], ["j’", ":1s"], ["tu", ":2s"], ["il", ":3s"], ["on", ":3s"], ["elle", ":3s"], ["iel", ":3s"], ["nous", ":1p"], ["vous", ":2p"], ["ils", ":3p"], ["elles", ":3p"], ["iels", ":3p"] ]); function suggVerbMode (sFlex, cMode, sSuj) { let lMode; if (cMode == ":I") { lMode = [":Ip", ":Iq", ":Is", ":If"]; } else if (cMode == ":S") { lMode = [":Sp", ":Sq"]; } else if (cMode.startsWith(":I") || cMode.startsWith(":S")) { lMode = [cMode]; } else { return ""; } let sWho = _dQuiEst.gl_get(sSuj.toLowerCase(), ":3s"); let aSugg = new Set(); |
︙ | ︙ | |||
255 256 257 258 259 260 261 | return Array.from(aSugg).join("|"); } return ""; } //// Nouns and adjectives | | < < < < < < < < < < < < | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | return Array.from(aSugg).join("|"); } return ""; } //// Nouns and adjectives function suggPlur (sFlex, bSelfSugg=false) { // returns plural forms assuming sFlex is singular let aSugg = new Set(); if (sFlex.endsWith("l")) { if (sFlex.endsWith("al") && sFlex.length > 2 && gc_engine.oSpellChecker.isValid(sFlex.slice(0,-1)+"ux")) { aSugg.add(sFlex.slice(0,-1)+"ux"); } if (sFlex.endsWith("ail") && sFlex.length > 3 && gc_engine.oSpellChecker.isValid(sFlex.slice(0,-2)+"ux")) { aSugg.add(sFlex.slice(0,-2)+"ux"); |
︙ | ︙ | |||
295 296 297 298 299 300 301 | aSugg.add(sFlex+"s"); } if (gc_engine.oSpellChecker.isValid(sFlex+"x")) { aSugg.add(sFlex+"x"); } } else { if (gc_engine.oSpellChecker.isValid(sFlex+"S")) { | | | | | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | aSugg.add(sFlex+"s"); } if (gc_engine.oSpellChecker.isValid(sFlex+"x")) { aSugg.add(sFlex+"x"); } } else { if (gc_engine.oSpellChecker.isValid(sFlex+"S")) { aSugg.add(sFlex+"S"); } if (gc_engine.oSpellChecker.isValid(sFlex+"X")) { aSugg.add(sFlex+"X"); } } if (mfsp.hasMiscPlural(sFlex)) { mfsp.getMiscPlural(sFlex).forEach(function(x) { aSugg.add(x); }); } if (aSugg.size == 0 && bSelfSugg && (sFlex.endsWith("s") || sFlex.endsWith("x") || sFlex.endsWith("S") || sFlex.endsWith("X"))) { aSugg.add(sFlex); } aSugg.delete(""); if (aSugg.size > 0) { return Array.from(aSugg).join("|"); } return ""; } function suggSing (sFlex, bSelfSugg=true) { // returns singular forms assuming sFlex is plural let aSugg = new Set(); if (sFlex.endsWith("ux")) { if (gc_engine.oSpellChecker.isValid(sFlex.slice(0,-2)+"l")) { aSugg.add(sFlex.slice(0,-2)+"l"); } if (gc_engine.oSpellChecker.isValid(sFlex.slice(0,-2)+"il")) { |
︙ | ︙ | |||
393 394 395 396 397 398 399 | if (!sMorph.includes(":V")) { // not a verb if (sMorph.includes(":m") || sMorph.includes(":e")) { aSugg.add(suggPlur(sFlex)); } else { let sStem = cregex.getLemmaOfMorph(sMorph); if (mfsp.isMasForm(sStem)) { | | | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | if (!sMorph.includes(":V")) { // not a verb if (sMorph.includes(":m") || sMorph.includes(":e")) { aSugg.add(suggPlur(sFlex)); } else { let sStem = cregex.getLemmaOfMorph(sMorph); if (mfsp.isMasForm(sStem)) { aSugg.add(suggPlur(sStem, true)); } } } else { // a verb let sVerb = cregex.getLemmaOfMorph(sMorph); if (conj.hasConj(sVerb, ":PQ", ":Q2")) { aSugg.add(conj.getConj(sVerb, ":PQ", ":Q2")); |
︙ | ︙ |
Modified gc_lang/fr/modules/gce_suggestions.py from [af90e8e3f3] to [8bef0dbc3f].
︙ | ︙ | |||
166 167 168 169 170 171 172 | def suggVerbInfi (sFlex): "returns infinitive forms of <sFlex>" return "|".join([ sStem for sStem in _oSpellChecker.getLemma(sFlex) if conj.isVerb(sStem) ]) _dQuiEst = { "je": ":1s", "j’": ":1s", "tu": ":2s", "il": ":3s", "on": ":3s", "elle": ":3s", "iel": ":3s", \ "nous": ":1p", "vous": ":2p", "ils": ":3p", "elles": ":3p", "iels": ":3p" } | < < | | | < < < < < < < < < | | | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | def suggVerbInfi (sFlex): "returns infinitive forms of <sFlex>" return "|".join([ sStem for sStem in _oSpellChecker.getLemma(sFlex) if conj.isVerb(sStem) ]) _dQuiEst = { "je": ":1s", "j’": ":1s", "tu": ":2s", "il": ":3s", "on": ":3s", "elle": ":3s", "iel": ":3s", \ "nous": ":1p", "vous": ":2p", "ils": ":3p", "elles": ":3p", "iels": ":3p" } def suggVerbMode (sFlex, cMode, sSuj): "returns other conjugations of <sFlex> acconding to <cMode> and <sSuj>" if cMode == ":I": lMode = [":Ip", ":Iq", ":Is", ":If"] elif cMode == ":S": lMode = [":Sp", ":Sq"] elif cMode.startswith((":I", ":S")): lMode = [cMode] else: return "" sWho = _dQuiEst.get(sSuj.lower(), ":3s") aSugg = set() for sStem in _oSpellChecker.getLemma(sFlex): tTags = conj._getTags(sStem) if tTags: for sTense in lMode: if conj._hasConjWithTags(tTags, sTense, sWho): aSugg.add(conj._getConjWithTags(sStem, tTags, sTense, sWho)) if aSugg: return "|".join(aSugg) return "" ## Nouns and adjectives def suggPlur (sFlex, bSelfSugg=False): "returns plural forms assuming sFlex is singular" aSugg = set() if sFlex.endswith("l"): if sFlex.endswith("al") and len(sFlex) > 2 and _oSpellChecker.isValid(sFlex[:-1]+"ux"): aSugg.add(sFlex[:-1]+"ux") if sFlex.endswith("ail") and len(sFlex) > 3 and _oSpellChecker.isValid(sFlex[:-2]+"ux"): aSugg.add(sFlex[:-2]+"ux") if sFlex.endswith("L"): if sFlex.endswith("AL") and len(sFlex) > 2 and _oSpellChecker.isValid(sFlex[:-1]+"UX"): aSugg.add(sFlex[:-1]+"UX") if sFlex.endswith("AIL") and len(sFlex) > 3 and _oSpellChecker.isValid(sFlex[:-2]+"UX"): aSugg.add(sFlex[:-2]+"UX") if sFlex[-1:].islower(): if _oSpellChecker.isValid(sFlex+"s"): aSugg.add(sFlex+"s") if _oSpellChecker.isValid(sFlex+"x"): aSugg.add(sFlex+"x") else: if _oSpellChecker.isValid(sFlex+"S"): aSugg.add(sFlex+"S") if _oSpellChecker.isValid(sFlex+"X"): aSugg.add(sFlex+"X") if mfsp.hasMiscPlural(sFlex): aSugg.update(mfsp.getMiscPlural(sFlex)) if not aSugg and bSelfSugg and sFlex.endswith(("s", "x", "S", "X")): aSugg.add(sFlex) aSugg.discard("") if aSugg: return "|".join(aSugg) |
︙ | ︙ | |||
298 299 300 301 302 303 304 | if not ":V" in sMorph: # not a verb if ":m" in sMorph or ":e" in sMorph: aSugg.add(suggPlur(sFlex)) else: sStem = cr.getLemmaOfMorph(sMorph) if mfsp.isMasForm(sStem): | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | if not ":V" in sMorph: # not a verb if ":m" in sMorph or ":e" in sMorph: aSugg.add(suggPlur(sFlex)) else: sStem = cr.getLemmaOfMorph(sMorph) if mfsp.isMasForm(sStem): aSugg.add(suggPlur(sStem, True)) else: # a verb sVerb = cr.getLemmaOfMorph(sMorph) if conj.hasConj(sVerb, ":PQ", ":Q2"): aSugg.add(conj.getConj(sVerb, ":PQ", ":Q2")) elif conj.hasConj(sVerb, ":PQ", ":Q1"): sSugg = conj.getConj(sVerb, ":PQ", ":Q1") |
︙ | ︙ |
Modified gc_lang/fr/rules.grx from [aeba1ed251] to [6130f02351].
︙ | ︙ | |||
2577 2578 2579 2580 2581 2582 2583 | TEST: {{Prend-lui}} le pouls. ->> Prends-lui|Prenons-lui|Prenez-lui TEST: {{apport-lui}}. ->> TEST: {{Expliques-leur}} comment faire. ->> Explique-leur|Expliquons-leur|Expliquez-leur TEST: {{fou-leur}} la paix ->> fous-leur TEST: {{explique-leurs}} de quoi il est question. ->> explique-leur TEST: {{calcul-leurs}} ça. ->> calcul-leur TEST: {{aller-y}} ->> allez-y|vas-y|allons-y | | | 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 | TEST: {{Prend-lui}} le pouls. ->> Prends-lui|Prenons-lui|Prenez-lui TEST: {{apport-lui}}. ->> TEST: {{Expliques-leur}} comment faire. ->> Explique-leur|Expliquons-leur|Expliquez-leur TEST: {{fou-leur}} la paix ->> fous-leur TEST: {{explique-leurs}} de quoi il est question. ->> explique-leur TEST: {{calcul-leurs}} ça. ->> calcul-leur TEST: {{aller-y}} ->> allez-y|vas-y|allons-y TEST: {{expliquer-en}} ->> expliquez-en|expliques-en|expliquons-en TEST: {{appuis-en}} ->> appuies-en TEST: {{appuis-y}} ->> appuies-y TEST: {{demande-en}} ->> demandes-en TEST: {{demande-y}} comment faire ->> demandes-y TEST: c’est mon chez-moi TEST: c’est ton chez-toi TEST: penses-y |
︙ | ︙ | |||
6883 6884 6885 6886 6887 6888 6889 | avenir devant [moi|toi|soi|lui|elle|nous|vous|eux|elles] <<- /pleo/ morph(<1, ":A.*:[me]:[si]") ->> avenir && Pléonasme. >coup de foudre [immédiat+s|instantané+ses|soudain] <<- /pleo/ ->> \1 \2 \3 && Pléonasme. [paire+s] de >jumeau | | | 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 | avenir devant [moi|toi|soi|lui|elle|nous|vous|eux|elles] <<- /pleo/ morph(<1, ":A.*:[me]:[si]") ->> avenir && Pléonasme. >coup de foudre [immédiat+s|instantané+ses|soudain] <<- /pleo/ ->> \1 \2 \3 && Pléonasme. [paire+s] de >jumeau <<- /pleo/ ->> =suggPlur(\-1, True) && Pléonasme. >panacée >universel <<- /pleo/ ->> \1|remède universel && Pléonasme. >secousse [>séismique|>sismique] <<- /pleo/ ->> secousse tellurique|secousses telluriques|tremblement de terre && Pléonasme. |
︙ | ︙ |