Index: compile_rules.py ================================================================== --- compile_rules.py +++ compile_rules.py @@ -8,10 +8,12 @@ DEF = {} FUNCTIONS = [] +RULESET = set() # set of rule-ids to check if there is several rules with the same id + JSREGEXES = {} WORDLIMITLEFT = r"(? 0: if not tGroups: - print("# warning: groups positioning code for JavaScript should be defined at line " + sLineId) + print("# Warning: groups positioning code for JavaScript should be defined at line " + sLineId) else: if nGroup != len(tGroups): - print("# error: groups positioning code irrelevant at line " + sLineId) + print("# Error: groups positioning code irrelevant at line " + sLineId) ## word limit if cWordLimitLeft == '[' and not sRegex.startswith(("^", '’', "'", ",")): sRegex = WORDLIMITLEFT + sRegex if cWordLimitRight == ']' and not sRegex.endswith(("$", '’', "'", ",")): @@ -318,50 +323,50 @@ if sMsg[0:1] == "=": sMsg = prepareFunction(sMsg[1:]) FUNCTIONS.append(("m"+sIdAction, sMsg)) for x in re.finditer("group[(](\d+)[)]", sMsg): if int(x.group(1)) > nGroup: - print("# error in groups in message at line " + sIdAction + " ("+str(nGroup)+" groups only)") + print("# Error in groups in message at line " + sIdAction + " ("+str(nGroup)+" groups only)") sMsg = "=m"+sIdAction else: for x in re.finditer(r"\\(\d+)", sMsg): if int(x.group(1)) > nGroup: - print("# error in groups in message at line " + sIdAction + " ("+str(nGroup)+" groups only)") + print("# Error in groups in message at line " + sIdAction + " ("+str(nGroup)+" groups only)") if re.search("[.]\\w+[(]", sMsg): - print("# error in message at line " + sIdAction + ": This message looks like code. Line should begin with =") + print("# Error in message at line " + sIdAction + ": This message looks like code. Line should begin with =") if sAction[0:1] == "=" or cAction == "=": if "define" in sAction and not re.search(r"define\(\\\d+ *, *\[.*\] *\)", sAction): - print("# error in action at line " + sIdAction + ": second argument for define must be a list of strings") + print("# Error in action at line " + sIdAction + ": second argument for define must be a list of strings") sAction = prepareFunction(sAction) sAction = sAction.replace("m.group(i[4])", "m.group("+str(iGroup)+")") for x in re.finditer("group[(](\d+)[)]", sAction): if int(x.group(1)) > nGroup: - print("# error in groups in replacement at line " + sIdAction + " ("+str(nGroup)+" groups only)") + print("# Error in groups in replacement at line " + sIdAction + " ("+str(nGroup)+" groups only)") else: for x in re.finditer(r"\\(\d+)", sAction): if int(x.group(1)) > nGroup: - print("# error in groups in replacement at line " + sIdAction + " ("+str(nGroup)+" groups only)") + print("# Error in groups in replacement at line " + sIdAction + " ("+str(nGroup)+" groups only)") if re.search("[.]\\w+[(]", sAction): - print("# error in action at line " + sIdAction + ": This action looks like code. Line should begin with =") + print("# Error in action at line " + sIdAction + ": This action looks like code. Line should begin with =") if cAction == "-": ## error detected if not sAction: - print("# error in action at line " + sIdAction + ": This action is empty.") + print("# Error in action at line " + sIdAction + ": This action is empty.") if sAction[0:1] == "=": FUNCTIONS.append(("s"+sIdAction, sAction[1:])) sAction = "=s"+sIdAction elif sAction.startswith('"') and sAction.endswith('"'): sAction = sAction[1:-1] if not sMsg: - print("# error in action at line " + sIdAction + ": the message is empty.") + print("# Error in action at line " + sIdAction + ": the message is empty.") return [sCondition, cAction, sAction, iGroup, sMsg, sURL] elif cAction == "~": ## text preprocessor if not sAction: - print("# error in action at line " + sIdAction + ": This action is empty.") + print("# Error in action at line " + sIdAction + ": This action is empty.") if sAction[0:1] == "=": FUNCTIONS.append(("p"+sIdAction, sAction[1:])) sAction = "=p"+sIdAction elif sAction.startswith('"') and sAction.endswith('"'): sAction = sAction[1:-1] @@ -369,11 +374,11 @@ elif cAction == "=": ## disambiguator if sAction[0:1] == "=": sAction = sAction[1:] if not sAction: - print("# error in action at line " + sIdAction + ": This action is empty.") + print("# Error in action at line " + sIdAction + ": This action is empty.") FUNCTIONS.append(("d"+sIdAction, sAction)) sAction = "d"+sIdAction return [sCondition, cAction, sAction] elif cAction == ">": ## no action, break loop if condition is False Index: gc_lang/fr/rules.grx ================================================================== --- gc_lang/fr/rules.grx +++ gc_lang/fr/rules.grx @@ -422,11 +422,11 @@ # IP __[s]__ \d+[.:]\d+[.:]\d+[.:]\d+ <<- ~>> * # mètres (m) __[s>__ "\d+ (m) " @@w <<- ~1>> _ # heures -__[s]__ (?:à |)[012]?\d[h:]\d\d(?:[m:]\d\ds?|) <<- ~>> * +__[s]__ (?:de |à |)[012]?\d[h:]\d\d(?:[m:]\d\ds?|) <<- ~>> * # crochets __[s]__ \[…\] <<- ~>> * __[s]__ \[({w_1})\] @@1 <<- \1.isdigit() ~>> * <<- __else__ ~>> _ @@ -1893,11 +1893,11 @@ TEST: __ocr__ {{Us}} arrive demain. # il / i1 / if / 11 -__[i]/ocr(ocr_il_ils2)__ +__[i]/ocr(ocr_il_ils3)__ [i1][1f]s? <<- not \0.endswith("s") ->> Il|il # Erreur de numérisation ? <<- __else__ ->> Ils|ils # Erreur de numérisation ? TEST: __ocr__ {{i1s}} en savent beaucoup trop pour leur propre bien. @@ -3102,11 +3102,11 @@ (se) (?:qu[ei]?|dont|malgré|pourquoi|avec|pour|par) @@0 <<- -1>> ce # Confusion. Exemples : ce bâtiment, se perdre.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=2440 __[i]/conf(conf_qui_se_verbe)__ qui (ce) ({w_2}) @@4,$ <<- morphex(\2, ":V", ":[NAQ].*:[me]") or before(r"(?i)\b[cs]e +") -1>> se # Confusion probable. Exemples : ce bâtiment, se perdre.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=2440 -__[i]/conf(conf_ce_être)__ +__[i]/conf(conf_ceux_ce_être)__ (ceux) (?:ne |)(?:sont|serai(?:en|)[ts]?|f[uû](?:ren|)t|n’(?!ayant|étant)\w+) @@0 <<- -1>> ce # Confusion.|http://www.intellego.fr/soutien-scolaire-6eme/aide-scolaire-francais/ce-ceux-ou-se/3829 __[s]/conf(conf_ce_ne_être_doit)__ ([sS]e) n(?:e |’)({être}|d[eouû]\w+|p[oeuû]\w+) @@0,$ <<- morph(\2, ">(?:être|pouvoir|devoir) .*:3s", False) @@ -3453,14 +3453,14 @@ # quand / quant / qu’en __[i]/conf(conf_quant_à)__ (?(?:arriver|venir|à|revenir|partir|aller) ") -1>> quant # Confusion probable. Quand = à quel moment. Quant à = à propos de. -__[i]/conf(conf_quand)__ quant(?! à| aux?| est[ -]il d(?:es?|u) ) <<- ->> quand # Confusion. Quand = à quel moment. Quant à = à propos de. +__[i]/conf(conf_quand1)__ quant(?! à| aux?| est[ -]il d(?:es?|u) ) <<- ->> quand # Confusion. Quand = à quel moment. Quant à = à propos de. __[i]/conf(conf_qu_en1)__ (quan[dt]) est[ -]il d(?:es?|u) @@0 <<- -1>> qu’en # Confusion. Ce qu’il en est de… → Qu’en est-il de… ? __[i]/conf(conf_qu_en2)__ (quan[dt]) ({w_2}ant) @@0,$ <<- morph(\2, ":P", False) -1>> qu’en # Confusion probable. -__[i]/conf(conf_quand)__ +__[i]/conf(conf_quand2)__ (qu en) (?:je|tu|ils?) @@0 <<- not after("^ +ne s(?:ai[st]|u[st]|urent|avai(?:[ts]|ent)) ") -1>> quand # Confusion probable. Pour évoquer un moment, écrivez : TEST: {{Quant}} est-il du chien ? TEST: {{Quand}} à ma santé, elle est défaillante. @@ -6958,11 +6958,11 @@ TEST: {{comme même}} il y va fort, le saligaud ! TEST: La météo disait qu’il ferait beau temps, mais il pleut {{comme même}}… # quel que soit / quoi qu’il en soit -__[i]/conf(conf_quel_que_soit)__ +__[i]/conf(conf_quel_que_soit1)__ quelques? soi(?:ent|t|s|) <<- ->> quel que soit|quelle que soit|quels que soient|quelles que soient # Confusion.|https://fr.wiktionary.org/wiki/quel_que_soit __[i]/conf(conf_quoi_qu_il_en_soit)__ quoiqu il en soit <<- not morph(word(1), ":[AQ]", False) ->> quoi qu’il en soit # Confusion.|https://fr.wiktionary.org/wiki/quoi_qu%E2%80%99il_en_soit @@ -7103,11 +7103,11 @@ (?:chez|don de|sur|avec|pour) (soit) @@$ <<- not after(" soit ") -1>> soi # Confusion probable. __[i]/conf(conf_en_soi)__ (?> soi # Confusion probable. -__[i]/conf(conf_quel_que_soit)__ +__[i]/conf(conf_quel_que_soit2)__ quel(?:le|)s? que (soi(?:es?|)) @@$ <<- -1>> soit|soient # Confusion probable. __[i]/conf(conf_soi_même1)__ (soi[tes]s? mêmes?) @@$ <<- morph(word(-1), ":[YQ]|>(?:avec|contre|par|pour|sur) ", False, True) -1>> soi-même # Confusion probable : moi-même, toi-même, lui-même, elle-même, soi-même, elles-mêmes, eux-mêmes. __[i]/conf(conf_soi_même2)__ @@ -8026,11 +8026,11 @@ TEST: Elle te laisse finir le travail. TEST: Je me laisse de quoi finir. TEST: Il te laisse trois jours de délai. -__[i]/ppas(ppas_me_te_laisser_adj)__ +__[i]/ppas(ppas_nous_les_laisser_adj)__ (nous|les) +(laiss\w*) +({w_3}) @@0,w,$ <<- morph(\2, ">laisser ", False) and morphex(\3, ":[AQ].*:s", ":(?:[YG]|[AQ].*:[ip])") and (\1.endswith("es") or ( \1.endswith("us") and not \2.endswith("ons") )) -3>> =suggPlur(@) # Accord avec « \1 » : « \3 » devrait être au pluriel. TEST: je les laisse {{indifférent}}. @@ -8551,33 +8551,33 @@ -3>> =suggFemPlur(@) # Accord avec le sujet « \1 » : « \3 » devrait être au féminin pluriel. TEST: elles se sentent {{perdu}} -__[i]/ppas(ppas_le_verbe)__ +__[i]/ppas(ppas_le_verbe_pensée)__ le ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2}[esx]) @@w,$ <<- morph(\1, ">(?:trouver|considérer|croire|rendre|voilà) ", False) and morphex(\2, ":[AQ]:(?:[me]:p|f)", ":(?:G|Y|[AQ]:m:[is])") -2>> =suggMasSing(@) # Accord avec le COD “le” : « \2 » doit être au masculin singulier. -__[i]/ppas(ppas_la_verbe)__ +__[i]/ppas(ppas_la_verbe_pensée)__ la ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2}[uiéesx]) @@w,$ <<- morph(\1, ">(?:trouver|considérer|croire|rendre|voilà) ", False) and morphex(\2, ":[AQ]:(?:[fe]:p|m)", ":(?:G|Y|[AQ]:f:[is])") -2>> =suggFemSing(@) # Accord avec le COD “la” : « \2 » doit être au féminin singulier. -__[i]/ppas(ppas_les_verbe)__ +__[i]/ppas(ppas_les_verbe_pensée)__ les ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2}) @@w,$ <<- morph(\1, ">(?:trouver|considérer|croire|rendre|voilà) ", False) and morphex(\2, ":[AQ].*:s", ":(?:G|Y|[AQ].*:[ip])") -2>> =suggPlur(@) # Accord avec le COD “les” : « \2 » doit être au pluriel. -__[i]/ppas(ppas_me_te_verbe)__ +__[i]/ppas(ppas_me_te_verbe_pensée)__ ([mt]e) ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2}[sx]) @@0,w,$ <<- morph(\2, ">(?:trouver|considérer|croire|rendre|voilà) ", False) and morphex(\3, ":[AQ].*:p", ":(?:G|Y|[AQ].*:[is])") -3>> =suggSing(@) # Accord avec le pronom “\1” : « \3 » doit être au singulier. -__[i]/ppas(ppas_se_verbe)__ +__[i]/ppas(ppas_se_verbe_pensée)__ se ((?:trouv|consid[éè]r|cr[ouû]|rend)\w*) +({w_3}) @@w,$ <<- morph(\1, ">(?:trouver|considérer|croire|rendre) .*:3s", False) and morphex(\2, ":[AQ].*:p", ":(?:G|Y|[AQ].*:[is])") -2>> =suggSing(@) # Accord avec le pronom “se” (le verbe étant au singulier) : « \2 » doit être au singulier. <<- morph(\1, ">(?:trouver|considérer|croire|rendre) .*:3p", False) and morphex(\2, ":[AQ].*:s", ":(?:G|Y|[AQ].*:[ip])") -2>> =suggSing(@) # Accord avec le pronom “se” (le verbe étant au pluriel) : « \2 » doit être au pluriel. -__[i]/ppas(ppas_nous_verbe)__ +__[i]/ppas(ppas_nous_verbe_pensée)__ nous ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2}) @@w,$ <<- ( morphex(\1, ">(?:trouver|considérer|croire|rendre|voilà) ", ":1p") or (morph(\1, ">(?:trouver|considérer|croire) .*:1p", False) and before(r"\bn(?:ous|e) +$")) ) and morphex(\2, ":[AQ].*:s", ":(?:G|Y|[AQ].*:[ip])") -2>> =suggPlur(@) # Accord avec le pronom “nous” : « \2 » doit être au pluriel. @@ -8681,11 +8681,11 @@ # Le participe passé devrait être au masculin singulier.|http://fr.wikipedia.org/wiki/Accord_du_participe_pass%C3%A9_en_fran%C3%A7ais TEST: des hommes, des femmes, des enfants qui ne leur avaient {{faits}} que du bien. -__[i]/ppas(ppas_avoir)__ +__[i]/ppas(ppas_avoir_ppas_mas_sing)__ avoir +({w_2}) @@$ <<- not re.search("(?i)^(?:confiance|cours|envie|peine|prise|crainte|cure|affaire|hâte|force|recours)$", \1) and morphex(\1, ":Q.*:(?:f|m:p)", ":m:[si]") and before("(?i)(?:après +$|sans +$|pour +$|que? +$|quand +$|, +$|^ *$)") -1>> =suggMasSing(@) # Le participe passé devrait être au masculin singulier.|http://fr.wikipedia.org/wiki/Accord_du_participe_pass%C3%A9_en_fran%C3%A7ais @@ -8790,11 +8790,11 @@ # Le participe passé devrait être au masculin singulier.|http://fr.wikipedia.org/wiki/Accord_du_participe_pass%C3%A9_en_fran%C3%A7ais TEST: ce que ça a {{donnée}} -__[i]/ppas(ppas_avoir)__ +__[i]/ppas(ppas_avoir_conf_infi)__ ({avoir}) +({w_2}e[rz]) @@0,$ <<- not re.search("^(?:A|avions)$", \1) and morph(\1, ":V0a", False) and morph(\2, ":V.+:(?:Y|2p)", False) -2>> =suggVerbPpas(@, ":m:s") # Incohérence avec « \1 » : « \2 » n’est pas un participe passé. <<- __also__ and \1 == "a" and \2.endswith("r") and not before(r"(?i)\b(?:[mtn]’|il +|on +|elle +)$") -1>> à # Confusion probable : “a” est une conjugaison du verbe avoir. Pour la préposition, écrivez : @@ -10237,16 +10237,16 @@ TEST: Je {{voudrai}} qu’il soit déjà là. TEST: J’aimerai ces cours-là autant que les autres. TEST: J’aimerai la danse et la musique, puisque vous l’exigez. -__[i>/vmode(vmode_j_aurais_aimé_que_avoir_être)__ - j’(aurai) +(?:aimé|souhaité|préféré|voulu) +(?:que? |> ) @@2 +__[i>/vmode(vmode_j_aurais_aimé_que_avoir_être1)__ + j’(aurai) +(?:aimé|souhaité|préféré|voulu) +(?:que? |ne |> ) @@2 <<- -1>> aurais|eusse # Pour un souhait passé, utilisez le conditionnel passé et non le futur antérieur. Exemple pour le futur antérieur : « quand j’aurai fini… » -__[i]/vmode(vmode_j_aurais_aimé_que_avoir_être)__ - j’(aurai) +(?:aimé|souhaité|préféré|voulu) +({infi}|ne) @@2,$ - <<- morph(\2, ":[YX]", False) +__[i]/vmode(vmode_j_aurais_aimé_que_avoir_être2)__ + j’(aurai) +(?:aimé|souhaité|préféré|voulu) +(?:[nmtsl]’|)({infi}) @@2,$ + <<- morph(\2, ":Y", False) -1>> aurais|eusse # Pour un souhait passé, utilisez le conditionnel passé et non le futur antérieur. Exemple pour le futur antérieur : « quand j’aurai fini… » TEST: J’{{aurai}} aimé nous offrir ce magnifique cadeau. TEST: j’{{aurai}} voulu être un artiste. TEST: j’{{aurai}} préféré ne pas avoir à l’entendre.