Index: compile_rules.py ================================================================== --- compile_rules.py +++ compile_rules.py @@ -5,19 +5,19 @@ import copy import json from distutils import file_util -DEF = {} -FUNCTIONS = [] - -RULESET = set() # set of rule-ids to check if there is several rules with the same id - -JSREGEXES = {} - -WORDLIMITLEFT = r"(?.+i?", sRegex) if m: - JSREGEXES[sLineId] = m.group(0) + dJSREGEXES[sLineId] = m.group(0) sRegex = sRegex[:m.start()].strip() if "" in sRegex or "" in sRegex: print("# Error: JavaScript regex not delimited at line " + sLineId) return None @@ -219,11 +219,11 @@ # quotes ? if sRegex.startswith('"') and sRegex.endswith('"'): sRegex = sRegex[1:-1] ## definitions - for sDef, sRepl in DEF.items(): + for sDef, sRepl in dDEF.items(): sRegex = sRegex.replace(sDef, sRepl) ## count number of groups (must be done before modifying the regex) nGroup = countGroupInRegex(sRegex) if nGroup > 0: @@ -233,13 +233,13 @@ if nGroup != len(tGroups): print("# Error: groups positioning code irrelevant at line " + sLineId) ## word limit if cWordLimitLeft == '[' and not sRegex.startswith(("^", '’', "'", ",")): - sRegex = WORDLIMITLEFT + sRegex + sRegex = sWORDLIMITLEFT + sRegex if cWordLimitRight == ']' and not sRegex.endswith(("$", '’', "'", ",")): - sRegex = sRegex + WORDLIMITRIGHT + sRegex = sRegex + sWORDLIMITRIGHT ## casing mode if cCaseMode == "i": bCaseInsensitive = True if not sRegex.startswith("(?i)"): @@ -280,11 +280,11 @@ return [sOption, sRegex, bCaseInsensitive, sLineId, sRuleId, nPriority, lActions, tGroups] def createAction (sIdAction, sAction, nGroup): "returns an action to perform as a tuple (condition, action type, action[, iGroup [, message, URL ]])" - global FUNCTIONS + global lFUNCTIONS m = re.search(r"([-~=>])(\d*|)>>", sAction) if not m: print("# No action at line " + sIdAction) return None @@ -291,11 +291,11 @@ #### CONDITION sCondition = sAction[:m.start()].strip() if sCondition: sCondition = prepareFunction(sCondition) - FUNCTIONS.append(("c_"+sIdAction, sCondition)) + lFUNCTIONS.append(("c_"+sIdAction, sCondition)) for x in re.finditer("[.](?:group|start|end)[(](\d+)[)]", sCondition): if int(x.group(1)) > nGroup: print("# Error in groups in condition at line " + sIdAction + " ("+str(nGroup)+" groups only)") if ".match" in sCondition: print("# Error. JS compatibility. Don't use .match() in condition, use .search()") @@ -321,11 +321,11 @@ if mURL: sURL = mURL.group(1).strip() sMsg = sMsg[:mURL.start(0)].strip() if sMsg[0:1] == "=": sMsg = prepareFunction(sMsg[1:]) - FUNCTIONS.append(("m_"+sIdAction, sMsg)) + lFUNCTIONS.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)") sMsg = "=m_"+sIdAction else: @@ -353,11 +353,11 @@ if cAction == "-": ## error detected --> suggestion if not sAction: print("# Error in action at line " + sIdAction + ": This action is empty.") if sAction[0:1] == "=": - FUNCTIONS.append(("s_"+sIdAction, sAction[1:])) + lFUNCTIONS.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.") @@ -365,11 +365,11 @@ elif cAction == "~": ## text processor if not sAction: print("# Error in action at line " + sIdAction + ": This action is empty.") if sAction[0:1] == "=": - FUNCTIONS.append(("p_"+sIdAction, sAction[1:])) + lFUNCTIONS.append(("p_"+sIdAction, sAction[1:])) sAction = "=p_"+sIdAction elif sAction.startswith('"') and sAction.endswith('"'): sAction = sAction[1:-1] return [sCondition, cAction, sAction, iGroup] elif cAction == "=": @@ -376,11 +376,11 @@ ## disambiguator if sAction[0:1] == "=": sAction = sAction[1:] if not sAction: print("# Error in action at line " + sIdAction + ": This action is empty.") - FUNCTIONS.append(("d_"+sIdAction, sAction)) + lFUNCTIONS.append(("d_"+sIdAction, sAction)) sAction = "d_"+sIdAction return [sCondition, cAction, sAction] elif cAction == ">": ## no action, break loop if condition is False return [sCondition, cAction, ""] @@ -404,12 +404,12 @@ bCaseInsensitive = False if "(?i)" in sRegex: sRegex = sRegex.replace("(?i)", "") bCaseInsensitive = True lNegLookBeforeRegex = [] - if WORDLIMITLEFT in sRegex: - sRegex = sRegex.replace(WORDLIMITLEFT, "") + if sWORDLIMITLEFT in sRegex: + sRegex = sRegex.replace(sWORDLIMITLEFT, "") lNegLookBeforeRegex = ["[a-zA-Zà-öÀ-Ö0-9_ø-ÿØ-ßĀ-ʯ.,–-]$"] sRegex = sRegex.replace("[\\w", "[a-zA-Zà-öÀ-Ö0-9_ø-ÿØ-ßĀ-ʯ") sRegex = sRegex.replace("\\w", "[a-zA-Zà-öÀ-Ö0-9_ø-ÿØ-ßĀ-ʯ]") sRegex = sRegex.replace("[.]", r"\.") if not sRegex.startswith(""): @@ -438,11 +438,11 @@ # error messages for aAction in lRuleJS[6]: if aAction[1] == "-": aAction[4] = aAction[4].replace("« ", "« ").replace(" »", " »") # js regexes - lRuleJS[1], lNegLookBehindRegex = regex2js( JSREGEXES.get(lRuleJS[3], lRuleJS[1]) ) + lRuleJS[1], lNegLookBehindRegex = regex2js( dJSREGEXES.get(lRuleJS[3], lRuleJS[1]) ) lRuleJS.append(lNegLookBehindRegex) return lRuleJS def writeRulesToJSArray (lRules): @@ -544,11 +544,11 @@ "compile rules, returns a dictionary of values" # for clarity purpose, don’t create any file here # removing comments, zeroing empty lines, creating definitions, storing tests, merging rule lines print(" parsing rules...") - global DEF + global dDEF lLine = [] lRuleLine = [] lTest = [] lOpt = [] for i, sLine in enumerate(lRules, 1): @@ -557,11 +557,11 @@ elif sLine.startswith("#"): pass elif sLine.startswith("DEF:"): m = re.match("DEF: +([a-zA-Z_][a-zA-Z_0-9]*) +(.+)$", sLine.strip()) if m: - DEF["{"+m.group(1)+"}"] = m.group(2) + dDEF["{"+m.group(1)+"}"] = m.group(2) else: print("Error in definition: ", end="") print(sLine.strip()) elif sLine.startswith("TEST:"): lTest.append("{:<8}".format(i) + " " + sLine[5:].strip()) @@ -613,11 +613,11 @@ # creating file with all functions callable by rules print(" creating callables...") sPyCallables = "# generated code, do not edit\n" sJSCallables = "// generated code, do not edit\nconst oEvalFunc = {\n" - for sFuncName, sReturn in FUNCTIONS: + for sFuncName, sReturn in lFUNCTIONS: cType = sFuncName[0:1] if cType == "c": # condition sParams = "s, sx, m, dDA, sCountry, bCondMemo" elif cType == "m": # message sParams = "s, m"