Grammalecte  Hex Artifact Content

Artifact 482c80fae9974055856f55cf66373160e95c37aededae269c94afc8dd9b15e50:


0000: 22 22 22 0a 47 72 61 6d 6d 61 6c 65 63 74 65 3a  """.Grammalecte:
0010: 20 63 6f 6d 70 69 6c 65 20 72 75 6c 65 73 0a 43   compile rules.C
0020: 72 65 61 74 65 20 61 20 44 69 72 65 63 74 20 41  reate a Direct A
0030: 63 79 63 6c 69 63 20 52 75 6c 65 20 47 72 61 70  cyclic Rule Grap
0040: 68 73 20 28 44 41 52 47 73 29 0a 22 22 22 0a 0a  hs (DARGs)."""..
0050: 69 6d 70 6f 72 74 20 72 65 0a 69 6d 70 6f 72 74  import re.import
0060: 20 74 72 61 63 65 62 61 63 6b 0a 69 6d 70 6f 72   traceback.impor
0070: 74 20 6a 73 6f 6e 0a 0a 69 6d 70 6f 72 74 20 64  t json..import d
0080: 61 72 67 0a 0a 0a 64 41 43 54 49 4f 4e 53 20 3d  arg...dACTIONS =
0090: 20 7b 7d 0a 64 46 55 4e 43 54 49 4f 4e 53 20 3d   {}.dFUNCTIONS =
00a0: 20 7b 7d 0a 64 46 55 4e 43 4e 41 4d 45 20 3d 20   {}.dFUNCNAME = 
00b0: 7b 7d 0a 0a 0a 64 65 66 20 63 72 65 61 74 65 46  {}...def createF
00c0: 75 6e 63 74 69 6f 6e 20 28 73 54 79 70 65 2c 20  unction (sType, 
00d0: 73 41 63 74 69 6f 6e 49 64 2c 20 73 43 6f 64 65  sActionId, sCode
00e0: 2c 20 62 53 74 61 72 74 57 69 74 68 45 71 75 61  , bStartWithEqua
00f0: 6c 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 22 63  l=False):.    "c
0100: 72 65 61 74 65 20 61 20 66 75 6e 63 74 69 6f 6e  reate a function
0110: 20 28 73 74 6f 72 65 64 20 69 6e 20 3c 64 46 55   (stored in <dFU
0120: 4e 43 54 49 4f 4e 53 3e 29 20 61 6e 64 20 72 65  NCTIONS>) and re
0130: 74 75 72 6e 20 66 75 6e 63 74 69 6f 6e 20 6e 61  turn function na
0140: 6d 65 22 0a 20 20 20 20 73 43 6f 64 65 20 3d 20  me".    sCode = 
0150: 70 72 65 70 61 72 65 46 75 6e 63 74 69 6f 6e 28  prepareFunction(
0160: 73 43 6f 64 65 29 0a 20 20 20 20 69 66 20 73 54  sCode).    if sT
0170: 79 70 65 20 6e 6f 74 20 69 6e 20 64 46 55 4e 43  ype not in dFUNC
0180: 4e 41 4d 45 3a 0a 20 20 20 20 20 20 20 20 64 46  NAME:.        dF
0190: 55 4e 43 4e 41 4d 45 5b 73 54 79 70 65 5d 20 3d  UNCNAME[sType] =
01a0: 20 7b 7d 0a 20 20 20 20 69 66 20 73 43 6f 64 65   {}.    if sCode
01b0: 20 6e 6f 74 20 69 6e 20 64 46 55 4e 43 4e 41 4d   not in dFUNCNAM
01c0: 45 5b 73 54 79 70 65 5d 3a 0a 20 20 20 20 20 20  E[sType]:.      
01d0: 20 20 64 46 55 4e 43 4e 41 4d 45 5b 73 54 79 70    dFUNCNAME[sTyp
01e0: 65 5d 5b 73 43 6f 64 65 5d 20 3d 20 6c 65 6e 28  e][sCode] = len(
01f0: 64 46 55 4e 43 4e 41 4d 45 5b 73 54 79 70 65 5d  dFUNCNAME[sType]
0200: 29 2b 31 0a 20 20 20 20 73 46 75 6e 63 4e 61 6d  )+1.    sFuncNam
0210: 65 20 3d 20 22 5f 67 5f 22 20 2b 20 73 54 79 70  e = "_g_" + sTyp
0220: 65 20 2b 20 22 5f 22 20 2b 20 73 74 72 28 64 46  e + "_" + str(dF
0230: 55 4e 43 4e 41 4d 45 5b 73 54 79 70 65 5d 5b 73  UNCNAME[sType][s
0240: 43 6f 64 65 5d 29 0a 20 20 20 20 64 46 55 4e 43  Code]).    dFUNC
0250: 54 49 4f 4e 53 5b 73 46 75 6e 63 4e 61 6d 65 5d  TIONS[sFuncName]
0260: 20 3d 20 73 43 6f 64 65 0a 20 20 20 20 72 65 74   = sCode.    ret
0270: 75 72 6e 20 73 46 75 6e 63 4e 61 6d 65 20 20 69  urn sFuncName  i
0280: 66 20 6e 6f 74 20 62 53 74 61 72 74 57 69 74 68  f not bStartWith
0290: 45 71 75 61 6c 20 20 65 6c 73 65 20 22 3d 22 2b  Equal  else "="+
02a0: 73 46 75 6e 63 4e 61 6d 65 0a 0a 0a 64 65 66 20  sFuncName...def 
02b0: 73 74 6f 72 65 41 63 74 69 6f 6e 20 28 73 41 63  storeAction (sAc
02c0: 74 69 6f 6e 49 64 2c 20 61 41 63 74 69 6f 6e 29  tionId, aAction)
02d0: 3a 0a 20 20 20 20 22 73 74 6f 72 65 20 3c 61 41  :.    "store <aA
02e0: 63 74 69 6f 6e 3e 20 69 6e 20 3c 64 41 43 54 49  ction> in <dACTI
02f0: 4f 4e 53 3e 20 61 76 6f 69 64 69 6e 67 20 64 75  ONS> avoiding du
0300: 70 6c 69 63 61 74 65 73 22 0a 20 20 20 20 6e 56  plicates".    nV
0310: 61 72 20 3d 20 30 0a 20 20 20 20 77 68 69 6c 65  ar = 0.    while
0320: 20 54 72 75 65 3a 0a 20 20 20 20 20 20 20 20 73   True:.        s
0330: 41 63 74 69 6f 6e 4e 61 6d 65 20 3d 20 73 41 63  ActionName = sAc
0340: 74 69 6f 6e 49 64 20 2b 20 73 74 72 28 6e 56 61  tionId + str(nVa
0350: 72 29 0a 20 20 20 20 20 20 20 20 69 66 20 73 41  r).        if sA
0360: 63 74 69 6f 6e 4e 61 6d 65 20 6e 6f 74 20 69 6e  ctionName not in
0370: 20 64 41 43 54 49 4f 4e 53 3a 0a 20 20 20 20 20   dACTIONS:.     
0380: 20 20 20 20 20 20 20 64 41 43 54 49 4f 4e 53 5b         dACTIONS[
0390: 73 41 63 74 69 6f 6e 4e 61 6d 65 5d 20 3d 20 61  sActionName] = a
03a0: 41 63 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20  Action.         
03b0: 20 20 20 72 65 74 75 72 6e 20 73 41 63 74 69 6f     return sActio
03c0: 6e 4e 61 6d 65 0a 20 20 20 20 20 20 20 20 65 6c  nName.        el
03d0: 69 66 20 61 41 63 74 69 6f 6e 20 3d 3d 20 64 41  if aAction == dA
03e0: 43 54 49 4f 4e 53 5b 73 41 63 74 69 6f 6e 4e 61  CTIONS[sActionNa
03f0: 6d 65 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20  me]:.           
0400: 20 72 65 74 75 72 6e 20 73 41 63 74 69 6f 6e 4e   return sActionN
0410: 61 6d 65 0a 20 20 20 20 20 20 20 20 6e 56 61 72  ame.        nVar
0420: 20 2b 3d 20 31 0a 0a 0a 64 65 66 20 70 72 65 70   += 1...def prep
0430: 61 72 65 46 75 6e 63 74 69 6f 6e 20 28 73 43 6f  areFunction (sCo
0440: 64 65 29 3a 0a 20 20 20 20 22 63 6f 6e 76 65 72  de):.    "conver
0450: 74 20 73 69 6d 70 6c 65 20 72 75 6c 65 20 73 79  t simple rule sy
0460: 6e 74 61 78 20 74 6f 20 61 20 73 74 72 69 6e 67  ntax to a string
0470: 20 6f 66 20 50 79 74 68 6f 6e 20 63 6f 64 65 22   of Python code"
0480: 0a 20 20 20 20 69 66 20 73 43 6f 64 65 5b 30 3a  .    if sCode[0:
0490: 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20  1] == "=":.     
04a0: 20 20 20 73 43 6f 64 65 20 3d 20 73 43 6f 64 65     sCode = sCode
04b0: 5b 31 3a 5d 0a 20 20 20 20 73 43 6f 64 65 20 3d  [1:].    sCode =
04c0: 20 73 43 6f 64 65 2e 72 65 70 6c 61 63 65 28 22   sCode.replace("
04d0: 5f 5f 61 6c 73 6f 5f 5f 22 2c 20 22 62 43 6f 6e  __also__", "bCon
04e0: 64 4d 65 6d 6f 22 29 0a 20 20 20 20 73 43 6f 64  dMemo").    sCod
04f0: 65 20 3d 20 73 43 6f 64 65 2e 72 65 70 6c 61 63  e = sCode.replac
0500: 65 28 22 5f 5f 65 6c 73 65 5f 5f 22 2c 20 22 6e  e("__else__", "n
0510: 6f 74 20 62 43 6f 6e 64 4d 65 6d 6f 22 29 0a 20  ot bCondMemo"). 
0520: 20 20 20 73 43 6f 64 65 20 3d 20 73 43 6f 64 65     sCode = sCode
0530: 2e 72 65 70 6c 61 63 65 28 22 73 43 6f 6e 74 65  .replace("sConte
0540: 78 74 22 2c 20 22 5f 73 41 70 70 43 6f 6e 74 65  xt", "_sAppConte
0550: 78 74 22 29 0a 20 20 20 20 73 43 6f 64 65 20 3d  xt").    sCode =
0560: 20 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70 68   re.sub(r"(morph
0570: 7c 6d 6f 72 70 68 56 43 7c 61 6e 61 6c 79 73 65  |morphVC|analyse
0580: 7c 76 61 6c 75 65 7c 64 69 73 70 6c 61 79 49 6e  |value|displayIn
0590: 66 6f 29 5b 28 5d 5c 5c 28 5c 64 2b 29 22 2c 20  fo)[(]\\(\d+)", 
05a0: 27 67 5f 5c 5c 31 28 6c 54 6f 6b 65 6e 5b 6e 54  'g_\\1(lToken[nT
05b0: 6f 6b 65 6e 4f 66 66 73 65 74 2b 5c 5c 32 5d 27  okenOffset+\\2]'
05c0: 2c 20 73 43 6f 64 65 29 0a 20 20 20 20 73 43 6f  , sCode).    sCo
05d0: 64 65 20 3d 20 72 65 2e 73 75 62 28 72 22 28 6d  de = re.sub(r"(m
05e0: 6f 72 70 68 7c 6d 6f 72 70 68 56 43 7c 61 6e 61  orph|morphVC|ana
05f0: 6c 79 73 65 7c 76 61 6c 75 65 7c 64 69 73 70 6c  lyse|value|displ
0600: 61 79 49 6e 66 6f 29 5b 28 5d 5c 5c 2d 28 5c 64  ayInfo)[(]\\-(\d
0610: 2b 29 22 2c 20 27 67 5f 5c 5c 31 28 6c 54 6f 6b  +)", 'g_\\1(lTok
0620: 65 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 2d 5c 5c  en[nLastToken-\\
0630: 32 2b 31 5d 27 2c 20 73 43 6f 64 65 29 0a 20 20  2+1]', sCode).  
0640: 20 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62    sCode = re.sub
0650: 28 72 22 28 73 65 6c 65 63 74 7c 65 78 63 6c 75  (r"(select|exclu
0660: 64 65 7c 64 65 66 69 6e 65 7c 64 65 66 69 6e 65  de|define|define
0670: 5f 66 72 6f 6d 29 5b 28 5d 5b 5c 5c 5d 28 5c 64  _from)[(][\\](\d
0680: 2b 29 22 2c 20 27 67 5f 5c 5c 31 28 6c 54 6f 6b  +)", 'g_\\1(lTok
0690: 65 6e 5b 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2b  en[nTokenOffset+
06a0: 5c 5c 32 5d 27 2c 20 73 43 6f 64 65 29 0a 20 20  \\2]', sCode).  
06b0: 20 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62    sCode = re.sub
06c0: 28 72 22 28 73 65 6c 65 63 74 7c 65 78 63 6c 75  (r"(select|exclu
06d0: 64 65 7c 64 65 66 69 6e 65 7c 64 65 66 69 6e 65  de|define|define
06e0: 5f 66 72 6f 6d 29 5b 28 5d 5b 5c 5c 5d 2d 28 5c  _from)[(][\\]-(\
06f0: 64 2b 29 22 2c 20 27 67 5f 5c 5c 31 28 6c 54 6f  d+)", 'g_\\1(lTo
0700: 6b 65 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 2d 5c  ken[nLastToken-\
0710: 5c 32 2b 31 5d 27 2c 20 73 43 6f 64 65 29 0a 20  \2+1]', sCode). 
0720: 20 20 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75     sCode = re.su
0730: 62 28 72 22 28 74 61 67 5f 62 65 66 6f 72 65 7c  b(r"(tag_before|
0740: 74 61 67 5f 61 66 74 65 72 29 5b 28 5d 5b 5c 5c  tag_after)[(][\\
0750: 5d 28 5c 64 2b 29 22 2c 20 27 67 5f 5c 5c 31 28  ](\d+)", 'g_\\1(
0760: 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 4f 66 66  lToken[nTokenOff
0770: 73 65 74 2b 5c 5c 32 5d 2c 20 64 54 61 67 73 27  set+\\2], dTags'
0780: 2c 20 73 43 6f 64 65 29 0a 20 20 20 20 73 43 6f  , sCode).    sCo
0790: 64 65 20 3d 20 72 65 2e 73 75 62 28 72 22 28 74  de = re.sub(r"(t
07a0: 61 67 5f 62 65 66 6f 72 65 7c 74 61 67 5f 61 66  ag_before|tag_af
07b0: 74 65 72 29 5b 28 5d 5b 5c 5c 5d 2d 28 5c 64 2b  ter)[(][\\]-(\d+
07c0: 29 22 2c 20 27 67 5f 5c 5c 31 28 6c 54 6f 6b 65  )", 'g_\\1(lToke
07d0: 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 2d 5c 5c 32  n[nLastToken-\\2
07e0: 2b 31 5d 2c 20 64 54 61 67 73 27 2c 20 73 43 6f  +1], dTags', sCo
07f0: 64 65 29 0a 20 20 20 20 73 43 6f 64 65 20 3d 20  de).    sCode = 
0800: 72 65 2e 73 75 62 28 72 22 73 70 61 63 65 5f 61  re.sub(r"space_a
0810: 66 74 65 72 5b 28 5d 5b 5c 5c 5d 28 5c 64 2b 29  fter[(][\\](\d+)
0820: 22 2c 20 27 67 5f 73 70 61 63 65 5f 62 65 74 77  ", 'g_space_betw
0830: 65 65 6e 5f 74 6f 6b 65 6e 73 28 6c 54 6f 6b 65  een_tokens(lToke
0840: 6e 5b 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2b 5c  n[nTokenOffset+\
0850: 5c 31 5d 2c 20 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b  \1], lToken[nTok
0860: 65 6e 4f 66 66 73 65 74 2b 5c 5c 31 2b 31 5d 27  enOffset+\\1+1]'
0870: 2c 20 73 43 6f 64 65 29 0a 20 20 20 20 73 43 6f  , sCode).    sCo
0880: 64 65 20 3d 20 72 65 2e 73 75 62 28 72 22 73 70  de = re.sub(r"sp
0890: 61 63 65 5f 61 66 74 65 72 5b 28 5d 5b 5c 5c 5d  ace_after[(][\\]
08a0: 2d 28 5c 64 2b 29 22 2c 20 27 67 5f 73 70 61 63  -(\d+)", 'g_spac
08b0: 65 5f 62 65 74 77 65 65 6e 5f 74 6f 6b 65 6e 73  e_between_tokens
08c0: 28 6c 54 6f 6b 65 6e 5b 6e 4c 61 73 74 54 6f 6b  (lToken[nLastTok
08d0: 65 6e 2d 5c 5c 31 2b 31 5d 2c 20 6c 54 6f 6b 65  en-\\1+1], lToke
08e0: 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 2d 5c 5c 31  n[nLastToken-\\1
08f0: 2b 32 5d 27 2c 20 73 43 6f 64 65 29 0a 20 20 20  +2]', sCode).   
0900: 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62 28   sCode = re.sub(
0910: 72 22 61 6e 61 6c 79 73 65 5f 77 69 74 68 5f 6e  r"analyse_with_n
0920: 65 78 74 5b 28 5d 5b 5c 5c 5d 28 5c 64 2b 29 22  ext[(][\\](\d+)"
0930: 2c 20 27 67 5f 6d 65 72 67 65 64 5f 61 6e 61 6c  , 'g_merged_anal
0940: 79 73 65 28 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65  yse(lToken[nToke
0950: 6e 4f 66 66 73 65 74 2b 5c 5c 31 5d 2c 20 6c 54  nOffset+\\1], lT
0960: 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 4f 66 66 73 65  oken[nTokenOffse
0970: 74 2b 5c 5c 31 2b 31 5d 27 2c 20 73 43 6f 64 65  t+\\1+1]', sCode
0980: 29 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 72 65  ).    sCode = re
0990: 2e 73 75 62 28 72 22 61 6e 61 6c 79 73 65 5f 77  .sub(r"analyse_w
09a0: 69 74 68 5f 6e 65 78 74 5b 28 5d 5b 5c 5c 5d 2d  ith_next[(][\\]-
09b0: 28 5c 64 2b 29 22 2c 20 27 67 5f 6d 65 72 67 65  (\d+)", 'g_merge
09c0: 64 5f 61 6e 61 6c 79 73 65 28 6c 54 6f 6b 65 6e  d_analyse(lToken
09d0: 5b 6e 4c 61 73 74 54 6f 6b 65 6e 2d 5c 5c 31 2b  [nLastToken-\\1+
09e0: 31 5d 2c 20 6c 54 6f 6b 65 6e 5b 6e 4c 61 73 74  1], lToken[nLast
09f0: 54 6f 6b 65 6e 2d 5c 5c 31 2b 32 5d 27 2c 20 73  Token-\\1+2]', s
0a00: 43 6f 64 65 29 0a 20 20 20 20 73 43 6f 64 65 20  Code).    sCode 
0a10: 3d 20 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70  = re.sub(r"(morp
0a20: 68 7c 61 6e 61 6c 79 73 65 7c 76 61 6c 75 65 29  h|analyse|value)
0a30: 5c 28 3e 31 22 2c 20 27 67 5f 5c 5c 31 28 6c 54  \(>1", 'g_\\1(lT
0a40: 6f 6b 65 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 2b  oken[nLastToken+
0a50: 31 5d 27 2c 20 73 43 6f 64 65 29 20 20 20 20 20  1]', sCode)     
0a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a70: 20 20 23 20 6e 65 78 74 20 74 6f 6b 65 6e 0a 20    # next token. 
0a80: 20 20 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75     sCode = re.su
0a90: 62 28 72 22 28 6d 6f 72 70 68 7c 61 6e 61 6c 79  b(r"(morph|analy
0aa0: 73 65 7c 76 61 6c 75 65 29 5c 28 3c 31 22 2c 20  se|value)\(<1", 
0ab0: 27 67 5f 5c 5c 31 28 6c 54 6f 6b 65 6e 5b 6e 54  'g_\\1(lToken[nT
0ac0: 6f 6b 65 6e 4f 66 66 73 65 74 5d 27 2c 20 73 43  okenOffset]', sC
0ad0: 6f 64 65 29 20 20 20 20 20 20 20 20 20 20 20 20  ode)            
0ae0: 20 20 20 20 20 20 20 20 20 20 20 23 20 70 72 65             # pre
0af0: 76 69 6f 75 73 20 74 6f 6b 65 6e 0a 20 20 20 20  vious token.    
0b00: 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62 28 72  sCode = re.sub(r
0b10: 22 28 6d 6f 72 70 68 7c 61 6e 61 6c 79 73 65 7c  "(morph|analyse|
0b20: 76 61 6c 75 65 29 5c 28 3e 28 5c 64 2b 29 22 2c  value)\(>(\d+)",
0b30: 20 27 67 5f 5c 5c 31 28 67 5f 74 6f 6b 65 6e 28   'g_\\1(g_token(
0b40: 6c 54 6f 6b 65 6e 2c 20 6e 4c 61 73 74 54 6f 6b  lToken, nLastTok
0b50: 65 6e 2b 5c 5c 32 29 27 2c 20 73 43 6f 64 65 29  en+\\2)', sCode)
0b60: 20 20 20 20 20 20 20 20 23 20 6e 65 78 74 20 74          # next t
0b70: 6f 6b 65 6e 0a 20 20 20 20 73 43 6f 64 65 20 3d  oken.    sCode =
0b80: 20 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70 68   re.sub(r"(morph
0b90: 7c 61 6e 61 6c 79 73 65 7c 76 61 6c 75 65 29 5c  |analyse|value)\
0ba0: 28 3c 28 5c 64 2b 29 22 2c 20 27 67 5f 5c 5c 31  (<(\d+)", 'g_\\1
0bb0: 28 67 5f 74 6f 6b 65 6e 28 6c 54 6f 6b 65 6e 2c  (g_token(lToken,
0bc0: 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2b 31 2d   nTokenOffset+1-
0bd0: 5c 5c 32 29 27 2c 20 73 43 6f 64 65 29 20 20 20  \\2)', sCode)   
0be0: 20 23 20 70 72 65 76 69 6f 75 73 20 74 6f 6b 65   # previous toke
0bf0: 6e 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 72 65  n.    sCode = re
0c00: 2e 73 75 62 28 72 22 5c 62 73 70 65 6c 6c 20 2a  .sub(r"\bspell *
0c10: 5b 28 5d 22 2c 20 27 5f 6f 53 70 65 6c 6c 43 68  [(]", '_oSpellCh
0c20: 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 27 2c  ecker.isValid(',
0c30: 20 73 43 6f 64 65 29 0a 20 20 20 20 73 43 6f 64   sCode).    sCod
0c40: 65 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62 62  e = re.sub(r"\bb
0c50: 65 66 6f 72 65 5c 28 5c 73 2a 22 2c 20 27 6c 6f  efore\(\s*", 'lo
0c60: 6f 6b 28 73 53 65 6e 74 65 6e 63 65 5b 3a 6c 54  ok(sSentence[:lT
0c70: 6f 6b 65 6e 5b 31 2b 6e 54 6f 6b 65 6e 4f 66 66  oken[1+nTokenOff
0c80: 73 65 74 5d 5b 22 6e 53 74 61 72 74 22 5d 5d 2c  set]["nStart"]],
0c90: 20 27 2c 20 73 43 6f 64 65 29 20 20 20 20 20 20   ', sCode)      
0ca0: 20 20 20 20 23 20 62 65 66 6f 72 65 28 73 43 6f      # before(sCo
0cb0: 64 65 29 0a 20 20 20 20 73 43 6f 64 65 20 3d 20  de).    sCode = 
0cc0: 72 65 2e 73 75 62 28 72 22 5c 62 61 66 74 65 72  re.sub(r"\bafter
0cd0: 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 53  \(\s*", 'look(sS
0ce0: 65 6e 74 65 6e 63 65 5b 6c 54 6f 6b 65 6e 5b 6e  entence[lToken[n
0cf0: 4c 61 73 74 54 6f 6b 65 6e 5d 5b 22 6e 45 6e 64  LastToken]["nEnd
0d00: 22 5d 3a 5d 2c 20 27 2c 20 73 43 6f 64 65 29 20  "]:], ', sCode) 
0d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d20: 23 20 61 66 74 65 72 28 73 43 6f 64 65 29 0a 20  # after(sCode). 
0d30: 20 20 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75     sCode = re.su
0d40: 62 28 72 22 5c 62 62 65 66 6f 72 65 30 5c 28 5c  b(r"\bbefore0\(\
0d50: 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 53 65 6e 74  s*", 'look(sSent
0d60: 65 6e 63 65 30 5b 3a 6c 54 6f 6b 65 6e 5b 31 2b  ence0[:lToken[1+
0d70: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 5d 5b 22 6e  nTokenOffset]["n
0d80: 53 74 61 72 74 22 5d 5d 2c 20 27 2c 20 73 43 6f  Start"]], ', sCo
0d90: 64 65 29 20 20 20 20 20 20 20 20 23 20 62 65 66  de)        # bef
0da0: 6f 72 65 30 28 73 43 6f 64 65 29 0a 20 20 20 20  ore0(sCode).    
0db0: 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62 28 72  sCode = re.sub(r
0dc0: 22 5c 62 61 66 74 65 72 30 5c 28 5c 73 2a 22 2c  "\bafter0\(\s*",
0dd0: 20 27 6c 6f 6f 6b 28 73 53 65 6e 74 65 6e 63 65   'look(sSentence
0de0: 5b 6c 54 6f 6b 65 6e 5b 6e 4c 61 73 74 54 6f 6b  [lToken[nLastTok
0df0: 65 6e 5d 5b 22 6e 45 6e 64 22 5d 3a 5d 2c 20 27  en]["nEnd"]:], '
0e00: 2c 20 73 43 6f 64 65 29 20 20 20 20 20 20 20 20  , sCode)        
0e10: 20 20 20 20 20 20 20 20 23 20 61 66 74 65 72 30          # after0
0e20: 28 73 43 6f 64 65 29 0a 20 20 20 20 73 43 6f 64  (sCode).    sCod
0e30: 65 20 3d 20 72 65 2e 73 75 62 28 72 22 5b 5c 5c  e = re.sub(r"[\\
0e40: 5d 28 5c 64 2b 29 22 2c 20 27 6c 54 6f 6b 65 6e  ](\d+)", 'lToken
0e50: 5b 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2b 5c 5c  [nTokenOffset+\\
0e60: 31 5d 5b 22 73 56 61 6c 75 65 22 5d 27 2c 20 73  1]["sValue"]', s
0e70: 43 6f 64 65 29 0a 20 20 20 20 73 43 6f 64 65 20  Code).    sCode 
0e80: 3d 20 72 65 2e 73 75 62 28 72 22 5b 5c 5c 5d 2d  = re.sub(r"[\\]-
0e90: 28 5c 64 2b 29 22 2c 20 27 6c 54 6f 6b 65 6e 5b  (\d+)", 'lToken[
0ea0: 6e 4c 61 73 74 54 6f 6b 65 6e 2d 5c 5c 31 2b 31  nLastToken-\\1+1
0eb0: 5d 5b 22 73 56 61 6c 75 65 22 5d 27 2c 20 73 43  ]["sValue"]', sC
0ec0: 6f 64 65 29 0a 20 20 20 20 72 65 74 75 72 6e 20  ode).    return 
0ed0: 73 43 6f 64 65 0a 0a 0a 64 65 66 20 67 65 6e 54  sCode...def genT
0ee0: 6f 6b 65 6e 4c 69 6e 65 73 20 28 73 54 6f 6b 65  okenLines (sToke
0ef0: 6e 4c 69 6e 65 2c 20 64 44 65 66 29 3a 0a 20 20  nLine, dDef):.  
0f00: 20 20 22 74 6f 6b 65 6e 69 7a 65 20 61 20 73 74    "tokenize a st
0f10: 72 69 6e 67 20 61 6e 64 20 72 65 74 75 72 6e 20  ring and return 
0f20: 61 20 6c 69 73 74 20 6f 66 20 6c 69 6e 65 73 20  a list of lines 
0f30: 6f 66 20 74 6f 6b 65 6e 73 22 0a 20 20 20 20 6c  of tokens".    l
0f40: 54 6f 6b 65 6e 20 3d 20 73 54 6f 6b 65 6e 4c 69  Token = sTokenLi
0f50: 6e 65 2e 73 70 6c 69 74 28 29 0a 20 20 20 20 6c  ne.split().    l
0f60: 54 6f 6b 65 6e 4c 69 6e 65 73 20 3d 20 4e 6f 6e  TokenLines = Non
0f70: 65 0a 20 20 20 20 66 6f 72 20 73 54 6f 6b 65 6e  e.    for sToken
0f80: 20 69 6e 20 6c 54 6f 6b 65 6e 3a 0a 20 20 20 20   in lToken:.    
0f90: 20 20 20 20 23 20 6f 70 74 69 6f 6e 61 6c 20 74      # optional t
0fa0: 6f 6b 65 6e 3f 0a 20 20 20 20 20 20 20 20 62 4e  oken?.        bN
0fb0: 75 6c 6c 50 6f 73 73 69 62 6c 65 20 3d 20 73 54  ullPossible = sT
0fc0: 6f 6b 65 6e 2e 73 74 61 72 74 73 77 69 74 68 28  oken.startswith(
0fd0: 22 3f 22 29 20 61 6e 64 20 73 54 6f 6b 65 6e 2e  "?") and sToken.
0fe0: 65 6e 64 73 77 69 74 68 28 22 c2 bf 22 29 0a 20  endswith(".."). 
0ff0: 20 20 20 20 20 20 20 69 66 20 62 4e 75 6c 6c 50         if bNullP
1000: 6f 73 73 69 62 6c 65 3a 0a 20 20 20 20 20 20 20  ossible:.       
1010: 20 20 20 20 20 73 54 6f 6b 65 6e 20 3d 20 73 54       sToken = sT
1020: 6f 6b 65 6e 5b 31 3a 2d 31 5d 0a 20 20 20 20 20  oken[1:-1].     
1030: 20 20 20 23 20 74 6f 6b 65 6e 20 77 69 74 68 20     # token with 
1040: 64 65 66 69 6e 69 74 69 6f 6e 3f 0a 20 20 20 20  definition?.    
1050: 20 20 20 20 69 66 20 73 54 6f 6b 65 6e 2e 73 74      if sToken.st
1060: 61 72 74 73 77 69 74 68 28 22 28 7b 22 29 20 61  artswith("({") a
1070: 6e 64 20 73 54 6f 6b 65 6e 2e 65 6e 64 73 77 69  nd sToken.endswi
1080: 74 68 28 22 7d 29 22 29 20 61 6e 64 20 73 54 6f  th("})") and sTo
1090: 6b 65 6e 5b 31 3a 2d 31 5d 20 69 6e 20 64 44 65  ken[1:-1] in dDe
10a0: 66 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  f:.            s
10b0: 54 6f 6b 65 6e 20 3d 20 22 28 22 20 2b 20 64 44  Token = "(" + dD
10c0: 65 66 5b 73 54 6f 6b 65 6e 5b 31 3a 2d 31 5d 5d  ef[sToken[1:-1]]
10d0: 20 2b 20 22 29 22 0a 20 20 20 20 20 20 20 20 65   + ")".        e
10e0: 6c 69 66 20 73 54 6f 6b 65 6e 2e 73 74 61 72 74  lif sToken.start
10f0: 73 77 69 74 68 28 22 7b 22 29 20 61 6e 64 20 73  swith("{") and s
1100: 54 6f 6b 65 6e 2e 65 6e 64 73 77 69 74 68 28 22  Token.endswith("
1110: 7d 22 29 20 61 6e 64 20 73 54 6f 6b 65 6e 20 69  }") and sToken i
1120: 6e 20 64 44 65 66 3a 0a 20 20 20 20 20 20 20 20  n dDef:.        
1130: 20 20 20 20 73 54 6f 6b 65 6e 20 3d 20 64 44 65      sToken = dDe
1140: 66 5b 73 54 6f 6b 65 6e 5d 0a 20 20 20 20 20 20  f[sToken].      
1150: 20 20 69 66 20 28 20 28 73 54 6f 6b 65 6e 2e 73    if ( (sToken.s
1160: 74 61 72 74 73 77 69 74 68 28 22 5b 22 29 20 61  tartswith("[") a
1170: 6e 64 20 73 54 6f 6b 65 6e 2e 65 6e 64 73 77 69  nd sToken.endswi
1180: 74 68 28 22 5d 22 29 29 20 6f 72 20 28 73 54 6f  th("]")) or (sTo
1190: 6b 65 6e 2e 73 74 61 72 74 73 77 69 74 68 28 22  ken.startswith("
11a0: 28 5b 22 29 20 61 6e 64 20 73 54 6f 6b 65 6e 2e  ([") and sToken.
11b0: 65 6e 64 73 77 69 74 68 28 22 5d 29 22 29 29 20  endswith("])")) 
11c0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  ):.            #
11d0: 20 6d 75 6c 74 69 70 6c 65 20 74 6f 6b 65 6e 0a   multiple token.
11e0: 20 20 20 20 20 20 20 20 20 20 20 20 62 53 65 6c              bSel
11f0: 65 63 74 65 64 47 72 6f 75 70 20 3d 20 73 54 6f  ectedGroup = sTo
1200: 6b 65 6e 2e 73 74 61 72 74 73 77 69 74 68 28 22  ken.startswith("
1210: 28 22 29 20 61 6e 64 20 73 54 6f 6b 65 6e 2e 65  (") and sToken.e
1220: 6e 64 73 77 69 74 68 28 22 29 22 29 0a 20 20 20  ndswith(")").   
1230: 20 20 20 20 20 20 20 20 20 69 66 20 62 53 65 6c           if bSel
1240: 65 63 74 65 64 47 72 6f 75 70 3a 0a 20 20 20 20  ectedGroup:.    
1250: 20 20 20 20 20 20 20 20 20 20 20 20 73 54 6f 6b              sTok
1260: 65 6e 20 3d 20 73 54 6f 6b 65 6e 5b 31 3a 2d 31  en = sToken[1:-1
1270: 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 4e  ].            lN
1280: 65 77 54 6f 6b 65 6e 20 3d 20 73 54 6f 6b 65 6e  ewToken = sToken
1290: 5b 31 3a 2d 31 5d 2e 73 70 6c 69 74 28 22 7c 22  [1:-1].split("|"
12a0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  ).            if
12b0: 20 6e 6f 74 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73   not lTokenLines
12c0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
12d0: 20 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 20 3d 20    lTokenLines = 
12e0: 5b 20 5b 22 28 22 2b 73 2b 22 29 22 5d 20 20 66  [ ["("+s+")"]  f
12f0: 6f 72 20 73 20 20 69 6e 20 6c 4e 65 77 54 6f 6b  or s  in lNewTok
1300: 65 6e 20 5d 20 20 69 66 20 62 53 65 6c 65 63 74  en ]  if bSelect
1310: 65 64 47 72 6f 75 70 20 20 65 6c 73 65 20 5b 20  edGroup  else [ 
1320: 5b 73 5d 20 20 66 6f 72 20 73 20 20 69 6e 20 6c  [s]  for s  in l
1330: 4e 65 77 54 6f 6b 65 6e 20 5d 0a 20 20 20 20 20  NewToken ].     
1340: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62 4e             if bN
1350: 75 6c 6c 50 6f 73 73 69 62 6c 65 3a 0a 20 20 20  ullPossible:.   
1360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1370: 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 2e 65 78 74   lTokenLines.ext
1380: 65 6e 64 28 5b 20 5b 5d 20 20 66 6f 72 20 69 20  end([ []  for i 
1390: 20 69 6e 20 72 61 6e 67 65 28 6c 65 6e 28 6c 4e   in range(len(lN
13a0: 65 77 54 6f 6b 65 6e 29 2b 31 29 20 5d 29 0a 20  ewToken)+1) ]). 
13b0: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
13c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
13d0: 20 6c 4e 65 77 54 65 6d 70 20 3d 20 5b 5d 0a 20   lNewTemp = []. 
13e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
13f0: 66 20 62 4e 75 6c 6c 50 6f 73 73 69 62 6c 65 3a  f bNullPossible:
1400: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1410: 20 20 20 20 20 66 6f 72 20 61 52 75 6c 65 20 69       for aRule i
1420: 6e 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20  n lTokenLines:. 
1430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1440: 20 20 20 20 20 20 20 66 6f 72 20 73 45 6c 65 6d         for sElem
1450: 20 69 6e 20 6c 4e 65 77 54 6f 6b 65 6e 3a 0a 20   in lNewToken:. 
1460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1470: 20 20 20 20 20 20 20 20 20 20 20 61 4e 65 77 52             aNewR
1480: 75 6c 65 20 3d 20 6c 69 73 74 28 61 52 75 6c 65  ule = list(aRule
1490: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
14a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 4e                aN
14b0: 65 77 52 75 6c 65 2e 61 70 70 65 6e 64 28 73 45  ewRule.append(sE
14c0: 6c 65 6d 29 0a 20 20 20 20 20 20 20 20 20 20 20  lem).           
14d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14e0: 20 6c 4e 65 77 54 65 6d 70 2e 61 70 70 65 6e 64   lNewTemp.append
14f0: 28 61 4e 65 77 52 75 6c 65 29 0a 20 20 20 20 20  (aNewRule).     
1500: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
1510: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1520: 20 20 20 20 20 73 45 6c 65 6d 31 20 3d 20 6c 4e       sElem1 = lN
1530: 65 77 54 6f 6b 65 6e 2e 70 6f 70 28 30 29 0a 20  ewToken.pop(0). 
1540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1550: 20 20 20 66 6f 72 20 61 52 75 6c 65 20 69 6e 20     for aRule in 
1560: 6c 54 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20 20 20  lTokenLines:.   
1570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1580: 20 20 20 20 20 66 6f 72 20 73 45 6c 65 6d 20 69       for sElem i
1590: 6e 20 6c 4e 65 77 54 6f 6b 65 6e 3a 0a 20 20 20  n lNewToken:.   
15a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15b0: 20 20 20 20 20 20 20 20 20 61 4e 65 77 52 75 6c           aNewRul
15c0: 65 20 3d 20 6c 69 73 74 28 61 52 75 6c 65 29 0a  e = list(aRule).
15d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15e0: 20 20 20 20 20 20 20 20 20 20 20 20 61 4e 65 77              aNew
15f0: 52 75 6c 65 2e 61 70 70 65 6e 64 28 22 28 22 20  Rule.append("(" 
1600: 2b 20 73 45 6c 65 6d 20 2b 20 22 29 22 20 20 69  + sElem + ")"  i
1610: 66 20 62 53 65 6c 65 63 74 65 64 47 72 6f 75 70  f bSelectedGroup
1620: 20 20 65 6c 73 65 20 73 45 6c 65 6d 29 0a 20 20    else sElem).  
1630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1640: 20 20 20 20 20 20 20 20 20 20 6c 4e 65 77 54 65            lNewTe
1650: 6d 70 2e 61 70 70 65 6e 64 28 61 4e 65 77 52 75  mp.append(aNewRu
1660: 6c 65 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  le).            
1670: 20 20 20 20 20 20 20 20 20 20 20 20 61 52 75 6c              aRul
1680: 65 2e 61 70 70 65 6e 64 28 22 28 22 20 2b 20 73  e.append("(" + s
1690: 45 6c 65 6d 31 20 2b 20 22 29 22 20 20 69 66 20  Elem1 + ")"  if 
16a0: 62 53 65 6c 65 63 74 65 64 47 72 6f 75 70 20 20  bSelectedGroup  
16b0: 65 6c 73 65 20 73 45 6c 65 6d 31 29 0a 20 20 20  else sElem1).   
16c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 54 6f               lTo
16d0: 6b 65 6e 4c 69 6e 65 73 2e 65 78 74 65 6e 64 28  kenLines.extend(
16e0: 6c 4e 65 77 54 65 6d 70 29 0a 20 20 20 20 20 20  lNewTemp).      
16f0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
1700: 20 20 20 20 23 20 73 69 6d 70 6c 65 20 74 6f 6b      # simple tok
1710: 65 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  en.            i
1720: 66 20 6e 6f 74 20 6c 54 6f 6b 65 6e 4c 69 6e 65  f not lTokenLine
1730: 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  s:.             
1740: 20 20 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 20 3d     lTokenLines =
1750: 20 5b 5b 73 54 6f 6b 65 6e 5d 2c 20 5b 5d 5d 20   [[sToken], []] 
1760: 20 69 66 20 62 4e 75 6c 6c 50 6f 73 73 69 62 6c   if bNullPossibl
1770: 65 20 20 65 6c 73 65 20 5b 5b 73 54 6f 6b 65 6e  e  else [[sToken
1780: 5d 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 65  ]].            e
1790: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
17a0: 20 20 20 20 20 69 66 20 62 4e 75 6c 6c 50 6f 73       if bNullPos
17b0: 73 69 62 6c 65 3a 0a 20 20 20 20 20 20 20 20 20  sible:.         
17c0: 20 20 20 20 20 20 20 20 20 20 20 6c 4e 65 77 54             lNewT
17d0: 65 6d 70 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20  emp = [].       
17e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72               for
17f0: 20 61 52 75 6c 65 20 69 6e 20 6c 54 6f 6b 65 6e   aRule in lToken
1800: 4c 69 6e 65 73 3a 0a 20 20 20 20 20 20 20 20 20  Lines:.         
1810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
1820: 4e 65 77 20 3d 20 6c 69 73 74 28 61 52 75 6c 65  New = list(aRule
1830: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
1840: 20 20 20 20 20 20 20 20 20 20 6c 4e 65 77 2e 61            lNew.a
1850: 70 70 65 6e 64 28 73 54 6f 6b 65 6e 29 0a 20 20  ppend(sToken).  
1860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1870: 20 20 20 20 20 20 6c 4e 65 77 54 65 6d 70 2e 61        lNewTemp.a
1880: 70 70 65 6e 64 28 6c 4e 65 77 29 0a 20 20 20 20  ppend(lNew).    
1890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18a0: 6c 54 6f 6b 65 6e 4c 69 6e 65 73 2e 65 78 74 65  lTokenLines.exte
18b0: 6e 64 28 6c 4e 65 77 54 65 6d 70 29 0a 20 20 20  nd(lNewTemp).   
18c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73               els
18d0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
18e0: 20 20 20 20 20 20 20 66 6f 72 20 61 52 75 6c 65         for aRule
18f0: 20 69 6e 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 3a   in lTokenLines:
1900: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1910: 20 20 20 20 20 20 20 20 20 61 52 75 6c 65 2e 61           aRule.a
1920: 70 70 65 6e 64 28 73 54 6f 6b 65 6e 29 0a 20 20  ppend(sToken).  
1930: 20 20 66 6f 72 20 61 52 75 6c 65 20 69 6e 20 6c    for aRule in l
1940: 54 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20 20 20 20  TokenLines:.    
1950: 20 20 20 20 79 69 65 6c 64 20 61 52 75 6c 65 0a      yield aRule.
1960: 0a 0a 64 65 66 20 63 72 65 61 74 65 52 75 6c 65  ..def createRule
1970: 20 28 69 4c 69 6e 65 2c 20 73 52 75 6c 65 4e 61   (iLine, sRuleNa
1980: 6d 65 2c 20 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20  me, sTokenLine, 
1990: 69 41 63 74 69 6f 6e 42 6c 6f 63 6b 2c 20 73 41  iActionBlock, sA
19a0: 63 74 69 6f 6e 73 2c 20 6e 50 72 69 6f 72 69 74  ctions, nPriorit
19b0: 79 2c 20 64 4f 70 74 50 72 69 6f 72 69 74 79 2c  y, dOptPriority,
19c0: 20 64 44 65 66 29 3a 0a 20 20 20 20 22 67 65 6e   dDef):.    "gen
19d0: 65 72 61 74 6f 72 3a 20 63 72 65 61 74 65 20 72  erator: create r
19e0: 75 6c 65 20 61 73 20 6c 69 73 74 22 0a 20 20 20  ule as list".   
19f0: 20 23 20 70 72 69 6e 74 28 69 4c 69 6e 65 2c 20   # print(iLine, 
1a00: 22 2f 2f 22 2c 20 73 52 75 6c 65 4e 61 6d 65 2c  "//", sRuleName,
1a10: 20 22 2f 2f 22 2c 20 73 54 6f 6b 65 6e 4c 69 6e   "//", sTokenLin
1a20: 65 2c 20 22 2f 2f 22 2c 20 73 41 63 74 69 6f 6e  e, "//", sAction
1a30: 73 2c 20 22 2f 2f 22 2c 20 6e 50 72 69 6f 72 69  s, "//", nPriori
1a40: 74 79 29 0a 20 20 20 20 66 6f 72 20 6c 54 6f 6b  ty).    for lTok
1a50: 65 6e 20 69 6e 20 67 65 6e 54 6f 6b 65 6e 4c 69  en in genTokenLi
1a60: 6e 65 73 28 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20  nes(sTokenLine, 
1a70: 64 44 65 66 29 3a 0a 20 20 20 20 20 20 20 20 23  dDef):.        #
1a80: 20 43 61 6c 63 75 6c 61 74 65 20 70 6f 73 69 74   Calculate posit
1a90: 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 64 50 6f  ions.        dPo
1aa0: 73 20 3d 20 7b 7d 20 20 20 23 20 6b 65 79 3a 20  s = {}   # key: 
1ab0: 69 47 72 6f 75 70 2c 20 76 61 6c 75 65 3a 20 69  iGroup, value: i
1ac0: 54 6f 6b 65 6e 0a 20 20 20 20 20 20 20 20 69 47  Token.        iG
1ad0: 72 6f 75 70 20 3d 20 30 0a 20 20 20 20 20 20 20  roup = 0.       
1ae0: 20 23 69 66 20 69 4c 69 6e 65 20 3d 3d 20 33 39   #if iLine == 39
1af0: 37 31 3a 20 23 20 64 65 62 75 67 0a 20 20 20 20  71: # debug.    
1b00: 20 20 20 20 23 20 20 20 20 70 72 69 6e 74 28 22      #    print("
1b10: 20 22 2e 6a 6f 69 6e 28 6c 54 6f 6b 65 6e 29 29   ".join(lToken))
1b20: 0a 20 20 20 20 20 20 20 20 66 6f 72 20 69 2c 20  .        for i, 
1b30: 73 54 6f 6b 65 6e 20 69 6e 20 65 6e 75 6d 65 72  sToken in enumer
1b40: 61 74 65 28 6c 54 6f 6b 65 6e 29 3a 0a 20 20 20  ate(lToken):.   
1b50: 20 20 20 20 20 20 20 20 20 69 66 20 73 54 6f 6b           if sTok
1b60: 65 6e 2e 73 74 61 72 74 73 77 69 74 68 28 22 28  en.startswith("(
1b70: 22 29 20 61 6e 64 20 73 54 6f 6b 65 6e 2e 65 6e  ") and sToken.en
1b80: 64 73 77 69 74 68 28 22 29 22 29 3a 0a 20 20 20  dswith(")"):.   
1b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 54 6f               lTo
1ba0: 6b 65 6e 5b 69 5d 20 3d 20 73 54 6f 6b 65 6e 5b  ken[i] = sToken[
1bb0: 31 3a 2d 31 5d 0a 20 20 20 20 20 20 20 20 20 20  1:-1].          
1bc0: 20 20 20 20 20 20 69 47 72 6f 75 70 20 2b 3d 20        iGroup += 
1bd0: 31 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  1.              
1be0: 20 20 64 50 6f 73 5b 69 47 72 6f 75 70 5d 20 3d    dPos[iGroup] =
1bf0: 20 69 20 2b 20 31 20 20 20 20 23 20 77 65 20 61   i + 1    # we a
1c00: 64 64 20 31 2c 20 66 6f 72 20 77 65 20 63 6f 75  dd 1, for we cou
1c10: 6e 74 20 74 6f 6b 65 6e 73 20 66 72 6f 6d 20 31  nt tokens from 1
1c20: 20 74 6f 20 6e 20 28 6e 6f 74 20 66 72 6f 6d 20   to n (not from 
1c30: 30 29 0a 0a 20 20 20 20 20 20 20 20 23 20 50 61  0)..        # Pa
1c40: 72 73 65 20 61 63 74 69 6f 6e 73 0a 20 20 20 20  rse actions.    
1c50: 20 20 20 20 66 6f 72 20 69 41 63 74 69 6f 6e 2c      for iAction,
1c60: 20 73 41 63 74 69 6f 6e 20 69 6e 20 65 6e 75 6d   sAction in enum
1c70: 65 72 61 74 65 28 73 41 63 74 69 6f 6e 73 2e 73  erate(sActions.s
1c80: 70 6c 69 74 28 22 20 3c 3c 2d 20 22 29 29 3a 0a  plit(" <<- ")):.
1c90: 20 20 20 20 20 20 20 20 20 20 20 20 73 41 63 74              sAct
1ca0: 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 2e 73 74  ion = sAction.st
1cb0: 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 20 20  rip().          
1cc0: 20 20 69 66 20 73 41 63 74 69 6f 6e 3a 0a 20 20    if sAction:.  
1cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 41                sA
1ce0: 63 74 69 6f 6e 49 64 20 3d 20 73 52 75 6c 65 4e  ctionId = sRuleN
1cf0: 61 6d 65 20 2b 20 22 5f 5f 62 22 20 2b 20 73 74  ame + "__b" + st
1d00: 72 28 69 41 63 74 69 6f 6e 42 6c 6f 63 6b 29 20  r(iActionBlock) 
1d10: 2b 20 22 5f 61 22 20 2b 20 73 74 72 28 69 41 63  + "_a" + str(iAc
1d20: 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 20 20  tion).          
1d30: 20 20 20 20 20 20 61 41 63 74 69 6f 6e 20 3d 20        aAction = 
1d40: 63 72 65 61 74 65 41 63 74 69 6f 6e 28 73 41 63  createAction(sAc
1d50: 74 69 6f 6e 49 64 2c 20 73 41 63 74 69 6f 6e 2c  tionId, sAction,
1d60: 20 6e 50 72 69 6f 72 69 74 79 2c 20 64 4f 70 74   nPriority, dOpt
1d70: 50 72 69 6f 72 69 74 79 2c 20 6c 65 6e 28 6c 54  Priority, len(lT
1d80: 6f 6b 65 6e 29 2c 20 64 50 6f 73 29 0a 20 20 20  oken), dPos).   
1d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
1da0: 61 41 63 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20  aAction:.       
1db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 41 63               sAc
1dc0: 74 69 6f 6e 4e 61 6d 65 20 3d 20 73 74 6f 72 65  tionName = store
1dd0: 41 63 74 69 6f 6e 28 73 41 63 74 69 6f 6e 49 64  Action(sActionId
1de0: 2c 20 61 41 63 74 69 6f 6e 29 0a 20 20 20 20 20  , aAction).     
1df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
1e00: 52 65 73 75 6c 74 20 3d 20 6c 69 73 74 28 6c 54  Result = list(lT
1e10: 6f 6b 65 6e 29 0a 20 20 20 20 20 20 20 20 20 20  oken).          
1e20: 20 20 20 20 20 20 20 20 20 20 6c 52 65 73 75 6c            lResul
1e30: 74 2e 65 78 74 65 6e 64 28 5b 22 23 23 22 2b 73  t.extend(["##"+s
1e40: 74 72 28 69 4c 69 6e 65 29 2c 20 73 41 63 74 69  tr(iLine), sActi
1e50: 6f 6e 4e 61 6d 65 5d 29 0a 20 20 20 20 20 20 20  onName]).       
1e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 69 66               #if
1e70: 20 69 4c 69 6e 65 20 3d 3d 20 31 33 33 34 31 3a   iLine == 13341:
1e80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1e90: 20 20 20 20 20 23 20 20 20 20 70 72 69 6e 74 28       #    print(
1ea0: 22 20 20 22 2e 6a 6f 69 6e 28 6c 54 6f 6b 65 6e  "  ".join(lToken
1eb0: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  )).             
1ec0: 20 20 20 20 20 20 20 23 20 20 20 20 70 72 69 6e         #    prin
1ed0: 74 28 73 41 63 74 69 6f 6e 49 64 2c 20 61 41 63  t(sActionId, aAc
1ee0: 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 20 20  tion).          
1ef0: 20 20 20 20 20 20 20 20 20 20 79 69 65 6c 64 20            yield 
1f00: 6c 52 65 73 75 6c 74 0a 20 20 20 20 20 20 20 20  lResult.        
1f10: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
1f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f30: 20 20 70 72 69 6e 74 28 22 20 23 20 45 72 72 6f    print(" # Erro
1f40: 72 20 6f 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c  r on action at l
1f50: 69 6e 65 3a 22 2c 20 69 4c 69 6e 65 29 0a 20 20  ine:", iLine).  
1f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f70: 20 20 70 72 69 6e 74 28 73 54 6f 6b 65 6e 4c 69    print(sTokenLi
1f80: 6e 65 2c 20 22 5c 6e 22 2c 20 73 41 63 74 69 6f  ne, "\n", sActio
1f90: 6e 73 29 0a 0a 0a 64 65 66 20 63 68 61 6e 67 65  ns)...def change
1fa0: 52 65 66 65 72 65 6e 63 65 54 6f 6b 65 6e 20 28  ReferenceToken (
1fb0: 73 54 65 78 74 2c 20 64 50 6f 73 29 3a 0a 20 20  sText, dPos):.  
1fc0: 20 20 22 63 68 61 6e 67 65 20 67 72 6f 75 70 20    "change group 
1fd0: 72 65 66 65 72 65 6e 63 65 20 69 6e 20 3c 73 54  reference in <sT
1fe0: 65 78 74 3e 20 77 69 74 68 20 76 61 6c 75 65 73  ext> with values
1ff0: 20 69 6e 20 3c 64 50 6f 73 3e 22 0a 20 20 20 20   in <dPos>".    
2000: 66 6f 72 20 69 20 69 6e 20 72 61 6e 67 65 28 6c  for i in range(l
2010: 65 6e 28 64 50 6f 73 29 2c 20 30 2c 20 2d 31 29  en(dPos), 0, -1)
2020: 3a 0a 20 20 20 20 20 20 20 20 73 54 65 78 74 20  :.        sText 
2030: 3d 20 73 54 65 78 74 2e 72 65 70 6c 61 63 65 28  = sText.replace(
2040: 22 5c 5c 22 2b 73 74 72 28 69 29 2c 20 22 5c 5c  "\\"+str(i), "\\
2050: 22 2b 73 74 72 28 64 50 6f 73 5b 69 5d 29 29 0a  "+str(dPos[i])).
2060: 20 20 20 20 72 65 74 75 72 6e 20 73 54 65 78 74      return sText
2070: 0a 0a 0a 64 65 66 20 63 68 65 63 6b 54 6f 6b 65  ...def checkToke
2080: 6e 4e 75 6d 62 65 72 73 20 28 73 54 65 78 74 2c  nNumbers (sText,
2090: 20 73 41 63 74 69 6f 6e 49 64 2c 20 6e 54 6f 6b   sActionId, nTok
20a0: 65 6e 29 3a 0a 20 20 20 20 22 63 68 65 63 6b 20  en):.    "check 
20b0: 69 66 20 74 6f 6b 65 6e 20 72 65 66 65 72 65 6e  if token referen
20c0: 63 65 73 20 69 6e 20 3c 73 54 65 78 74 3e 20 67  ces in <sText> g
20d0: 72 65 61 74 65 72 20 74 68 61 6e 20 3c 6e 54 6f  reater than <nTo
20e0: 6b 65 6e 3e 20 28 64 65 62 75 67 67 69 6e 67 29  ken> (debugging)
20f0: 22 0a 20 20 20 20 66 6f 72 20 78 20 69 6e 20 72  ".    for x in r
2100: 65 2e 66 69 6e 64 69 74 65 72 28 72 22 5c 5c 28  e.finditer(r"\\(
2110: 5c 64 2b 29 22 2c 20 73 54 65 78 74 29 3a 0a 20  \d+)", sText):. 
2120: 20 20 20 20 20 20 20 69 66 20 69 6e 74 28 78 2e         if int(x.
2130: 67 72 6f 75 70 28 31 29 29 20 3e 20 6e 54 6f 6b  group(1)) > nTok
2140: 65 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  en:.            
2150: 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69  print("# Error i
2160: 6e 20 74 6f 6b 65 6e 20 69 6e 64 65 78 20 61 74  n token index at
2170: 20 6c 69 6e 65 20 22 20 2b 20 73 41 63 74 69 6f   line " + sActio
2180: 6e 49 64 20 2b 20 22 20 28 22 2b 73 74 72 28 6e  nId + " ("+str(n
2190: 54 6f 6b 65 6e 29 2b 22 20 74 6f 6b 65 6e 73 20  Token)+" tokens 
21a0: 6f 6e 6c 79 29 22 29 0a 20 20 20 20 20 20 20 20  only)").        
21b0: 20 20 20 20 70 72 69 6e 74 28 73 54 65 78 74 29      print(sText)
21c0: 0a 0a 0a 64 65 66 20 63 68 65 63 6b 49 66 54 68  ...def checkIfTh
21d0: 65 72 65 49 73 43 6f 64 65 20 28 73 54 65 78 74  ereIsCode (sText
21e0: 2c 20 73 41 63 74 69 6f 6e 49 64 29 3a 0a 20 20  , sActionId):.  
21f0: 20 20 22 63 68 65 63 6b 20 69 66 20 74 68 65 72    "check if ther
2200: 65 20 69 73 20 63 6f 64 65 20 69 6e 20 3c 73 54  e is code in <sT
2210: 65 78 74 3e 20 28 64 65 62 75 67 67 69 6e 67 29  ext> (debugging)
2220: 22 0a 20 20 20 20 69 66 20 72 65 2e 73 65 61 72  ".    if re.sear
2230: 63 68 28 22 5b 2e 5d 5c 5c 77 2b 5b 28 5d 7c 73  ch("[.]\\w+[(]|s
2240: 75 67 67 5c 5c 77 2b 5b 28 5d 7c 5c 5c 28 5b 30  ugg\\w+[(]|\\([0
2250: 2d 39 5d 7c 5c 5c 5b 5b 30 2d 39 5d 22 2c 20 73  -9]|\\[[0-9]", s
2260: 54 65 78 74 29 3a 0a 20 20 20 20 20 20 20 20 70  Text):.        p
2270: 72 69 6e 74 28 22 23 20 57 61 72 6e 69 6e 67 20  rint("# Warning 
2280: 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 41 63 74  at line " + sAct
2290: 69 6f 6e 49 64 20 2b 20 22 3a 20 20 54 68 69 73  ionId + ":  This
22a0: 20 6d 65 73 73 61 67 65 20 6c 6f 6f 6b 73 20 6c   message looks l
22b0: 69 6b 65 20 63 6f 64 65 2e 20 4c 69 6e 65 20 73  ike code. Line s
22c0: 68 6f 75 6c 64 20 70 72 6f 62 61 62 6c 79 20 62  hould probably b
22d0: 65 67 69 6e 20 77 69 74 68 20 3d 22 29 0a 20 20  egin with =").  
22e0: 20 20 20 20 20 20 70 72 69 6e 74 28 73 54 65 78        print(sTex
22f0: 74 29 0a 0a 0a 64 65 66 20 63 72 65 61 74 65 41  t)...def createA
2300: 63 74 69 6f 6e 20 28 73 41 63 74 69 6f 6e 49 64  ction (sActionId
2310: 2c 20 73 41 63 74 69 6f 6e 2c 20 6e 50 72 69 6f  , sAction, nPrio
2320: 72 69 74 79 2c 20 64 4f 70 74 50 72 69 6f 72 69  rity, dOptPriori
2330: 74 79 2c 20 6e 54 6f 6b 65 6e 2c 20 64 50 6f 73  ty, nToken, dPos
2340: 29 3a 0a 20 20 20 20 22 63 72 65 61 74 65 20 61  ):.    "create a
2350: 63 74 69 6f 6e 20 72 75 6c 65 20 61 73 20 61 20  ction rule as a 
2360: 6c 69 73 74 22 0a 20 20 20 20 23 20 4f 70 74 69  list".    # Opti
2370: 6f 6e 0a 20 20 20 20 73 4f 70 74 69 6f 6e 20 3d  on.    sOption =
2380: 20 46 61 6c 73 65 0a 20 20 20 20 6d 20 3d 20 72   False.    m = r
2390: 65 2e 6d 61 74 63 68 28 22 2f 28 5c 5c 77 2b 29  e.match("/(\\w+)
23a0: 2f 22 2c 20 73 41 63 74 69 6f 6e 29 0a 20 20 20  /", sAction).   
23b0: 20 69 66 20 6d 3a 0a 20 20 20 20 20 20 20 20 73   if m:.        s
23c0: 4f 70 74 69 6f 6e 20 3d 20 6d 2e 67 72 6f 75 70  Option = m.group
23d0: 28 31 29 0a 20 20 20 20 20 20 20 20 73 41 63 74  (1).        sAct
23e0: 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 6d 2e  ion = sAction[m.
23f0: 65 6e 64 28 29 3a 5d 2e 73 74 72 69 70 28 29 0a  end():].strip().
2400: 20 20 20 20 69 66 20 6e 50 72 69 6f 72 69 74 79      if nPriority
2410: 20 3d 3d 20 2d 31 3a 0a 20 20 20 20 20 20 20 20   == -1:.        
2420: 6e 50 72 69 6f 72 69 74 79 20 3d 20 64 4f 70 74  nPriority = dOpt
2430: 50 72 69 6f 72 69 74 79 2e 67 65 74 28 73 4f 70  Priority.get(sOp
2440: 74 69 6f 6e 2c 20 34 29 0a 0a 20 20 20 20 23 20  tion, 4)..    # 
2450: 76 61 6c 69 64 20 61 63 74 69 6f 6e 3f 0a 20 20  valid action?.  
2460: 20 20 6d 20 3d 20 72 65 2e 73 65 61 72 63 68 28    m = re.search(
2470: 72 22 28 3f 50 3c 61 63 74 69 6f 6e 3e 5b 2d 7e  r"(?P<action>[-~
2480: 3d 2f 25 3e 5d 29 28 3f 50 3c 73 74 61 72 74 3e  =/%>])(?P<start>
2490: 2d 3f 5c 64 2b 5c 2e 3f 7c 29 28 3f 50 3c 65 6e  -?\d+\.?|)(?P<en
24a0: 64 3e 3a 5c 2e 3f 2d 3f 5c 64 2b 7c 29 28 3f 50  d>:\.?-?\d+|)(?P
24b0: 3c 63 61 73 69 6e 67 3e 3a 7c 29 3e 3e 22 2c 20  <casing>:|)>>", 
24c0: 73 41 63 74 69 6f 6e 29 0a 20 20 20 20 69 66 20  sAction).    if 
24d0: 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20 20 70  not m:.        p
24e0: 72 69 6e 74 28 22 20 23 20 45 72 72 6f 72 2e 20  rint(" # Error. 
24f0: 4e 6f 20 61 63 74 69 6f 6e 20 66 6f 75 6e 64 20  No action found 
2500: 61 74 3a 20 22 2c 20 73 41 63 74 69 6f 6e 49 64  at: ", sActionId
2510: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ).        return
2520: 20 4e 6f 6e 65 0a 0a 20 20 20 20 23 20 43 6f 6e   None..    # Con
2530: 64 69 74 69 6f 6e 0a 20 20 20 20 73 43 6f 6e 64  dition.    sCond
2540: 69 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b  ition = sAction[
2550: 3a 6d 2e 73 74 61 72 74 28 29 5d 2e 73 74 72 69  :m.start()].stri
2560: 70 28 29 0a 20 20 20 20 69 66 20 73 43 6f 6e 64  p().    if sCond
2570: 69 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 73  ition:.        s
2580: 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 63 68 61 6e  Condition = chan
2590: 67 65 52 65 66 65 72 65 6e 63 65 54 6f 6b 65 6e  geReferenceToken
25a0: 28 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 64 50 6f  (sCondition, dPo
25b0: 73 29 0a 20 20 20 20 20 20 20 20 73 43 6f 6e 64  s).        sCond
25c0: 69 74 69 6f 6e 20 3d 20 63 72 65 61 74 65 46 75  ition = createFu
25d0: 6e 63 74 69 6f 6e 28 22 63 6f 6e 64 22 2c 20 73  nction("cond", s
25e0: 41 63 74 69 6f 6e 49 64 2c 20 73 43 6f 6e 64 69  ActionId, sCondi
25f0: 74 69 6f 6e 29 0a 20 20 20 20 65 6c 73 65 3a 0a  tion).    else:.
2600: 20 20 20 20 20 20 20 20 73 43 6f 6e 64 69 74 69          sConditi
2610: 6f 6e 20 3d 20 22 22 0a 0a 20 20 20 20 23 20 43  on = ""..    # C
2620: 61 73 65 20 73 65 6e 73 69 74 69 76 69 74 79 0a  ase sensitivity.
2630: 20 20 20 20 62 43 61 73 65 53 65 6e 73 69 74 69      bCaseSensiti
2640: 76 69 74 79 20 3d 20 46 61 6c 73 65 20 69 66 20  vity = False if 
2650: 6d 2e 67 72 6f 75 70 28 22 63 61 73 69 6e 67 22  m.group("casing"
2660: 29 20 3d 3d 20 22 3a 22 20 65 6c 73 65 20 54 72  ) == ":" else Tr
2670: 75 65 0a 0a 20 20 20 20 23 20 41 63 74 69 6f 6e  ue..    # Action
2680: 0a 20 20 20 20 63 41 63 74 69 6f 6e 20 3d 20 6d  .    cAction = m
2690: 2e 67 72 6f 75 70 28 22 61 63 74 69 6f 6e 22 29  .group("action")
26a0: 0a 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 73  .    sAction = s
26b0: 41 63 74 69 6f 6e 5b 6d 2e 65 6e 64 28 29 3a 5d  Action[m.end():]
26c0: 2e 73 74 72 69 70 28 29 0a 20 20 20 20 73 41 63  .strip().    sAc
26d0: 74 69 6f 6e 20 3d 20 63 68 61 6e 67 65 52 65 66  tion = changeRef
26e0: 65 72 65 6e 63 65 54 6f 6b 65 6e 28 73 41 63 74  erenceToken(sAct
26f0: 69 6f 6e 2c 20 64 50 6f 73 29 0a 20 20 20 20 23  ion, dPos).    #
2700: 20 74 61 72 67 65 74 0a 20 20 20 20 63 53 74 61   target.    cSta
2710: 72 74 4c 69 6d 69 74 20 3d 20 22 3c 22 0a 20 20  rtLimit = "<".  
2720: 20 20 63 45 6e 64 4c 69 6d 69 74 20 3d 20 22 3e    cEndLimit = ">
2730: 22 0a 20 20 20 20 69 66 20 6e 6f 74 20 6d 2e 67  ".    if not m.g
2740: 72 6f 75 70 28 22 73 74 61 72 74 22 29 3a 0a 20  roup("start"):. 
2750: 20 20 20 20 20 20 20 69 53 74 61 72 74 41 63 74         iStartAct
2760: 69 6f 6e 20 3d 20 31 0a 20 20 20 20 20 20 20 20  ion = 1.        
2770: 69 45 6e 64 41 63 74 69 6f 6e 20 3d 20 30 0a 20  iEndAction = 0. 
2780: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
2790: 20 69 66 20 63 41 63 74 69 6f 6e 20 21 3d 20 22   if cAction != "
27a0: 2d 22 20 61 6e 64 20 28 6d 2e 67 72 6f 75 70 28  -" and (m.group(
27b0: 22 73 74 61 72 74 22 29 2e 65 6e 64 73 77 69 74  "start").endswit
27c0: 68 28 22 2e 22 29 20 6f 72 20 6d 2e 67 72 6f 75  h(".") or m.grou
27d0: 70 28 22 65 6e 64 22 29 2e 73 74 61 72 74 73 77  p("end").startsw
27e0: 69 74 68 28 22 3a 2e 22 29 29 3a 0a 20 20 20 20  ith(":.")):.    
27f0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 20          print(" 
2800: 23 20 45 72 72 6f 72 2e 20 57 72 6f 6e 67 20 73  # Error. Wrong s
2810: 65 6c 65 63 74 69 6f 6e 20 6f 6e 20 74 6f 6b 65  election on toke
2820: 6e 73 2e 22 2c 20 73 41 63 74 69 6f 6e 49 64 29  ns.", sActionId)
2830: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74  .            ret
2840: 75 72 6e 20 4e 6f 6e 65 0a 20 20 20 20 20 20 20  urn None.       
2850: 20 69 66 20 6d 2e 67 72 6f 75 70 28 22 73 74 61   if m.group("sta
2860: 72 74 22 29 2e 65 6e 64 73 77 69 74 68 28 22 2e  rt").endswith(".
2870: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
2880: 63 53 74 61 72 74 4c 69 6d 69 74 20 3d 20 22 3e  cStartLimit = ">
2890: 22 0a 20 20 20 20 20 20 20 20 69 53 74 61 72 74  ".        iStart
28a0: 41 63 74 69 6f 6e 20 3d 20 69 6e 74 28 6d 2e 67  Action = int(m.g
28b0: 72 6f 75 70 28 22 73 74 61 72 74 22 29 2e 72 73  roup("start").rs
28c0: 74 72 69 70 28 22 2e 22 29 29 0a 20 20 20 20 20  trip(".")).     
28d0: 20 20 20 69 66 20 6e 6f 74 20 6d 2e 67 72 6f 75     if not m.grou
28e0: 70 28 22 65 6e 64 22 29 3a 0a 20 20 20 20 20 20  p("end"):.      
28f0: 20 20 20 20 20 20 69 45 6e 64 41 63 74 69 6f 6e        iEndAction
2900: 20 3d 20 69 53 74 61 72 74 41 63 74 69 6f 6e 0a   = iStartAction.
2910: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
2920: 20 20 20 20 20 20 20 20 20 20 69 66 20 6d 2e 67            if m.g
2930: 72 6f 75 70 28 22 65 6e 64 22 29 2e 73 74 61 72  roup("end").star
2940: 74 73 77 69 74 68 28 22 3a 2e 22 29 3a 0a 20 20  tswith(":."):.  
2950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 45                cE
2960: 6e 64 4c 69 6d 69 74 20 3d 20 22 3c 22 0a 20 20  ndLimit = "<".  
2970: 20 20 20 20 20 20 20 20 20 20 69 45 6e 64 41 63            iEndAc
2980: 74 69 6f 6e 20 3d 20 69 6e 74 28 6d 2e 67 72 6f  tion = int(m.gro
2990: 75 70 28 22 65 6e 64 22 29 2e 6c 73 74 72 69 70  up("end").lstrip
29a0: 28 22 3a 2e 22 29 29 0a 20 20 20 20 69 66 20 64  (":.")).    if d
29b0: 50 6f 73 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28  Pos and m.group(
29c0: 22 73 74 61 72 74 22 29 3a 0a 20 20 20 20 20 20  "start"):.      
29d0: 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 20    try:.         
29e0: 20 20 20 69 53 74 61 72 74 41 63 74 69 6f 6e 20     iStartAction 
29f0: 3d 20 64 50 6f 73 2e 67 65 74 28 69 53 74 61 72  = dPos.get(iStar
2a00: 74 41 63 74 69 6f 6e 2c 20 69 53 74 61 72 74 41  tAction, iStartA
2a10: 63 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 20  ction).         
2a20: 20 20 20 69 66 20 69 45 6e 64 41 63 74 69 6f 6e     if iEndAction
2a30: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
2a40: 20 20 69 45 6e 64 41 63 74 69 6f 6e 20 3d 20 64    iEndAction = d
2a50: 50 6f 73 2e 67 65 74 28 69 45 6e 64 41 63 74 69  Pos.get(iEndActi
2a60: 6f 6e 2c 20 69 45 6e 64 41 63 74 69 6f 6e 29 0a  on, iEndAction).
2a70: 20 20 20 20 20 20 20 20 65 78 63 65 70 74 3a 0a          except:.
2a80: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
2a90: 74 28 22 23 20 45 72 72 6f 72 2e 20 57 72 6f 6e  t("# Error. Wron
2aa0: 67 20 67 72 6f 75 70 73 20 69 6e 3a 20 22 20 2b  g groups in: " +
2ab0: 20 73 41 63 74 69 6f 6e 49 64 29 0a 20 20 20 20   sActionId).    
2ac0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 20          print(" 
2ad0: 20 69 53 74 61 72 74 41 63 74 69 6f 6e 3a 22 2c   iStartAction:",
2ae0: 20 69 53 74 61 72 74 41 63 74 69 6f 6e 2c 20 22   iStartAction, "
2af0: 69 45 6e 64 41 63 74 69 6f 6e 3a 22 2c 20 69 45  iEndAction:", iE
2b00: 6e 64 41 63 74 69 6f 6e 29 0a 20 20 20 20 20 20  ndAction).      
2b10: 20 20 20 20 20 20 70 72 69 6e 74 28 22 20 22 2c        print(" ",
2b20: 20 64 50 6f 73 29 0a 20 20 20 20 69 66 20 69 53   dPos).    if iS
2b30: 74 61 72 74 41 63 74 69 6f 6e 20 3c 20 30 3a 0a  tartAction < 0:.
2b40: 20 20 20 20 20 20 20 20 69 53 74 61 72 74 41 63          iStartAc
2b50: 74 69 6f 6e 20 2b 3d 20 31 0a 20 20 20 20 69 66  tion += 1.    if
2b60: 20 69 45 6e 64 41 63 74 69 6f 6e 20 3c 20 30 3a   iEndAction < 0:
2b70: 0a 20 20 20 20 20 20 20 20 69 45 6e 64 41 63 74  .        iEndAct
2b80: 69 6f 6e 20 2b 3d 20 31 0a 0a 20 20 20 20 69 66  ion += 1..    if
2b90: 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 2d 22 3a   cAction == "-":
2ba0: 0a 20 20 20 20 20 20 20 20 23 23 20 65 72 72 6f  .        ## erro
2bb0: 72 0a 20 20 20 20 20 20 20 20 69 4d 73 67 20 3d  r.        iMsg =
2bc0: 20 73 41 63 74 69 6f 6e 2e 66 69 6e 64 28 22 20   sAction.find(" 
2bd0: 23 20 22 29 0a 20 20 20 20 20 20 20 20 69 66 20  # ").        if 
2be0: 69 4d 73 67 20 3d 3d 20 2d 31 3a 0a 20 20 20 20  iMsg == -1:.    
2bf0: 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 22          sMsg = "
2c00: 23 20 45 72 72 6f 72 2e 20 45 72 72 6f 72 20 6d  # Error. Error m
2c10: 65 73 73 61 67 65 20 6e 6f 74 20 66 6f 75 6e 64  essage not found
2c20: 2e 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  .".            s
2c30: 55 52 4c 20 3d 20 22 22 0a 20 20 20 20 20 20 20  URL = "".       
2c40: 20 20 20 20 20 70 72 69 6e 74 28 73 4d 73 67 20       print(sMsg 
2c50: 2b 20 22 20 41 63 74 69 6f 6e 20 69 64 3a 20 22  + " Action id: "
2c60: 20 2b 20 73 41 63 74 69 6f 6e 49 64 29 0a 20 20   + sActionId).  
2c70: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
2c80: 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 73          sMsg = s
2c90: 41 63 74 69 6f 6e 5b 69 4d 73 67 2b 33 3a 5d 2e  Action[iMsg+3:].
2ca0: 73 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20  strip().        
2cb0: 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 73 41      sAction = sA
2cc0: 63 74 69 6f 6e 5b 3a 69 4d 73 67 5d 2e 73 74 72  ction[:iMsg].str
2cd0: 69 70 28 29 0a 20 20 20 20 20 20 20 20 20 20 20  ip().           
2ce0: 20 73 55 52 4c 20 3d 20 22 22 0a 20 20 20 20 20   sURL = "".     
2cf0: 20 20 20 20 20 20 20 6d 55 52 4c 20 3d 20 72 65         mURL = re
2d00: 2e 73 65 61 72 63 68 28 22 5b 7c 5d 20 2a 28 68  .search("[|] *(h
2d10: 74 74 70 73 3f 3a 2f 2f 2e 2a 29 22 2c 20 73 4d  ttps?://.*)", sM
2d20: 73 67 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  sg).            
2d30: 69 66 20 6d 55 52 4c 3a 0a 20 20 20 20 20 20 20  if mURL:.       
2d40: 20 20 20 20 20 20 20 20 20 73 55 52 4c 20 3d 20           sURL = 
2d50: 6d 55 52 4c 2e 67 72 6f 75 70 28 31 29 2e 73 74  mURL.group(1).st
2d60: 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 20 20  rip().          
2d70: 20 20 20 20 20 20 73 4d 73 67 20 3d 20 73 4d 73        sMsg = sMs
2d80: 67 5b 3a 6d 55 52 4c 2e 73 74 61 72 74 28 30 29  g[:mURL.start(0)
2d90: 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20 20  ].strip().      
2da0: 20 20 20 20 20 20 63 68 65 63 6b 54 6f 6b 65 6e        checkToken
2db0: 4e 75 6d 62 65 72 73 28 73 4d 73 67 2c 20 73 41  Numbers(sMsg, sA
2dc0: 63 74 69 6f 6e 49 64 2c 20 6e 54 6f 6b 65 6e 29  ctionId, nToken)
2dd0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
2de0: 73 4d 73 67 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22  sMsg[0:1] == "="
2df0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
2e00: 20 20 73 4d 73 67 20 3d 20 63 72 65 61 74 65 46    sMsg = createF
2e10: 75 6e 63 74 69 6f 6e 28 22 6d 73 67 22 2c 20 73  unction("msg", s
2e20: 41 63 74 69 6f 6e 49 64 2c 20 73 4d 73 67 2c 20  ActionId, sMsg, 
2e30: 54 72 75 65 29 0a 20 20 20 20 20 20 20 20 20 20  True).          
2e40: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
2e50: 20 20 20 20 20 20 20 20 63 68 65 63 6b 49 66 54          checkIfT
2e60: 68 65 72 65 49 73 43 6f 64 65 28 73 4d 73 67 2c  hereIsCode(sMsg,
2e70: 20 73 41 63 74 69 6f 6e 49 64 29 0a 0a 20 20 20   sActionId)..   
2e80: 20 23 20 63 68 65 63 6b 69 6e 67 20 63 6f 6e 73   # checking cons
2e90: 69 73 74 61 6e 63 79 0a 20 20 20 20 63 68 65 63  istancy.    chec
2ea0: 6b 54 6f 6b 65 6e 4e 75 6d 62 65 72 73 28 73 41  kTokenNumbers(sA
2eb0: 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 49 64  ction, sActionId
2ec0: 2c 20 6e 54 6f 6b 65 6e 29 0a 0a 20 20 20 20 69  , nToken)..    i
2ed0: 66 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3e 22  f cAction == ">"
2ee0: 3a 0a 20 20 20 20 20 20 20 20 23 23 20 6e 6f 20  :.        ## no 
2ef0: 61 63 74 69 6f 6e 2c 20 62 72 65 61 6b 20 6c 6f  action, break lo
2f00: 6f 70 20 69 66 20 63 6f 6e 64 69 74 69 6f 6e 20  op if condition 
2f10: 69 73 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20  is False.       
2f20: 20 72 65 74 75 72 6e 20 5b 73 4f 70 74 69 6f 6e   return [sOption
2f30: 2c 20 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 63 41  , sCondition, cA
2f40: 63 74 69 6f 6e 2c 20 22 22 5d 0a 0a 20 20 20 20  ction, ""]..    
2f50: 69 66 20 6e 6f 74 20 73 41 63 74 69 6f 6e 20 61  if not sAction a
2f60: 6e 64 20 63 41 63 74 69 6f 6e 20 21 3d 20 22 25  nd cAction != "%
2f70: 22 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  ":.        print
2f80: 28 22 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74  ("# Error in act
2f90: 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ion at line " + 
2fa0: 73 41 63 74 69 6f 6e 49 64 20 2b 20 22 3a 20 20  sActionId + ":  
2fb0: 54 68 69 73 20 61 63 74 69 6f 6e 20 69 73 20 65  This action is e
2fc0: 6d 70 74 79 2e 22 29 0a 0a 20 20 20 20 69 66 20  mpty.")..    if 
2fd0: 73 41 63 74 69 6f 6e 5b 30 3a 31 5d 20 21 3d 20  sAction[0:1] != 
2fe0: 22 3d 22 20 61 6e 64 20 63 41 63 74 69 6f 6e 20  "=" and cAction 
2ff0: 21 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20  != "=":.        
3000: 63 68 65 63 6b 49 66 54 68 65 72 65 49 73 43 6f  checkIfThereIsCo
3010: 64 65 28 73 41 63 74 69 6f 6e 2c 20 73 41 63 74  de(sAction, sAct
3020: 69 6f 6e 49 64 29 0a 0a 20 20 20 20 69 66 20 63  ionId)..    if c
3030: 41 63 74 69 6f 6e 20 3d 3d 20 22 2d 22 3a 0a 20  Action == "-":. 
3040: 20 20 20 20 20 20 20 23 23 20 65 72 72 6f 72 20         ## error 
3050: 64 65 74 65 63 74 65 64 20 2d 2d 3e 20 73 75 67  detected --> sug
3060: 67 65 73 74 69 6f 6e 0a 20 20 20 20 20 20 20 20  gestion.        
3070: 69 66 20 73 41 63 74 69 6f 6e 5b 30 3a 31 5d 20  if sAction[0:1] 
3080: 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20  == "=":.        
3090: 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 63 72      sAction = cr
30a0: 65 61 74 65 46 75 6e 63 74 69 6f 6e 28 22 73 75  eateFunction("su
30b0: 67 67 22 2c 20 73 41 63 74 69 6f 6e 49 64 2c 20  gg", sActionId, 
30c0: 73 41 63 74 69 6f 6e 2c 20 54 72 75 65 29 0a 20  sAction, True). 
30d0: 20 20 20 20 20 20 20 65 6c 69 66 20 73 41 63 74         elif sAct
30e0: 69 6f 6e 2e 73 74 61 72 74 73 77 69 74 68 28 27  ion.startswith('
30f0: 22 27 29 20 61 6e 64 20 73 41 63 74 69 6f 6e 2e  "') and sAction.
3100: 65 6e 64 73 77 69 74 68 28 27 22 27 29 3a 0a 20  endswith('"'):. 
3110: 20 20 20 20 20 20 20 20 20 20 20 73 41 63 74 69             sActi
3120: 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a 2d  on = sAction[1:-
3130: 31 5d 0a 20 20 20 20 20 20 20 20 69 66 20 6e 6f  1].        if no
3140: 74 20 73 4d 73 67 3a 0a 20 20 20 20 20 20 20 20  t sMsg:.        
3150: 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72      print("# Err
3160: 6f 72 20 69 6e 20 61 63 74 69 6f 6e 20 61 74 20  or in action at 
3170: 6c 69 6e 65 20 22 20 2b 20 73 41 63 74 69 6f 6e  line " + sAction
3180: 49 64 20 2b 20 22 3a 20 20 54 68 65 20 6d 65 73  Id + ":  The mes
3190: 73 61 67 65 20 69 73 20 65 6d 70 74 79 2e 22 29  sage is empty.")
31a0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
31b0: 5b 73 4f 70 74 69 6f 6e 2c 20 73 43 6f 6e 64 69  [sOption, sCondi
31c0: 74 69 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73  tion, cAction, s
31d0: 41 63 74 69 6f 6e 2c 20 69 53 74 61 72 74 41 63  Action, iStartAc
31e0: 74 69 6f 6e 2c 20 69 45 6e 64 41 63 74 69 6f 6e  tion, iEndAction
31f0: 2c 20 63 53 74 61 72 74 4c 69 6d 69 74 2c 20 63  , cStartLimit, c
3200: 45 6e 64 4c 69 6d 69 74 2c 20 62 43 61 73 65 53  EndLimit, bCaseS
3210: 65 6e 73 69 74 69 76 69 74 79 2c 20 6e 50 72 69  ensitivity, nPri
3220: 6f 72 69 74 79 2c 20 73 4d 73 67 2c 20 73 55 52  ority, sMsg, sUR
3230: 4c 5d 0a 20 20 20 20 65 6c 69 66 20 63 41 63 74  L].    elif cAct
3240: 69 6f 6e 20 3d 3d 20 22 7e 22 3a 0a 20 20 20 20  ion == "~":.    
3250: 20 20 20 20 23 23 20 74 65 78 74 20 70 72 6f 63      ## text proc
3260: 65 73 73 6f 72 0a 20 20 20 20 20 20 20 20 69 66  essor.        if
3270: 20 73 41 63 74 69 6f 6e 5b 30 3a 31 5d 20 3d 3d   sAction[0:1] ==
3280: 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20   "=":.          
3290: 20 20 73 41 63 74 69 6f 6e 20 3d 20 63 72 65 61    sAction = crea
32a0: 74 65 46 75 6e 63 74 69 6f 6e 28 22 74 70 22 2c  teFunction("tp",
32b0: 20 73 41 63 74 69 6f 6e 49 64 2c 20 73 41 63 74   sActionId, sAct
32c0: 69 6f 6e 2c 20 54 72 75 65 29 0a 20 20 20 20 20  ion, True).     
32d0: 20 20 20 65 6c 69 66 20 73 41 63 74 69 6f 6e 2e     elif sAction.
32e0: 73 74 61 72 74 73 77 69 74 68 28 27 22 27 29 20  startswith('"') 
32f0: 61 6e 64 20 73 41 63 74 69 6f 6e 2e 65 6e 64 73  and sAction.ends
3300: 77 69 74 68 28 27 22 27 29 3a 0a 20 20 20 20 20  with('"'):.     
3310: 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d         sAction =
3320: 20 73 41 63 74 69 6f 6e 5b 31 3a 2d 31 5d 0a 20   sAction[1:-1]. 
3330: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b 73         return [s
3340: 4f 70 74 69 6f 6e 2c 20 73 43 6f 6e 64 69 74 69  Option, sConditi
3350: 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41 63  on, cAction, sAc
3360: 74 69 6f 6e 2c 20 69 53 74 61 72 74 41 63 74 69  tion, iStartActi
3370: 6f 6e 2c 20 69 45 6e 64 41 63 74 69 6f 6e 2c 20  on, iEndAction, 
3380: 62 43 61 73 65 53 65 6e 73 69 74 69 76 69 74 79  bCaseSensitivity
3390: 5d 0a 20 20 20 20 65 6c 69 66 20 63 41 63 74 69  ].    elif cActi
33a0: 6f 6e 20 3d 3d 20 22 25 22 20 6f 72 20 63 41 63  on == "%" or cAc
33b0: 74 69 6f 6e 20 3d 3d 20 22 2f 22 3a 0a 20 20 20  tion == "/":.   
33c0: 20 20 20 20 20 23 23 20 74 61 67 73 0a 20 20 20       ## tags.   
33d0: 20 20 20 20 20 72 65 74 75 72 6e 20 5b 73 4f 70       return [sOp
33e0: 74 69 6f 6e 2c 20 73 43 6f 6e 64 69 74 69 6f 6e  tion, sCondition
33f0: 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41 63 74 69  , cAction, sActi
3400: 6f 6e 2c 20 69 53 74 61 72 74 41 63 74 69 6f 6e  on, iStartAction
3410: 2c 20 69 45 6e 64 41 63 74 69 6f 6e 5d 0a 20 20  , iEndAction].  
3420: 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 20 3d    elif cAction =
3430: 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 23  = "=":.        #
3440: 23 20 64 69 73 61 6d 62 69 67 75 61 74 6f 72 0a  # disambiguator.
3450: 20 20 20 20 20 20 20 20 69 66 20 22 64 65 66 69          if "defi
3460: 6e 65 28 22 20 69 6e 20 73 41 63 74 69 6f 6e 20  ne(" in sAction 
3470: 61 6e 64 20 6e 6f 74 20 72 65 2e 73 65 61 72 63  and not re.searc
3480: 68 28 72 22 64 65 66 69 6e 65 5c 28 5c 5c 5c 64  h(r"define\(\\\d
3490: 2b 20 2a 2c 20 2a 5c 5b 2e 2a 5c 5d 20 2a 5c 29  + *, *\[.*\] *\)
34a0: 22 2c 20 73 41 63 74 69 6f 6e 29 3a 0a 20 20 20  ", sAction):.   
34b0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
34c0: 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69 6f  # Error in actio
34d0: 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 41  n at line " + sA
34e0: 63 74 69 6f 6e 49 64 20 2b 20 22 3a 20 73 65 63  ctionId + ": sec
34f0: 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 66 6f 72  ond argument for
3500: 20 3c 64 65 66 69 6e 65 3e 20 6d 75 73 74 20 62   <define> must b
3510: 65 20 61 20 6c 69 73 74 20 6f 66 20 73 74 72 69  e a list of stri
3520: 6e 67 73 22 29 0a 20 20 20 20 20 20 20 20 73 41  ngs").        sA
3530: 63 74 69 6f 6e 20 3d 20 63 72 65 61 74 65 46 75  ction = createFu
3540: 6e 63 74 69 6f 6e 28 22 64 61 22 2c 20 73 41 63  nction("da", sAc
3550: 74 69 6f 6e 49 64 2c 20 73 41 63 74 69 6f 6e 29  tionId, sAction)
3560: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
3570: 5b 73 4f 70 74 69 6f 6e 2c 20 73 43 6f 6e 64 69  [sOption, sCondi
3580: 74 69 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73  tion, cAction, s
3590: 41 63 74 69 6f 6e 5d 0a 20 20 20 20 65 6c 73 65  Action].    else
35a0: 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28  :.        print(
35b0: 22 20 23 20 55 6e 6b 6e 6f 77 6e 20 61 63 74 69  " # Unknown acti
35c0: 6f 6e 2e 22 2c 20 73 41 63 74 69 6f 6e 49 64 29  on.", sActionId)
35d0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
35e0: 4e 6f 6e 65 0a 0a 0a 64 65 66 20 6d 61 6b 65 20  None...def make 
35f0: 28 6c 52 75 6c 65 2c 20 64 44 65 66 2c 20 73 4c  (lRule, dDef, sL
3600: 61 6e 67 2c 20 64 4f 70 74 50 72 69 6f 72 69 74  ang, dOptPriorit
3610: 79 2c 20 62 4a 61 76 61 53 63 72 69 70 74 29 3a  y, bJavaScript):
3620: 0a 20 20 20 20 22 63 6f 6d 70 69 6c 65 20 72 75  .    "compile ru
3630: 6c 65 73 2c 20 72 65 74 75 72 6e 73 20 61 20 64  les, returns a d
3640: 69 63 74 69 6f 6e 61 72 79 20 6f 66 20 76 61 6c  ictionary of val
3650: 75 65 73 22 0a 20 20 20 20 23 20 66 6f 72 20 63  ues".    # for c
3660: 6c 61 72 69 74 79 20 70 75 72 70 6f 73 65 2c 20  larity purpose, 
3670: 64 6f 6e e2 80 99 74 20 63 72 65 61 74 65 20 61  don...t create a
3680: 6e 79 20 66 69 6c 65 20 68 65 72 65 0a 0a 20 20  ny file here..  
3690: 20 20 23 20 72 65 6d 6f 76 69 6e 67 20 63 6f 6d    # removing com
36a0: 6d 65 6e 74 73 2c 20 7a 65 72 6f 69 6e 67 20 65  ments, zeroing e
36b0: 6d 70 74 79 20 6c 69 6e 65 73 2c 20 63 72 65 61  mpty lines, crea
36c0: 74 69 6e 67 20 64 65 66 69 6e 69 74 69 6f 6e 73  ting definitions
36d0: 2c 20 73 74 6f 72 69 6e 67 20 74 65 73 74 73 2c  , storing tests,
36e0: 20 6d 65 72 67 69 6e 67 20 72 75 6c 65 20 6c 69   merging rule li
36f0: 6e 65 73 0a 20 20 20 20 70 72 69 6e 74 28 22 20  nes.    print(" 
3700: 20 70 61 72 73 69 6e 67 20 72 75 6c 65 73 2e 2e   parsing rules..
3710: 2e 22 29 0a 20 20 20 20 6c 54 6f 6b 65 6e 4c 69  .").    lTokenLi
3720: 6e 65 20 3d 20 5b 5d 0a 20 20 20 20 73 41 63 74  ne = [].    sAct
3730: 69 6f 6e 73 20 3d 20 22 22 0a 20 20 20 20 6e 50  ions = "".    nP
3740: 72 69 6f 72 69 74 79 20 3d 20 2d 31 0a 20 20 20  riority = -1.   
3750: 20 64 41 6c 6c 47 72 61 70 68 20 3d 20 7b 7d 0a   dAllGraph = {}.
3760: 20 20 20 20 73 47 72 61 70 68 4e 61 6d 65 20 3d      sGraphName =
3770: 20 22 22 0a 20 20 20 20 69 41 63 74 69 6f 6e 42   "".    iActionB
3780: 6c 6f 63 6b 20 3d 20 30 0a 20 20 20 20 61 52 75  lock = 0.    aRu
3790: 6c 65 4e 61 6d 65 20 3d 20 73 65 74 28 29 0a 0a  leName = set()..
37a0: 20 20 20 20 66 6f 72 20 69 2c 20 73 4c 69 6e 65      for i, sLine
37b0: 20 69 6e 20 6c 52 75 6c 65 3a 0a 20 20 20 20 20   in lRule:.     
37c0: 20 20 20 73 4c 69 6e 65 20 3d 20 73 4c 69 6e 65     sLine = sLine
37d0: 2e 72 73 74 72 69 70 28 29 0a 20 20 20 20 20 20  .rstrip().      
37e0: 20 20 69 66 20 22 5c 74 22 20 69 6e 20 73 4c 69    if "\t" in sLi
37f0: 6e 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ne:.            
3800: 23 20 74 61 62 75 6c 61 74 69 6f 6e 20 6e 6f 74  # tabulation not
3810: 20 61 6c 6c 6f 77 65 64 0a 20 20 20 20 20 20 20   allowed.       
3820: 20 20 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f       print("Erro
3830: 72 2e 20 54 61 62 75 6c 61 74 69 6f 6e 20 61 74  r. Tabulation at
3840: 20 6c 69 6e 65 3a 20 22 2c 20 69 29 0a 20 20 20   line: ", i).   
3850: 20 20 20 20 20 20 20 20 20 65 78 69 74 28 29 0a           exit().
3860: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69          elif sLi
3870: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 40  ne.startswith("@
3880: 40 40 40 47 52 41 50 48 3a 20 22 29 3a 0a 20 20  @@@GRAPH: "):.  
3890: 20 20 20 20 20 20 20 20 20 20 23 20 72 75 6c 65            # rule
38a0: 73 20 67 72 61 70 68 20 63 61 6c 6c 0a 20 20 20  s graph call.   
38b0: 20 20 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e           m = re.
38c0: 6d 61 74 63 68 28 72 22 40 40 40 40 47 52 41 50  match(r"@@@@GRAP
38d0: 48 3a 20 2a 28 5c 77 2b 29 22 2c 20 73 4c 69 6e  H: *(\w+)", sLin
38e0: 65 2e 73 74 72 69 70 28 29 29 0a 20 20 20 20 20  e.strip()).     
38f0: 20 20 20 20 20 20 20 69 66 20 6d 3a 0a 20 20 20         if m:.   
3900: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 47 72               sGr
3910: 61 70 68 4e 61 6d 65 20 3d 20 6d 2e 67 72 6f 75  aphName = m.grou
3920: 70 28 31 29 0a 20 20 20 20 20 20 20 20 20 20 20  p(1).           
3930: 20 20 20 20 20 69 66 20 73 47 72 61 70 68 4e 61       if sGraphNa
3940: 6d 65 20 69 6e 20 64 41 6c 6c 47 72 61 70 68 3a  me in dAllGraph:
3950: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3960: 20 20 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f       print("Erro
3970: 72 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 69 20  r at line " + i 
3980: 2b 20 22 2e 20 47 72 61 70 68 20 6e 61 6d 65 20  + ". Graph name 
3990: 3c 22 20 2b 20 73 47 72 61 70 68 4e 61 6d 65 20  <" + sGraphName 
39a0: 2b 20 22 3e 20 61 6c 72 65 61 64 79 20 65 78 69  + "> already exi
39b0: 73 74 73 2e 22 29 0a 20 20 20 20 20 20 20 20 20  sts.").         
39c0: 20 20 20 20 20 20 20 20 20 20 20 65 78 69 74 28             exit(
39d0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
39e0: 20 20 64 41 6c 6c 47 72 61 70 68 5b 73 47 72 61    dAllGraph[sGra
39f0: 70 68 4e 61 6d 65 5d 20 3d 20 5b 5d 0a 20 20 20  phName] = [].   
3a00: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
3a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
3a20: 72 69 6e 74 28 22 45 72 72 6f 72 2e 20 47 72 61  rint("Error. Gra
3a30: 70 68 20 6e 61 6d 65 20 6e 6f 74 20 66 6f 75 6e  ph name not foun
3a40: 64 20 61 74 20 6c 69 6e 65 22 2c 20 69 29 0a 20  d at line", i). 
3a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65                 e
3a60: 78 69 74 28 29 0a 20 20 20 20 20 20 20 20 65 6c  xit().        el
3a70: 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77  if sLine.startsw
3a80: 69 74 68 28 22 5f 5f 22 29 20 61 6e 64 20 73 4c  ith("__") and sL
3a90: 69 6e 65 2e 65 6e 64 73 77 69 74 68 28 22 5f 5f  ine.endswith("__
3aa0: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
3ab0: 23 20 6e 65 77 20 72 75 6c 65 20 67 72 6f 75 70  # new rule group
3ac0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d  .            m =
3ad0: 20 72 65 2e 6d 61 74 63 68 28 22 5f 5f 28 5c 5c   re.match("__(\\
3ae0: 77 2b 29 28 21 5c 5c 64 7c 29 5f 5f 22 2c 20 73  w+)(!\\d|)__", s
3af0: 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20  Line).          
3b00: 20 20 69 66 20 6d 3a 0a 20 20 20 20 20 20 20 20    if m:.        
3b10: 20 20 20 20 20 20 20 20 73 52 75 6c 65 4e 61 6d          sRuleNam
3b20: 65 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29 0a 20  e = m.group(1). 
3b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
3b40: 66 20 73 52 75 6c 65 4e 61 6d 65 20 69 6e 20 61  f sRuleName in a
3b50: 52 75 6c 65 4e 61 6d 65 3a 0a 20 20 20 20 20 20  RuleName:.      
3b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
3b70: 69 6e 74 28 22 45 72 72 6f 72 20 61 74 20 6c 69  int("Error at li
3b80: 6e 65 20 22 20 2b 20 69 20 2b 20 22 2e 20 52 75  ne " + i + ". Ru
3b90: 6c 65 20 6e 61 6d 65 20 3c 22 20 2b 20 73 52 75  le name <" + sRu
3ba0: 6c 65 4e 61 6d 65 20 2b 20 22 3e 20 61 6c 72 65  leName + "> alre
3bb0: 61 64 79 20 65 78 69 73 74 73 2e 22 29 0a 20 20  ady exists.").  
3bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3bd0: 20 20 65 78 69 74 28 29 0a 20 20 20 20 20 20 20    exit().       
3be0: 20 20 20 20 20 20 20 20 20 69 41 63 74 69 6f 6e           iAction
3bf0: 42 6c 6f 63 6b 20 3d 20 31 0a 20 20 20 20 20 20  Block = 1.      
3c00: 20 20 20 20 20 20 20 20 20 20 6e 50 72 69 6f 72            nPrior
3c10: 69 74 79 20 3d 20 69 6e 74 28 6d 2e 67 72 6f 75  ity = int(m.grou
3c20: 70 28 32 29 5b 31 3a 5d 29 20 69 66 20 6d 2e 67  p(2)[1:]) if m.g
3c30: 72 6f 75 70 28 32 29 20 20 65 6c 73 65 20 2d 31  roup(2)  else -1
3c40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
3c50: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
3c60: 20 20 20 70 72 69 6e 74 28 22 53 79 6e 74 61 78     print("Syntax
3c70: 20 65 72 72 6f 72 20 69 6e 20 72 75 6c 65 20 67   error in rule g
3c80: 72 6f 75 70 3a 20 22 2c 20 73 4c 69 6e 65 2c 20  roup: ", sLine, 
3c90: 22 20 2d 2d 20 6c 69 6e 65 3a 22 2c 20 69 29 0a  " -- line:", i).
3ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3cb0: 65 78 69 74 28 29 0a 20 20 20 20 20 20 20 20 65  exit().        e
3cc0: 6c 69 66 20 72 65 2e 73 65 61 72 63 68 28 22 5e  lif re.search("^
3cd0: 20 20 20 20 2b 3c 3c 2d 20 22 2c 20 73 4c 69 6e      +<<- ", sLin
3ce0: 65 29 20 6f 72 20 28 73 4c 69 6e 65 2e 73 74 61  e) or (sLine.sta
3cf0: 72 74 73 77 69 74 68 28 22 20 20 20 20 20 20 20  rtswith("       
3d00: 20 22 29 20 61 6e 64 20 6e 6f 74 20 73 4c 69 6e   ") and not sLin
3d10: 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 20 20  e.startswith("  
3d20: 20 20 20 20 20 20 7c 7c 22 29 29 20 5c 0a 20 20        ||")) \.  
3d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6f 72                or
3d40: 20 72 65 2e 73 65 61 72 63 68 28 22 5e 20 20 20   re.search("^   
3d50: 20 2b 23 22 2c 20 73 4c 69 6e 65 29 20 6f 72 20   +#", sLine) or 
3d60: 72 65 2e 73 65 61 72 63 68 28 72 22 5b 2d 7e 3d  re.search(r"[-~=
3d70: 3e 2f 25 5d 28 3f 3a 2d 3f 5c 64 5c 2e 3f 28 3f  >/%](?:-?\d\.?(?
3d80: 3a 3a 5c 2e 3f 2d 3f 5c 64 2b 7c 29 7c 29 3e 3e  ::\.?-?\d+|)|)>>
3d90: 20 22 2c 20 73 4c 69 6e 65 29 20 3a 0a 20 20 20   ", sLine) :.   
3da0: 20 20 20 20 20 20 20 20 20 23 20 61 63 74 69 6f           # actio
3db0: 6e 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ns.            s
3dc0: 41 63 74 69 6f 6e 73 20 2b 3d 20 22 20 22 20 2b  Actions += " " +
3dd0: 20 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 0a 20   sLine.strip(). 
3de0: 20 20 20 20 20 20 20 65 6c 69 66 20 72 65 2e 6d         elif re.m
3df0: 61 74 63 68 28 22 5b 20 c2 a0 5d 2a 24 22 2c 20  atch("[ ..]*$", 
3e00: 73 4c 69 6e 65 29 3a 0a 20 20 20 20 20 20 20 20  sLine):.        
3e10: 20 20 20 20 23 20 65 6d 70 74 79 20 6c 69 6e 65      # empty line
3e20: 20 74 6f 20 65 6e 64 20 6d 65 72 67 69 6e 67 0a   to end merging.
3e30: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e              if n
3e40: 6f 74 20 6c 54 6f 6b 65 6e 4c 69 6e 65 3a 0a 20  ot lTokenLine:. 
3e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63                 c
3e60: 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20 20 20 20  ontinue.        
3e70: 20 20 20 20 69 66 20 6e 6f 74 20 73 41 63 74 69      if not sActi
3e80: 6f 6e 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ons:.           
3e90: 20 20 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f       print("Erro
3ea0: 72 2e 20 4e 6f 20 61 63 74 69 6f 6e 20 66 6f 75  r. No action fou
3eb0: 6e 64 20 61 74 20 6c 69 6e 65 3a 22 2c 20 69 29  nd at line:", i)
3ec0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3ed0: 20 65 78 69 74 28 29 0a 20 20 20 20 20 20 20 20   exit().        
3ee0: 20 20 20 20 69 66 20 6e 6f 74 20 73 47 72 61 70      if not sGrap
3ef0: 68 4e 61 6d 65 3a 0a 20 20 20 20 20 20 20 20 20  hName:.         
3f00: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 45 72         print("Er
3f10: 72 6f 72 2e 20 41 6c 6c 20 72 75 6c 65 73 20 6d  ror. All rules m
3f20: 75 73 74 20 62 65 6c 6f 6e 67 20 74 6f 20 61 20  ust belong to a 
3f30: 6e 61 6d 65 64 20 67 72 61 70 68 2e 20 4c 69 6e  named graph. Lin
3f40: 65 3a 20 22 2c 20 69 29 0a 20 20 20 20 20 20 20  e: ", i).       
3f50: 20 20 20 20 20 20 20 20 20 65 78 69 74 28 29 0a           exit().
3f60: 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20              for 
3f70: 6a 2c 20 73 54 6f 6b 65 6e 4c 69 6e 65 20 69 6e  j, sTokenLine in
3f80: 20 6c 54 6f 6b 65 6e 4c 69 6e 65 3a 0a 20 20 20   lTokenLine:.   
3f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 64 41 6c               dAl
3fa0: 6c 47 72 61 70 68 5b 73 47 72 61 70 68 4e 61 6d  lGraph[sGraphNam
3fb0: 65 5d 2e 61 70 70 65 6e 64 28 28 6a 2c 20 73 52  e].append((j, sR
3fc0: 75 6c 65 4e 61 6d 65 2c 20 73 54 6f 6b 65 6e 4c  uleName, sTokenL
3fd0: 69 6e 65 2c 20 69 41 63 74 69 6f 6e 42 6c 6f 63  ine, iActionBloc
3fe0: 6b 2c 20 73 41 63 74 69 6f 6e 73 2c 20 6e 50 72  k, sActions, nPr
3ff0: 69 6f 72 69 74 79 29 29 0a 20 20 20 20 20 20 20  iority)).       
4000: 20 20 20 20 20 6c 54 6f 6b 65 6e 4c 69 6e 65 2e       lTokenLine.
4010: 63 6c 65 61 72 28 29 0a 20 20 20 20 20 20 20 20  clear().        
4020: 20 20 20 20 73 41 63 74 69 6f 6e 73 20 3d 20 22      sActions = "
4030: 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 41  ".            iA
4040: 63 74 69 6f 6e 42 6c 6f 63 6b 20 2b 3d 20 31 0a  ctionBlock += 1.
4050: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69          elif sLi
4060: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 20  ne.startswith(" 
4070: 20 20 20 22 29 3a 0a 20 20 20 20 20 20 20 20 20     "):.         
4080: 20 20 20 23 20 74 6f 6b 65 6e 73 0a 20 20 20 20     # tokens.    
4090: 20 20 20 20 20 20 20 20 73 4c 69 6e 65 20 3d 20          sLine = 
40a0: 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 0a 20 20  sLine.strip().  
40b0: 20 20 20 20 20 20 20 20 20 20 69 66 20 73 4c 69            if sLi
40c0: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 7c  ne.startswith("|
40d0: 7c 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  |"):.           
40e0: 20 20 20 20 20 69 50 72 65 76 4c 69 6e 65 2c 20       iPrevLine, 
40f0: 73 50 72 65 76 4c 69 6e 65 20 3d 20 6c 54 6f 6b  sPrevLine = lTok
4100: 65 6e 4c 69 6e 65 5b 2d 31 5d 0a 20 20 20 20 20  enLine[-1].     
4110: 20 20 20 20 20 20 20 20 20 20 20 6c 54 6f 6b 65             lToke
4120: 6e 4c 69 6e 65 5b 2d 31 5d 20 3d 20 5b 69 50 72  nLine[-1] = [iPr
4130: 65 76 4c 69 6e 65 2c 20 73 50 72 65 76 4c 69 6e  evLine, sPrevLin
4140: 65 20 2b 20 22 20 22 20 2b 20 73 4c 69 6e 65 5b  e + " " + sLine[
4150: 32 3a 5d 5d 0a 20 20 20 20 20 20 20 20 20 20 20  2:]].           
4160: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
4170: 20 20 20 20 20 20 20 6c 54 6f 6b 65 6e 4c 69 6e         lTokenLin
4180: 65 2e 61 70 70 65 6e 64 28 5b 69 2c 20 73 4c 69  e.append([i, sLi
4190: 6e 65 5d 29 0a 20 20 20 20 20 20 20 20 65 6c 73  ne]).        els
41a0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  e:.            p
41b0: 72 69 6e 74 28 22 55 6e 6b 6e 6f 77 6e 20 6c 69  rint("Unknown li
41c0: 6e 65 3a 22 29 0a 20 20 20 20 20 20 20 20 20 20  ne:").          
41d0: 20 20 70 72 69 6e 74 28 73 4c 69 6e 65 29 0a 0a    print(sLine)..
41e0: 20 20 20 20 23 20 70 72 6f 63 65 73 73 69 6e 67      # processing
41f0: 20 72 75 6c 65 73 0a 20 20 20 20 70 72 69 6e 74   rules.    print
4200: 28 22 20 20 70 72 65 70 61 72 69 6e 67 20 72 75  ("  preparing ru
4210: 6c 65 73 2e 2e 2e 22 29 0a 20 20 20 20 66 6f 72  les...").    for
4220: 20 73 47 72 61 70 68 4e 61 6d 65 2c 20 6c 52 75   sGraphName, lRu
4230: 6c 65 4c 69 6e 65 20 69 6e 20 64 41 6c 6c 47 72  leLine in dAllGr
4240: 61 70 68 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20  aph.items():.   
4250: 20 20 20 20 20 6c 50 72 65 70 61 72 65 64 52 75       lPreparedRu
4260: 6c 65 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20 20  le = [].        
4270: 66 6f 72 20 69 2c 20 73 52 75 6c 65 47 72 6f 75  for i, sRuleGrou
4280: 70 2c 20 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20 69  p, sTokenLine, i
4290: 41 63 74 69 6f 6e 42 6c 6f 63 6b 2c 20 73 41 63  ActionBlock, sAc
42a0: 74 69 6f 6e 73 2c 20 6e 50 72 69 6f 72 69 74 79  tions, nPriority
42b0: 20 69 6e 20 6c 52 75 6c 65 4c 69 6e 65 3a 0a 20   in lRuleLine:. 
42c0: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 6c             for l
42d0: 52 75 6c 65 20 69 6e 20 63 72 65 61 74 65 52 75  Rule in createRu
42e0: 6c 65 28 69 2c 20 73 52 75 6c 65 47 72 6f 75 70  le(i, sRuleGroup
42f0: 2c 20 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20 69 41  , sTokenLine, iA
4300: 63 74 69 6f 6e 42 6c 6f 63 6b 2c 20 73 41 63 74  ctionBlock, sAct
4310: 69 6f 6e 73 2c 20 6e 50 72 69 6f 72 69 74 79 2c  ions, nPriority,
4320: 20 64 4f 70 74 50 72 69 6f 72 69 74 79 2c 20 64   dOptPriority, d
4330: 44 65 66 29 3a 0a 20 20 20 20 20 20 20 20 20 20  Def):.          
4340: 20 20 20 20 20 20 6c 50 72 65 70 61 72 65 64 52        lPreparedR
4350: 75 6c 65 2e 61 70 70 65 6e 64 28 6c 52 75 6c 65  ule.append(lRule
4360: 29 0a 20 20 20 20 20 20 20 20 23 20 47 72 61 70  ).        # Grap
4370: 68 20 63 72 65 61 74 69 6f 6e 0a 20 20 20 20 20  h creation.     
4380: 20 20 20 6f 44 41 52 47 20 3d 20 64 61 72 67 2e     oDARG = darg.
4390: 44 41 52 47 28 6c 50 72 65 70 61 72 65 64 52 75  DARG(lPreparedRu
43a0: 6c 65 2c 20 73 4c 61 6e 67 29 0a 20 20 20 20 20  le, sLang).     
43b0: 20 20 20 64 41 6c 6c 47 72 61 70 68 5b 73 47 72     dAllGraph[sGr
43c0: 61 70 68 4e 61 6d 65 5d 20 3d 20 6f 44 41 52 47  aphName] = oDARG
43d0: 2e 63 72 65 61 74 65 47 72 61 70 68 28 29 0a 20  .createGraph(). 
43e0: 20 20 20 20 20 20 20 23 20 44 65 62 75 67 67 69         # Debuggi
43f0: 6e 67 0a 20 20 20 20 20 20 20 20 69 66 20 46 61  ng.        if Fa
4400: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
4410: 20 70 72 69 6e 74 28 22 5c 6e 52 55 4c 45 53 3a   print("\nRULES:
4420: 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  ").            f
4430: 6f 72 20 65 20 69 6e 20 6c 50 72 65 70 61 72 65  or e in lPrepare
4440: 64 52 75 6c 65 3a 0a 20 20 20 20 20 20 20 20 20  dRule:.         
4450: 20 20 20 20 20 20 20 69 66 20 65 5b 2d 32 5d 20         if e[-2] 
4460: 3d 3d 20 22 23 23 32 32 31 31 22 3a 0a 20 20 20  == "##2211":.   
4470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4480: 20 70 72 69 6e 74 28 65 29 0a 20 20 20 20 20 20   print(e).      
4490: 20 20 69 66 20 46 61 6c 73 65 3a 0a 20 20 20 20    if False:.    
44a0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 5c          print("\
44b0: 6e 47 52 41 50 48 3a 22 2c 20 73 47 72 61 70 68  nGRAPH:", sGraph
44c0: 4e 61 6d 65 29 0a 20 20 20 20 20 20 20 20 20 20  Name).          
44d0: 20 20 66 6f 72 20 6b 2c 20 76 20 69 6e 20 64 41    for k, v in dA
44e0: 6c 6c 47 72 61 70 68 5b 73 47 72 61 70 68 4e 61  llGraph[sGraphNa
44f0: 6d 65 5d 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20  me].items():.   
4500: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
4510: 6e 74 28 6b 2c 20 22 5c 74 22 2c 20 76 29 0a 0a  nt(k, "\t", v)..
4520: 20 20 20 20 23 20 63 72 65 61 74 69 6e 67 20 66      # creating f
4530: 69 6c 65 20 77 69 74 68 20 61 6c 6c 20 66 75 6e  ile with all fun
4540: 63 74 69 6f 6e 73 20 63 61 6c 6c 61 62 6c 65 20  ctions callable 
4550: 62 79 20 72 75 6c 65 73 0a 20 20 20 20 70 72 69  by rules.    pri
4560: 6e 74 28 22 20 20 63 72 65 61 74 69 6e 67 20 63  nt("  creating c
4570: 61 6c 6c 61 62 6c 65 73 2e 2e 2e 22 29 0a 20 20  allables...").  
4580: 20 20 73 50 79 43 61 6c 6c 61 62 6c 65 73 20 3d    sPyCallables =
4590: 20 22 23 20 67 65 6e 65 72 61 74 65 64 20 63 6f   "# generated co
45a0: 64 65 2c 20 64 6f 20 6e 6f 74 20 65 64 69 74 5c  de, do not edit\
45b0: 6e 22 0a 20 20 20 20 23 73 4a 53 43 61 6c 6c 61  n".    #sJSCalla
45c0: 62 6c 65 73 20 3d 20 22 2f 2f 20 67 65 6e 65 72  bles = "// gener
45d0: 61 74 65 64 20 63 6f 64 65 2c 20 64 6f 20 6e 6f  ated code, do no
45e0: 74 20 65 64 69 74 5c 6e 63 6f 6e 73 74 20 6f 45  t edit\nconst oE
45f0: 76 61 6c 46 75 6e 63 20 3d 20 7b 5c 6e 22 0a 20  valFunc = {\n". 
4600: 20 20 20 66 6f 72 20 73 46 75 6e 63 4e 61 6d 65     for sFuncName
4610: 2c 20 73 52 65 74 75 72 6e 20 69 6e 20 64 46 55  , sReturn in dFU
4620: 4e 43 54 49 4f 4e 53 2e 69 74 65 6d 73 28 29 3a  NCTIONS.items():
4630: 0a 20 20 20 20 20 20 20 20 69 66 20 73 46 75 6e  .        if sFun
4640: 63 4e 61 6d 65 2e 73 74 61 72 74 73 77 69 74 68  cName.startswith
4650: 28 22 5f 67 5f 63 6f 6e 64 5f 22 29 3a 20 23 20  ("_g_cond_"): # 
4660: 63 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 20 20  condition.      
4670: 20 20 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20        sParams = 
4680: 22 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f  "lToken, nTokenO
4690: 66 66 73 65 74 2c 20 6e 4c 61 73 74 54 6f 6b 65  ffset, nLastToke
46a0: 6e 2c 20 73 43 6f 75 6e 74 72 79 2c 20 62 43 6f  n, sCountry, bCo
46b0: 6e 64 4d 65 6d 6f 2c 20 64 54 61 67 73 2c 20 73  ndMemo, dTags, s
46c0: 53 65 6e 74 65 6e 63 65 2c 20 73 53 65 6e 74 65  Sentence, sSente
46d0: 6e 63 65 30 22 0a 20 20 20 20 20 20 20 20 65 6c  nce0".        el
46e0: 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61  if sFuncName.sta
46f0: 72 74 73 77 69 74 68 28 22 67 5f 6d 73 67 5f 22  rtswith("g_msg_"
4700: 29 3a 20 23 20 6d 65 73 73 61 67 65 0a 20 20 20  ): # message.   
4710: 20 20 20 20 20 20 20 20 20 73 50 61 72 61 6d 73           sParams
4720: 20 3d 20 22 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b   = "lToken, nTok
4730: 65 6e 4f 66 66 73 65 74 2c 20 6e 4c 61 73 74 54  enOffset, nLastT
4740: 6f 6b 65 6e 22 0a 20 20 20 20 20 20 20 20 65 6c  oken".        el
4750: 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61  if sFuncName.sta
4760: 72 74 73 77 69 74 68 28 22 5f 67 5f 73 75 67 67  rtswith("_g_sugg
4770: 5f 22 29 3a 20 23 20 73 75 67 67 65 73 74 69 6f  _"): # suggestio
4780: 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 50  n.            sP
4790: 61 72 61 6d 73 20 3d 20 22 6c 54 6f 6b 65 6e 2c  arams = "lToken,
47a0: 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2c 20 6e   nTokenOffset, n
47b0: 4c 61 73 74 54 6f 6b 65 6e 22 0a 20 20 20 20 20  LastToken".     
47c0: 20 20 20 65 6c 69 66 20 73 46 75 6e 63 4e 61 6d     elif sFuncNam
47d0: 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 5f 67  e.startswith("_g
47e0: 5f 74 70 5f 22 29 3a 20 23 20 74 65 78 74 20 70  _tp_"): # text p
47f0: 72 65 70 72 6f 63 65 73 73 6f 72 0a 20 20 20 20  reprocessor.    
4800: 20 20 20 20 20 20 20 20 73 50 61 72 61 6d 73 20          sParams 
4810: 3d 20 22 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65  = "lToken, nToke
4820: 6e 4f 66 66 73 65 74 2c 20 6e 4c 61 73 74 54 6f  nOffset, nLastTo
4830: 6b 65 6e 22 0a 20 20 20 20 20 20 20 20 65 6c 69  ken".        eli
4840: 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61 72  f sFuncName.star
4850: 74 73 77 69 74 68 28 22 5f 67 5f 64 61 5f 22 29  tswith("_g_da_")
4860: 3a 20 23 20 64 69 73 61 6d 62 69 67 75 61 74 6f  : # disambiguato
4870: 72 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 50  r.            sP
4880: 61 72 61 6d 73 20 3d 20 22 6c 54 6f 6b 65 6e 2c  arams = "lToken,
4890: 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2c 20 6e   nTokenOffset, n
48a0: 4c 61 73 74 54 6f 6b 65 6e 22 0a 20 20 20 20 20  LastToken".     
48b0: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
48c0: 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 55 6e       print("# Un
48d0: 6b 6e 6f 77 6e 20 66 75 6e 63 74 69 6f 6e 20 74  known function t
48e0: 79 70 65 20 69 6e 20 5b 22 20 2b 20 73 46 75 6e  ype in [" + sFun
48f0: 63 4e 61 6d 65 20 2b 20 22 5d 22 29 0a 20 20 20  cName + "]").   
4900: 20 20 20 20 20 20 20 20 20 63 6f 6e 74 69 6e 75           continu
4910: 65 0a 20 20 20 20 20 20 20 20 73 50 79 43 61 6c  e.        sPyCal
4920: 6c 61 62 6c 65 73 20 2b 3d 20 22 64 65 66 20 7b  lables += "def {
4930: 7d 20 28 7b 7d 29 3a 5c 6e 22 2e 66 6f 72 6d 61  } ({}):\n".forma
4940: 74 28 73 46 75 6e 63 4e 61 6d 65 2c 20 73 50 61  t(sFuncName, sPa
4950: 72 61 6d 73 29 0a 20 20 20 20 20 20 20 20 73 50  rams).        sP
4960: 79 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 20  yCallables += " 
4970: 20 20 20 72 65 74 75 72 6e 20 22 20 2b 20 73 52     return " + sR
4980: 65 74 75 72 6e 20 2b 20 22 5c 6e 22 0a 20 20 20  eturn + "\n".   
4990: 20 20 20 20 20 23 73 4a 53 43 61 6c 6c 61 62 6c       #sJSCallabl
49a0: 65 73 20 2b 3d 20 22 20 20 20 20 7b 7d 3a 20 66  es += "    {}: f
49b0: 75 6e 63 74 69 6f 6e 20 28 7b 7d 29 22 2e 66 6f  unction ({})".fo
49c0: 72 6d 61 74 28 73 46 75 6e 63 4e 61 6d 65 2c 20  rmat(sFuncName, 
49d0: 73 50 61 72 61 6d 73 29 20 2b 20 22 20 7b 5c 6e  sParams) + " {\n
49e0: 22 0a 20 20 20 20 20 20 20 20 23 73 4a 53 43 61  ".        #sJSCa
49f0: 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 20 20 20 20  llables += "    
4a00: 20 20 20 20 72 65 74 75 72 6e 20 22 20 2b 20 6a      return " + j
4a10: 73 63 6f 6e 76 2e 70 79 32 6a 73 28 73 52 65 74  sconv.py2js(sRet
4a20: 75 72 6e 29 20 2b 20 22 3b 5c 6e 22 0a 20 20 20  urn) + ";\n".   
4a30: 20 20 20 20 20 23 73 4a 53 43 61 6c 6c 61 62 6c       #sJSCallabl
4a40: 65 73 20 2b 3d 20 22 20 20 20 20 7d 2c 5c 6e 22  es += "    },\n"
4a50: 0a 20 20 20 20 23 73 4a 53 43 61 6c 6c 61 62 6c  .    #sJSCallabl
4a60: 65 73 20 2b 3d 20 22 7d 5c 6e 22 0a 0a 20 20 20  es += "}\n"..   
4a70: 20 23 20 44 65 62 75 67 67 69 6e 67 0a 20 20 20   # Debugging.   
4a80: 20 69 66 20 46 61 6c 73 65 3a 0a 20 20 20 20 20   if False:.     
4a90: 20 20 20 70 72 69 6e 74 28 22 5c 6e 41 63 74 69     print("\nActi
4aa0: 6f 6e 73 3a 22 29 0a 20 20 20 20 20 20 20 20 66  ons:").        f
4ab0: 6f 72 20 73 41 63 74 69 6f 6e 4e 61 6d 65 2c 20  or sActionName, 
4ac0: 61 41 63 74 69 6f 6e 20 69 6e 20 64 41 43 54 49  aAction in dACTI
4ad0: 4f 4e 53 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20  ONS.items():.   
4ae0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 73           print(s
4af0: 41 63 74 69 6f 6e 4e 61 6d 65 2c 20 61 41 63 74  ActionName, aAct
4b00: 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 70 72 69  ion).        pri
4b10: 6e 74 28 22 5c 6e 46 75 6e 63 74 69 6f 6e 73 3a  nt("\nFunctions:
4b20: 22 29 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  ").        print
4b30: 28 73 50 79 43 61 6c 6c 61 62 6c 65 73 29 0a 0a  (sPyCallables)..
4b40: 20 20 20 20 23 20 52 65 73 75 6c 74 0a 20 20 20      # Result.   
4b50: 20 72 65 74 75 72 6e 20 7b 0a 20 20 20 20 20 20   return {.      
4b60: 20 20 22 67 72 61 70 68 5f 63 61 6c 6c 61 62 6c    "graph_callabl
4b70: 65 73 22 3a 20 73 50 79 43 61 6c 6c 61 62 6c 65  es": sPyCallable
4b80: 73 2c 0a 20 20 20 20 20 20 20 20 22 72 75 6c 65  s,.        "rule
4b90: 73 5f 67 72 61 70 68 73 22 3a 20 64 41 6c 6c 47  s_graphs": dAllG
4ba0: 72 61 70 68 2c 0a 20 20 20 20 20 20 20 20 22 72  raph,.        "r
4bb0: 75 6c 65 73 5f 61 63 74 69 6f 6e 73 22 3a 20 64  ules_actions": d
4bc0: 41 43 54 49 4f 4e 53 0a 20 20 20 20 7d 0a        ACTIONS.    }.