@@ -1,6 +1,9 @@ -# Create a Direct Acyclic Rule Graph (DARG) +""" +Grammalecte: compile rules +Create a Direct Acyclic Rule Graphs (DARGs) +""" import re import traceback import json @@ -10,10 +13,11 @@ dACTIONS = {} dFUNCTIONS = {} def prepareFunction (s, bTokenValue=False): + "convert simple rule syntax to a string of Python code" s = s.replace("__also__", "bCondMemo") s = s.replace("__else__", "not bCondMemo") s = re.sub(r"(morph|analyse|displayInfo)[(]\\(\d+)", 'g_\\1(lToken[\\2+nTokenOffset]', s) s = re.sub(r"(select|exclude|define)[(][\\](\d+)", 'g_\\1(lToken[\\2+nTokenOffset], dTags', s) s = re.sub(r"(tag_before|tag_after)[(][\\](\d+)", 'g_\\1(lToken[\\2+nTokenOffset], dTags', s) @@ -37,11 +41,11 @@ def genTokenLines (sTokenLine, dDef): "tokenize a string and return a list of lines of tokens" lToken = sTokenLine.split() lTokenLines = None - for i, sToken in enumerate(lToken): + for sToken in lToken: # optional token? bNullPossible = sToken.startswith("?") and sToken.endswith("¿") if bNullPossible: sToken = sToken[1:-1] # token with definition? @@ -94,10 +98,11 @@ for aRule in lTokenLines: yield aRule def createRule (iLine, sRuleName, sTokenLine, iActionBlock, sActions, nPriority, dDef): + "generator: create rule as list" # print(iLine, "//", sRuleName, "//", sTokenLine, "//", sActions, "//", nPriority) for lToken in genTokenLines(sTokenLine, dDef): # Calculate positions dPos = {} # key: iGroup, value: iToken iGroup = 0 @@ -119,29 +124,33 @@ lResult.extend(["##"+str(iLine), sActionId]) yield lResult def changeReferenceToken (sText, dPos): + "change group reference in with values in " for i in range(len(dPos), 0, -1): sText = sText.replace("\\"+str(i), "\\"+str(dPos[i])) return sText def checkTokenNumbers (sText, sActionId, nToken): + "check if token references in greater than (debugging)" for x in re.finditer(r"\\(\d+)", sText): if int(x.group(1)) > nToken: print("# Error in token index at line " + sActionId + " ("+str(nToken)+" tokens only)") print(sText) def checkIfThereIsCode (sText, sActionId): + "check if there is code in (debugging)" if re.search("[.]\\w+[(]|sugg\\w+[(]|\\([0-9]|\\[[0-9]", sText): print("# Warning at line " + sActionId + ": This message looks like code. Line should probably begin with =") print(sText) def createAction (sActionId, sAction, nPriority, nToken, dPos): + "create action rule as a list" # Option sOption = False m = re.match("/(\\w+)/", sAction) if m: sOption = m.group(1) @@ -367,11 +376,10 @@ print(sActionName, aAction) print("\nFunctions:") print(sPyCallables) # Result - d = { + return { "graph_callables": sPyCallables, "rules_graphs": dAllGraph, "rules_actions": dACTIONS } - return d