Grammalecte  Check-in [5d4721e754]

Overview
Comment:[build] variable renaming and line id instead of rule id to identify rules
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | build
Files: files | file ages | folders
SHA3-256: 5d4721e754a2fa3a73f2198b2b25c67f8ac7eef820872c8e43ea73f6fa4397ab
User & Date: olr on 2020-06-15 07:43:47
Other Links: manifest | tags
Context
2020-06-15
12:49
[fr] ajustements: typographie check-in: fc1bc3e152 user: olr tags: trunk, fr
07:43
[build] variable renaming and line id instead of rule id to identify rules check-in: 5d4721e754 user: olr tags: trunk, build
07:29
[fr] ajustements check-in: efb4fbf4aa user: olr tags: trunk, fr
Changes

Modified compile_rules.py from [5777dcbe33] to [07c9f4297a].

131
132
133
134
135
136
137
138

139
140
141
142

143
144
145
146
147
148
149
131
132
133
134
135
136
137

138
139
140
141

142
143
144
145
146
147
148
149







-
+



-
+







        return re.compile(sRegex).groups
    except re.error:
        traceback.print_exc()
        print(sRegex)
    return 0


def createRule (s, nIdLine, sLang, bParagraph, dOptPriority):
def createRule (s, nLineId, sLang, bParagraph, dOptPriority):
    "returns rule as list [option name, regex, bCaseInsensitive, identifier, list of actions]"
    global dJSREGEXES

    sLineId = f"#{nIdLine}" + ("p" if bParagraph else "s")
    sLineId = f"#{nLineId}" + ("p" if bParagraph else "s")
    sRuleId = sLineId

    #### GRAPH CALL
    if s.startswith("@@@@"):
        if bParagraph:
            print("Error. Graph call can be made only after the first pass (sentence by sentence)")
            exit()
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
267

268
269
270
271

272
273
274

275
276
277
278

279
280
281
282

283
284
285
286
287
288
289
290


291
292
293


294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320

321
322
323
324


325
326

327
328

329
330
331
332
333

334
335
336
337
338
339
340

341
342
343
344
345
346
347


348
349
350
351

352
353
354
355
356
357


358
359
360
361
362
363
364
365
366


367
368

369
370
371
372
373
374
375
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
266

267
268
269
270

271
272
273

274
275
276
277

278
279
280
281

282
283
284
285
286
287
288


289
290
291


292
293
294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319

320
321
322


323
324
325

326
327

328
329
330
331
332

333
334
335
336
337
338
339

340
341
342
343
344
345


346
347
348
349
350

351
352
353
354
355


356
357
358
359
360
361
362
363
364


365
366
367

368
369
370
371
372
373
374
375







-
+













-
+



-
+


-
+



-
+



-
+






-
-
+
+

-
-
+
+






-
+










-
+








-
+


-
-
+
+

-
+

-
+




-
+






-
+





-
-
+
+



-
+




-
-
+
+







-
-
+
+

-
+







    for _ in re.finditer(r"\(\?:[^)]*\([\[\w -]", sRegex):
        print(f"# Warning: groups inside non grouping parenthesis in regex at line {sLineId}")

    #### PARSE ACTIONS
    lActions = []
    nAction = 1
    for sAction in s.split(" <<- "):
        t = createAction(sRuleId + "_" + str(nAction), sAction, nGroup)
        t = createAction(sLineId, sRuleId + "_" + str(nAction), sAction, nGroup)
        nAction += 1
        if t:
            lActions.append(t)
    if not lActions:
        return None

    return [sOption, sRegex, bCaseInsensitive, sLineId, sRuleId, nPriority, lActions, tGroups]


def checkReferenceNumbers (sText, sActionId, nToken):
    "check if token references in <sText> greater than <nToken> (debugging)"
    for x in re.finditer(r"\\(\d+)", sText):
        if int(x.group(1)) > nToken:
            print(f"# Error in token index at line {sActionId} ({nToken} tokens only)")
            print(f"# Error in token index at line {sLineId} / {sActionId} ({nToken} tokens only)")
            print(sText)


def checkIfThereIsCode (sText, sActionId):
def checkIfThereIsCode (sText, sLineId, sActionId):
    "check if there is code in <sText> (debugging)"
    if re.search("[.]\\w+[(]|sugg\\w+[(]|\\([0-9]|\\[[0-9]", sText):
        print(f"# Warning at line {sActionId}:  This message looks like code. Line should probably begin with =")
        print(f"# Warning at line {sLineId} / {sActionId}:  This message looks like code. Line should probably begin with =")
        print(sText)


