Index: compile_rules_graph.py ================================================================== --- compile_rules_graph.py +++ compile_rules_graph.py @@ -81,11 +81,12 @@ iGroup += 1 dPos[iGroup] = i + 1 # we add 1, for we count tokens from 1 to n (not from 0) # Parse actions for nAction, sAction in enumerate(sActions.split(" <<- ")): - if sAction.strip(): + sAction = sAction.strip() + if sAction: sActionId = sRuleName + "_a" + str(nAction) aAction = createAction(sActionId, sAction, nPriority, len(lToken), dPos) if aAction: dACTIONS[sActionId] = aAction lResult = list(lToken) @@ -98,10 +99,17 @@ s = s.replace("\\"+str(i), "\\"+str(dPos[i])) return s def createAction (sIdAction, sAction, nPriority, nToken, dPos): + # Option + sOption = False + m = re.match("/(\\w+)/", sAction) + if m: + sOption = m.group(1) + sAction = sAction[m.end():].strip() + # valid action? m = re.search("(?P[-~=])(?P\\d+|)(?P:\\d+|)>> ", sAction) if not m: print(" # Error. No action found at: ", sIdAction) print(" ==", sAction, "==") return None @@ -183,33 +191,33 @@ sAction = "=g_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.") - return [sCondition, cAction, sAction, iStartAction, iEndAction, nPriority, sMsg, sURL] + return [sOption, sCondition, cAction, sAction, iStartAction, iEndAction, nPriority, sMsg, sURL] elif cAction == "~": ## text processor if not sAction: print("# Error in action at line " + sIdAction + ": This action is empty.") if sAction[0:1] == "=": lFUNCTIONS.append(("g_p_"+sIdAction, sAction[1:])) sAction = "=g_p_"+sIdAction elif sAction.startswith('"') and sAction.endswith('"'): sAction = sAction[1:-1] - return [sCondition, cAction, sAction, iStartAction, iEndAction] + return [sOption, sCondition, cAction, sAction, iStartAction, iEndAction] elif cAction == "=": ## disambiguator if sAction[0:1] == "=": sAction = sAction[1:] if not sAction: print("# Error in action at line " + sIdAction + ": This action is empty.") lFUNCTIONS.append(("g_d_"+sIdAction, sAction)) sAction = "g_d_"+sIdAction - return [sCondition, cAction, sAction] + return [sOption, sCondition, cAction, sAction] elif cAction == ">": ## no action, break loop if condition is False - return [sCondition, cAction, ""] + return [sOption, sCondition, cAction, ""] else: print("# Unknown action at line " + sIdAction) return None Index: gc_core/py/lang_core/gc_engine.py ================================================================== --- gc_core/py/lang_core/gc_engine.py +++ gc_core/py/lang_core/gc_engine.py @@ -656,49 +656,50 @@ "execute actions found in the DARG" dErrs = {} bChange = False for sLineId, nextNodeKey in dNode.items(): for sRuleId in dGraph[nextNodeKey]: - bCondMemo = None - sFuncCond, cActionType, sWhat, *eAct = dRule[sRuleId] - # action in lActions: [ condition, action type, replacement/suggestion/action[, iTokenStart, iTokenEnd[, nPriority, message, URL]] ] - try: - bCondMemo = not sFuncCond or globals()[sFuncCond](self.lToken, nTokenOffset, sCountry, bCondMemo) - if bCondMemo: - if cActionType == "-": - # grammar error - nTokenErrorStart = nTokenOffset + eAct[0] - nTokenErrorEnd = nTokenOffset + eAct[1] - nErrorStart = self.nOffset + self.lToken[nTokenErrorStart]["nStart"] - nErrorEnd = self.nOffset + self.lToken[nTokenErrorEnd]["nEnd"] - if nErrorStart not in dErrs or eAct[2] > dPriority[nErrorStart]: - dErrs[nErrorStart] = self.createError(sWhat, nTokenOffset, nTokenErrorStart, nErrorStart, nErrorEnd, sLineId, sRuleId, True, eAct[3], eAct[4], bShowRuleId, "notype", bContext) - dPriority[nErrorStart] = eAct[2] - if bDebug: - print("-", sRuleId, dErrs[nErrorStart]) - elif cActionType == "~": - # text processor - self._tagAndPrepareTokenForRewriting(sWhat, nTokenOffset + eAct[0], nTokenOffset + eAct[1]) - if bDebug: - print("~", sRuleId) - bChange = True - elif cActionType == "=": - # disambiguation - globals()[sWhat](self.lToken, nTokenOffset) - if bDebug: - print("=", sRuleId) - elif cActionType == ">": - # we do nothing, this test is just a condition to apply all following actions - if bDebug: - print(">", sRuleId) - pass - else: - print("# error: unknown action at " + sLineId) - elif cActionType == ">": - if bDebug: - print(">!", sRuleId) - break + try: + bCondMemo = None + sOption, sFuncCond, cActionType, sWhat, *eAct = dRule[sRuleId] + # action in lActions: [ condition, action type, replacement/suggestion/action[, iTokenStart, iTokenEnd[, nPriority, message, URL]] ] + if not sOption or dOptions.get(sOption, False): + bCondMemo = not sFuncCond or globals()[sFuncCond](self.lToken, nTokenOffset, sCountry, bCondMemo) + if bCondMemo: + if cActionType == "-": + # grammar error + nTokenErrorStart = nTokenOffset + eAct[0] + nTokenErrorEnd = nTokenOffset + eAct[1] + nErrorStart = self.nOffset + self.lToken[nTokenErrorStart]["nStart"] + nErrorEnd = self.nOffset + self.lToken[nTokenErrorEnd]["nEnd"] + if nErrorStart not in dErrs or eAct[2] > dPriority[nErrorStart]: + dErrs[nErrorStart] = self.createError(sWhat, nTokenOffset, nTokenErrorStart, nErrorStart, nErrorEnd, sLineId, sRuleId, True, eAct[3], eAct[4], bShowRuleId, "notype", bContext) + dPriority[nErrorStart] = eAct[2] + if bDebug: + print("-", sRuleId, dErrs[nErrorStart]) + elif cActionType == "~": + # text processor + self._tagAndPrepareTokenForRewriting(sWhat, nTokenOffset + eAct[0], nTokenOffset + eAct[1]) + if bDebug: + print("~", sRuleId) + bChange = True + elif cActionType == "=": + # disambiguation + globals()[sWhat](self.lToken, nTokenOffset) + if bDebug: + print("=", sRuleId) + elif cActionType == ">": + # we do nothing, this test is just a condition to apply all following actions + if bDebug: + print(">", sRuleId) + pass + else: + print("# error: unknown action at " + sLineId) + elif cActionType == ">": + if bDebug: + print(">!", sRuleId) + break except Exception as e: raise Exception(str(e), sLineId) return bChange, dErrs def _createWriterError (self, sSugg, nTokenOffset, iFirstToken, nStart, nEnd, sLineId, sRuleId, bUppercase, sMsg, sURL, bShowRuleId, sOption, bContext):