Index: compile_rules_graph.py ================================================================== --- compile_rules_graph.py +++ compile_rules_graph.py @@ -11,10 +11,11 @@ dACTIONS = {} dFUNCTIONS = {} dFUNCNAME = {} dDECLENSIONS = {} +dANTIPATTERNS = {} def createFunction (sType, sCode, bStartWithEqual=False): "create a function (stored in ) and return function name" sCode = prepareFunction(sCode) @@ -154,39 +155,51 @@ def createRule (iLine, sRuleName, sTokenLine, iActionBlock, sActions, nPriority, dOptPriority, dDef, dDecl): "generator: create rule as list" # print(iLine, "//", sRuleName, "//", sTokenLine, "//", sActions, "//", nPriority) - for lToken in genTokenLines(sTokenLine, dDef, dDecl): - # Calculate positions - dPos = {} # key: iGroup, value: iToken - iGroup = 0 - #if iLine == 15818: # debug - # print(" ".join(lToken)) - for i, sToken in enumerate(lToken): - if sToken.startswith("(") and sToken.endswith(")"): - lToken[i] = sToken[1:-1] - iGroup += 1 - dPos[iGroup] = i + 1 # we add 1, for we count tokens from 1 to n (not from 0) - - # Parse actions - for iAction, sAction in enumerate(sActions.split(" <<- ")): - sAction = sAction.strip() - if sAction: - sActionId = sRuleName + "__b" + str(iActionBlock) + "_a" + str(iAction) - aAction = createAction(sActionId, sAction, nPriority, dOptPriority, len(lToken), dPos) - if aAction: - sActionName = storeAction(sActionId, aAction) - lResult = list(lToken) - lResult.extend(["##"+str(iLine), sActionName]) - #if iLine == 13341: - # print(" ".join(lToken)) - # print(sActionId, aAction) - yield lResult - else: - print(" # Error on action at line:", iLine) - print(sTokenLine, "\n", sActions) + if sTokenLine.startswith("!!") and sTokenLine.endswith("¡¡"): + # antipattern + sTokenLine = sTokenLine[2:-2].strip() + if sRuleName not in dANTIPATTERNS: + dANTIPATTERNS[sRuleName]= [] + for lToken in genTokenLines(sTokenLine, dDef, dDecl): + dANTIPATTERNS[sRuleName].append(lToken) + else: + # pattern + for lToken in genTokenLines(sTokenLine, dDef, dDecl): + if sRuleName in dANTIPATTERNS and lToken in dANTIPATTERNS[sRuleName]: + # matches an antipattern -> discard + continue + # Calculate positions + dPos = {} # key: iGroup, value: iToken + iGroup = 0 + #if iLine == 15818: # debug + # print(" ".join(lToken)) + for i, sToken in enumerate(lToken): + if sToken.startswith("(") and sToken.endswith(")"): + lToken[i] = sToken[1:-1] + iGroup += 1 + dPos[iGroup] = i + 1 # we add 1, for we count tokens from 1 to n (not from 0) + + # Parse actions + for iAction, sAction in enumerate(sActions.split(" <<- ")): + sAction = sAction.strip() + if sAction: + sActionId = sRuleName + "__b" + str(iActionBlock) + "_a" + str(iAction) + aAction = createAction(sActionId, sAction, nPriority, dOptPriority, len(lToken), dPos) + if aAction: + sActionName = storeAction(sActionId, aAction) + lResult = list(lToken) + lResult.extend(["##"+str(iLine), sActionName]) + #if iLine == 13341: + # print(" ".join(lToken)) + # print(sActionId, aAction) + yield lResult + else: + print(" # Error on action at line:", iLine) + print(sTokenLine, "\n", sActions) def changeReferenceToken (sText, dPos): "change group reference in with values in " if "\\" not in sText: Index: gc_lang/fr/rules.grx ================================================================== --- gc_lang/fr/rules.grx +++ gc_lang/fr/rules.grx @@ -6105,15 +6105,12 @@ TEST: travailler {{a}} bonne distance des fourneaux. TEST: Il l’a fait {{a}} cause de toi. __conf_à_cor_et_à_cri__ - a [corps|>cor] [et|est] [à|a] [>cri|crie|cries|crit] - à [corps|cors] [et|est] [à|a] [>cri|crie|cries|crit] - à cor est [à|a] [>cri|crie|cries|crit] - à cor et a [>cri|crie|cries|crit] - à cor et à [cris|crie|cries|crit] + !! à cor et à cri ¡¡ + [a|à] [corps|cor+s] [et|est|es|ait|ais|aies|é|è|ei|ai|aient] [à|a] [cri+s|crie+s|crit] <<- /conf/ ->> à cor et à cri # Locution adverbiale invariable. (Le cor est un instrument à vent utilisé pour la chasse.)|https://fr.wiktionary.org/wiki/%C3%A0_cor_et_%C3%A0_cri TEST: Elles hurlèrent {{à corps et à cris}}. TEST: manifester sa colère à cor et à cri. @@ -6160,61 +6157,61 @@ TEST: Elles avaient bien l’intention d’en parler. TEST: J’ai mis ces trésors de côté spécialement à votre intention __conf_à_moindre_cout__ - [a|à] >moindre [>cou|>coup] + !! à moindre [cout|coût] ¡¡ + [a|à] [moindre+s] [>cou|>coup|cout+s|coût+s] <<- /conf/ ->> à moindre coût # Confusion. Pour évoquer des dépenses, écrivez “coût”. +TEST: {{à moindres coups}} +TEST: tout acheter à moindre coût + __conf_à_moindres_frais__ - a >moindre [>frai|>frêt] - à moindre [>frai|>frêt] - à moindres [frai|>frêt] + !! à moindres frais ¡¡ + [a|à] [moindre+s] [frai+s|>frêt] <<- /conf/ ->> à moindres frais # Pour évoquer des dépenses, écrivez “frais” (pluriel). TEST: {{a moindre frais}} TEST: S’en sortir à moindres frais, pas si simple. __conf_à_parts_égales__ - a [part|parts|par|pare|pares] >égale - à [part|par|pare|pares] >égale - à parts [égal|égals|égale] + !! à parts égales ¡¡ + [a|à] [part|parts|par|pare|pares] [égale+s] <<- /conf/ ->> à parts égales # Locution “à parts égales” (toujours au pluriel). TEST: {{à part égale}} TEST: un partage à parts égales __conf_à_peu_près__ - a [peu|peux|peut] [près|>pré|>prête] - à [peux|peut] [près|>pré|>prête] - à peu [>pré|>prête] + !! à peu près ¡¡ + [a|à] [peu|peux|peut] [près|>pré|>prête] <<- /conf/ ->> à peu près # Confusion.|https://fr.wiktionary.org/wiki/%C3%A0_peu_pr%C3%A8s <<- ~>> * TEST: C’est {{à peu prêt}} la même chose. TEST: elle est {{a peut près}} au point. TEST: C’est à peu près ça. __conf_à_pleines_dents__ - a [>plaine|>pleine] [>dent|>dan] - à [>plaine|pleine] [>dent|>dan] - à pleines [dent|>dan] + !! à pleines dents ¡¡ + [a|à] [>plaine|pleine+s] [dent+s|>dan] <<- /conf/ ->> à pleines dents # Locution “à pleines dents” (toujours au pluriel). TEST: Elle mord la vie {{à plaine dent}}. __conf_à_tire_d_aile__ à tire d’ >aile <<- /tu/ ->> à tire-d’aile # Trait d’union manquant. Locution “à tire-d’aile”.|https://fr.wiktionary.org/wiki/%C3%A0_tire-d%E2%80%99aile - [a|à] >tir d’ [>aile|elle|elles|ail] - a >tire d’ [>aile|elle|elles|ail] + !! à tire-d’aile ¡¡ + [a|à] [>tir|>tire] d’ [>aile|elle|elles|ail] [a|à] [tir-d’aile|tirs-d’aile|tir-d’ailes|tirs-d’ailes] <<- /conf/ ->> à tire-d’aile # Confusion. Locution “à tire-d’aile”.|https://fr.wiktionary.org/wiki/%C3%A0_tire-d%E2%80%99aile TEST: venir {{à tir d’ail}} jusqu’ici TEST: Elle arrivait à tire-d’aile. @@ -6232,13 +6229,14 @@ TEST: Au nom du progrès, les Victoriens en mal de modernisation rasèrent à tire-larigot les églises et les bâtiments jugés trop anciens. __conf_à_vau_l_eau__ + !! à vau-l’eau ¡¡ [a|à] [volo|vo-lo] [à|a] [>veau|>vau|vo|vos] l’ [o|os|au|aux|>eau] - a [vau-l’eau|vaux-l’eau] + [a|à] [vau-l’eau|vaux-l’eau] <<- /conf/ ->> à vau-l’eau # Confusion. Locution “à vau-l’eau”, qui signifie “au fil de l’eau, sans contrôle”.|https://fr.wiktionary.org/wiki/%C3%A0_vau-l%E2%80%99eau TEST: tout part {{à veau l’eau}} TEST: On décida de tout laisser partir {{à vau l’o}} TEST: une dérive à vau-l’eau. @@ -6727,15 +6725,13 @@ TEST: Je me suis trompé. {{Autant}} pour moi. TEST: Je me suis trompé. {{Au tan}} pour moi. __conf_autant_que_faire_se_peut!7__ - [au|aux] [temps|tant|>tan] [que|qu’] [faire|ferre|>fer] [se|ce] [peu|peut|peux] - >autan [que|qu’] [faire|ferre|>fer] [se|ce] [peu|peut|peux] - autant [que|qu’] [ferre|>fer] [se|ce] [peu|peut|peux] - autant [que|qu’] [faire|ferre|>fer] ce [peu|peut|peux] - autant [que|qu’] [faire|ferre|>fer] [se|ce] [peu|peux] + !! autant que faire se peut ¡¡ + [au|aux] [temps|tant|>tan] [que|qu’] [faire|ferre|ferres|>fer] [se|ce] [peu|peut|peux] + [>autan|autant] [que|qu’] [faire|ferre|ferres|>fer] [se|ce] [peu|peut|peux] <<- /conf/ ->> autant que faire se peut # Locution adverbiale : « autant que faire se peut ».|https://fr.wiktionary.org/wiki/autant_que_faire_se_peut TEST: on va y arriver, {{au temps que faire se peu}}… TEST: autant que faire se peut, il faut éviter la confusion entre ces deux discours. @@ -7033,14 +7029,14 @@ TEST: on va lui régler son {{conte}}, à cet enculé. TEST: tout {{conte}} fait, ça reste un salopard. __conf_conte_de_fée__ - [comte|comtes|>compte] de bonnes femmes - [comte|comtes|>compte] de >fée - [comte|comtes|>compte] [>allégorique|>fantastique|>littéraire|merveilleux|moral|moraux|oral|oraux|>populaire|>satirique|>traditionnelle] - [comte|comtes|>compte] et >légende + [comte+s|>compte] de bonne+s >femme + [comte+s|>compte] de >fée + [comte+s|>compte] [>allégorique|>fantastique|>littéraire|merveilleux|moral|moraux|oral|oraux|>populaire|>satirique|>traditionnelle] + [comte+s|>compte] et >légende <<- /conf/ -1>> conte|contes # Confusion probable. Si vous parlez d’un récit, écrivez :|https://fr.wiktionary.org/wiki/conte TEST: Encore un {{comte}} de fée, assez de ces fadaises ! TEST: c’est un {{compte}} allégorique. TEST: {{Comptes}} et légendes des Terres du Milieu. @@ -7081,11 +7077,11 @@ TEST: Elle souffla puissamment dans le {{corps}} de chasse. # cour / cours / court __conf_cour_cours_court_courre__ - au [cour|court|courre|courres|courts] [de|d’|des|du] + au [cour|court+s|courre+s] [de|d’|des|du] <<- /conf/ -2>> cours # Confusion. Locution “au cours de”. Une cour… Un cours… Adjectif : court(e). en cour martiale en cour [de|d’] [cassation|justice] en cour d’ [>assise] @@ -7200,24 +7196,22 @@ TEST: ils ont tant d’avantages. # de part en part __conf_de_part_en_part__ - [de|d’] [par|parts|pare|pares|part] [en|an] [par|parts|pare|pares] - [de|d’] [par|parts|pare|pares] [en|an] [par|parts|pare|pares|part] - [de|d’] part an part + !! de part en part ¡¡ + [de|d’] [par|part|parts|pare|pares] [en|an] [par|part|parts|pare|pares] <<- /conf/ ->> de part en part # Confusion. Locution “de part en part”.|https://fr.wiktionary.org/wiki/de_part_en_part TEST: {{de par en par}} ->> de part en part TEST: ils essayèrent tout, de part en part. # de temps à autre __conf_de_temps_à_autre__ - [de|d’] [>tan|tant] [à|a] >autre - [de|d’] [>tan|tant|temps] a >autre - [de|d’] [>tan|tant|temps] [à|a] autres + !! [de|d’] temps à autre ¡¡ + [de|d’] [>tan|tant|temps] [à|a] [autre+s] <<- /conf/ ->> de temps à autre # Confusion. Locution “de temps à autre”.|https://fr.wiktionary.org/wiki/de_temps_%C3%A0_autre TEST: Il continuait son travail, mâchonnant de temps à autre une grosse chique qui tour à tour lui gonflait chaque joue. TEST: Il venait {{de temps à autres}}. TEST: {{de tan à autre}}, c’était correct de venir par ici. @@ -9486,10 +9480,12 @@ TEST: 15 {{Septembre}} ->> septembre TEST: 23 {{Messidor}} ->> messidor TEST: ils viendront en {{Mars}}. ->> mars TEST: le comité d’éthique qui statuera dans les meilleurs délais sur la situation de Véronique Avril TEST: VENDREDI 23 NOVEMBRE 2018 À 18:09 +TEST: André Juin était un sculpteur français. +TODO: La bataille de Monte Cassino révèle le génie militaire du général Juin. # Assemblée __maj_Assemblée_nationale__ assemblée nationale @@ -12744,10 +12740,11 @@ >couler à ?grands¿ flots >demander [assistance|audience|conseil|pardon] [>donner|>redonner] [naissance|sens|suite|vie] [>donner|>redonner] quartier libre >élire domicile + >étouffer dans l’ œuf >faire [allusion|assaut|attention|chaud|confiance|connaissance|compliqué|copain-copain|date|débat|défaut|demi-tour|écran|envie|erreur|état|exception|figure|froid|front|grève|halte|honte|illusion|mouche|office|part|peur|polémique|plaisir|preuve|rage|scandale|sens|signe|usage|volte-face] >faire amende honorable >faire bande à part >faire bon accueil >faire bonne figure @@ -22214,12 +22211,10 @@ TODO: La Mustang est une voiture. TODO: Il faut se bien connaître soi-même. TODO: C’est lui ou moi qui a gagné. TODO: Des copains plus vieux que moi qui fumaient. TODO: Des copains plus vieux que toi qui fumaient. -TODO: André Juin était un sculpteur français. -TODO: La bataille de Monte Cassino révèle le génie militaire du général Juin. TODO: Les côtes sont dans leur ensemble extrêmement découpées. !!! Indécidable !! TEST: Du sable fin grippe les rouages (accord avec ce qui précède). TEST: Du monde noir sortent les envahisseurs (accord avec ce qui suit). Index: misc/grammalecte.sublime-color-scheme ================================================================== --- misc/grammalecte.sublime-color-scheme +++ misc/grammalecte.sublime-color-scheme @@ -1,15 +1,15 @@ { "name": "Grammalecte Color Scheme", "globals": { - "background": "hsl(210, 20%, 14%)", + "background": "hsl(210, 20%, 15%)", "foreground": "hsl(210, 20%, 95%)", "caret": "hsl(210, 20%, 80%)", "block_caret": "red", - "line_highlight": "hsl(210, 60%, 30%)", + "line_highlight": "hsl(210, 60%, 25%)", "bracket_options": "underline bold", "selection": "hsl(210, 50%, 20%)", "selection_border": "hsl(210, 80%, 40%)", "selection_border_width": "1", @@ -27,11 +27,12 @@ { "name": "Comment", "scope": "comment", "foreground": "hsl(210, 10%, 50%)" }, { "name": "Bookmark", "scope": "bookmark", "foreground": "#A0F0FF", "background": "#0050A0", }, { "name": "Graphline", "scope": "graphline", "foreground": "hsl(0, 100%, 80%)", "background": "hsl(0, 100%, 20%)", "font_style": "bold", }, { "name": "Error message", "scope": "string.message", "foreground": "hsl(0, 50%, 65%)", }, - { "name": "Error message", "scope": "string.escape", "foreground": "hsl(0, 50%, 85%)", }, + { "name": "Error message esc", "scope": "string.message.esc", "foreground": "hsl(30, 100%, 65%)", "background": "hsl(60, 100%, 12%)", "font_style": "bold" }, + { "name": "Error message URL", "scope": "string.message.url", "foreground": "hsl(180, 100%, 35%)", "background": "hsl(180, 100%, 12%)", }, { "name": "Test header", "scope": "test.header", "foreground": "hsl(150, 100%, 60%)", "font_style": "bold" }, { "name": "Test option", "scope": "test.error", "foreground": "hsl(0, 90%, 67%)", }, { "name": "Todo", "scope": "todo", "foreground": "hsl(20, 90%, 60%)", "font_style": "bold", }, { "name": "Entity brackets", "scope": "entity.brackets", "foreground": "#90A0A0", "background": "#203030", }, @@ -53,27 +54,29 @@ { "name": "Rule action option", "scope": "rule.actionoption", "foreground": "hsl(0, 50%, 50%)", "background": "hsl(330, 50%, 20%)", "font_style": "bold", }, { "name": "Rule option name", "scope": "rule.optionname", "foreground": "hsl(330, 80%, 80%)", "background": "hsl(330, 60%, 20%)", "font_style": "bold", }, { "name": "Rule name (regex)", "scope": "rule.rulename_regex", "foreground": "#A0A0A0", "font_style": "italic", }, { "name": "Rule name (graph)", "scope": "rule.rulename_graph", "foreground": "#F0D080", }, { "name": "Rule priority", "scope": "rule.priority", "foreground": "#F06060", }, + { "name": "Rule antipattern", "scope": "rule.antipattern", "foreground": "hsl(0, 80%, 60%)", "background": "hsl(0, 50%, 20%)" }, + { "name": "Rule antipattern token", "scope": "rule.antipattern.token", "foreground": "hsl(0, 60%, 90%)", }, { "name": "Entity Valid", "scope": "entity.valid", "foreground": "hsl(150, 100%, 80%)", "background": "hsl(150, 100%, 20%)", "font_style": "bold", }, { "name": "Entity Invalid", "scope": "entity.invalid", "foreground": "hsl(0, 100%, 80%)", "background": "hsl(0, 100%, 20%)", "font_style": "bold", }, - { "name": "String meta", "scope": "string.meta", "foreground": "hsl(270, 100%, 90%)", "background": "hsl(270, 100%, 40%)", }, - { "name": "String token", "scope": "string.token", "foreground": "hsl(240, 50%, 90%)", "background": "hsl(240, 50%, 40%)", }, - { "name": "String Jumptoken", "scope": "string.jumptoken", "foreground": "hsl(0, 50%, 90%)", "background": "hsl(10, 50%, 40%)", }, - { "name": "String lemma", "scope": "string.lemma", "foreground": "hsl(210, 100%, 80%)", "background": "hsl(210, 100%, 15%)", }, - { "name": "String tag", "scope": "string.tag", "foreground": "hsl(30, 100%, 90%)", "background": "hsl(30, 100%, 20%)", }, - { "name": "String regex", "scope": "string.regex", "foreground": "hsl(60, 100%, 80%)", "background": "hsl(60, 100%, 10%)", }, - { "name": "String morph regex", "scope": "string.morph.regex", "foreground": "hsl(150, 80%, 90%)", "background": "hsl(150, 80%, 10%)", }, - { "name": "String morph negregex","scope": "string.morph.negregex","foreground": "hsl(0, 80%, 90%)", "background": "hsl(0, 80%, 10%)", }, + { "name": "Token meta", "scope": "string.meta", "foreground": "hsl(270, 100%, 90%)", "background": "hsl(270, 100%, 40%)", }, + { "name": "Token token", "scope": "string.token", "foreground": "hsl(240, 50%, 90%)", "background": "hsl(240, 50%, 40%)", }, + { "name": "Token Jumptoken", "scope": "string.jumptoken", "foreground": "hsl(0, 50%, 90%)", "background": "hsl(10, 50%, 40%)", }, + { "name": "Token lemma", "scope": "string.lemma", "foreground": "hsl(210, 100%, 80%)", "background": "hsl(210, 100%, 15%)", }, + { "name": "Token tag", "scope": "string.tag", "foreground": "hsl(30, 100%, 90%)", "background": "hsl(30, 100%, 20%)", }, + { "name": "Token regex", "scope": "string.regex", "foreground": "hsl(60, 100%, 80%)", "background": "hsl(60, 100%, 10%)", }, + { "name": "Token morph regex", "scope": "string.morph.regex", "foreground": "hsl(150, 80%, 90%)", "background": "hsl(150, 80%, 10%)", }, + { "name": "Token morph negregex", "scope": "string.morph.negregex","foreground": "hsl(0, 80%, 90%)", "background": "hsl(0, 80%, 10%)", }, { "name": "Keyword Python", "scope": "keyword.python", "foreground": "#A0A0A0", }, { "name": "Keyword", "scope": "keyword - (source.c keyword.operator | source.c++ keyword.operator | source.objc keyword.operator | source.objc++ keyword.operator), keyword.operator.word", "foreground": "#F06070", }, - { "name": "String", "scope": "string", "foreground": "hsl(60, 80%, 75%)", }, + { "name": "String", "scope": "string", "foreground": "hsl(40, 100%, 80%)", }, { "name": "Number", "scope": "constant.numeric", "foreground": "hsl(270, 100%, 70%)", "font_style": "bold", }, { "name": "Built-in constant", "scope": "constant.language", "foreground": "#AE81FF", "font_style": "italic", }, { "name": "User-defined constant", "scope": "constant.character, constant.other", "foreground": "#AE81FF", }, Index: misc/grammalecte.sublime-syntax ================================================================== --- misc/grammalecte.sublime-syntax +++ misc/grammalecte.sublime-syntax @@ -16,17 +16,18 @@ # Comments begin with a '#' and finish at the end of the line - match: '^#.*' scope: comment # Error message - - match: '(?<= )#[^|]+' + - match: '(?<= )# ' scope: string.message push: + - meta_scope: string.message - match: '\\-?[0-9]+' - scope: string.message.escape + scope: string.message.esc - match: '\| ?https?://[\w./%?&=#+-]+' - scope: string.other + scope: string.message.url - match: $ pop: true # Numbers - match: '\b(-)?[0-9.]+\b' @@ -87,10 +88,15 @@ - match: '/(\w+)/' scope: rule.actionoption captures: 1: rule.optionname + - match: '!!(.+)¡¡' + scope: rule.antipattern + captures: + 1: rule.antipattern.token + # Definitions and options - match: '^OPT(?:GROUP|LANG|PRIORITY)/|^OPT(?:SOFTWARE|COLORTHEME):|^COLOR/' scope: options.command - match: '^OPT(?:LABEL|COLOR|)/'