def createAction (sIdAction, sAction, nGroup):
def createAction (sLineId, sActionId, sAction, nGroup):
    "returns an action to perform as a tuple (condition, action type, action[, iGroup [, message, URL ]])"
    m = re.search(r"([-~=>])(\d*|)>>", sAction)
    if not m:
        print(f"# No action at line {sIdAction}")
        print(f"# No action at line {sLineId} / {sActionId}")
        return None

    #### CONDITION
    sCondition = sAction[:m.start()].strip()
    if sCondition:
        sCondition = prepareFunction(sCondition)
        lFUNCTIONS.append(("_c_"+sIdAction, sCondition))
        checkReferenceNumbers(sCondition, sIdAction, nGroup)
        lFUNCTIONS.append(("_c_"+sActionId, sCondition))
        checkReferenceNumbers(sCondition, sActionId, nGroup)
        if ".match" in sCondition:
            print("# Error. JS compatibility. Don't use .match() in condition, use .search()")
        sCondition = "_c_"+sIdAction
            print(f"# Error at line {sLineId} / {sActionId}. JS compatibility. Don't use .match() in condition, use .search()")
        sCondition = "_c_"+sActionId
    else:
        sCondition = None

    #### iGroup / positioning
    iGroup = int(m.group(2)) if m.group(2) else 0
    if iGroup > nGroup:
        print(f"# Selected group > group number in regex at line {sIdAction}")
        print(f"# Error. Selected group > group number in regex at line {sLineId} / {sActionId}")

    #### ACTION
    sAction = sAction[m.end():].strip()
    cAction = m.group(1)
    if cAction == "-":
        ## error
        iMsg = sAction.find(" && ")
        if iMsg == -1:
            sMsg = "# Error. Error message not found."
            sURL = ""
            print(f"# No message. Action id: {sIdAction}")
            print(f"# No message. Id: {sLineId} / {sActionId}")
        else:
            sMsg = sAction[iMsg+4:].strip()
            sAction = sAction[:iMsg].strip()
            sURL = ""
            mURL = re.search("[|] *(https?://.*)", sMsg)
            if mURL:
                sURL = mURL.group(1).strip()
                sMsg = sMsg[:mURL.start(0)].strip()
            checkReferenceNumbers(sMsg, sIdAction, nGroup)
            checkReferenceNumbers(sMsg, sActionId, nGroup)
            if sMsg[0:1] == "=":
                sMsg = prepareFunction(sMsg[1:])
                lFUNCTIONS.append(("_m_"+sIdAction, sMsg))
                sMsg = "=_m_"+sIdAction
                lFUNCTIONS.append(("_m_"+sActionId, sMsg))
                sMsg = "=_m_"+sActionId
            else:
                checkIfThereIsCode(sMsg, sIdAction)
                checkIfThereIsCode(sMsg, sLineId, sActionId)

    checkReferenceNumbers(sAction, sIdAction, nGroup)
    checkReferenceNumbers(sAction, sActionId, nGroup)
    if sAction[0:1] == "=" or cAction == "=":
        sAction = prepareFunction(sAction)
        sAction = sAction.replace("m.group(i[4])", "m.group("+str(iGroup)+")")
    else:
        checkIfThereIsCode(sAction, sIdAction)
        checkIfThereIsCode(sAction, sLineId, sActionId)

    if cAction == ">":
        ## no action, break loop if condition is False
        return [sCondition, cAction, ""]

    if not sAction:
        print(f"# Error in action at line {sIdAction}:  This action is empty.")
        print(f"# Error in action at line {sLineId} / {sActionId}:  This action is empty.")
        return None

    if cAction == "-":
        ## error detected --> suggestion
        if sAction[0:1] == "=":
            lFUNCTIONS.append(("_s_"+sIdAction, sAction[1:]))
            sAction = "=_s_"+sIdAction
            lFUNCTIONS.append(("_s_"+sActionId, sAction[1:]))
            sAction = "=_s_"+sActionId
        elif sAction.startswith('"') and sAction.endswith('"'):
            sAction = sAction[1:-1]
        if not sMsg:
            print(f"# Error in action at line {sIdAction}:  the message is empty.")
            print(f"# Error in action at line {sLineId} / {sActionId}:  the message is empty.")
        return [sCondition, cAction, sAction, iGroup, sMsg, sURL]
    if cAction == "~":
        ## text processor
        if sAction[0:1] == "=":
            lFUNCTIONS.append(("_p_"+sIdAction, sAction[1:]))
            sAction = "=_p_"+sIdAction
            lFUNCTIONS.append(("_p_"+sActionId, sAction[1:]))
            sAction = "=_p_"+sActionId
        elif sAction.startswith('"') and sAction.endswith('"'):
            sAction = sAction[1:-1]
        return [sCondition, cAction, sAction, iGroup]
    if cAction == "=":
        ## disambiguator
        if sAction[0:1] == "=":
            sAction = sAction[1:]
        lFUNCTIONS.append(("_d_"+sIdAction, sAction))
        sAction = "_d_"+sIdAction
        lFUNCTIONS.append(("_d_"+sActionId, sAction))
        sAction = "_d_"+sActionId
        return [sCondition, cAction, sAction]
    print(f"# Unknown action at line {sIdAction}")
    print(f"# Unknown action at line {sLineId} / {sActionId}")
    return None


def _calcRulesStats (lRules):
    "count rules and actions"
    d = {'=':0, '~': 0, '-': 0, '>': 0}
    for aRule in lRules: