Grammalecte  Hex Artifact Content

Artifact 3fa8a2a061e8cf0bcdcdd874d49f63983561773d8c6d8bb5d0d53019f2dac638:


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 0a 0a 64 65 66 20 70 72 65 70 61 72   {}...def prepar
00b0: 65 46 75 6e 63 74 69 6f 6e 20 28 73 2c 20 62 54  eFunction (s, bT
00c0: 6f 6b 65 6e 56 61 6c 75 65 3d 46 61 6c 73 65 29  okenValue=False)
00d0: 3a 0a 20 20 20 20 22 63 6f 6e 76 65 72 74 20 73  :.    "convert s
00e0: 69 6d 70 6c 65 20 72 75 6c 65 20 73 79 6e 74 61  imple rule synta
00f0: 78 20 74 6f 20 61 20 73 74 72 69 6e 67 20 6f 66  x to a string of
0100: 20 50 79 74 68 6f 6e 20 63 6f 64 65 22 0a 20 20   Python code".  
0110: 20 20 73 20 3d 20 73 2e 72 65 70 6c 61 63 65 28    s = s.replace(
0120: 22 5f 5f 61 6c 73 6f 5f 5f 22 2c 20 22 62 43 6f  "__also__", "bCo
0130: 6e 64 4d 65 6d 6f 22 29 0a 20 20 20 20 73 20 3d  ndMemo").    s =
0140: 20 73 2e 72 65 70 6c 61 63 65 28 22 5f 5f 65 6c   s.replace("__el
0150: 73 65 5f 5f 22 2c 20 22 6e 6f 74 20 62 43 6f 6e  se__", "not bCon
0160: 64 4d 65 6d 6f 22 29 0a 20 20 20 20 73 20 3d 20  dMemo").    s = 
0170: 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70 68 7c  re.sub(r"(morph|
0180: 61 6e 61 6c 79 73 65 7c 76 61 6c 75 65 7c 64 69  analyse|value|di
0190: 73 70 6c 61 79 49 6e 66 6f 29 5b 28 5d 5c 5c 28  splayInfo)[(]\\(
01a0: 5c 64 2b 29 22 2c 20 27 67 5f 5c 5c 31 28 6c 54  \d+)", 'g_\\1(lT
01b0: 6f 6b 65 6e 5b 5c 5c 32 2b 6e 54 6f 6b 65 6e 4f  oken[\\2+nTokenO
01c0: 66 66 73 65 74 5d 27 2c 20 73 29 0a 20 20 20 20  ffset]', s).    
01d0: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 28 73 65  s = re.sub(r"(se
01e0: 6c 65 63 74 7c 65 78 63 6c 75 64 65 7c 64 65 66  lect|exclude|def
01f0: 69 6e 65 29 5b 28 5d 5b 5c 5c 5d 28 5c 64 2b 29  ine)[(][\\](\d+)
0200: 22 2c 20 27 67 5f 5c 5c 31 28 6c 54 6f 6b 65 6e  ", 'g_\\1(lToken
0210: 5b 5c 5c 32 2b 6e 54 6f 6b 65 6e 4f 66 66 73 65  [\\2+nTokenOffse
0220: 74 5d 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  t]', s).    s = 
0230: 72 65 2e 73 75 62 28 72 22 28 74 61 67 5f 62 65  re.sub(r"(tag_be
0240: 66 6f 72 65 7c 74 61 67 5f 61 66 74 65 72 29 5b  fore|tag_after)[
0250: 28 5d 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27 67  (][\\](\d+)", 'g
0260: 5f 5c 5c 31 28 6c 54 6f 6b 65 6e 5b 5c 5c 32 2b  _\\1(lToken[\\2+
0270: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 5d 2c 20 64  nTokenOffset], d
0280: 54 61 67 73 27 2c 20 73 29 0a 20 20 20 20 73 20  Tags', s).    s 
0290: 3d 20 72 65 2e 73 75 62 28 72 22 73 70 61 63 65  = re.sub(r"space
02a0: 5f 61 66 74 65 72 5b 28 5d 5b 5c 5c 5d 28 5c 64  _after[(][\\](\d
02b0: 2b 29 22 2c 20 27 67 5f 73 70 61 63 65 5f 62 65  +)", 'g_space_be
02c0: 74 77 65 65 6e 5f 74 6f 6b 65 6e 73 28 6c 54 6f  tween_tokens(lTo
02d0: 6b 65 6e 5b 5c 5c 31 2b 6e 54 6f 6b 65 6e 4f 66  ken[\\1+nTokenOf
02e0: 66 73 65 74 5d 2c 20 6c 54 6f 6b 65 6e 5b 5c 5c  fset], lToken[\\
02f0: 31 2b 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2b 31  1+nTokenOffset+1
0300: 5d 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72  ]', s).    s = r
0310: 65 2e 73 75 62 28 72 22 61 6e 61 6c 79 73 65 5f  e.sub(r"analyse_
0320: 77 69 74 68 5f 6e 65 78 74 5b 28 5d 5b 5c 5c 5d  with_next[(][\\]
0330: 28 5c 64 2b 29 22 2c 20 27 67 5f 6d 65 72 67 65  (\d+)", 'g_merge
0340: 64 5f 61 6e 61 6c 79 73 65 28 6c 54 6f 6b 65 6e  d_analyse(lToken
0350: 5b 5c 5c 31 2b 6e 54 6f 6b 65 6e 4f 66 66 73 65  [\\1+nTokenOffse
0360: 74 5d 2c 20 6c 54 6f 6b 65 6e 5b 5c 5c 31 2b 6e  t], lToken[\\1+n
0370: 54 6f 6b 65 6e 4f 66 66 73 65 74 2b 31 5d 27 2c  TokenOffset+1]',
0380: 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73   s).    s = re.s
0390: 75 62 28 72 22 28 73 77 69 74 63 68 47 65 6e 64  ub(r"(switchGend
03a0: 65 72 7c 68 61 73 28 3f 3a 28 3f 3a 4d 61 73 7c  er|has(?:(?:Mas|
03b0: 46 65 6d 29 46 6f 72 6d 29 7c 53 69 6d 69 6c 29  Fem)Form)|Simil)
03c0: 5b 28 5d 5c 5c 28 5c 64 2b 29 22 2c 20 27 5c 5c  [(]\\(\d+)", '\\
03d0: 31 28 6c 54 6f 6b 65 6e 5b 5c 5c 32 2b 6e 54 6f  1(lToken[\\2+nTo
03e0: 6b 65 6e 4f 66 66 73 65 74 5d 5b 22 73 56 61 6c  kenOffset]["sVal
03f0: 75 65 22 5d 27 2c 20 73 29 0a 20 20 20 20 73 20  ue"]', s).    s 
0400: 3d 20 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70  = re.sub(r"(morp
0410: 68 7c 61 6e 61 6c 79 73 65 7c 76 61 6c 75 65 29  h|analyse|value)
0420: 5c 28 3e 31 22 2c 20 27 67 5f 5c 5c 31 28 6c 54  \(>1", 'g_\\1(lT
0430: 6f 6b 65 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 2b  oken[nLastToken+
0440: 31 5d 27 2c 20 73 29 20 20 20 20 20 20 20 20 20  1]', s)         
0450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
0460: 6e 65 78 74 20 74 6f 6b 65 6e 0a 20 20 20 20 73  next token.    s
0470: 20 3d 20 72 65 2e 73 75 62 28 72 22 28 6d 6f 72   = re.sub(r"(mor
0480: 70 68 7c 61 6e 61 6c 79 73 65 7c 76 61 6c 75 65  ph|analyse|value
0490: 29 5c 28 3c 31 22 2c 20 27 67 5f 5c 5c 31 28 6c  )\(<1", 'g_\\1(l
04a0: 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 4f 66 66 73  Token[nTokenOffs
04b0: 65 74 5d 27 2c 20 73 29 20 20 20 20 20 20 20 20  et]', s)        
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
04d0: 20 70 72 65 76 69 6f 75 73 20 74 6f 6b 65 6e 0a   previous token.
04e0: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
04f0: 22 5b 5c 5c 5d 28 5c 64 2b 29 5c 2e 69 73 28 75  "[\\](\d+)\.is(u
0500: 70 70 65 72 7c 6c 6f 77 65 72 7c 74 69 74 6c 65  pper|lower|title
0510: 29 5c 28 5c 29 22 2c 20 27 6c 54 6f 6b 65 6e 5b  )\(\)", 'lToken[
0520: 5c 5c 31 2b 6e 54 6f 6b 65 6e 4f 66 66 73 65 74  \\1+nTokenOffset
0530: 5d 5b 22 73 56 61 6c 75 65 22 5d 2e 69 73 5c 5c  ]["sValue"].is\\
0540: 32 28 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d  2()', s).    s =
0550: 20 72 65 2e 73 75 62 28 72 22 5b 5c 5c 5d 28 5c   re.sub(r"[\\](\
0560: 64 2b 29 5c 2e 28 73 74 61 72 74 73 77 69 74 68  d+)\.(startswith
0570: 7c 65 6e 64 73 77 69 74 68 29 5c 28 22 2c 20 27  |endswith)\(", '
0580: 6c 54 6f 6b 65 6e 5b 5c 5c 31 2b 6e 54 6f 6b 65  lToken[\\1+nToke
0590: 6e 4f 66 66 73 65 74 5d 5b 22 73 56 61 6c 75 65  nOffset]["sValue
05a0: 22 5d 2e 5c 5c 32 28 27 2c 20 73 29 0a 20 20 20  "].\\2(', s).   
05b0: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62   s = re.sub(r"\b
05c0: 73 70 65 6c 6c 20 2a 5b 28 5d 22 2c 20 27 5f 6f  spell *[(]", '_o
05d0: 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69 73 56  SpellChecker.isV
05e0: 61 6c 69 64 28 27 2c 20 73 29 0a 20 20 20 20 73  alid(', s).    s
05f0: 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62 62 65   = re.sub(r"\bbe
0600: 66 6f 72 65 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f  fore\(\s*", 'loo
0610: 6b 28 73 53 65 6e 74 65 6e 63 65 5b 3a 6c 54 6f  k(sSentence[:lTo
0620: 6b 65 6e 5b 31 2b 6e 54 6f 6b 65 6e 4f 66 66 73  ken[1+nTokenOffs
0630: 65 74 5d 5b 22 6e 53 74 61 72 74 22 5d 5d 2c 20  et]["nStart"]], 
0640: 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 23  ', s)          #
0650: 20 62 65 66 6f 72 65 28 73 29 0a 20 20 20 20 73   before(s).    s
0660: 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62 61 66   = re.sub(r"\baf
0670: 74 65 72 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b  ter\(\s*", 'look
0680: 28 73 53 65 6e 74 65 6e 63 65 5b 6c 54 6f 6b 65  (sSentence[lToke
0690: 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 5d 5b 22 6e  n[nLastToken]["n
06a0: 45 6e 64 22 5d 3a 5d 2c 20 27 2c 20 73 29 20 20  End"]:], ', s)  
06b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
06c0: 20 61 66 74 65 72 28 73 29 0a 20 20 20 20 73 20   after(s).    s 
06d0: 3d 20 72 65 2e 73 75 62 28 72 22 5c 62 62 65 66  = re.sub(r"\bbef
06e0: 6f 72 65 30 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f  ore0\(\s*", 'loo
06f0: 6b 28 73 53 65 6e 74 65 6e 63 65 30 5b 3a 6c 54  k(sSentence0[:lT
0700: 6f 6b 65 6e 5b 31 2b 6e 54 6f 6b 65 6e 4f 66 66  oken[1+nTokenOff
0710: 73 65 74 5d 5b 22 6e 53 74 61 72 74 22 5d 5d 2c  set]["nStart"]],
0720: 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 23 20   ', s)        # 
0730: 62 65 66 6f 72 65 30 28 73 29 0a 20 20 20 20 73  before0(s).    s
0740: 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62 61 66   = re.sub(r"\baf
0750: 74 65 72 30 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f  ter0\(\s*", 'loo
0760: 6b 28 73 53 65 6e 74 65 6e 63 65 5b 6c 54 6f 6b  k(sSentence[lTok
0770: 65 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 5d 5b 22  en[nLastToken]["
0780: 6e 45 6e 64 22 5d 3a 5d 2c 20 27 2c 20 73 29 20  nEnd"]:], ', s) 
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
07a0: 20 61 66 74 65 72 30 28 73 29 0a 20 20 20 20 69   after0(s).    i
07b0: 66 20 62 54 6f 6b 65 6e 56 61 6c 75 65 3a 0a 20  f bTokenValue:. 
07c0: 20 20 20 20 20 20 20 23 20 74 6f 6b 65 6e 20 76         # token v
07d0: 61 6c 75 65 73 20 61 72 65 20 75 73 65 64 20 61  alues are used a
07e0: 73 20 70 61 72 61 6d 65 74 65 72 0a 20 20 20 20  s parameter.    
07f0: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
0800: 22 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27 6c 54  "[\\](\d+)", 'lT
0810: 6f 6b 65 6e 5b 5c 5c 31 2b 6e 54 6f 6b 65 6e 4f  oken[\\1+nTokenO
0820: 66 66 73 65 74 5d 5b 22 73 56 61 6c 75 65 22 5d  ffset]["sValue"]
0830: 27 2c 20 73 29 0a 20 20 20 20 65 6c 73 65 3a 0a  ', s).    else:.
0840: 20 20 20 20 20 20 20 20 23 20 74 6f 6b 65 6e 73          # tokens
0850: 20 75 73 65 64 20 61 73 20 70 61 72 61 6d 65 74   used as paramet
0860: 65 72 0a 20 20 20 20 20 20 20 20 73 20 3d 20 72  er.        s = r
0870: 65 2e 73 75 62 28 72 22 5b 5c 5c 5d 28 5c 64 2b  e.sub(r"[\\](\d+
0880: 29 22 2c 20 27 6c 54 6f 6b 65 6e 5b 5c 5c 31 2b  )", 'lToken[\\1+
0890: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 5d 27 2c 20  nTokenOffset]', 
08a0: 73 29 0a 20 20 20 20 72 65 74 75 72 6e 20 73 0a  s).    return s.
08b0: 0a 0a 64 65 66 20 67 65 6e 54 6f 6b 65 6e 4c 69  ..def genTokenLi
08c0: 6e 65 73 20 28 73 54 6f 6b 65 6e 4c 69 6e 65 2c  nes (sTokenLine,
08d0: 20 64 44 65 66 29 3a 0a 20 20 20 20 22 74 6f 6b   dDef):.    "tok
08e0: 65 6e 69 7a 65 20 61 20 73 74 72 69 6e 67 20 61  enize a string a
08f0: 6e 64 20 72 65 74 75 72 6e 20 61 20 6c 69 73 74  nd return a list
0900: 20 6f 66 20 6c 69 6e 65 73 20 6f 66 20 74 6f 6b   of lines of tok
0910: 65 6e 73 22 0a 20 20 20 20 6c 54 6f 6b 65 6e 20  ens".    lToken 
0920: 3d 20 73 54 6f 6b 65 6e 4c 69 6e 65 2e 73 70 6c  = sTokenLine.spl
0930: 69 74 28 29 0a 20 20 20 20 6c 54 6f 6b 65 6e 4c  it().    lTokenL
0940: 69 6e 65 73 20 3d 20 4e 6f 6e 65 0a 20 20 20 20  ines = None.    
0950: 66 6f 72 20 73 54 6f 6b 65 6e 20 69 6e 20 6c 54  for sToken in lT
0960: 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20 20 23 20  oken:.        # 
0970: 6f 70 74 69 6f 6e 61 6c 20 74 6f 6b 65 6e 3f 0a  optional token?.
0980: 20 20 20 20 20 20 20 20 62 4e 75 6c 6c 50 6f 73          bNullPos
0990: 73 69 62 6c 65 20 3d 20 73 54 6f 6b 65 6e 2e 73  sible = sToken.s
09a0: 74 61 72 74 73 77 69 74 68 28 22 3f 22 29 20 61  tartswith("?") a
09b0: 6e 64 20 73 54 6f 6b 65 6e 2e 65 6e 64 73 77 69  nd sToken.endswi
09c0: 74 68 28 22 c2 bf 22 29 0a 20 20 20 20 20 20 20  th("..").       
09d0: 20 69 66 20 62 4e 75 6c 6c 50 6f 73 73 69 62 6c   if bNullPossibl
09e0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  e:.            s
09f0: 54 6f 6b 65 6e 20 3d 20 73 54 6f 6b 65 6e 5b 31  Token = sToken[1
0a00: 3a 2d 31 5d 0a 20 20 20 20 20 20 20 20 23 20 74  :-1].        # t
0a10: 6f 6b 65 6e 20 77 69 74 68 20 64 65 66 69 6e 69  oken with defini
0a20: 74 69 6f 6e 3f 0a 20 20 20 20 20 20 20 20 69 66  tion?.        if
0a30: 20 73 54 6f 6b 65 6e 2e 73 74 61 72 74 73 77 69   sToken.startswi
0a40: 74 68 28 22 28 7b 22 29 20 61 6e 64 20 73 54 6f  th("({") and sTo
0a50: 6b 65 6e 2e 65 6e 64 73 77 69 74 68 28 22 7d 29  ken.endswith("})
0a60: 22 29 20 61 6e 64 20 73 54 6f 6b 65 6e 5b 31 3a  ") and sToken[1:
0a70: 2d 31 5d 20 69 6e 20 64 44 65 66 3a 0a 20 20 20  -1] in dDef:.   
0a80: 20 20 20 20 20 20 20 20 20 73 54 6f 6b 65 6e 20           sToken 
0a90: 3d 20 22 28 22 20 2b 20 64 44 65 66 5b 73 54 6f  = "(" + dDef[sTo
0aa0: 6b 65 6e 5b 31 3a 2d 31 5d 5d 20 2b 20 22 29 22  ken[1:-1]] + ")"
0ab0: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 54  .        elif sT
0ac0: 6f 6b 65 6e 2e 73 74 61 72 74 73 77 69 74 68 28  oken.startswith(
0ad0: 22 7b 22 29 20 61 6e 64 20 73 54 6f 6b 65 6e 2e  "{") and sToken.
0ae0: 65 6e 64 73 77 69 74 68 28 22 7d 22 29 20 61 6e  endswith("}") an
0af0: 64 20 73 54 6f 6b 65 6e 20 69 6e 20 64 44 65 66  d sToken in dDef
0b00: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 54  :.            sT
0b10: 6f 6b 65 6e 20 3d 20 64 44 65 66 5b 73 54 6f 6b  oken = dDef[sTok
0b20: 65 6e 5d 0a 20 20 20 20 20 20 20 20 69 66 20 28  en].        if (
0b30: 20 28 73 54 6f 6b 65 6e 2e 73 74 61 72 74 73 77   (sToken.startsw
0b40: 69 74 68 28 22 5b 22 29 20 61 6e 64 20 73 54 6f  ith("[") and sTo
0b50: 6b 65 6e 2e 65 6e 64 73 77 69 74 68 28 22 5d 22  ken.endswith("]"
0b60: 29 29 20 6f 72 20 28 73 54 6f 6b 65 6e 2e 73 74  )) or (sToken.st
0b70: 61 72 74 73 77 69 74 68 28 22 28 5b 22 29 20 61  artswith("([") a
0b80: 6e 64 20 73 54 6f 6b 65 6e 2e 65 6e 64 73 77 69  nd sToken.endswi
0b90: 74 68 28 22 5d 29 22 29 29 20 29 3a 0a 20 20 20  th("])")) ):.   
0ba0: 20 20 20 20 20 20 20 20 20 23 20 6d 75 6c 74 69           # multi
0bb0: 70 6c 65 20 74 6f 6b 65 6e 0a 20 20 20 20 20 20  ple token.      
0bc0: 20 20 20 20 20 20 62 53 65 6c 65 63 74 65 64 47        bSelectedG
0bd0: 72 6f 75 70 20 3d 20 73 54 6f 6b 65 6e 2e 73 74  roup = sToken.st
0be0: 61 72 74 73 77 69 74 68 28 22 28 22 29 20 61 6e  artswith("(") an
0bf0: 64 20 73 54 6f 6b 65 6e 2e 65 6e 64 73 77 69 74  d sToken.endswit
0c00: 68 28 22 29 22 29 0a 20 20 20 20 20 20 20 20 20  h(")").         
0c10: 20 20 20 69 66 20 62 53 65 6c 65 63 74 65 64 47     if bSelectedG
0c20: 72 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20 20  roup:.          
0c30: 20 20 20 20 20 20 73 54 6f 6b 65 6e 20 3d 20 73        sToken = s
0c40: 54 6f 6b 65 6e 5b 31 3a 2d 31 5d 0a 20 20 20 20  Token[1:-1].    
0c50: 20 20 20 20 20 20 20 20 6c 4e 65 77 54 6f 6b 65          lNewToke
0c60: 6e 20 3d 20 73 54 6f 6b 65 6e 5b 31 3a 2d 31 5d  n = sToken[1:-1]
0c70: 2e 73 70 6c 69 74 28 22 7c 22 29 0a 20 20 20 20  .split("|").    
0c80: 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 6c          if not l
0c90: 54 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20 20 20 20  TokenLines:.    
0ca0: 20 20 20 20 20 20 20 20 20 20 20 20 6c 54 6f 6b              lTok
0cb0: 65 6e 4c 69 6e 65 73 20 3d 20 5b 20 5b 73 5d 20  enLines = [ [s] 
0cc0: 20 66 6f 72 20 73 20 20 69 6e 20 6c 4e 65 77 54   for s  in lNewT
0cd0: 6f 6b 65 6e 20 5d 0a 20 20 20 20 20 20 20 20 20  oken ].         
0ce0: 20 20 20 20 20 20 20 69 66 20 62 4e 75 6c 6c 50         if bNullP
0cf0: 6f 73 73 69 62 6c 65 3a 0a 20 20 20 20 20 20 20  ossible:.       
0d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 54 6f               lTo
0d10: 6b 65 6e 4c 69 6e 65 73 2e 65 78 74 65 6e 64 28  kenLines.extend(
0d20: 5b 20 5b 5d 20 20 66 6f 72 20 69 20 20 69 6e 20  [ []  for i  in 
0d30: 72 61 6e 67 65 28 6c 65 6e 28 6c 4e 65 77 54 6f  range(len(lNewTo
0d40: 6b 65 6e 29 2b 31 29 20 5d 29 0a 20 20 20 20 20  ken)+1) ]).     
0d50: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 4e 65               lNe
0d70: 77 54 65 6d 70 20 3d 20 5b 5d 0a 20 20 20 20 20  wTemp = [].     
0d80: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62 4e             if bN
0d90: 75 6c 6c 50 6f 73 73 69 62 6c 65 3a 0a 20 20 20  ullPossible:.   
0da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0db0: 20 66 6f 72 20 61 52 75 6c 65 20 69 6e 20 6c 54   for aRule in lT
0dc0: 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20 20 20 20 20  okenLines:.     
0dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0de0: 20 20 20 66 6f 72 20 73 45 6c 65 6d 20 69 6e 20     for sElem in 
0df0: 6c 4e 65 77 54 6f 6b 65 6e 3a 0a 20 20 20 20 20  lNewToken:.     
0e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e10: 20 20 20 20 20 20 20 61 4e 65 77 52 75 6c 65 20         aNewRule 
0e20: 3d 20 6c 69 73 74 28 61 52 75 6c 65 29 0a 20 20  = list(aRule).  
0e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e40: 20 20 20 20 20 20 20 20 20 20 61 4e 65 77 52 75            aNewRu
0e50: 6c 65 2e 61 70 70 65 6e 64 28 73 45 6c 65 6d 29  le.append(sElem)
0e60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 4e 65               lNe
0e80: 77 54 65 6d 70 2e 61 70 70 65 6e 64 28 61 4e 65  wTemp.append(aNe
0e90: 77 52 75 6c 65 29 0a 20 20 20 20 20 20 20 20 20  wRule).         
0ea0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
0eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ec0: 20 73 45 6c 65 6d 31 20 3d 20 6c 4e 65 77 54 6f   sElem1 = lNewTo
0ed0: 6b 65 6e 2e 70 6f 70 28 30 29 0a 20 20 20 20 20  ken.pop(0).     
0ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 66                 f
0ef0: 6f 72 20 61 52 75 6c 65 20 69 6e 20 6c 54 6f 6b  or aRule in lTok
0f00: 65 6e 4c 69 6e 65 73 3a 0a 20 20 20 20 20 20 20  enLines:.       
0f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f20: 20 66 6f 72 20 73 45 6c 65 6d 20 69 6e 20 6c 4e   for sElem in lN
0f30: 65 77 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20  ewToken:.       
0f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f50: 20 20 20 20 20 61 4e 65 77 52 75 6c 65 20 3d 20       aNewRule = 
0f60: 6c 69 73 74 28 61 52 75 6c 65 29 0a 20 20 20 20  list(aRule).    
0f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f80: 20 20 20 20 20 20 20 20 61 4e 65 77 52 75 6c 65          aNewRule
0f90: 2e 61 70 70 65 6e 64 28 22 28 22 20 2b 20 73 45  .append("(" + sE
0fa0: 6c 65 6d 20 2b 20 22 29 22 20 20 69 66 20 62 53  lem + ")"  if bS
0fb0: 65 6c 65 63 74 65 64 47 72 6f 75 70 20 20 65 6c  electedGroup  el
0fc0: 73 65 20 73 45 6c 65 6d 29 0a 20 20 20 20 20 20  se sElem).      
0fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0fe0: 20 20 20 20 20 20 6c 4e 65 77 54 65 6d 70 2e 61        lNewTemp.a
0ff0: 70 70 65 6e 64 28 61 4e 65 77 52 75 6c 65 29 0a  ppend(aNewRule).
1000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1010: 20 20 20 20 20 20 20 20 61 52 75 6c 65 2e 61 70          aRule.ap
1020: 70 65 6e 64 28 22 28 22 20 2b 20 73 45 6c 65 6d  pend("(" + sElem
1030: 31 20 2b 20 22 29 22 20 20 69 66 20 62 53 65 6c  1 + ")"  if bSel
1040: 65 63 74 65 64 47 72 6f 75 70 20 20 65 6c 73 65  ectedGroup  else
1050: 20 73 45 6c 65 6d 31 29 0a 20 20 20 20 20 20 20   sElem1).       
1060: 20 20 20 20 20 20 20 20 20 6c 54 6f 6b 65 6e 4c           lTokenL
1070: 69 6e 65 73 2e 65 78 74 65 6e 64 28 6c 4e 65 77  ines.extend(lNew
1080: 54 65 6d 70 29 0a 20 20 20 20 20 20 20 20 65 6c  Temp).        el
1090: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
10a0: 23 20 73 69 6d 70 6c 65 20 74 6f 6b 65 6e 0a 20  # simple token. 
10b0: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e 6f             if no
10c0: 74 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20  t lTokenLines:. 
10d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
10e0: 54 6f 6b 65 6e 4c 69 6e 65 73 20 3d 20 5b 5b 73  TokenLines = [[s
10f0: 54 6f 6b 65 6e 5d 2c 20 5b 5d 5d 20 20 69 66 20  Token], []]  if 
1100: 62 4e 75 6c 6c 50 6f 73 73 69 62 6c 65 20 20 65  bNullPossible  e
1110: 6c 73 65 20 5b 5b 73 54 6f 6b 65 6e 5d 5d 0a 20  lse [[sToken]]. 
1120: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
1130: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1140: 20 69 66 20 62 4e 75 6c 6c 50 6f 73 73 69 62 6c   if bNullPossibl
1150: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
1160: 20 20 20 20 20 20 20 6c 4e 65 77 54 65 6d 70 20         lNewTemp 
1170: 3d 20 5b 5d 0a 20 20 20 20 20 20 20 20 20 20 20  = [].           
1180: 20 20 20 20 20 20 20 20 20 66 6f 72 20 61 52 75           for aRu
1190: 6c 65 20 69 6e 20 6c 54 6f 6b 65 6e 4c 69 6e 65  le in lTokenLine
11a0: 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  s:.             
11b0: 20 20 20 20 20 20 20 20 20 20 20 6c 4e 65 77 20             lNew 
11c0: 3d 20 6c 69 73 74 28 61 52 75 6c 65 29 0a 20 20  = list(aRule).  
11d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11e0: 20 20 20 20 20 20 6c 4e 65 77 2e 61 70 70 65 6e        lNew.appen
11f0: 64 28 73 54 6f 6b 65 6e 29 0a 20 20 20 20 20 20  d(sToken).      
1200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1210: 20 20 6c 4e 65 77 54 65 6d 70 2e 61 70 70 65 6e    lNewTemp.appen
1220: 64 28 6c 4e 65 77 29 0a 20 20 20 20 20 20 20 20  d(lNew).        
1230: 20 20 20 20 20 20 20 20 20 20 20 20 6c 54 6f 6b              lTok
1240: 65 6e 4c 69 6e 65 73 2e 65 78 74 65 6e 64 28 6c  enLines.extend(l
1250: 4e 65 77 54 65 6d 70 29 0a 20 20 20 20 20 20 20  NewTemp).       
1260: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
1270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1280: 20 20 20 66 6f 72 20 61 52 75 6c 65 20 69 6e 20     for aRule in 
1290: 6c 54 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20 20 20  lTokenLines:.   
12a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12b0: 20 20 20 20 20 61 52 75 6c 65 2e 61 70 70 65 6e       aRule.appen
12c0: 64 28 73 54 6f 6b 65 6e 29 0a 20 20 20 20 66 6f  d(sToken).    fo
12d0: 72 20 61 52 75 6c 65 20 69 6e 20 6c 54 6f 6b 65  r aRule in lToke
12e0: 6e 4c 69 6e 65 73 3a 0a 20 20 20 20 20 20 20 20  nLines:.        
12f0: 79 69 65 6c 64 20 61 52 75 6c 65 0a 0a 0a 64 65  yield aRule...de
1300: 66 20 63 72 65 61 74 65 52 75 6c 65 20 28 69 4c  f createRule (iL
1310: 69 6e 65 2c 20 73 52 75 6c 65 4e 61 6d 65 2c 20  ine, sRuleName, 
1320: 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20 69 41 63 74  sTokenLine, iAct
1330: 69 6f 6e 42 6c 6f 63 6b 2c 20 73 41 63 74 69 6f  ionBlock, sActio
1340: 6e 73 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20 64  ns, nPriority, d
1350: 44 65 66 29 3a 0a 20 20 20 20 22 67 65 6e 65 72  Def):.    "gener
1360: 61 74 6f 72 3a 20 63 72 65 61 74 65 20 72 75 6c  ator: create rul
1370: 65 20 61 73 20 6c 69 73 74 22 0a 20 20 20 20 23  e as list".    #
1380: 20 70 72 69 6e 74 28 69 4c 69 6e 65 2c 20 22 2f   print(iLine, "/
1390: 2f 22 2c 20 73 52 75 6c 65 4e 61 6d 65 2c 20 22  /", sRuleName, "
13a0: 2f 2f 22 2c 20 73 54 6f 6b 65 6e 4c 69 6e 65 2c  //", sTokenLine,
13b0: 20 22 2f 2f 22 2c 20 73 41 63 74 69 6f 6e 73 2c   "//", sActions,
13c0: 20 22 2f 2f 22 2c 20 6e 50 72 69 6f 72 69 74 79   "//", nPriority
13d0: 29 0a 20 20 20 20 66 6f 72 20 6c 54 6f 6b 65 6e  ).    for lToken
13e0: 20 69 6e 20 67 65 6e 54 6f 6b 65 6e 4c 69 6e 65   in genTokenLine
13f0: 73 28 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20 64 44  s(sTokenLine, dD
1400: 65 66 29 3a 0a 20 20 20 20 20 20 20 20 23 20 43  ef):.        # C
1410: 61 6c 63 75 6c 61 74 65 20 70 6f 73 69 74 69 6f  alculate positio
1420: 6e 73 0a 20 20 20 20 20 20 20 20 64 50 6f 73 20  ns.        dPos 
1430: 3d 20 7b 7d 20 20 20 23 20 6b 65 79 3a 20 69 47  = {}   # key: iG
1440: 72 6f 75 70 2c 20 76 61 6c 75 65 3a 20 69 54 6f  roup, value: iTo
1450: 6b 65 6e 0a 20 20 20 20 20 20 20 20 69 47 72 6f  ken.        iGro
1460: 75 70 20 3d 20 30 0a 20 20 20 20 20 20 20 20 66  up = 0.        f
1470: 6f 72 20 69 2c 20 73 54 6f 6b 65 6e 20 69 6e 20  or i, sToken in 
1480: 65 6e 75 6d 65 72 61 74 65 28 6c 54 6f 6b 65 6e  enumerate(lToken
1490: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  ):.            i
14a0: 66 20 73 54 6f 6b 65 6e 2e 73 74 61 72 74 73 77  f sToken.startsw
14b0: 69 74 68 28 22 28 22 29 20 61 6e 64 20 73 54 6f  ith("(") and sTo
14c0: 6b 65 6e 2e 65 6e 64 73 77 69 74 68 28 22 29 22  ken.endswith(")"
14d0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
14e0: 20 20 20 6c 54 6f 6b 65 6e 5b 69 5d 20 3d 20 73     lToken[i] = s
14f0: 54 6f 6b 65 6e 5b 31 3a 2d 31 5d 0a 20 20 20 20  Token[1:-1].    
1500: 20 20 20 20 20 20 20 20 20 20 20 20 69 47 72 6f              iGro
1510: 75 70 20 2b 3d 20 31 0a 20 20 20 20 20 20 20 20  up += 1.        
1520: 20 20 20 20 20 20 20 20 64 50 6f 73 5b 69 47 72          dPos[iGr
1530: 6f 75 70 5d 20 3d 20 69 20 2b 20 31 20 20 20 20  oup] = i + 1    
1540: 23 20 77 65 20 61 64 64 20 31 2c 20 66 6f 72 20  # we add 1, for 
1550: 77 65 20 63 6f 75 6e 74 20 74 6f 6b 65 6e 73 20  we count tokens 
1560: 66 72 6f 6d 20 31 20 74 6f 20 6e 20 28 6e 6f 74  from 1 to n (not
1570: 20 66 72 6f 6d 20 30 29 0a 0a 20 20 20 20 20 20   from 0)..      
1580: 20 20 23 20 50 61 72 73 65 20 61 63 74 69 6f 6e    # Parse action
1590: 73 0a 20 20 20 20 20 20 20 20 66 6f 72 20 69 41  s.        for iA
15a0: 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 20 69  ction, sAction i
15b0: 6e 20 65 6e 75 6d 65 72 61 74 65 28 73 41 63 74  n enumerate(sAct
15c0: 69 6f 6e 73 2e 73 70 6c 69 74 28 22 20 3c 3c 2d  ions.split(" <<-
15d0: 20 22 29 29 3a 0a 20 20 20 20 20 20 20 20 20 20   ")):.          
15e0: 20 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74    sAction = sAct
15f0: 69 6f 6e 2e 73 74 72 69 70 28 29 0a 20 20 20 20  ion.strip().    
1600: 20 20 20 20 20 20 20 20 69 66 20 73 41 63 74 69          if sActi
1610: 6f 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  on:.            
1620: 20 20 20 20 73 41 63 74 69 6f 6e 49 64 20 3d 20      sActionId = 
1630: 73 52 75 6c 65 4e 61 6d 65 20 2b 20 22 5f 5f 62  sRuleName + "__b
1640: 22 20 2b 20 73 74 72 28 69 41 63 74 69 6f 6e 42  " + str(iActionB
1650: 6c 6f 63 6b 29 20 2b 20 22 5f 61 22 20 2b 20 73  lock) + "_a" + s
1660: 74 72 28 69 41 63 74 69 6f 6e 29 20 2b 20 22 5f  tr(iAction) + "_
1670: 22 20 2b 20 73 74 72 28 6c 65 6e 28 6c 54 6f 6b  " + str(len(lTok
1680: 65 6e 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  en)).           
1690: 20 20 20 20 20 61 41 63 74 69 6f 6e 20 3d 20 63       aAction = c
16a0: 72 65 61 74 65 41 63 74 69 6f 6e 28 73 41 63 74  reateAction(sAct
16b0: 69 6f 6e 49 64 2c 20 73 41 63 74 69 6f 6e 2c 20  ionId, sAction, 
16c0: 6e 50 72 69 6f 72 69 74 79 2c 20 6c 65 6e 28 6c  nPriority, len(l
16d0: 54 6f 6b 65 6e 29 2c 20 64 50 6f 73 29 0a 20 20  Token), dPos).  
16e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
16f0: 20 61 41 63 74 69 6f 6e 3a 0a 20 20 20 20 20 20   aAction:.      
1700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64 41                dA
1710: 43 54 49 4f 4e 53 5b 73 41 63 74 69 6f 6e 49 64  CTIONS[sActionId
1720: 5d 20 3d 20 61 41 63 74 69 6f 6e 0a 20 20 20 20  ] = aAction.    
1730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1740: 6c 52 65 73 75 6c 74 20 3d 20 6c 69 73 74 28 6c  lResult = list(l
1750: 54 6f 6b 65 6e 29 0a 20 20 20 20 20 20 20 20 20  Token).         
1760: 20 20 20 20 20 20 20 20 20 20 20 6c 52 65 73 75             lResu
1770: 6c 74 2e 65 78 74 65 6e 64 28 5b 22 23 23 22 2b  lt.extend(["##"+
1780: 73 74 72 28 69 4c 69 6e 65 29 2c 20 73 41 63 74  str(iLine), sAct
1790: 69 6f 6e 49 64 5d 29 0a 20 20 20 20 20 20 20 20  ionId]).        
17a0: 20 20 20 20 20 20 20 20 20 20 20 20 79 69 65 6c              yiel
17b0: 64 20 6c 52 65 73 75 6c 74 0a 20 20 20 20 20 20  d lResult.      
17c0: 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a            else:.
17d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17e0: 20 20 20 20 70 72 69 6e 74 28 22 20 23 20 45 72      print(" # Er
17f0: 72 6f 72 20 6f 6e 20 61 63 74 69 6f 6e 20 61 74  ror on action at
1800: 20 6c 69 6e 65 3a 22 2c 20 69 4c 69 6e 65 29 0a   line:", iLine).
1810: 0a 0a 64 65 66 20 63 68 61 6e 67 65 52 65 66 65  ..def changeRefe
1820: 72 65 6e 63 65 54 6f 6b 65 6e 20 28 73 54 65 78  renceToken (sTex
1830: 74 2c 20 64 50 6f 73 29 3a 0a 20 20 20 20 22 63  t, dPos):.    "c
1840: 68 61 6e 67 65 20 67 72 6f 75 70 20 72 65 66 65  hange group refe
1850: 72 65 6e 63 65 20 69 6e 20 3c 73 54 65 78 74 3e  rence in <sText>
1860: 20 77 69 74 68 20 76 61 6c 75 65 73 20 69 6e 20   with values in 
1870: 3c 64 50 6f 73 3e 22 0a 20 20 20 20 66 6f 72 20  <dPos>".    for 
1880: 69 20 69 6e 20 72 61 6e 67 65 28 6c 65 6e 28 64  i in range(len(d
1890: 50 6f 73 29 2c 20 30 2c 20 2d 31 29 3a 0a 20 20  Pos), 0, -1):.  
18a0: 20 20 20 20 20 20 73 54 65 78 74 20 3d 20 73 54        sText = sT
18b0: 65 78 74 2e 72 65 70 6c 61 63 65 28 22 5c 5c 22  ext.replace("\\"
18c0: 2b 73 74 72 28 69 29 2c 20 22 5c 5c 22 2b 73 74  +str(i), "\\"+st
18d0: 72 28 64 50 6f 73 5b 69 5d 29 29 0a 20 20 20 20  r(dPos[i])).    
18e0: 72 65 74 75 72 6e 20 73 54 65 78 74 0a 0a 0a 64  return sText...d
18f0: 65 66 20 63 68 65 63 6b 54 6f 6b 65 6e 4e 75 6d  ef checkTokenNum
1900: 62 65 72 73 20 28 73 54 65 78 74 2c 20 73 41 63  bers (sText, sAc
1910: 74 69 6f 6e 49 64 2c 20 6e 54 6f 6b 65 6e 29 3a  tionId, nToken):
1920: 0a 20 20 20 20 22 63 68 65 63 6b 20 69 66 20 74  .    "check if t
1930: 6f 6b 65 6e 20 72 65 66 65 72 65 6e 63 65 73 20  oken references 
1940: 69 6e 20 3c 73 54 65 78 74 3e 20 67 72 65 61 74  in <sText> great
1950: 65 72 20 74 68 61 6e 20 3c 6e 54 6f 6b 65 6e 3e  er than <nToken>
1960: 20 28 64 65 62 75 67 67 69 6e 67 29 22 0a 20 20   (debugging)".  
1970: 20 20 66 6f 72 20 78 20 69 6e 20 72 65 2e 66 69    for x in re.fi
1980: 6e 64 69 74 65 72 28 72 22 5c 5c 28 5c 64 2b 29  nditer(r"\\(\d+)
1990: 22 2c 20 73 54 65 78 74 29 3a 0a 20 20 20 20 20  ", sText):.     
19a0: 20 20 20 69 66 20 69 6e 74 28 78 2e 67 72 6f 75     if int(x.grou
19b0: 70 28 31 29 29 20 3e 20 6e 54 6f 6b 65 6e 3a 0a  p(1)) > nToken:.
19c0: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
19d0: 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20 74 6f  t("# Error in to
19e0: 6b 65 6e 20 69 6e 64 65 78 20 61 74 20 6c 69 6e  ken index at lin
19f0: 65 20 22 20 2b 20 73 41 63 74 69 6f 6e 49 64 20  e " + sActionId 
1a00: 2b 20 22 20 28 22 2b 73 74 72 28 6e 54 6f 6b 65  + " ("+str(nToke
1a10: 6e 29 2b 22 20 74 6f 6b 65 6e 73 20 6f 6e 6c 79  n)+" tokens only
1a20: 29 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  )").            
1a30: 70 72 69 6e 74 28 73 54 65 78 74 29 0a 0a 0a 64  print(sText)...d
1a40: 65 66 20 63 68 65 63 6b 49 66 54 68 65 72 65 49  ef checkIfThereI
1a50: 73 43 6f 64 65 20 28 73 54 65 78 74 2c 20 73 41  sCode (sText, sA
1a60: 63 74 69 6f 6e 49 64 29 3a 0a 20 20 20 20 22 63  ctionId):.    "c
1a70: 68 65 63 6b 20 69 66 20 74 68 65 72 65 20 69 73  heck if there is
1a80: 20 63 6f 64 65 20 69 6e 20 3c 73 54 65 78 74 3e   code in <sText>
1a90: 20 28 64 65 62 75 67 67 69 6e 67 29 22 0a 20 20   (debugging)".  
1aa0: 20 20 69 66 20 72 65 2e 73 65 61 72 63 68 28 22    if re.search("
1ab0: 5b 2e 5d 5c 5c 77 2b 5b 28 5d 7c 73 75 67 67 5c  [.]\\w+[(]|sugg\
1ac0: 5c 77 2b 5b 28 5d 7c 5c 5c 28 5b 30 2d 39 5d 7c  \w+[(]|\\([0-9]|
1ad0: 5c 5c 5b 5b 30 2d 39 5d 22 2c 20 73 54 65 78 74  \\[[0-9]", sText
1ae0: 29 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  ):.        print
1af0: 28 22 23 20 57 61 72 6e 69 6e 67 20 61 74 20 6c  ("# Warning at l
1b00: 69 6e 65 20 22 20 2b 20 73 41 63 74 69 6f 6e 49  ine " + sActionI
1b10: 64 20 2b 20 22 3a 20 20 54 68 69 73 20 6d 65 73  d + ":  This mes
1b20: 73 61 67 65 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20  sage looks like 
1b30: 63 6f 64 65 2e 20 4c 69 6e 65 20 73 68 6f 75 6c  code. Line shoul
1b40: 64 20 70 72 6f 62 61 62 6c 79 20 62 65 67 69 6e  d probably begin
1b50: 20 77 69 74 68 20 3d 22 29 0a 20 20 20 20 20 20   with =").      
1b60: 20 20 70 72 69 6e 74 28 73 54 65 78 74 29 0a 0a    print(sText)..
1b70: 0a 64 65 66 20 63 72 65 61 74 65 41 63 74 69 6f  .def createActio
1b80: 6e 20 28 73 41 63 74 69 6f 6e 49 64 2c 20 73 41  n (sActionId, sA
1b90: 63 74 69 6f 6e 2c 20 6e 50 72 69 6f 72 69 74 79  ction, nPriority
1ba0: 2c 20 6e 54 6f 6b 65 6e 2c 20 64 50 6f 73 29 3a  , nToken, dPos):
1bb0: 0a 20 20 20 20 22 63 72 65 61 74 65 20 61 63 74  .    "create act
1bc0: 69 6f 6e 20 72 75 6c 65 20 61 73 20 61 20 6c 69  ion rule as a li
1bd0: 73 74 22 0a 20 20 20 20 23 20 4f 70 74 69 6f 6e  st".    # Option
1be0: 0a 20 20 20 20 73 4f 70 74 69 6f 6e 20 3d 20 46  .    sOption = F
1bf0: 61 6c 73 65 0a 20 20 20 20 6d 20 3d 20 72 65 2e  alse.    m = re.
1c00: 6d 61 74 63 68 28 22 2f 28 5c 5c 77 2b 29 2f 22  match("/(\\w+)/"
1c10: 2c 20 73 41 63 74 69 6f 6e 29 0a 20 20 20 20 69  , sAction).    i
1c20: 66 20 6d 3a 0a 20 20 20 20 20 20 20 20 73 4f 70  f m:.        sOp
1c30: 74 69 6f 6e 20 3d 20 6d 2e 67 72 6f 75 70 28 31  tion = m.group(1
1c40: 29 0a 20 20 20 20 20 20 20 20 73 41 63 74 69 6f  ).        sActio
1c50: 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 6d 2e 65 6e  n = sAction[m.en
1c60: 64 28 29 3a 5d 2e 73 74 72 69 70 28 29 0a 20 20  d():].strip().  
1c70: 20 20 23 20 76 61 6c 69 64 20 61 63 74 69 6f 6e    # valid action
1c80: 3f 0a 20 20 20 20 6d 20 3d 20 72 65 2e 73 65 61  ?.    m = re.sea
1c90: 72 63 68 28 72 22 28 3f 50 3c 61 63 74 69 6f 6e  rch(r"(?P<action
1ca0: 3e 5b 2d 7e 3d 2f 3e 5d 29 28 3f 50 3c 73 74 61  >[-~=/>])(?P<sta
1cb0: 72 74 3e 5c 64 2b 5c 2e 3f 7c 29 28 3f 50 3c 65  rt>\d+\.?|)(?P<e
1cc0: 6e 64 3e 3a 5c 2e 3f 5c 64 2b 7c 29 3e 3e 22 2c  nd>:\.?\d+|)>>",
1cd0: 20 73 41 63 74 69 6f 6e 29 0a 20 20 20 20 69 66   sAction).    if
1ce0: 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20 20   not m:.        
1cf0: 70 72 69 6e 74 28 22 20 23 20 45 72 72 6f 72 2e  print(" # Error.
1d00: 20 4e 6f 20 61 63 74 69 6f 6e 20 66 6f 75 6e 64   No action found
1d10: 20 61 74 3a 20 22 2c 20 73 41 63 74 69 6f 6e 49   at: ", sActionI
1d20: 64 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  d).        retur
1d30: 6e 20 4e 6f 6e 65 0a 20 20 20 20 23 20 43 6f 6e  n None.    # Con
1d40: 64 69 74 69 6f 6e 0a 20 20 20 20 73 43 6f 6e 64  dition.    sCond
1d50: 69 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b  ition = sAction[
1d60: 3a 6d 2e 73 74 61 72 74 28 29 5d 2e 73 74 72 69  :m.start()].stri
1d70: 70 28 29 0a 20 20 20 20 69 66 20 73 43 6f 6e 64  p().    if sCond
1d80: 69 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 73  ition:.        s
1d90: 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 70 72 65 70  Condition = prep
1da0: 61 72 65 46 75 6e 63 74 69 6f 6e 28 73 43 6f 6e  areFunction(sCon
1db0: 64 69 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20  dition).        
1dc0: 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 63 68 61  sCondition = cha
1dd0: 6e 67 65 52 65 66 65 72 65 6e 63 65 54 6f 6b 65  ngeReferenceToke
1de0: 6e 28 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 64 50  n(sCondition, dP
1df0: 6f 73 29 0a 20 20 20 20 20 20 20 20 64 46 55 4e  os).        dFUN
1e00: 43 54 49 4f 4e 53 5b 22 5f 67 5f 63 5f 22 2b 73  CTIONS["_g_c_"+s
1e10: 41 63 74 69 6f 6e 49 64 5d 20 3d 20 73 43 6f 6e  ActionId] = sCon
1e20: 64 69 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 73  dition.        s
1e30: 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 22 5f 67 5f  Condition = "_g_
1e40: 63 5f 22 2b 73 41 63 74 69 6f 6e 49 64 0a 20 20  c_"+sActionId.  
1e50: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
1e60: 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 22 22 0a  sCondition = "".
1e70: 20 20 20 20 23 20 41 63 74 69 6f 6e 0a 20 20 20      # Action.   
1e80: 20 63 41 63 74 69 6f 6e 20 3d 20 6d 2e 67 72 6f   cAction = m.gro
1e90: 75 70 28 22 61 63 74 69 6f 6e 22 29 0a 20 20 20  up("action").   
1ea0: 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69   sAction = sActi
1eb0: 6f 6e 5b 6d 2e 65 6e 64 28 29 3a 5d 2e 73 74 72  on[m.end():].str
1ec0: 69 70 28 29 0a 20 20 20 20 73 41 63 74 69 6f 6e  ip().    sAction
1ed0: 20 3d 20 63 68 61 6e 67 65 52 65 66 65 72 65 6e   = changeReferen
1ee0: 63 65 54 6f 6b 65 6e 28 73 41 63 74 69 6f 6e 2c  ceToken(sAction,
1ef0: 20 64 50 6f 73 29 0a 20 20 20 20 69 66 20 6e 6f   dPos).    if no
1f00: 74 20 6d 2e 67 72 6f 75 70 28 22 73 74 61 72 74  t m.group("start
1f10: 22 29 3a 0a 20 20 20 20 20 20 20 20 69 53 74 61  "):.        iSta
1f20: 72 74 41 63 74 69 6f 6e 20 3d 20 31 0a 20 20 20  rtAction = 1.   
1f30: 20 20 20 20 20 69 45 6e 64 41 63 74 69 6f 6e 20       iEndAction 
1f40: 3d 20 30 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20  = 0.    else:.  
1f50: 20 20 20 20 20 20 69 66 20 63 41 63 74 69 6f 6e        if cAction
1f60: 20 21 3d 20 22 2d 22 20 61 6e 64 20 28 6d 2e 67   != "-" and (m.g
1f70: 72 6f 75 70 28 22 73 74 61 72 74 22 29 2e 65 6e  roup("start").en
1f80: 64 73 77 69 74 68 28 22 2e 22 29 20 6f 72 20 6d  dswith(".") or m
1f90: 2e 67 72 6f 75 70 28 22 65 6e 64 22 29 2e 73 74  .group("end").st
1fa0: 61 72 74 73 77 69 74 68 28 22 3a 2e 22 29 29 3a  artswith(":.")):
1fb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69  .            pri
1fc0: 6e 74 28 22 20 23 20 45 72 72 6f 72 2e 20 57 72  nt(" # Error. Wr
1fd0: 6f 6e 67 20 73 65 6c 65 63 74 69 6f 6e 20 6f 6e  ong selection on
1fe0: 20 74 6f 6b 65 6e 73 2e 22 2c 20 73 41 63 74 69   tokens.", sActi
1ff0: 6f 6e 49 64 29 0a 20 20 20 20 20 20 20 20 20 20  onId).          
2000: 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20    return None.  
2010: 20 20 20 20 20 20 69 53 74 61 72 74 41 63 74 69        iStartActi
2020: 6f 6e 20 3d 20 69 6e 74 28 6d 2e 67 72 6f 75 70  on = int(m.group
2030: 28 22 73 74 61 72 74 22 29 29 20 20 69 66 20 6e  ("start"))  if n
2040: 6f 74 20 6d 2e 67 72 6f 75 70 28 22 73 74 61 72  ot m.group("star
2050: 74 22 29 2e 65 6e 64 73 77 69 74 68 28 22 2e 22  t").endswith("."
2060: 29 20 20 65 6c 73 65 20 69 6e 74 28 22 2d 22 2b  )  else int("-"+
2070: 6d 2e 67 72 6f 75 70 28 22 73 74 61 72 74 22 29  m.group("start")
2080: 5b 3a 2d 31 5d 29 0a 20 20 20 20 20 20 20 20 69  [:-1]).        i
2090: 66 20 6e 6f 74 20 6d 2e 67 72 6f 75 70 28 22 65  f not m.group("e
20a0: 6e 64 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  nd"):.          
20b0: 20 20 69 45 6e 64 41 63 74 69 6f 6e 20 3d 20 69    iEndAction = i
20c0: 53 74 61 72 74 41 63 74 69 6f 6e 0a 20 20 20 20  StartAction.    
20d0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
20e0: 20 20 20 20 20 20 69 45 6e 64 41 63 74 69 6f 6e        iEndAction
20f0: 20 3d 20 69 6e 74 28 6d 2e 67 72 6f 75 70 28 22   = int(m.group("
2100: 65 6e 64 22 29 5b 31 3a 5d 29 20 20 69 66 20 6e  end")[1:])  if n
2110: 6f 74 20 6d 2e 67 72 6f 75 70 28 22 65 6e 64 22  ot m.group("end"
2120: 29 2e 73 74 61 72 74 73 77 69 74 68 28 22 3a 2e  ).startswith(":.
2130: 22 29 20 20 65 6c 73 65 20 69 6e 74 28 22 2d 22  ")  else int("-"
2140: 20 2b 20 6d 2e 67 72 6f 75 70 28 22 65 6e 64 22   + m.group("end"
2150: 29 5b 32 3a 5d 29 0a 20 20 20 20 69 66 20 64 50  )[2:]).    if dP
2160: 6f 73 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28 22  os and m.group("
2170: 73 74 61 72 74 22 29 3a 0a 20 20 20 20 20 20 20  start"):.       
2180: 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 20 20   try:.          
2190: 20 20 69 53 74 61 72 74 41 63 74 69 6f 6e 20 3d    iStartAction =
21a0: 20 64 50 6f 73 5b 69 53 74 61 72 74 41 63 74 69   dPos[iStartActi
21b0: 6f 6e 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  on].            
21c0: 69 66 20 69 45 6e 64 41 63 74 69 6f 6e 3a 0a 20  if iEndAction:. 
21d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
21e0: 45 6e 64 41 63 74 69 6f 6e 20 3d 20 64 50 6f 73  EndAction = dPos
21f0: 5b 69 45 6e 64 41 63 74 69 6f 6e 5d 0a 20 20 20  [iEndAction].   
2200: 20 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20 20       except:.   
2210: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
2220: 23 20 45 72 72 6f 72 2e 20 57 72 6f 6e 67 20 67  # Error. Wrong g
2230: 72 6f 75 70 73 20 69 6e 3a 20 22 20 2b 20 73 41  roups in: " + sA
2240: 63 74 69 6f 6e 49 64 29 0a 20 20 20 20 20 20 20  ctionId).       
2250: 20 20 20 20 20 70 72 69 6e 74 28 22 20 20 69 53       print("  iS
2260: 74 61 72 74 41 63 74 69 6f 6e 3a 22 2c 20 69 53  tartAction:", iS
2270: 74 61 72 74 41 63 74 69 6f 6e 2c 20 22 69 45 6e  tartAction, "iEn
2280: 64 41 63 74 69 6f 6e 3a 22 2c 20 69 45 6e 64 41  dAction:", iEndA
2290: 63 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 20  ction).         
22a0: 20 20 20 70 72 69 6e 74 28 22 20 22 2c 20 64 50     print(" ", dP
22b0: 6f 73 29 0a 0a 20 20 20 20 69 66 20 63 41 63 74  os)..    if cAct
22c0: 69 6f 6e 20 3d 3d 20 22 2d 22 3a 0a 20 20 20 20  ion == "-":.    
22d0: 20 20 20 20 23 23 20 65 72 72 6f 72 0a 20 20 20      ## error.   
22e0: 20 20 20 20 20 69 4d 73 67 20 3d 20 73 41 63 74       iMsg = sAct
22f0: 69 6f 6e 2e 66 69 6e 64 28 22 20 23 20 22 29 0a  ion.find(" # ").
2300: 20 20 20 20 20 20 20 20 69 66 20 69 4d 73 67 20          if iMsg 
2310: 3d 3d 20 2d 31 3a 0a 20 20 20 20 20 20 20 20 20  == -1:.         
2320: 20 20 20 73 4d 73 67 20 3d 20 22 23 20 45 72 72     sMsg = "# Err
2330: 6f 72 2e 20 45 72 72 6f 72 20 6d 65 73 73 61 67  or. Error messag
2340: 65 20 6e 6f 74 20 66 6f 75 6e 64 2e 22 0a 20 20  e not found.".  
2350: 20 20 20 20 20 20 20 20 20 20 73 55 52 4c 20 3d            sURL =
2360: 20 22 22 0a 20 20 20 20 20 20 20 20 20 20 20 20   "".            
2370: 70 72 69 6e 74 28 73 4d 73 67 20 2b 20 22 20 41  print(sMsg + " A
2380: 63 74 69 6f 6e 20 69 64 3a 20 22 20 2b 20 73 41  ction id: " + sA
2390: 63 74 69 6f 6e 49 64 29 0a 20 20 20 20 20 20 20  ctionId).       
23a0: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
23b0: 20 20 20 73 4d 73 67 20 3d 20 73 41 63 74 69 6f     sMsg = sActio
23c0: 6e 5b 69 4d 73 67 2b 33 3a 5d 2e 73 74 72 69 70  n[iMsg+3:].strip
23d0: 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ().            s
23e0: 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e  Action = sAction
23f0: 5b 3a 69 4d 73 67 5d 2e 73 74 72 69 70 28 29 0a  [:iMsg].strip().
2400: 20 20 20 20 20 20 20 20 20 20 20 20 73 55 52 4c              sURL
2410: 20 3d 20 22 22 0a 20 20 20 20 20 20 20 20 20 20   = "".          
2420: 20 20 6d 55 52 4c 20 3d 20 72 65 2e 73 65 61 72    mURL = re.sear
2430: 63 68 28 22 5b 7c 5d 20 2a 28 68 74 74 70 73 3f  ch("[|] *(https?
2440: 3a 2f 2f 2e 2a 29 22 2c 20 73 4d 73 67 29 0a 20  ://.*)", sMsg). 
2450: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6d 55             if mU
2460: 52 4c 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  RL:.            
2470: 20 20 20 20 73 55 52 4c 20 3d 20 6d 55 52 4c 2e      sURL = mURL.
2480: 67 72 6f 75 70 28 31 29 2e 73 74 72 69 70 28 29  group(1).strip()
2490: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
24a0: 20 73 4d 73 67 20 3d 20 73 4d 73 67 5b 3a 6d 55   sMsg = sMsg[:mU
24b0: 52 4c 2e 73 74 61 72 74 28 30 29 5d 2e 73 74 72  RL.start(0)].str
24c0: 69 70 28 29 0a 20 20 20 20 20 20 20 20 20 20 20  ip().           
24d0: 20 63 68 65 63 6b 54 6f 6b 65 6e 4e 75 6d 62 65   checkTokenNumbe
24e0: 72 73 28 73 4d 73 67 2c 20 73 41 63 74 69 6f 6e  rs(sMsg, sAction
24f0: 49 64 2c 20 6e 54 6f 6b 65 6e 29 0a 20 20 20 20  Id, nToken).    
2500: 20 20 20 20 20 20 20 20 69 66 20 73 4d 73 67 5b          if sMsg[
2510: 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20  0:1] == "=":.   
2520: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 4d 73               sMs
2530: 67 20 3d 20 70 72 65 70 61 72 65 46 75 6e 63 74  g = prepareFunct
2540: 69 6f 6e 28 73 4d 73 67 5b 31 3a 5d 2c 20 54 72  ion(sMsg[1:], Tr
2550: 75 65 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  ue).            
2560: 20 20 20 20 64 46 55 4e 43 54 49 4f 4e 53 5b 22      dFUNCTIONS["
2570: 67 5f 6d 5f 22 2b 73 41 63 74 69 6f 6e 49 64 5d  g_m_"+sActionId]
2580: 20 3d 20 73 4d 73 67 0a 20 20 20 20 20 20 20 20   = sMsg.        
2590: 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 22          sMsg = "
25a0: 3d 67 5f 6d 5f 22 2b 73 41 63 74 69 6f 6e 49 64  =g_m_"+sActionId
25b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
25c0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
25d0: 20 20 20 63 68 65 63 6b 49 66 54 68 65 72 65 49     checkIfThereI
25e0: 73 43 6f 64 65 28 73 4d 73 67 2c 20 73 41 63 74  sCode(sMsg, sAct
25f0: 69 6f 6e 49 64 29 0a 0a 20 20 20 20 23 20 63 68  ionId)..    # ch
2600: 65 63 6b 69 6e 67 20 63 6f 6e 73 69 73 74 61 6e  ecking consistan
2610: 63 79 0a 20 20 20 20 63 68 65 63 6b 54 6f 6b 65  cy.    checkToke
2620: 6e 4e 75 6d 62 65 72 73 28 73 41 63 74 69 6f 6e  nNumbers(sAction
2630: 2c 20 73 41 63 74 69 6f 6e 49 64 2c 20 6e 54 6f  , sActionId, nTo
2640: 6b 65 6e 29 0a 0a 20 20 20 20 69 66 20 63 41 63  ken)..    if cAc
2650: 74 69 6f 6e 20 3d 3d 20 22 3e 22 3a 0a 20 20 20  tion == ">":.   
2660: 20 20 20 20 20 23 23 20 6e 6f 20 61 63 74 69 6f       ## no actio
2670: 6e 2c 20 62 72 65 61 6b 20 6c 6f 6f 70 20 69 66  n, break loop if
2680: 20 63 6f 6e 64 69 74 69 6f 6e 20 69 73 20 46 61   condition is Fa
2690: 6c 73 65 0a 20 20 20 20 20 20 20 20 72 65 74 75  lse.        retu
26a0: 72 6e 20 5b 73 4f 70 74 69 6f 6e 2c 20 73 43 6f  rn [sOption, sCo
26b0: 6e 64 69 74 69 6f 6e 2c 20 63 41 63 74 69 6f 6e  ndition, cAction
26c0: 2c 20 22 22 5d 0a 0a 20 20 20 20 69 66 20 6e 6f  , ""]..    if no
26d0: 74 20 73 41 63 74 69 6f 6e 3a 0a 20 20 20 20 20  t sAction:.     
26e0: 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f     print("# Erro
26f0: 72 20 69 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c  r in action at l
2700: 69 6e 65 20 22 20 2b 20 73 41 63 74 69 6f 6e 49  ine " + sActionI
2710: 64 20 2b 20 22 3a 20 20 54 68 69 73 20 61 63 74  d + ":  This act
2720: 69 6f 6e 20 69 73 20 65 6d 70 74 79 2e 22 29 0a  ion is empty.").
2730: 0a 20 20 20 20 69 66 20 73 41 63 74 69 6f 6e 5b  .    if sAction[
2740: 30 3a 31 5d 20 21 3d 20 22 3d 22 20 61 6e 64 20  0:1] != "=" and 
2750: 63 41 63 74 69 6f 6e 20 21 3d 20 22 3d 22 3a 0a  cAction != "=":.
2760: 20 20 20 20 20 20 20 20 63 68 65 63 6b 49 66 54          checkIfT
2770: 68 65 72 65 49 73 43 6f 64 65 28 73 41 63 74 69  hereIsCode(sActi
2780: 6f 6e 2c 20 73 41 63 74 69 6f 6e 49 64 29 0a 0a  on, sActionId)..
2790: 20 20 20 20 69 66 20 63 41 63 74 69 6f 6e 20 3d      if cAction =
27a0: 3d 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 23  = "-":.        #
27b0: 23 20 65 72 72 6f 72 20 64 65 74 65 63 74 65 64  # error detected
27c0: 20 2d 2d 3e 20 73 75 67 67 65 73 74 69 6f 6e 0a   --> suggestion.
27d0: 20 20 20 20 20 20 20 20 69 66 20 73 41 63 74 69          if sActi
27e0: 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a  on[0:1] == "=":.
27f0: 20 20 20 20 20 20 20 20 20 20 20 20 73 41 63 74              sAct
2800: 69 6f 6e 20 3d 20 70 72 65 70 61 72 65 46 75 6e  ion = prepareFun
2810: 63 74 69 6f 6e 28 73 41 63 74 69 6f 6e 2c 20 54  ction(sAction, T
2820: 72 75 65 29 0a 20 20 20 20 20 20 20 20 20 20 20  rue).           
2830: 20 64 46 55 4e 43 54 49 4f 4e 53 5b 22 5f 67 5f   dFUNCTIONS["_g_
2840: 73 5f 22 2b 73 41 63 74 69 6f 6e 49 64 5d 20 3d  s_"+sActionId] =
2850: 20 73 41 63 74 69 6f 6e 5b 31 3a 5d 0a 20 20 20   sAction[1:].   
2860: 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e           sAction
2870: 20 3d 20 22 3d 5f 67 5f 73 5f 22 2b 73 41 63 74   = "=_g_s_"+sAct
2880: 69 6f 6e 49 64 0a 20 20 20 20 20 20 20 20 65 6c  ionId.        el
2890: 69 66 20 73 41 63 74 69 6f 6e 2e 73 74 61 72 74  if sAction.start
28a0: 73 77 69 74 68 28 27 22 27 29 20 61 6e 64 20 73  swith('"') and s
28b0: 41 63 74 69 6f 6e 2e 65 6e 64 73 77 69 74 68 28  Action.endswith(
28c0: 27 22 27 29 3a 0a 20 20 20 20 20 20 20 20 20 20  '"'):.          
28d0: 20 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74    sAction = sAct
28e0: 69 6f 6e 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20  ion[1:-1].      
28f0: 20 20 69 66 20 6e 6f 74 20 73 4d 73 67 3a 0a 20    if not sMsg:. 
2900: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
2910: 28 22 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74  ("# Error in act
2920: 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ion at line " + 
2930: 73 41 63 74 69 6f 6e 49 64 20 2b 20 22 3a 20 20  sActionId + ":  
2940: 54 68 65 20 6d 65 73 73 61 67 65 20 69 73 20 65  The message is e
2950: 6d 70 74 79 2e 22 29 0a 20 20 20 20 20 20 20 20  mpty.").        
2960: 72 65 74 75 72 6e 20 5b 73 4f 70 74 69 6f 6e 2c  return [sOption,
2970: 20 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 63 41 63   sCondition, cAc
2980: 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 2c 20 69  tion, sAction, i
2990: 53 74 61 72 74 41 63 74 69 6f 6e 2c 20 69 45 6e  StartAction, iEn
29a0: 64 41 63 74 69 6f 6e 2c 20 6e 50 72 69 6f 72 69  dAction, nPriori
29b0: 74 79 2c 20 73 4d 73 67 2c 20 73 55 52 4c 5d 0a  ty, sMsg, sURL].
29c0: 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e      elif cAction
29d0: 20 3d 3d 20 22 7e 22 3a 0a 20 20 20 20 20 20 20   == "~":.       
29e0: 20 23 23 20 74 65 78 74 20 70 72 6f 63 65 73 73   ## text process
29f0: 6f 72 0a 20 20 20 20 20 20 20 20 69 66 20 73 41  or.        if sA
2a00: 63 74 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d  ction[0:1] == "=
2a10: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ":.            s
2a20: 41 63 74 69 6f 6e 20 3d 20 70 72 65 70 61 72 65  Action = prepare
2a30: 46 75 6e 63 74 69 6f 6e 28 73 41 63 74 69 6f 6e  Function(sAction
2a40: 2c 20 54 72 75 65 29 0a 20 20 20 20 20 20 20 20  , True).        
2a50: 20 20 20 20 64 46 55 4e 43 54 49 4f 4e 53 5b 22      dFUNCTIONS["
2a60: 5f 67 5f 70 5f 22 2b 73 41 63 74 69 6f 6e 49 64  _g_p_"+sActionId
2a70: 5d 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a 5d 0a  ] = sAction[1:].
2a80: 20 20 20 20 20 20 20 20 20 20 20 20 73 41 63 74              sAct
2a90: 69 6f 6e 20 3d 20 22 3d 5f 67 5f 70 5f 22 2b 73  ion = "=_g_p_"+s
2aa0: 41 63 74 69 6f 6e 49 64 0a 20 20 20 20 20 20 20  ActionId.       
2ab0: 20 65 6c 69 66 20 73 41 63 74 69 6f 6e 2e 73 74   elif sAction.st
2ac0: 61 72 74 73 77 69 74 68 28 27 22 27 29 20 61 6e  artswith('"') an
2ad0: 64 20 73 41 63 74 69 6f 6e 2e 65 6e 64 73 77 69  d sAction.endswi
2ae0: 74 68 28 27 22 27 29 3a 0a 20 20 20 20 20 20 20  th('"'):.       
2af0: 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 73       sAction = s
2b00: 41 63 74 69 6f 6e 5b 31 3a 2d 31 5d 0a 20 20 20  Action[1:-1].   
2b10: 20 20 20 20 20 72 65 74 75 72 6e 20 5b 73 4f 70       return [sOp
2b20: 74 69 6f 6e 2c 20 73 43 6f 6e 64 69 74 69 6f 6e  tion, sCondition
2b30: 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41 63 74 69  , cAction, sActi
2b40: 6f 6e 2c 20 69 53 74 61 72 74 41 63 74 69 6f 6e  on, iStartAction
2b50: 2c 20 69 45 6e 64 41 63 74 69 6f 6e 5d 0a 20 20  , iEndAction].  
2b60: 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 20 3d    elif cAction =
2b70: 3d 20 22 2f 22 3a 0a 20 20 20 20 20 20 20 20 23  = "/":.        #
2b80: 23 20 74 61 67 73 0a 20 20 20 20 20 20 20 20 72  # tags.        r
2b90: 65 74 75 72 6e 20 5b 73 4f 70 74 69 6f 6e 2c 20  eturn [sOption, 
2ba0: 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 63 41 63 74  sCondition, cAct
2bb0: 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 2c 20 69 53  ion, sAction, iS
2bc0: 74 61 72 74 41 63 74 69 6f 6e 2c 20 69 45 6e 64  tartAction, iEnd
2bd0: 41 63 74 69 6f 6e 5d 0a 20 20 20 20 65 6c 69 66  Action].    elif
2be0: 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3d 22 3a   cAction == "=":
2bf0: 0a 20 20 20 20 20 20 20 20 23 23 20 64 69 73 61  .        ## disa
2c00: 6d 62 69 67 75 61 74 6f 72 0a 20 20 20 20 20 20  mbiguator.      
2c10: 20 20 69 66 20 73 41 63 74 69 6f 6e 5b 30 3a 31    if sAction[0:1
2c20: 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20  ] == "=":.      
2c30: 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20        sAction = 
2c40: 73 41 63 74 69 6f 6e 5b 31 3a 5d 0a 20 20 20 20  sAction[1:].    
2c50: 20 20 20 20 69 66 20 22 64 65 66 69 6e 65 22 20      if "define" 
2c60: 69 6e 20 73 41 63 74 69 6f 6e 20 61 6e 64 20 6e  in sAction and n
2c70: 6f 74 20 72 65 2e 73 65 61 72 63 68 28 72 22 64  ot re.search(r"d
2c80: 65 66 69 6e 65 5c 28 5c 5c 5c 64 2b 20 2a 2c 20  efine\(\\\d+ *, 
2c90: 2a 5c 5b 2e 2a 5c 5d 20 2a 5c 29 22 2c 20 73 41  *\[.*\] *\)", sA
2ca0: 63 74 69 6f 6e 29 3a 0a 20 20 20 20 20 20 20 20  ction):.        
2cb0: 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72      print("# Err
2cc0: 6f 72 20 69 6e 20 61 63 74 69 6f 6e 20 61 74 20  or in action at 
2cd0: 6c 69 6e 65 20 22 20 2b 20 73 41 63 74 69 6f 6e  line " + sAction
2ce0: 49 64 20 2b 20 22 3a 20 73 65 63 6f 6e 64 20 61  Id + ": second a
2cf0: 72 67 75 6d 65 6e 74 20 66 6f 72 20 3c 64 65 66  rgument for <def
2d00: 69 6e 65 3e 20 6d 75 73 74 20 62 65 20 61 20 6c  ine> must be a l
2d10: 69 73 74 20 6f 66 20 73 74 72 69 6e 67 73 22 29  ist of strings")
2d20: 0a 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e  .        sAction
2d30: 20 3d 20 70 72 65 70 61 72 65 46 75 6e 63 74 69   = prepareFuncti
2d40: 6f 6e 28 73 41 63 74 69 6f 6e 29 0a 20 20 20 20  on(sAction).    
2d50: 20 20 20 20 64 46 55 4e 43 54 49 4f 4e 53 5b 22      dFUNCTIONS["
2d60: 5f 67 5f 64 5f 22 2b 73 41 63 74 69 6f 6e 49 64  _g_d_"+sActionId
2d70: 5d 20 3d 20 73 41 63 74 69 6f 6e 0a 20 20 20 20  ] = sAction.    
2d80: 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 22 5f      sAction = "_
2d90: 67 5f 64 5f 22 2b 73 41 63 74 69 6f 6e 49 64 0a  g_d_"+sActionId.
2da0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b          return [
2db0: 73 4f 70 74 69 6f 6e 2c 20 73 43 6f 6e 64 69 74  sOption, sCondit
2dc0: 69 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41  ion, cAction, sA
2dd0: 63 74 69 6f 6e 5d 0a 20 20 20 20 65 6c 73 65 3a  ction].    else:
2de0: 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22  .        print("
2df0: 20 23 20 55 6e 6b 6e 6f 77 6e 20 61 63 74 69 6f   # Unknown actio
2e00: 6e 2e 22 2c 20 73 41 63 74 69 6f 6e 49 64 29 0a  n.", sActionId).
2e10: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e          return N
2e20: 6f 6e 65 0a 0a 0a 64 65 66 20 6d 61 6b 65 20 28  one...def make (
2e30: 6c 52 75 6c 65 2c 20 64 44 65 66 2c 20 73 4c 61  lRule, dDef, sLa
2e40: 6e 67 2c 20 62 4a 61 76 61 53 63 72 69 70 74 29  ng, bJavaScript)
2e50: 3a 0a 20 20 20 20 22 63 6f 6d 70 69 6c 65 20 72  :.    "compile r
2e60: 75 6c 65 73 2c 20 72 65 74 75 72 6e 73 20 61 20  ules, returns a 
2e70: 64 69 63 74 69 6f 6e 61 72 79 20 6f 66 20 76 61  dictionary of va
2e80: 6c 75 65 73 22 0a 20 20 20 20 23 20 66 6f 72 20  lues".    # for 
2e90: 63 6c 61 72 69 74 79 20 70 75 72 70 6f 73 65 2c  clarity purpose,
2ea0: 20 64 6f 6e e2 80 99 74 20 63 72 65 61 74 65 20   don...t create 
2eb0: 61 6e 79 20 66 69 6c 65 20 68 65 72 65 0a 0a 20  any file here.. 
2ec0: 20 20 20 23 20 72 65 6d 6f 76 69 6e 67 20 63 6f     # removing co
2ed0: 6d 6d 65 6e 74 73 2c 20 7a 65 72 6f 69 6e 67 20  mments, zeroing 
2ee0: 65 6d 70 74 79 20 6c 69 6e 65 73 2c 20 63 72 65  empty lines, cre
2ef0: 61 74 69 6e 67 20 64 65 66 69 6e 69 74 69 6f 6e  ating definition
2f00: 73 2c 20 73 74 6f 72 69 6e 67 20 74 65 73 74 73  s, storing tests
2f10: 2c 20 6d 65 72 67 69 6e 67 20 72 75 6c 65 20 6c  , merging rule l
2f20: 69 6e 65 73 0a 20 20 20 20 70 72 69 6e 74 28 22  ines.    print("
2f30: 20 20 70 61 72 73 69 6e 67 20 72 75 6c 65 73 2e    parsing rules.
2f40: 2e 2e 22 29 0a 20 20 20 20 6c 54 6f 6b 65 6e 4c  ..").    lTokenL
2f50: 69 6e 65 20 3d 20 5b 5d 0a 20 20 20 20 73 41 63  ine = [].    sAc
2f60: 74 69 6f 6e 73 20 3d 20 22 22 0a 20 20 20 20 6e  tions = "".    n
2f70: 50 72 69 6f 72 69 74 79 20 3d 20 34 0a 20 20 20  Priority = 4.   
2f80: 20 64 41 6c 6c 47 72 61 70 68 20 3d 20 7b 7d 0a   dAllGraph = {}.
2f90: 20 20 20 20 73 47 72 61 70 68 4e 61 6d 65 20 3d      sGraphName =
2fa0: 20 22 22 0a 20 20 20 20 69 41 63 74 69 6f 6e 42   "".    iActionB
2fb0: 6c 6f 63 6b 20 3d 20 30 0a 0a 20 20 20 20 66 6f  lock = 0..    fo
2fc0: 72 20 69 2c 20 73 4c 69 6e 65 20 69 6e 20 6c 52  r i, sLine in lR
2fd0: 75 6c 65 3a 0a 20 20 20 20 20 20 20 20 73 4c 69  ule:.        sLi
2fe0: 6e 65 20 3d 20 73 4c 69 6e 65 2e 72 73 74 72 69  ne = sLine.rstri
2ff0: 70 28 29 0a 20 20 20 20 20 20 20 20 69 66 20 22  p().        if "
3000: 5c 74 22 20 69 6e 20 73 4c 69 6e 65 3a 0a 20 20  \t" in sLine:.  
3010: 20 20 20 20 20 20 20 20 20 20 23 20 74 61 62 75            # tabu
3020: 6c 61 74 69 6f 6e 20 6e 6f 74 20 61 6c 6c 6f 77  lation not allow
3030: 65 64 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  ed.            p
3040: 72 69 6e 74 28 22 45 72 72 6f 72 2e 20 54 61 62  rint("Error. Tab
3050: 75 6c 61 74 69 6f 6e 20 61 74 20 6c 69 6e 65 3a  ulation at line:
3060: 20 22 2c 20 69 29 0a 20 20 20 20 20 20 20 20 20   ", i).         
3070: 20 20 20 65 78 69 74 28 29 0a 20 20 20 20 20 20     exit().      
3080: 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61    elif sLine.sta
3090: 72 74 73 77 69 74 68 28 22 40 40 40 40 47 52 41  rtswith("@@@@GRA
30a0: 50 48 3a 20 22 29 3a 0a 20 20 20 20 20 20 20 20  PH: "):.        
30b0: 20 20 20 20 23 20 72 75 6c 65 73 20 67 72 61 70      # rules grap
30c0: 68 20 63 61 6c 6c 0a 20 20 20 20 20 20 20 20 20  h call.         
30d0: 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28     m = re.match(
30e0: 72 22 40 40 40 40 47 52 41 50 48 3a 20 2a 28 5c  r"@@@@GRAPH: *(\
30f0: 77 2b 29 22 2c 20 73 4c 69 6e 65 2e 73 74 72 69  w+)", sLine.stri
3100: 70 28 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  p()).           
3110: 20 69 66 20 6d 3a 0a 20 20 20 20 20 20 20 20 20   if m:.         
3120: 20 20 20 20 20 20 20 73 47 72 61 70 68 4e 61 6d         sGraphNam
3130: 65 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29 0a 20  e = m.group(1). 
3140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
3150: 66 20 73 47 72 61 70 68 4e 61 6d 65 20 69 6e 20  f sGraphName in 
3160: 64 41 6c 6c 47 72 61 70 68 3a 0a 20 20 20 20 20  dAllGraph:.     
3170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
3180: 72 69 6e 74 28 22 45 72 72 6f 72 2e 20 47 72 6f  rint("Error. Gro
3190: 75 70 20 6e 61 6d 65 20 22 20 2b 20 73 47 72 61  up name " + sGra
31a0: 70 68 4e 61 6d 65 20 2b 20 22 20 61 6c 72 65 61  phName + " alrea
31b0: 64 79 20 65 78 69 73 74 73 2e 22 29 0a 20 20 20  dy exists.").   
31c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
31d0: 20 65 78 69 74 28 29 0a 20 20 20 20 20 20 20 20   exit().        
31e0: 20 20 20 20 20 20 20 20 64 41 6c 6c 47 72 61 70          dAllGrap
31f0: 68 5b 73 47 72 61 70 68 4e 61 6d 65 5d 20 3d 20  h[sGraphName] = 
3200: 5b 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 65  [].            e
3210: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
3220: 20 20 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f       print("Erro
3230: 72 2e 20 47 72 61 70 68 20 6e 61 6d 65 20 6e 6f  r. Graph name no
3240: 74 20 66 6f 75 6e 64 20 61 74 20 6c 69 6e 65 22  t found at line"
3250: 2c 20 69 29 0a 20 20 20 20 20 20 20 20 20 20 20  , i).           
3260: 20 20 20 20 20 65 78 69 74 28 29 0a 20 20 20 20       exit().    
3270: 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73      elif sLine.s
3280: 74 61 72 74 73 77 69 74 68 28 22 5f 5f 22 29 20  tartswith("__") 
3290: 61 6e 64 20 73 4c 69 6e 65 2e 65 6e 64 73 77 69  and sLine.endswi
32a0: 74 68 28 22 5f 5f 22 29 3a 0a 20 20 20 20 20 20  th("__"):.      
32b0: 20 20 20 20 20 20 23 20 6e 65 77 20 72 75 6c 65        # new rule
32c0: 20 67 72 6f 75 70 0a 20 20 20 20 20 20 20 20 20   group.         
32d0: 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28     m = re.match(
32e0: 22 5f 5f 28 5c 5c 77 2b 29 28 21 5c 5c 64 7c 29  "__(\\w+)(!\\d|)
32f0: 5f 5f 22 2c 20 73 4c 69 6e 65 29 0a 20 20 20 20  __", sLine).    
3300: 20 20 20 20 20 20 20 20 69 66 20 6d 3a 0a 20 20          if m:.  
3310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 52                sR
3320: 75 6c 65 4e 61 6d 65 20 3d 20 6d 2e 67 72 6f 75  uleName = m.grou
3330: 70 28 31 29 0a 20 20 20 20 20 20 20 20 20 20 20  p(1).           
3340: 20 20 20 20 20 69 41 63 74 69 6f 6e 42 6c 6f 63       iActionBloc
3350: 6b 20 3d 20 31 0a 20 20 20 20 20 20 20 20 20 20  k = 1.          
3360: 20 20 20 20 20 20 6e 50 72 69 6f 72 69 74 79 20        nPriority 
3370: 3d 20 69 6e 74 28 6d 2e 67 72 6f 75 70 28 32 29  = int(m.group(2)
3380: 5b 31 3a 5d 29 20 69 66 20 6d 2e 67 72 6f 75 70  [1:]) if m.group
3390: 28 32 29 20 20 65 6c 73 65 20 34 0a 20 20 20 20  (2)  else 4.    
33a0: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
33b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
33c0: 69 6e 74 28 22 45 72 72 6f 72 20 61 74 20 72 75  int("Error at ru
33d0: 6c 65 20 67 72 6f 75 70 3a 20 22 2c 20 73 4c 69  le group: ", sLi
33e0: 6e 65 2c 20 22 20 2d 2d 20 6c 69 6e 65 3a 22 2c  ne, " -- line:",
33f0: 20 69 29 0a 20 20 20 20 20 20 20 20 20 20 20 20   i).            
3400: 20 20 20 20 62 72 65 61 6b 0a 20 20 20 20 20 20      break.      
3410: 20 20 65 6c 69 66 20 72 65 2e 73 65 61 72 63 68    elif re.search
3420: 28 22 5e 20 20 20 20 2b 3c 3c 2d 20 22 2c 20 73  ("^    +<<- ", s
3430: 4c 69 6e 65 29 20 6f 72 20 73 4c 69 6e 65 2e 73  Line) or sLine.s
3440: 74 61 72 74 73 77 69 74 68 28 22 20 20 20 20 20  tartswith("     
3450: 20 20 20 22 29 20 5c 0a 20 20 20 20 20 20 20 20     ") \.        
3460: 20 20 20 20 20 20 20 20 6f 72 20 72 65 2e 73 65          or re.se
3470: 61 72 63 68 28 22 5e 20 20 20 20 2b 23 22 2c 20  arch("^    +#", 
3480: 73 4c 69 6e 65 29 20 6f 72 20 72 65 2e 73 65 61  sLine) or re.sea
3490: 72 63 68 28 72 22 5e 20 20 20 20 5b 2d 7e 3d 3e  rch(r"^    [-~=>
34a0: 2f 5d 28 3f 3a 5c 64 28 3f 3a 3a 5c 64 2b 7c 29  /](?:\d(?::\d+|)
34b0: 7c 29 3e 3e 20 22 2c 20 73 4c 69 6e 65 29 20 3a  |)>> ", sLine) :
34c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61  .            # a
34d0: 63 74 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 20  ctions.         
34e0: 20 20 20 73 41 63 74 69 6f 6e 73 20 2b 3d 20 22     sActions += "
34f0: 20 22 20 2b 20 73 4c 69 6e 65 2e 73 74 72 69 70   " + sLine.strip
3500: 28 29 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  ().        elif 
3510: 72 65 2e 6d 61 74 63 68 28 22 5b 20 c2 a0 5d 2a  re.match("[ ..]*
3520: 24 22 2c 20 73 4c 69 6e 65 29 3a 0a 20 20 20 20  $", sLine):.    
3530: 20 20 20 20 20 20 20 20 23 20 65 6d 70 74 79 20          # empty 
3540: 6c 69 6e 65 20 74 6f 20 65 6e 64 20 6d 65 72 67  line to end merg
3550: 69 6e 67 0a 20 20 20 20 20 20 20 20 20 20 20 20  ing.            
3560: 69 66 20 6e 6f 74 20 6c 54 6f 6b 65 6e 4c 69 6e  if not lTokenLin
3570: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
3580: 20 20 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20     continue.    
3590: 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 73          if not s
35a0: 41 63 74 69 6f 6e 73 3a 0a 20 20 20 20 20 20 20  Actions:.       
35b0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
35c0: 45 72 72 6f 72 2e 20 4e 6f 20 61 63 74 69 6f 6e  Error. No action
35d0: 20 66 6f 75 6e 64 20 61 74 20 6c 69 6e 65 3a 22   found at line:"
35e0: 2c 20 69 29 0a 20 20 20 20 20 20 20 20 20 20 20  , i).           
35f0: 20 20 20 20 20 65 78 69 74 28 29 0a 20 20 20 20       exit().    
3600: 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 73          if not s
3610: 47 72 61 70 68 4e 61 6d 65 3a 0a 20 20 20 20 20  GraphName:.     
3620: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
3630: 28 22 45 72 72 6f 72 2e 20 41 6c 6c 20 72 75 6c  ("Error. All rul
3640: 65 73 20 6d 75 73 74 20 62 65 6c 6f 6e 67 20 74  es must belong t
3650: 6f 20 61 20 6e 61 6d 65 64 20 67 72 61 70 68 2e  o a named graph.
3660: 20 4c 69 6e 65 3a 20 22 2c 20 69 29 0a 20 20 20   Line: ", i).   
3670: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 78 69               exi
3680: 74 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  t().            
3690: 66 6f 72 20 6a 2c 20 73 54 6f 6b 65 6e 4c 69 6e  for j, sTokenLin
36a0: 65 20 69 6e 20 6c 54 6f 6b 65 6e 4c 69 6e 65 3a  e in lTokenLine:
36b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
36c0: 20 64 41 6c 6c 47 72 61 70 68 5b 73 47 72 61 70   dAllGraph[sGrap
36d0: 68 4e 61 6d 65 5d 2e 61 70 70 65 6e 64 28 28 6a  hName].append((j
36e0: 2c 20 73 52 75 6c 65 4e 61 6d 65 2c 20 73 54 6f  , sRuleName, sTo
36f0: 6b 65 6e 4c 69 6e 65 2c 20 69 41 63 74 69 6f 6e  kenLine, iAction
3700: 42 6c 6f 63 6b 2c 20 73 41 63 74 69 6f 6e 73 2c  Block, sActions,
3710: 20 6e 50 72 69 6f 72 69 74 79 29 29 0a 20 20 20   nPriority)).   
3720: 20 20 20 20 20 20 20 20 20 6c 54 6f 6b 65 6e 4c           lTokenL
3730: 69 6e 65 2e 63 6c 65 61 72 28 29 0a 20 20 20 20  ine.clear().    
3740: 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e 73          sActions
3750: 20 3d 20 22 22 0a 20 20 20 20 20 20 20 20 20 20   = "".          
3760: 20 20 69 41 63 74 69 6f 6e 42 6c 6f 63 6b 20 2b    iActionBlock +
3770: 3d 20 31 0a 20 20 20 20 20 20 20 20 65 6c 69 66  = 1.        elif
3780: 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74   sLine.startswit
3790: 68 28 28 22 20 20 20 20 22 29 29 3a 0a 20 20 20  h(("    ")):.   
37a0: 20 20 20 20 20 20 20 20 20 23 20 74 6f 6b 65 6e           # token
37b0: 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 54  s.            lT
37c0: 6f 6b 65 6e 4c 69 6e 65 2e 61 70 70 65 6e 64 28  okenLine.append(
37d0: 5b 69 2c 20 73 4c 69 6e 65 2e 73 74 72 69 70 28  [i, sLine.strip(
37e0: 29 5d 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65  )]).        else
37f0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72  :.            pr
3800: 69 6e 74 28 22 55 6e 6b 6e 6f 77 6e 20 6c 69 6e  int("Unknown lin
3810: 65 3a 22 29 0a 20 20 20 20 20 20 20 20 20 20 20  e:").           
3820: 20 70 72 69 6e 74 28 73 4c 69 6e 65 29 0a 0a 20   print(sLine).. 
3830: 20 20 20 23 20 70 72 6f 63 65 73 73 69 6e 67 20     # processing 
3840: 72 75 6c 65 73 0a 20 20 20 20 70 72 69 6e 74 28  rules.    print(
3850: 22 20 20 70 72 65 70 61 72 69 6e 67 20 72 75 6c  "  preparing rul
3860: 65 73 2e 2e 2e 22 29 0a 20 20 20 20 66 6f 72 20  es...").    for 
3870: 73 47 72 61 70 68 4e 61 6d 65 2c 20 6c 52 75 6c  sGraphName, lRul
3880: 65 4c 69 6e 65 20 69 6e 20 64 41 6c 6c 47 72 61  eLine in dAllGra
3890: 70 68 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20 20  ph.items():.    
38a0: 20 20 20 20 6c 50 72 65 70 61 72 65 64 52 75 6c      lPreparedRul
38b0: 65 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20 20 66  e = [].        f
38c0: 6f 72 20 69 2c 20 73 52 75 6c 65 47 72 6f 75 70  or i, sRuleGroup
38d0: 2c 20 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20 69 41  , sTokenLine, iA
38e0: 63 74 69 6f 6e 42 6c 6f 63 6b 2c 20 73 41 63 74  ctionBlock, sAct
38f0: 69 6f 6e 73 2c 20 6e 50 72 69 6f 72 69 74 79 20  ions, nPriority 
3900: 69 6e 20 6c 52 75 6c 65 4c 69 6e 65 3a 0a 20 20  in lRuleLine:.  
3910: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 6c 52            for lR
3920: 75 6c 65 20 69 6e 20 63 72 65 61 74 65 52 75 6c  ule in createRul
3930: 65 28 69 2c 20 73 52 75 6c 65 47 72 6f 75 70 2c  e(i, sRuleGroup,
3940: 20 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20 69 41 63   sTokenLine, iAc
3950: 74 69 6f 6e 42 6c 6f 63 6b 2c 20 73 41 63 74 69  tionBlock, sActi
3960: 6f 6e 73 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20  ons, nPriority, 
3970: 64 44 65 66 29 3a 0a 20 20 20 20 20 20 20 20 20  dDef):.         
3980: 20 20 20 20 20 20 20 6c 50 72 65 70 61 72 65 64         lPrepared
3990: 52 75 6c 65 2e 61 70 70 65 6e 64 28 6c 52 75 6c  Rule.append(lRul
39a0: 65 29 0a 20 20 20 20 20 20 20 20 23 20 47 72 61  e).        # Gra
39b0: 70 68 20 63 72 65 61 74 69 6f 6e 0a 20 20 20 20  ph creation.    
39c0: 20 20 20 20 6f 44 41 52 47 20 3d 20 64 61 72 67      oDARG = darg
39d0: 2e 44 41 52 47 28 6c 50 72 65 70 61 72 65 64 52  .DARG(lPreparedR
39e0: 75 6c 65 2c 20 73 4c 61 6e 67 29 0a 20 20 20 20  ule, sLang).    
39f0: 20 20 20 20 64 41 6c 6c 47 72 61 70 68 5b 73 47      dAllGraph[sG
3a00: 72 61 70 68 4e 61 6d 65 5d 20 3d 20 6f 44 41 52  raphName] = oDAR
3a10: 47 2e 63 72 65 61 74 65 47 72 61 70 68 28 29 0a  G.createGraph().
3a20: 20 20 20 20 20 20 20 20 23 20 44 65 62 75 67 67          # Debugg
3a30: 69 6e 67 0a 20 20 20 20 20 20 20 20 23 70 72 69  ing.        #pri
3a40: 6e 74 28 22 5c 6e 47 52 41 50 48 3a 22 2c 20 73  nt("\nGRAPH:", s
3a50: 47 72 61 70 68 4e 61 6d 65 29 0a 20 20 20 20 20  GraphName).     
3a60: 20 20 20 23 66 6f 72 20 65 20 69 6e 20 6c 50 72     #for e in lPr
3a70: 65 70 61 72 65 64 52 75 6c 65 3a 0a 20 20 20 20  eparedRule:.    
3a80: 20 20 20 20 23 20 20 20 20 69 66 20 65 5b 2d 32      #    if e[-2
3a90: 5d 20 3d 3d 20 22 23 23 34 32 33 39 22 3a 0a 20  ] == "##4239":. 
3aa0: 20 20 20 20 20 20 20 23 20 20 20 20 20 20 20 20         #        
3ab0: 70 72 69 6e 74 28 65 29 0a 20 20 20 20 20 20 20  print(e).       
3ac0: 20 23 20 20 20 20 70 72 69 6e 74 28 65 29 0a 20   #    print(e). 
3ad0: 20 20 20 20 20 20 20 23 66 6f 72 20 6b 2c 20 76         #for k, v
3ae0: 20 69 6e 20 64 41 6c 6c 47 72 61 70 68 5b 73 47   in dAllGraph[sG
3af0: 72 61 70 68 4e 61 6d 65 5d 2e 69 74 65 6d 73 28  raphName].items(
3b00: 29 3a 0a 20 20 20 20 20 20 20 20 23 20 20 20 20  ):.        #    
3b10: 70 72 69 6e 74 28 6b 2c 20 22 5c 74 22 2c 20 76  print(k, "\t", v
3b20: 29 0a 0a 20 20 20 20 23 20 63 72 65 61 74 69 6e  )..    # creatin
3b30: 67 20 66 69 6c 65 20 77 69 74 68 20 61 6c 6c 20  g file with all 
3b40: 66 75 6e 63 74 69 6f 6e 73 20 63 61 6c 6c 61 62  functions callab
3b50: 6c 65 20 62 79 20 72 75 6c 65 73 0a 20 20 20 20  le by rules.    
3b60: 70 72 69 6e 74 28 22 20 20 63 72 65 61 74 69 6e  print("  creatin
3b70: 67 20 63 61 6c 6c 61 62 6c 65 73 2e 2e 2e 22 29  g callables...")
3b80: 0a 20 20 20 20 73 50 79 43 61 6c 6c 61 62 6c 65  .    sPyCallable
3b90: 73 20 3d 20 22 23 20 67 65 6e 65 72 61 74 65 64  s = "# generated
3ba0: 20 63 6f 64 65 2c 20 64 6f 20 6e 6f 74 20 65 64   code, do not ed
3bb0: 69 74 5c 6e 22 0a 20 20 20 20 23 73 4a 53 43 61  it\n".    #sJSCa
3bc0: 6c 6c 61 62 6c 65 73 20 3d 20 22 2f 2f 20 67 65  llables = "// ge
3bd0: 6e 65 72 61 74 65 64 20 63 6f 64 65 2c 20 64 6f  nerated code, do
3be0: 20 6e 6f 74 20 65 64 69 74 5c 6e 63 6f 6e 73 74   not edit\nconst
3bf0: 20 6f 45 76 61 6c 46 75 6e 63 20 3d 20 7b 5c 6e   oEvalFunc = {\n
3c00: 22 0a 20 20 20 20 66 6f 72 20 73 46 75 6e 63 4e  ".    for sFuncN
3c10: 61 6d 65 2c 20 73 52 65 74 75 72 6e 20 69 6e 20  ame, sReturn in 
3c20: 64 46 55 4e 43 54 49 4f 4e 53 2e 69 74 65 6d 73  dFUNCTIONS.items
3c30: 28 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73  ():.        if s
3c40: 46 75 6e 63 4e 61 6d 65 2e 73 74 61 72 74 73 77  FuncName.startsw
3c50: 69 74 68 28 22 5f 67 5f 63 5f 22 29 3a 20 23 20  ith("_g_c_"): # 
3c60: 63 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 20 20  condition.      
3c70: 20 20 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20        sParams = 
3c80: 22 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f  "lToken, nTokenO
3c90: 66 66 73 65 74 2c 20 6e 4c 61 73 74 54 6f 6b 65  ffset, nLastToke
3ca0: 6e 2c 20 73 43 6f 75 6e 74 72 79 2c 20 62 43 6f  n, sCountry, bCo
3cb0: 6e 64 4d 65 6d 6f 2c 20 64 54 61 67 73 2c 20 73  ndMemo, dTags, s
3cc0: 53 65 6e 74 65 6e 63 65 2c 20 73 53 65 6e 74 65  Sentence, sSente
3cd0: 6e 63 65 30 22 0a 20 20 20 20 20 20 20 20 65 6c  nce0".        el
3ce0: 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61  if sFuncName.sta
3cf0: 72 74 73 77 69 74 68 28 22 67 5f 6d 5f 22 29 3a  rtswith("g_m_"):
3d00: 20 23 20 6d 65 73 73 61 67 65 0a 20 20 20 20 20   # message.     
3d10: 20 20 20 20 20 20 20 73 50 61 72 61 6d 73 20 3d         sParams =
3d20: 20 22 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e   "lToken, nToken
3d30: 4f 66 66 73 65 74 22 0a 20 20 20 20 20 20 20 20  Offset".        
3d40: 65 6c 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73  elif sFuncName.s
3d50: 74 61 72 74 73 77 69 74 68 28 22 5f 67 5f 73 5f  tartswith("_g_s_
3d60: 22 29 3a 20 23 20 73 75 67 67 65 73 74 69 6f 6e  "): # suggestion
3d70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61  .            sPa
3d80: 72 61 6d 73 20 3d 20 22 6c 54 6f 6b 65 6e 2c 20  rams = "lToken, 
3d90: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 22 0a 20 20  nTokenOffset".  
3da0: 20 20 20 20 20 20 65 6c 69 66 20 73 46 75 6e 63        elif sFunc
3db0: 4e 61 6d 65 2e 73 74 61 72 74 73 77 69 74 68 28  Name.startswith(
3dc0: 22 5f 67 5f 70 5f 22 29 3a 20 23 20 70 72 65 70  "_g_p_"): # prep
3dd0: 72 6f 63 65 73 73 6f 72 0a 20 20 20 20 20 20 20  rocessor.       
3de0: 20 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20 22       sParams = "
3df0: 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f 66  lToken, nTokenOf
3e00: 66 73 65 74 22 0a 20 20 20 20 20 20 20 20 65 6c  fset".        el
3e10: 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61  if sFuncName.sta
3e20: 72 74 73 77 69 74 68 28 22 5f 67 5f 64 5f 22 29  rtswith("_g_d_")
3e30: 3a 20 23 20 64 69 73 61 6d 62 69 67 75 61 74 6f  : # disambiguato
3e40: 72 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 50  r.            sP
3e50: 61 72 61 6d 73 20 3d 20 22 6c 54 6f 6b 65 6e 2c  arams = "lToken,
3e60: 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 22 0a 20   nTokenOffset". 
3e70: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
3e80: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
3e90: 23 20 55 6e 6b 6e 6f 77 6e 20 66 75 6e 63 74 69  # Unknown functi
3ea0: 6f 6e 20 74 79 70 65 20 69 6e 20 5b 22 20 2b 20  on type in [" + 
3eb0: 73 46 75 6e 63 4e 61 6d 65 20 2b 20 22 5d 22 29  sFuncName + "]")
3ec0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e  .            con
3ed0: 74 69 6e 75 65 0a 20 20 20 20 20 20 20 20 73 50  tinue.        sP
3ee0: 79 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 64  yCallables += "d
3ef0: 65 66 20 7b 7d 20 28 7b 7d 29 3a 5c 6e 22 2e 66  ef {} ({}):\n".f
3f00: 6f 72 6d 61 74 28 73 46 75 6e 63 4e 61 6d 65 2c  ormat(sFuncName,
3f10: 20 73 50 61 72 61 6d 73 29 0a 20 20 20 20 20 20   sParams).      
3f20: 20 20 73 50 79 43 61 6c 6c 61 62 6c 65 73 20 2b    sPyCallables +
3f30: 3d 20 22 20 20 20 20 72 65 74 75 72 6e 20 22 20  = "    return " 
3f40: 2b 20 73 52 65 74 75 72 6e 20 2b 20 22 5c 6e 22  + sReturn + "\n"
3f50: 0a 20 20 20 20 20 20 20 20 23 73 4a 53 43 61 6c  .        #sJSCal
3f60: 6c 61 62 6c 65 73 20 2b 3d 20 22 20 20 20 20 7b  lables += "    {
3f70: 7d 3a 20 66 75 6e 63 74 69 6f 6e 20 28 7b 7d 29  }: function ({})
3f80: 22 2e 66 6f 72 6d 61 74 28 73 46 75 6e 63 4e 61  ".format(sFuncNa
3f90: 6d 65 2c 20 73 50 61 72 61 6d 73 29 20 2b 20 22  me, sParams) + "
3fa0: 20 7b 5c 6e 22 0a 20 20 20 20 20 20 20 20 23 73   {\n".        #s
3fb0: 4a 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22  JSCallables += "
3fc0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22          return "
3fd0: 20 2b 20 6a 73 63 6f 6e 76 2e 70 79 32 6a 73 28   + jsconv.py2js(
3fe0: 73 52 65 74 75 72 6e 29 20 2b 20 22 3b 5c 6e 22  sReturn) + ";\n"
3ff0: 0a 20 20 20 20 20 20 20 20 23 73 4a 53 43 61 6c  .        #sJSCal
4000: 6c 61 62 6c 65 73 20 2b 3d 20 22 20 20 20 20 7d  lables += "    }
4010: 2c 5c 6e 22 0a 20 20 20 20 23 73 4a 53 43 61 6c  ,\n".    #sJSCal
4020: 6c 61 62 6c 65 73 20 2b 3d 20 22 7d 5c 6e 22 0a  lables += "}\n".
4030: 0a 20 20 20 20 23 20 44 65 62 75 67 67 69 6e 67  .    # Debugging
4040: 0a 20 20 20 20 69 66 20 46 61 6c 73 65 3a 0a 20  .    if False:. 
4050: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 5c 6e         print("\n
4060: 41 63 74 69 6f 6e 73 3a 22 29 0a 20 20 20 20 20  Actions:").     
4070: 20 20 20 66 6f 72 20 73 41 63 74 69 6f 6e 4e 61     for sActionNa
4080: 6d 65 2c 20 61 41 63 74 69 6f 6e 20 69 6e 20 64  me, aAction in d
4090: 41 43 54 49 4f 4e 53 2e 69 74 65 6d 73 28 29 3a  ACTIONS.items():
40a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69  .            pri
40b0: 6e 74 28 73 41 63 74 69 6f 6e 4e 61 6d 65 2c 20  nt(sActionName, 
40c0: 61 41 63 74 69 6f 6e 29 0a 20 20 20 20 20 20 20  aAction).       
40d0: 20 70 72 69 6e 74 28 22 5c 6e 46 75 6e 63 74 69   print("\nFuncti
40e0: 6f 6e 73 3a 22 29 0a 20 20 20 20 20 20 20 20 70  ons:").        p
40f0: 72 69 6e 74 28 73 50 79 43 61 6c 6c 61 62 6c 65  rint(sPyCallable
4100: 73 29 0a 0a 20 20 20 20 23 20 52 65 73 75 6c 74  s)..    # Result
4110: 0a 20 20 20 20 72 65 74 75 72 6e 20 7b 0a 20 20  .    return {.  
4120: 20 20 20 20 20 20 22 67 72 61 70 68 5f 63 61 6c        "graph_cal
4130: 6c 61 62 6c 65 73 22 3a 20 73 50 79 43 61 6c 6c  lables": sPyCall
4140: 61 62 6c 65 73 2c 0a 20 20 20 20 20 20 20 20 22  ables,.        "
4150: 72 75 6c 65 73 5f 67 72 61 70 68 73 22 3a 20 64  rules_graphs": d
4160: 41 6c 6c 47 72 61 70 68 2c 0a 20 20 20 20 20 20  AllGraph,.      
4170: 20 20 22 72 75 6c 65 73 5f 61 63 74 69 6f 6e 73    "rules_actions
4180: 22 3a 20 64 41 43 54 49 4f 4e 53 0a 20 20 20 20  ": dACTIONS.    
4190: 7d 0a                                            }.