Grammalecte  Hex Artifact Content

Artifact ffaec91e64ac6c6c675a479a3370dd076d2a0cfbe2a70e1f0c53ff91b679ec82:


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 64 69 73 70 6c 61 79 49  analyse|displayI
0190: 6e 66 6f 29 5b 28 5d 5c 5c 28 5c 64 2b 29 22 2c  nfo)[(]\\(\d+)",
01a0: 20 27 67 5f 5c 5c 31 28 6c 54 6f 6b 65 6e 5b 5c   'g_\\1(lToken[\
01b0: 5c 32 2b 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 5d  \2+nTokenOffset]
01c0: 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65  ', s).    s = re
01d0: 2e 73 75 62 28 72 22 28 73 65 6c 65 63 74 7c 65  .sub(r"(select|e
01e0: 78 63 6c 75 64 65 7c 64 65 66 69 6e 65 29 5b 28  xclude|define)[(
01f0: 5d 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27 67 5f  ][\\](\d+)", 'g_
0200: 5c 5c 31 28 6c 54 6f 6b 65 6e 5b 5c 5c 32 2b 6e  \\1(lToken[\\2+n
0210: 54 6f 6b 65 6e 4f 66 66 73 65 74 5d 27 2c 20 73  TokenOffset]', s
0220: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0230: 28 72 22 28 74 61 67 5f 62 65 66 6f 72 65 7c 74  (r"(tag_before|t
0240: 61 67 5f 61 66 74 65 72 29 5b 28 5d 5b 5c 5c 5d  ag_after)[(][\\]
0250: 28 5c 64 2b 29 22 2c 20 27 67 5f 5c 5c 31 28 6c  (\d+)", 'g_\\1(l
0260: 54 6f 6b 65 6e 5b 5c 5c 32 2b 6e 54 6f 6b 65 6e  Token[\\2+nToken
0270: 4f 66 66 73 65 74 5d 2c 20 64 54 61 67 73 27 2c  Offset], dTags',
0280: 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73   s).    s = re.s
0290: 75 62 28 72 22 28 73 77 69 74 63 68 47 65 6e 64  ub(r"(switchGend
02a0: 65 72 7c 68 61 73 28 3f 3a 4d 61 73 7c 46 65 6d  er|has(?:Mas|Fem
02b0: 29 46 6f 72 6d 29 5b 28 5d 5c 5c 28 5c 64 2b 29  )Form)[(]\\(\d+)
02c0: 22 2c 20 27 5c 5c 31 28 6c 54 6f 6b 65 6e 5b 5c  ", '\\1(lToken[\
02d0: 5c 32 2b 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 5d  \2+nTokenOffset]
02e0: 5b 22 73 56 61 6c 75 65 22 5d 27 2c 20 73 29 0a  ["sValue"]', s).
02f0: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
0300: 22 28 6d 6f 72 70 68 7c 61 6e 61 6c 79 73 65 29  "(morph|analyse)
0310: 5c 28 3e 31 22 2c 20 27 67 5f 5c 5c 31 28 6c 54  \(>1", 'g_\\1(lT
0320: 6f 6b 65 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 2b  oken[nLastToken+
0330: 31 5d 27 2c 20 73 29 20 20 20 20 20 20 20 20 20  1]', s)         
0340: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 6e 65              # ne
0350: 78 74 20 74 6f 6b 65 6e 0a 20 20 20 20 73 20 3d  xt token.    s =
0360: 20 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70 68   re.sub(r"(morph
0370: 7c 61 6e 61 6c 79 73 65 29 5c 28 3c 31 22 2c 20  |analyse)\(<1", 
0380: 27 67 5f 5c 5c 31 28 6c 54 6f 6b 65 6e 5b 6e 54  'g_\\1(lToken[nT
0390: 6f 6b 65 6e 4f 66 66 73 65 74 5d 27 2c 20 73 29  okenOffset]', s)
03a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03b0: 20 20 20 20 20 23 20 70 72 65 76 69 6f 75 73 20       # previous 
03c0: 74 6f 6b 65 6e 0a 20 20 20 20 73 20 3d 20 72 65  token.    s = re
03d0: 2e 73 75 62 28 72 22 5b 5c 5c 5d 28 5c 64 2b 29  .sub(r"[\\](\d+)
03e0: 5c 2e 69 73 28 75 70 70 65 72 7c 6c 6f 77 65 72  \.is(upper|lower
03f0: 7c 74 69 74 6c 65 29 5c 28 5c 29 22 2c 20 27 6c  |title)\(\)", 'l
0400: 54 6f 6b 65 6e 5b 5c 5c 31 2b 6e 54 6f 6b 65 6e  Token[\\1+nToken
0410: 4f 66 66 73 65 74 5d 5b 22 73 56 61 6c 75 65 22  Offset]["sValue"
0420: 5d 2e 69 73 5c 5c 32 28 29 27 2c 20 73 29 0a 20  ].is\\2()', s). 
0430: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0440: 5c 62 73 70 65 6c 6c 20 2a 5b 28 5d 22 2c 20 27  \bspell *[(]", '
0450: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69  _oSpellChecker.i
0460: 73 56 61 6c 69 64 28 27 2c 20 73 29 0a 20 20 20  sValid(', s).   
0470: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62   s = re.sub(r"\b
0480: 62 65 66 6f 72 65 5c 28 5c 73 2a 22 2c 20 27 6c  before\(\s*", 'l
0490: 6f 6f 6b 28 73 53 65 6e 74 65 6e 63 65 5b 3a 6c  ook(sSentence[:l
04a0: 54 6f 6b 65 6e 5b 31 2b 6e 54 6f 6b 65 6e 4f 66  Token[1+nTokenOf
04b0: 66 73 65 74 5d 5b 22 6e 53 74 61 72 74 22 5d 5d  fset]["nStart"]]
04c0: 2c 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20  , ', s)         
04d0: 20 23 20 62 65 66 6f 72 65 28 73 29 0a 20 20 20   # before(s).   
04e0: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62   s = re.sub(r"\b
04f0: 61 66 74 65 72 5c 28 5c 73 2a 22 2c 20 27 6c 6f  after\(\s*", 'lo
0500: 6f 6b 28 73 53 65 6e 74 65 6e 63 65 5b 6c 54 6f  ok(sSentence[lTo
0510: 6b 65 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 5d 5b  ken[nLastToken][
0520: 22 6e 45 6e 64 22 5d 3a 5d 2c 20 27 2c 20 73 29  "nEnd"]:], ', s)
0530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0540: 20 23 20 61 66 74 65 72 28 73 29 0a 20 20 20 20   # after(s).    
0550: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62 62  s = re.sub(r"\bb
0560: 65 66 6f 72 65 30 5c 28 5c 73 2a 22 2c 20 27 6c  efore0\(\s*", 'l
0570: 6f 6f 6b 28 73 53 65 6e 74 65 6e 63 65 30 5b 3a  ook(sSentence0[:
0580: 6c 54 6f 6b 65 6e 5b 31 2b 6e 54 6f 6b 65 6e 4f  lToken[1+nTokenO
0590: 66 66 73 65 74 5d 5b 22 6e 53 74 61 72 74 22 5d  ffset]["nStart"]
05a0: 5d 2c 20 27 2c 20 73 29 20 20 20 20 20 20 20 20  ], ', s)        
05b0: 23 20 62 65 66 6f 72 65 30 28 73 29 0a 20 20 20  # before0(s).   
05c0: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62   s = re.sub(r"\b
05d0: 61 66 74 65 72 30 5c 28 5c 73 2a 22 2c 20 27 6c  after0\(\s*", 'l
05e0: 6f 6f 6b 28 73 53 65 6e 74 65 6e 63 65 5b 6c 54  ook(sSentence[lT
05f0: 6f 6b 65 6e 5b 6e 4c 61 73 74 54 6f 6b 65 6e 5d  oken[nLastToken]
0600: 5b 22 6e 45 6e 64 22 5d 3a 5d 2c 20 27 2c 20 73  ["nEnd"]:], ', s
0610: 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  )               
0620: 20 23 20 61 66 74 65 72 30 28 73 29 0a 20 20 20   # after0(s).   
0630: 20 69 66 20 62 54 6f 6b 65 6e 56 61 6c 75 65 3a   if bTokenValue:
0640: 0a 20 20 20 20 20 20 20 20 23 20 74 6f 6b 65 6e  .        # token
0650: 20 76 61 6c 75 65 73 20 61 72 65 20 75 73 65 64   values are used
0660: 20 61 73 20 70 61 72 61 6d 65 74 65 72 0a 20 20   as parameter.  
0670: 20 20 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62        s = re.sub
0680: 28 72 22 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27  (r"[\\](\d+)", '
0690: 6c 54 6f 6b 65 6e 5b 5c 5c 31 2b 6e 54 6f 6b 65  lToken[\\1+nToke
06a0: 6e 4f 66 66 73 65 74 5d 5b 22 73 56 61 6c 75 65  nOffset]["sValue
06b0: 22 5d 27 2c 20 73 29 0a 20 20 20 20 65 6c 73 65  "]', s).    else
06c0: 3a 0a 20 20 20 20 20 20 20 20 23 20 74 6f 6b 65  :.        # toke
06d0: 6e 73 20 75 73 65 64 20 61 73 20 70 61 72 61 6d  ns used as param
06e0: 65 74 65 72 0a 20 20 20 20 20 20 20 20 73 20 3d  eter.        s =
06f0: 20 72 65 2e 73 75 62 28 72 22 5b 5c 5c 5d 28 5c   re.sub(r"[\\](\
0700: 64 2b 29 22 2c 20 27 6c 54 6f 6b 65 6e 5b 5c 5c  d+)", 'lToken[\\
0710: 31 2b 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 5d 27  1+nTokenOffset]'
0720: 2c 20 73 29 0a 20 20 20 20 72 65 74 75 72 6e 20  , s).    return 
0730: 73 0a 0a 0a 64 65 66 20 67 65 6e 54 6f 6b 65 6e  s...def genToken
0740: 4c 69 6e 65 73 20 28 73 54 6f 6b 65 6e 4c 69 6e  Lines (sTokenLin
0750: 65 2c 20 64 44 65 66 29 3a 0a 20 20 20 20 22 74  e, dDef):.    "t
0760: 6f 6b 65 6e 69 7a 65 20 61 20 73 74 72 69 6e 67  okenize a string
0770: 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20 6c 69   and return a li
0780: 73 74 20 6f 66 20 6c 69 6e 65 73 20 6f 66 20 74  st of lines of t
0790: 6f 6b 65 6e 73 22 0a 20 20 20 20 6c 54 6f 6b 65  okens".    lToke
07a0: 6e 20 3d 20 73 54 6f 6b 65 6e 4c 69 6e 65 2e 73  n = sTokenLine.s
07b0: 70 6c 69 74 28 29 0a 20 20 20 20 6c 54 6f 6b 65  plit().    lToke
07c0: 6e 4c 69 6e 65 73 20 3d 20 4e 6f 6e 65 0a 20 20  nLines = None.  
07d0: 20 20 66 6f 72 20 73 54 6f 6b 65 6e 20 69 6e 20    for sToken in 
07e0: 6c 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20 20  lToken:.        
07f0: 23 20 6f 70 74 69 6f 6e 61 6c 20 74 6f 6b 65 6e  # optional token
0800: 3f 0a 20 20 20 20 20 20 20 20 62 4e 75 6c 6c 50  ?.        bNullP
0810: 6f 73 73 69 62 6c 65 20 3d 20 73 54 6f 6b 65 6e  ossible = sToken
0820: 2e 73 74 61 72 74 73 77 69 74 68 28 22 3f 22 29  .startswith("?")
0830: 20 61 6e 64 20 73 54 6f 6b 65 6e 2e 65 6e 64 73   and sToken.ends
0840: 77 69 74 68 28 22 c2 bf 22 29 0a 20 20 20 20 20  with("..").     
0850: 20 20 20 69 66 20 62 4e 75 6c 6c 50 6f 73 73 69     if bNullPossi
0860: 62 6c 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ble:.           
0870: 20 73 54 6f 6b 65 6e 20 3d 20 73 54 6f 6b 65 6e   sToken = sToken
0880: 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20 20 20 23  [1:-1].        #
0890: 20 74 6f 6b 65 6e 20 77 69 74 68 20 64 65 66 69   token with defi
08a0: 6e 69 74 69 6f 6e 3f 0a 20 20 20 20 20 20 20 20  nition?.        
08b0: 69 66 20 73 54 6f 6b 65 6e 2e 73 74 61 72 74 73  if sToken.starts
08c0: 77 69 74 68 28 22 28 7b 22 29 20 61 6e 64 20 73  with("({") and s
08d0: 54 6f 6b 65 6e 2e 65 6e 64 73 77 69 74 68 28 22  Token.endswith("
08e0: 7d 29 22 29 20 61 6e 64 20 73 54 6f 6b 65 6e 5b  })") and sToken[
08f0: 31 3a 2d 31 5d 20 69 6e 20 64 44 65 66 3a 0a 20  1:-1] in dDef:. 
0900: 20 20 20 20 20 20 20 20 20 20 20 73 54 6f 6b 65             sToke
0910: 6e 20 3d 20 22 28 22 20 2b 20 64 44 65 66 5b 73  n = "(" + dDef[s
0920: 54 6f 6b 65 6e 5b 31 3a 2d 31 5d 5d 20 2b 20 22  Token[1:-1]] + "
0930: 29 22 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  )".        elif 
0940: 73 54 6f 6b 65 6e 2e 73 74 61 72 74 73 77 69 74  sToken.startswit
0950: 68 28 22 7b 22 29 20 61 6e 64 20 73 54 6f 6b 65  h("{") and sToke
0960: 6e 2e 65 6e 64 73 77 69 74 68 28 22 7d 22 29 20  n.endswith("}") 
0970: 61 6e 64 20 73 54 6f 6b 65 6e 20 69 6e 20 64 44  and sToken in dD
0980: 65 66 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ef:.            
0990: 73 54 6f 6b 65 6e 20 3d 20 64 44 65 66 5b 73 54  sToken = dDef[sT
09a0: 6f 6b 65 6e 5d 0a 20 20 20 20 20 20 20 20 69 66  oken].        if
09b0: 20 28 20 28 73 54 6f 6b 65 6e 2e 73 74 61 72 74   ( (sToken.start
09c0: 73 77 69 74 68 28 22 5b 22 29 20 61 6e 64 20 73  swith("[") and s
09d0: 54 6f 6b 65 6e 2e 65 6e 64 73 77 69 74 68 28 22  Token.endswith("
09e0: 5d 22 29 29 20 6f 72 20 28 73 54 6f 6b 65 6e 2e  ]")) or (sToken.
09f0: 73 74 61 72 74 73 77 69 74 68 28 22 28 5b 22 29  startswith("([")
0a00: 20 61 6e 64 20 73 54 6f 6b 65 6e 2e 65 6e 64 73   and sToken.ends
0a10: 77 69 74 68 28 22 5d 29 22 29 29 20 29 3a 0a 20  with("])")) ):. 
0a20: 20 20 20 20 20 20 20 20 20 20 20 23 20 6d 75 6c             # mul
0a30: 74 69 70 6c 65 20 74 6f 6b 65 6e 0a 20 20 20 20  tiple token.    
0a40: 20 20 20 20 20 20 20 20 62 53 65 6c 65 63 74 65          bSelecte
0a50: 64 47 72 6f 75 70 20 3d 20 73 54 6f 6b 65 6e 2e  dGroup = sToken.
0a60: 73 74 61 72 74 73 77 69 74 68 28 22 28 22 29 20  startswith("(") 
0a70: 61 6e 64 20 73 54 6f 6b 65 6e 2e 65 6e 64 73 77  and sToken.endsw
0a80: 69 74 68 28 22 29 22 29 0a 20 20 20 20 20 20 20  ith(")").       
0a90: 20 20 20 20 20 69 66 20 62 53 65 6c 65 63 74 65       if bSelecte
0aa0: 64 47 72 6f 75 70 3a 0a 20 20 20 20 20 20 20 20  dGroup:.        
0ab0: 20 20 20 20 20 20 20 20 73 54 6f 6b 65 6e 20 3d          sToken =
0ac0: 20 73 54 6f 6b 65 6e 5b 31 3a 2d 31 5d 0a 20 20   sToken[1:-1].  
0ad0: 20 20 20 20 20 20 20 20 20 20 6c 4e 65 77 54 6f            lNewTo
0ae0: 6b 65 6e 20 3d 20 73 54 6f 6b 65 6e 5b 31 3a 2d  ken = sToken[1:-
0af0: 31 5d 2e 73 70 6c 69 74 28 22 7c 22 29 0a 20 20  1].split("|").  
0b00: 20 20 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74            if not
0b10: 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20 20   lTokenLines:.  
0b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 54                lT
0b30: 6f 6b 65 6e 4c 69 6e 65 73 20 3d 20 5b 20 5b 73  okenLines = [ [s
0b40: 5d 20 20 66 6f 72 20 73 20 20 69 6e 20 6c 4e 65  ]  for s  in lNe
0b50: 77 54 6f 6b 65 6e 20 5d 0a 20 20 20 20 20 20 20  wToken ].       
0b60: 20 20 20 20 20 20 20 20 20 69 66 20 62 4e 75 6c           if bNul
0b70: 6c 50 6f 73 73 69 62 6c 65 3a 0a 20 20 20 20 20  lPossible:.     
0b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
0b90: 54 6f 6b 65 6e 4c 69 6e 65 73 2e 65 78 74 65 6e  TokenLines.exten
0ba0: 64 28 5b 20 5b 5d 20 20 66 6f 72 20 69 20 20 69  d([ []  for i  i
0bb0: 6e 20 72 61 6e 67 65 28 6c 65 6e 28 6c 4e 65 77  n range(len(lNew
0bc0: 54 6f 6b 65 6e 29 2b 31 29 20 5d 29 0a 20 20 20  Token)+1) ]).   
0bd0: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
0be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
0bf0: 4e 65 77 54 65 6d 70 20 3d 20 5b 5d 0a 20 20 20  NewTemp = [].   
0c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
0c10: 62 4e 75 6c 6c 50 6f 73 73 69 62 6c 65 3a 0a 20  bNullPossible:. 
0c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c30: 20 20 20 66 6f 72 20 61 52 75 6c 65 20 69 6e 20     for aRule in 
0c40: 6c 54 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20 20 20  lTokenLines:.   
0c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c60: 20 20 20 20 20 66 6f 72 20 73 45 6c 65 6d 20 69       for sElem i
0c70: 6e 20 6c 4e 65 77 54 6f 6b 65 6e 3a 0a 20 20 20  n lNewToken:.   
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c90: 20 20 20 20 20 20 20 20 20 61 4e 65 77 52 75 6c           aNewRul
0ca0: 65 20 3d 20 6c 69 73 74 28 61 52 75 6c 65 29 0a  e = list(aRule).
0cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cc0: 20 20 20 20 20 20 20 20 20 20 20 20 61 4e 65 77              aNew
0cd0: 52 75 6c 65 2e 61 70 70 65 6e 64 28 73 45 6c 65  Rule.append(sEle
0ce0: 6d 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  m).             
0cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
0d00: 4e 65 77 54 65 6d 70 2e 61 70 70 65 6e 64 28 61  NewTemp.append(a
0d10: 4e 65 77 52 75 6c 65 29 0a 20 20 20 20 20 20 20  NewRule).       
0d20: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
0d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d40: 20 20 20 73 45 6c 65 6d 31 20 3d 20 6c 4e 65 77     sElem1 = lNew
0d50: 54 6f 6b 65 6e 2e 70 6f 70 28 30 29 0a 20 20 20  Token.pop(0).   
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d70: 20 66 6f 72 20 61 52 75 6c 65 20 69 6e 20 6c 54   for aRule in lT
0d80: 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20 20 20 20 20  okenLines:.     
0d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0da0: 20 20 20 66 6f 72 20 73 45 6c 65 6d 20 69 6e 20     for sElem in 
0db0: 6c 4e 65 77 54 6f 6b 65 6e 3a 0a 20 20 20 20 20  lNewToken:.     
0dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0dd0: 20 20 20 20 20 20 20 61 4e 65 77 52 75 6c 65 20         aNewRule 
0de0: 3d 20 6c 69 73 74 28 61 52 75 6c 65 29 0a 20 20  = list(aRule).  
0df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e00: 20 20 20 20 20 20 20 20 20 20 61 4e 65 77 52 75            aNewRu
0e10: 6c 65 2e 61 70 70 65 6e 64 28 22 28 22 20 2b 20  le.append("(" + 
0e20: 73 45 6c 65 6d 20 2b 20 22 29 22 20 20 69 66 20  sElem + ")"  if 
0e30: 62 53 65 6c 65 63 74 65 64 47 72 6f 75 70 20 20  bSelectedGroup  
0e40: 65 6c 73 65 20 73 45 6c 65 6d 29 0a 20 20 20 20  else sElem).    
0e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e60: 20 20 20 20 20 20 20 20 6c 4e 65 77 54 65 6d 70          lNewTemp
0e70: 2e 61 70 70 65 6e 64 28 61 4e 65 77 52 75 6c 65  .append(aNewRule
0e80: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
0e90: 20 20 20 20 20 20 20 20 20 20 61 52 75 6c 65 2e            aRule.
0ea0: 61 70 70 65 6e 64 28 22 28 22 20 2b 20 73 45 6c  append("(" + sEl
0eb0: 65 6d 31 20 2b 20 22 29 22 20 20 69 66 20 62 53  em1 + ")"  if bS
0ec0: 65 6c 65 63 74 65 64 47 72 6f 75 70 20 20 65 6c  electedGroup  el
0ed0: 73 65 20 73 45 6c 65 6d 31 29 0a 20 20 20 20 20  se sElem1).     
0ee0: 20 20 20 20 20 20 20 20 20 20 20 6c 54 6f 6b 65             lToke
0ef0: 6e 4c 69 6e 65 73 2e 65 78 74 65 6e 64 28 6c 4e  nLines.extend(lN
0f00: 65 77 54 65 6d 70 29 0a 20 20 20 20 20 20 20 20  ewTemp).        
0f10: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
0f20: 20 20 23 20 73 69 6d 70 6c 65 20 74 6f 6b 65 6e    # simple token
0f30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
0f40: 6e 6f 74 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 3a  not lTokenLines:
0f50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0f60: 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 20 3d 20 5b   lTokenLines = [
0f70: 5b 73 54 6f 6b 65 6e 5d 2c 20 5b 5d 5d 20 20 69  [sToken], []]  i
0f80: 66 20 62 4e 75 6c 6c 50 6f 73 73 69 62 6c 65 20  f bNullPossible 
0f90: 20 65 6c 73 65 20 5b 5b 73 54 6f 6b 65 6e 5d 5d   else [[sToken]]
0fa0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
0fb0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
0fc0: 20 20 20 69 66 20 62 4e 75 6c 6c 50 6f 73 73 69     if bNullPossi
0fd0: 62 6c 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ble:.           
0fe0: 20 20 20 20 20 20 20 20 20 6c 4e 65 77 54 65 6d           lNewTem
0ff0: 70 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20 20 20  p = [].         
1000: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 61             for a
1010: 52 75 6c 65 20 69 6e 20 6c 54 6f 6b 65 6e 4c 69  Rule in lTokenLi
1020: 6e 65 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20  nes:.           
1030: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 4e 65               lNe
1040: 77 20 3d 20 6c 69 73 74 28 61 52 75 6c 65 29 0a  w = list(aRule).
1050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1060: 20 20 20 20 20 20 20 20 6c 4e 65 77 2e 61 70 70          lNew.app
1070: 65 6e 64 28 73 54 6f 6b 65 6e 29 0a 20 20 20 20  end(sToken).    
1080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1090: 20 20 20 20 6c 4e 65 77 54 65 6d 70 2e 61 70 70      lNewTemp.app
10a0: 65 6e 64 28 6c 4e 65 77 29 0a 20 20 20 20 20 20  end(lNew).      
10b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 54                lT
10c0: 6f 6b 65 6e 4c 69 6e 65 73 2e 65 78 74 65 6e 64  okenLines.extend
10d0: 28 6c 4e 65 77 54 65 6d 70 29 0a 20 20 20 20 20  (lNewTemp).     
10e0: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
10f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1100: 20 20 20 20 20 66 6f 72 20 61 52 75 6c 65 20 69       for aRule i
1110: 6e 20 6c 54 6f 6b 65 6e 4c 69 6e 65 73 3a 0a 20  n lTokenLines:. 
1120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1130: 20 20 20 20 20 20 20 61 52 75 6c 65 2e 61 70 70         aRule.app
1140: 65 6e 64 28 73 54 6f 6b 65 6e 29 0a 20 20 20 20  end(sToken).    
1150: 66 6f 72 20 61 52 75 6c 65 20 69 6e 20 6c 54 6f  for aRule in lTo
1160: 6b 65 6e 4c 69 6e 65 73 3a 0a 20 20 20 20 20 20  kenLines:.      
1170: 20 20 79 69 65 6c 64 20 61 52 75 6c 65 0a 0a 0a    yield aRule...
1180: 64 65 66 20 63 72 65 61 74 65 52 75 6c 65 20 28  def createRule (
1190: 69 4c 69 6e 65 2c 20 73 52 75 6c 65 4e 61 6d 65  iLine, sRuleName
11a0: 2c 20 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20 69 41  , sTokenLine, iA
11b0: 63 74 69 6f 6e 42 6c 6f 63 6b 2c 20 73 41 63 74  ctionBlock, sAct
11c0: 69 6f 6e 73 2c 20 6e 50 72 69 6f 72 69 74 79 2c  ions, nPriority,
11d0: 20 64 44 65 66 29 3a 0a 20 20 20 20 22 67 65 6e   dDef):.    "gen
11e0: 65 72 61 74 6f 72 3a 20 63 72 65 61 74 65 20 72  erator: create r
11f0: 75 6c 65 20 61 73 20 6c 69 73 74 22 0a 20 20 20  ule as list".   
1200: 20 23 20 70 72 69 6e 74 28 69 4c 69 6e 65 2c 20   # print(iLine, 
1210: 22 2f 2f 22 2c 20 73 52 75 6c 65 4e 61 6d 65 2c  "//", sRuleName,
1220: 20 22 2f 2f 22 2c 20 73 54 6f 6b 65 6e 4c 69 6e   "//", sTokenLin
1230: 65 2c 20 22 2f 2f 22 2c 20 73 41 63 74 69 6f 6e  e, "//", sAction
1240: 73 2c 20 22 2f 2f 22 2c 20 6e 50 72 69 6f 72 69  s, "//", nPriori
1250: 74 79 29 0a 20 20 20 20 66 6f 72 20 6c 54 6f 6b  ty).    for lTok
1260: 65 6e 20 69 6e 20 67 65 6e 54 6f 6b 65 6e 4c 69  en in genTokenLi
1270: 6e 65 73 28 73 54 6f 6b 65 6e 4c 69 6e 65 2c 20  nes(sTokenLine, 
1280: 64 44 65 66 29 3a 0a 20 20 20 20 20 20 20 20 23  dDef):.        #
1290: 20 43 61 6c 63 75 6c 61 74 65 20 70 6f 73 69 74   Calculate posit
12a0: 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 64 50 6f  ions.        dPo
12b0: 73 20 3d 20 7b 7d 20 20 20 23 20 6b 65 79 3a 20  s = {}   # key: 
12c0: 69 47 72 6f 75 70 2c 20 76 61 6c 75 65 3a 20 69  iGroup, value: i
12d0: 54 6f 6b 65 6e 0a 20 20 20 20 20 20 20 20 69 47  Token.        iG
12e0: 72 6f 75 70 20 3d 20 30 0a 20 20 20 20 20 20 20  roup = 0.       
12f0: 20 66 6f 72 20 69 2c 20 73 54 6f 6b 65 6e 20 69   for i, sToken i
1300: 6e 20 65 6e 75 6d 65 72 61 74 65 28 6c 54 6f 6b  n enumerate(lTok
1310: 65 6e 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  en):.           
1320: 20 69 66 20 73 54 6f 6b 65 6e 2e 73 74 61 72 74   if sToken.start
1330: 73 77 69 74 68 28 22 28 22 29 20 61 6e 64 20 73  swith("(") and s
1340: 54 6f 6b 65 6e 2e 65 6e 64 73 77 69 74 68 28 22  Token.endswith("
1350: 29 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  )"):.           
1360: 20 20 20 20 20 6c 54 6f 6b 65 6e 5b 69 5d 20 3d       lToken[i] =
1370: 20 73 54 6f 6b 65 6e 5b 31 3a 2d 31 5d 0a 20 20   sToken[1:-1].  
1380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 47                iG
1390: 72 6f 75 70 20 2b 3d 20 31 0a 20 20 20 20 20 20  roup += 1.      
13a0: 20 20 20 20 20 20 20 20 20 20 64 50 6f 73 5b 69            dPos[i
13b0: 47 72 6f 75 70 5d 20 3d 20 69 20 2b 20 31 20 20  Group] = i + 1  
13c0: 20 20 23 20 77 65 20 61 64 64 20 31 2c 20 66 6f    # we add 1, fo
13d0: 72 20 77 65 20 63 6f 75 6e 74 20 74 6f 6b 65 6e  r we count token
13e0: 73 20 66 72 6f 6d 20 31 20 74 6f 20 6e 20 28 6e  s from 1 to n (n
13f0: 6f 74 20 66 72 6f 6d 20 30 29 0a 0a 20 20 20 20  ot from 0)..    
1400: 20 20 20 20 23 20 50 61 72 73 65 20 61 63 74 69      # Parse acti
1410: 6f 6e 73 0a 20 20 20 20 20 20 20 20 66 6f 72 20  ons.        for 
1420: 69 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e  iAction, sAction
1430: 20 69 6e 20 65 6e 75 6d 65 72 61 74 65 28 73 41   in enumerate(sA
1440: 63 74 69 6f 6e 73 2e 73 70 6c 69 74 28 22 20 3c  ctions.split(" <
1450: 3c 2d 20 22 29 2c 20 31 29 3a 0a 20 20 20 20 20  <- "), 1):.     
1460: 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d         sAction =
1470: 20 73 41 63 74 69 6f 6e 2e 73 74 72 69 70 28 29   sAction.strip()
1480: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
1490: 73 41 63 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20  sAction:.       
14a0: 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e           sAction
14b0: 49 64 20 3d 20 73 52 75 6c 65 4e 61 6d 65 20 2b  Id = sRuleName +
14c0: 20 22 5f 5f 62 22 20 2b 20 73 74 72 28 69 41 63   "__b" + str(iAc
14d0: 74 69 6f 6e 42 6c 6f 63 6b 29 20 2b 20 22 5f 61  tionBlock) + "_a
14e0: 22 20 2b 20 73 74 72 28 69 41 63 74 69 6f 6e 29  " + str(iAction)
14f0: 20 2b 20 22 5f 22 20 2b 20 73 74 72 28 6c 65 6e   + "_" + str(len
1500: 28 6c 54 6f 6b 65 6e 29 29 0a 20 20 20 20 20 20  (lToken)).      
1510: 20 20 20 20 20 20 20 20 20 20 61 41 63 74 69 6f            aActio
1520: 6e 20 3d 20 63 72 65 61 74 65 41 63 74 69 6f 6e  n = createAction
1530: 28 73 41 63 74 69 6f 6e 49 64 2c 20 73 41 63 74  (sActionId, sAct
1540: 69 6f 6e 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20  ion, nPriority, 
1550: 6c 65 6e 28 6c 54 6f 6b 65 6e 29 2c 20 64 50 6f  len(lToken), dPo
1560: 73 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  s).             
1570: 20 20 20 69 66 20 61 41 63 74 69 6f 6e 3a 0a 20     if aAction:. 
1580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1590: 20 20 20 64 41 43 54 49 4f 4e 53 5b 73 41 63 74     dACTIONS[sAct
15a0: 69 6f 6e 49 64 5d 20 3d 20 61 41 63 74 69 6f 6e  ionId] = aAction
15b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
15c0: 20 20 20 20 20 6c 52 65 73 75 6c 74 20 3d 20 6c       lResult = l
15d0: 69 73 74 28 6c 54 6f 6b 65 6e 29 0a 20 20 20 20  ist(lToken).    
15e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15f0: 6c 52 65 73 75 6c 74 2e 65 78 74 65 6e 64 28 5b  lResult.extend([
1600: 22 23 23 22 2b 73 74 72 28 69 4c 69 6e 65 29 2c  "##"+str(iLine),
1610: 20 73 41 63 74 69 6f 6e 49 64 5d 29 0a 20 20 20   sActionId]).   
1620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1630: 20 79 69 65 6c 64 20 6c 52 65 73 75 6c 74 0a 0a   yield lResult..
1640: 0a 64 65 66 20 63 68 61 6e 67 65 52 65 66 65 72  .def changeRefer
1650: 65 6e 63 65 54 6f 6b 65 6e 20 28 73 54 65 78 74  enceToken (sText
1660: 2c 20 64 50 6f 73 29 3a 0a 20 20 20 20 22 63 68  , dPos):.    "ch
1670: 61 6e 67 65 20 67 72 6f 75 70 20 72 65 66 65 72  ange group refer
1680: 65 6e 63 65 20 69 6e 20 3c 73 54 65 78 74 3e 20  ence in <sText> 
1690: 77 69 74 68 20 76 61 6c 75 65 73 20 69 6e 20 3c  with values in <
16a0: 64 50 6f 73 3e 22 0a 20 20 20 20 66 6f 72 20 69  dPos>".    for i
16b0: 20 69 6e 20 72 61 6e 67 65 28 6c 65 6e 28 64 50   in range(len(dP
16c0: 6f 73 29 2c 20 30 2c 20 2d 31 29 3a 0a 20 20 20  os), 0, -1):.   
16d0: 20 20 20 20 20 73 54 65 78 74 20 3d 20 73 54 65       sText = sTe
16e0: 78 74 2e 72 65 70 6c 61 63 65 28 22 5c 5c 22 2b  xt.replace("\\"+
16f0: 73 74 72 28 69 29 2c 20 22 5c 5c 22 2b 73 74 72  str(i), "\\"+str
1700: 28 64 50 6f 73 5b 69 5d 29 29 0a 20 20 20 20 72  (dPos[i])).    r
1710: 65 74 75 72 6e 20 73 54 65 78 74 0a 0a 0a 64 65  eturn sText...de
1720: 66 20 63 68 65 63 6b 54 6f 6b 65 6e 4e 75 6d 62  f checkTokenNumb
1730: 65 72 73 20 28 73 54 65 78 74 2c 20 73 41 63 74  ers (sText, sAct
1740: 69 6f 6e 49 64 2c 20 6e 54 6f 6b 65 6e 29 3a 0a  ionId, nToken):.
1750: 20 20 20 20 22 63 68 65 63 6b 20 69 66 20 74 6f      "check if to
1760: 6b 65 6e 20 72 65 66 65 72 65 6e 63 65 73 20 69  ken references i
1770: 6e 20 3c 73 54 65 78 74 3e 20 67 72 65 61 74 65  n <sText> greate
1780: 72 20 74 68 61 6e 20 3c 6e 54 6f 6b 65 6e 3e 20  r than <nToken> 
1790: 28 64 65 62 75 67 67 69 6e 67 29 22 0a 20 20 20  (debugging)".   
17a0: 20 66 6f 72 20 78 20 69 6e 20 72 65 2e 66 69 6e   for x in re.fin
17b0: 64 69 74 65 72 28 72 22 5c 5c 28 5c 64 2b 29 22  diter(r"\\(\d+)"
17c0: 2c 20 73 54 65 78 74 29 3a 0a 20 20 20 20 20 20  , sText):.      
17d0: 20 20 69 66 20 69 6e 74 28 78 2e 67 72 6f 75 70    if int(x.group
17e0: 28 31 29 29 20 3e 20 6e 54 6f 6b 65 6e 3a 0a 20  (1)) > nToken:. 
17f0: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
1800: 28 22 23 20 45 72 72 6f 72 20 69 6e 20 74 6f 6b  ("# Error in tok
1810: 65 6e 20 69 6e 64 65 78 20 61 74 20 6c 69 6e 65  en index at line
1820: 20 22 20 2b 20 73 41 63 74 69 6f 6e 49 64 20 2b   " + sActionId +
1830: 20 22 20 28 22 2b 73 74 72 28 6e 54 6f 6b 65 6e   " ("+str(nToken
1840: 29 2b 22 20 74 6f 6b 65 6e 73 20 6f 6e 6c 79 29  )+" tokens only)
1850: 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  ").            p
1860: 72 69 6e 74 28 73 54 65 78 74 29 0a 0a 0a 64 65  rint(sText)...de
1870: 66 20 63 68 65 63 6b 49 66 54 68 65 72 65 49 73  f checkIfThereIs
1880: 43 6f 64 65 20 28 73 54 65 78 74 2c 20 73 41 63  Code (sText, sAc
1890: 74 69 6f 6e 49 64 29 3a 0a 20 20 20 20 22 63 68  tionId):.    "ch
18a0: 65 63 6b 20 69 66 20 74 68 65 72 65 20 69 73 20  eck if there is 
18b0: 63 6f 64 65 20 69 6e 20 3c 73 54 65 78 74 3e 20  code in <sText> 
18c0: 28 64 65 62 75 67 67 69 6e 67 29 22 0a 20 20 20  (debugging)".   
18d0: 20 69 66 20 72 65 2e 73 65 61 72 63 68 28 22 5b   if re.search("[
18e0: 2e 5d 5c 5c 77 2b 5b 28 5d 7c 73 75 67 67 5c 5c  .]\\w+[(]|sugg\\
18f0: 77 2b 5b 28 5d 7c 5c 5c 28 5b 30 2d 39 5d 7c 5c  w+[(]|\\([0-9]|\
1900: 5c 5b 5b 30 2d 39 5d 22 2c 20 73 54 65 78 74 29  \[[0-9]", sText)
1910: 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28  :.        print(
1920: 22 23 20 57 61 72 6e 69 6e 67 20 61 74 20 6c 69  "# Warning at li
1930: 6e 65 20 22 20 2b 20 73 41 63 74 69 6f 6e 49 64  ne " + sActionId
1940: 20 2b 20 22 3a 20 20 54 68 69 73 20 6d 65 73 73   + ":  This mess
1950: 61 67 65 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20 63  age looks like c
1960: 6f 64 65 2e 20 4c 69 6e 65 20 73 68 6f 75 6c 64  ode. Line should
1970: 20 70 72 6f 62 61 62 6c 79 20 62 65 67 69 6e 20   probably begin 
1980: 77 69 74 68 20 3d 22 29 0a 20 20 20 20 20 20 20  with =").       
1990: 20 70 72 69 6e 74 28 73 54 65 78 74 29 0a 0a 0a   print(sText)...
19a0: 64 65 66 20 63 72 65 61 74 65 41 63 74 69 6f 6e  def createAction
19b0: 20 28 73 41 63 74 69 6f 6e 49 64 2c 20 73 41 63   (sActionId, sAc
19c0: 74 69 6f 6e 2c 20 6e 50 72 69 6f 72 69 74 79 2c  tion, nPriority,
19d0: 20 6e 54 6f 6b 65 6e 2c 20 64 50 6f 73 29 3a 0a   nToken, dPos):.
19e0: 20 20 20 20 22 63 72 65 61 74 65 20 61 63 74 69      "create acti
19f0: 6f 6e 20 72 75 6c 65 20 61 73 20 61 20 6c 69 73  on rule as a lis
1a00: 74 22 0a 20 20 20 20 23 20 4f 70 74 69 6f 6e 0a  t".    # Option.
1a10: 20 20 20 20 73 4f 70 74 69 6f 6e 20 3d 20 46 61      sOption = Fa
1a20: 6c 73 65 0a 20 20 20 20 6d 20 3d 20 72 65 2e 6d  lse.    m = re.m
1a30: 61 74 63 68 28 22 2f 28 5c 5c 77 2b 29 2f 22 2c  atch("/(\\w+)/",
1a40: 20 73 41 63 74 69 6f 6e 29 0a 20 20 20 20 69 66   sAction).    if
1a50: 20 6d 3a 0a 20 20 20 20 20 20 20 20 73 4f 70 74   m:.        sOpt
1a60: 69 6f 6e 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29  ion = m.group(1)
1a70: 0a 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e  .        sAction
1a80: 20 3d 20 73 41 63 74 69 6f 6e 5b 6d 2e 65 6e 64   = sAction[m.end
1a90: 28 29 3a 5d 2e 73 74 72 69 70 28 29 0a 20 20 20  ():].strip().   
1aa0: 20 23 20 76 61 6c 69 64 20 61 63 74 69 6f 6e 3f   # valid action?
1ab0: 0a 20 20 20 20 6d 20 3d 20 72 65 2e 73 65 61 72  .    m = re.sear
1ac0: 63 68 28 22 28 3f 50 3c 61 63 74 69 6f 6e 3e 5b  ch("(?P<action>[
1ad0: 2d 7e 3d 2f 5d 29 28 3f 50 3c 73 74 61 72 74 3e  -~=/])(?P<start>
1ae0: 5c 5c 64 2b 7c 29 28 3f 50 3c 65 6e 64 3e 3a 5c  \\d+|)(?P<end>:\
1af0: 5c 64 2b 7c 29 3e 3e 20 22 2c 20 73 41 63 74 69  \d+|)>> ", sActi
1b00: 6f 6e 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6d  on).    if not m
1b10: 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28  :.        print(
1b20: 22 20 23 20 45 72 72 6f 72 2e 20 4e 6f 20 61 63  " # Error. No ac
1b30: 74 69 6f 6e 20 66 6f 75 6e 64 20 61 74 3a 20 22  tion found at: "
1b40: 2c 20 73 41 63 74 69 6f 6e 49 64 29 0a 20 20 20  , sActionId).   
1b50: 20 20 20 20 20 70 72 69 6e 74 28 22 20 20 20 3d       print("   =
1b60: 3d 22 2c 20 73 41 63 74 69 6f 6e 2c 20 22 3d 3d  =", sAction, "==
1b70: 22 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ").        retur
1b80: 6e 20 4e 6f 6e 65 0a 20 20 20 20 23 20 43 6f 6e  n None.    # Con
1b90: 64 69 74 69 6f 6e 0a 20 20 20 20 73 43 6f 6e 64  dition.    sCond
1ba0: 69 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b  ition = sAction[
1bb0: 3a 6d 2e 73 74 61 72 74 28 29 5d 2e 73 74 72 69  :m.start()].stri
1bc0: 70 28 29 0a 20 20 20 20 69 66 20 73 43 6f 6e 64  p().    if sCond
1bd0: 69 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 73  ition:.        s
1be0: 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 70 72 65 70  Condition = prep
1bf0: 61 72 65 46 75 6e 63 74 69 6f 6e 28 73 43 6f 6e  areFunction(sCon
1c00: 64 69 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20  dition).        
1c10: 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 63 68 61  sCondition = cha
1c20: 6e 67 65 52 65 66 65 72 65 6e 63 65 54 6f 6b 65  ngeReferenceToke
1c30: 6e 28 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 64 50  n(sCondition, dP
1c40: 6f 73 29 0a 20 20 20 20 20 20 20 20 64 46 55 4e  os).        dFUN
1c50: 43 54 49 4f 4e 53 5b 22 5f 67 5f 63 5f 22 2b 73  CTIONS["_g_c_"+s
1c60: 41 63 74 69 6f 6e 49 64 5d 20 3d 20 73 43 6f 6e  ActionId] = sCon
1c70: 64 69 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 73  dition.        s
1c80: 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 22 5f 67 5f  Condition = "_g_
1c90: 63 5f 22 2b 73 41 63 74 69 6f 6e 49 64 0a 20 20  c_"+sActionId.  
1ca0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
1cb0: 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 22 22 0a  sCondition = "".
1cc0: 20 20 20 20 23 20 41 63 74 69 6f 6e 0a 20 20 20      # Action.   
1cd0: 20 63 41 63 74 69 6f 6e 20 3d 20 6d 2e 67 72 6f   cAction = m.gro
1ce0: 75 70 28 22 61 63 74 69 6f 6e 22 29 0a 20 20 20  up("action").   
1cf0: 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69   sAction = sActi
1d00: 6f 6e 5b 6d 2e 65 6e 64 28 29 3a 5d 2e 73 74 72  on[m.end():].str
1d10: 69 70 28 29 0a 20 20 20 20 73 41 63 74 69 6f 6e  ip().    sAction
1d20: 20 3d 20 63 68 61 6e 67 65 52 65 66 65 72 65 6e   = changeReferen
1d30: 63 65 54 6f 6b 65 6e 28 73 41 63 74 69 6f 6e 2c  ceToken(sAction,
1d40: 20 64 50 6f 73 29 0a 20 20 20 20 69 66 20 6e 6f   dPos).    if no
1d50: 74 20 6d 2e 67 72 6f 75 70 28 22 73 74 61 72 74  t m.group("start
1d60: 22 29 3a 0a 20 20 20 20 20 20 20 20 69 53 74 61  "):.        iSta
1d70: 72 74 41 63 74 69 6f 6e 20 3d 20 31 0a 20 20 20  rtAction = 1.   
1d80: 20 20 20 20 20 69 45 6e 64 41 63 74 69 6f 6e 20       iEndAction 
1d90: 3d 20 30 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20  = 0.    else:.  
1da0: 20 20 20 20 20 20 69 53 74 61 72 74 41 63 74 69        iStartActi
1db0: 6f 6e 20 3d 20 69 6e 74 28 6d 2e 67 72 6f 75 70  on = int(m.group
1dc0: 28 22 73 74 61 72 74 22 29 29 0a 20 20 20 20 20  ("start")).     
1dd0: 20 20 20 69 45 6e 64 41 63 74 69 6f 6e 20 3d 20     iEndAction = 
1de0: 69 6e 74 28 6d 2e 67 72 6f 75 70 28 22 65 6e 64  int(m.group("end
1df0: 22 29 5b 31 3a 5d 29 20 20 69 66 20 6d 2e 67 72  ")[1:])  if m.gr
1e00: 6f 75 70 28 22 65 6e 64 22 29 20 20 65 6c 73 65  oup("end")  else
1e10: 20 69 53 74 61 72 74 41 63 74 69 6f 6e 0a 20 20   iStartAction.  
1e20: 20 20 69 66 20 64 50 6f 73 20 61 6e 64 20 6d 2e    if dPos and m.
1e30: 67 72 6f 75 70 28 22 73 74 61 72 74 22 29 3a 0a  group("start"):.
1e40: 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20 20 20          try:.   
1e50: 20 20 20 20 20 20 20 20 20 69 53 74 61 72 74 41           iStartA
1e60: 63 74 69 6f 6e 20 3d 20 64 50 6f 73 5b 69 53 74  ction = dPos[iSt
1e70: 61 72 74 41 63 74 69 6f 6e 5d 0a 20 20 20 20 20  artAction].     
1e80: 20 20 20 20 20 20 20 69 66 20 69 45 6e 64 41 63         if iEndAc
1e90: 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 20 20  tion:.          
1ea0: 20 20 20 20 20 20 69 45 6e 64 41 63 74 69 6f 6e        iEndAction
1eb0: 20 3d 20 64 50 6f 73 5b 69 45 6e 64 41 63 74 69   = dPos[iEndActi
1ec0: 6f 6e 5d 0a 20 20 20 20 20 20 20 20 65 78 63 65  on].        exce
1ed0: 70 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  pt:.            
1ee0: 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 2e 20  print("# Error. 
1ef0: 57 72 6f 6e 67 20 67 72 6f 75 70 73 20 69 6e 3a  Wrong groups in:
1f00: 20 22 20 2b 20 73 41 63 74 69 6f 6e 49 64 29 0a   " + sActionId).
1f10: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
1f20: 74 28 22 20 20 69 53 74 61 72 74 41 63 74 69 6f  t("  iStartActio
1f30: 6e 3a 22 2c 20 69 53 74 61 72 74 41 63 74 69 6f  n:", iStartActio
1f40: 6e 2c 20 22 69 45 6e 64 41 63 74 69 6f 6e 3a 22  n, "iEndAction:"
1f50: 2c 20 69 45 6e 64 41 63 74 69 6f 6e 29 0a 20 20  , iEndAction).  
1f60: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
1f70: 22 20 22 2c 20 64 50 6f 73 29 0a 0a 20 20 20 20  " ", dPos)..    
1f80: 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 2d  if cAction == "-
1f90: 22 3a 0a 20 20 20 20 20 20 20 20 23 23 20 65 72  ":.        ## er
1fa0: 72 6f 72 0a 20 20 20 20 20 20 20 20 69 4d 73 67  ror.        iMsg
1fb0: 20 3d 20 73 41 63 74 69 6f 6e 2e 66 69 6e 64 28   = sAction.find(
1fc0: 22 20 23 20 22 29 0a 20 20 20 20 20 20 20 20 69  " # ").        i
1fd0: 66 20 69 4d 73 67 20 3d 3d 20 2d 31 3a 0a 20 20  f iMsg == -1:.  
1fe0: 20 20 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d            sMsg =
1ff0: 20 22 23 20 45 72 72 6f 72 2e 20 45 72 72 6f 72   "# Error. Error
2000: 20 6d 65 73 73 61 67 65 20 6e 6f 74 20 66 6f 75   message not fou
2010: 6e 64 2e 22 0a 20 20 20 20 20 20 20 20 20 20 20  nd.".           
2020: 20 73 55 52 4c 20 3d 20 22 22 0a 20 20 20 20 20   sURL = "".     
2030: 20 20 20 20 20 20 20 70 72 69 6e 74 28 73 4d 73         print(sMs
2040: 67 20 2b 20 22 20 41 63 74 69 6f 6e 20 69 64 3a  g + " Action id:
2050: 20 22 20 2b 20 73 41 63 74 69 6f 6e 49 64 29 0a   " + sActionId).
2060: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
2070: 20 20 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d            sMsg =
2080: 20 73 41 63 74 69 6f 6e 5b 69 4d 73 67 2b 33 3a   sAction[iMsg+3:
2090: 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20 20  ].strip().      
20a0: 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20        sAction = 
20b0: 73 41 63 74 69 6f 6e 5b 3a 69 4d 73 67 5d 2e 73  sAction[:iMsg].s
20c0: 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 20  trip().         
20d0: 20 20 20 73 55 52 4c 20 3d 20 22 22 0a 20 20 20     sURL = "".   
20e0: 20 20 20 20 20 20 20 20 20 6d 55 52 4c 20 3d 20           mURL = 
20f0: 72 65 2e 73 65 61 72 63 68 28 22 5b 7c 5d 20 2a  re.search("[|] *
2100: 28 68 74 74 70 73 3f 3a 2f 2f 2e 2a 29 22 2c 20  (https?://.*)", 
2110: 73 4d 73 67 29 0a 20 20 20 20 20 20 20 20 20 20  sMsg).          
2120: 20 20 69 66 20 6d 55 52 4c 3a 0a 20 20 20 20 20    if mURL:.     
2130: 20 20 20 20 20 20 20 20 20 20 20 73 55 52 4c 20             sURL 
2140: 3d 20 6d 55 52 4c 2e 67 72 6f 75 70 28 31 29 2e  = mURL.group(1).
2150: 73 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20  strip().        
2160: 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 73          sMsg = s
2170: 4d 73 67 5b 3a 6d 55 52 4c 2e 73 74 61 72 74 28  Msg[:mURL.start(
2180: 30 29 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20  0)].strip().    
2190: 20 20 20 20 20 20 20 20 63 68 65 63 6b 54 6f 6b          checkTok
21a0: 65 6e 4e 75 6d 62 65 72 73 28 73 4d 73 67 2c 20  enNumbers(sMsg, 
21b0: 73 41 63 74 69 6f 6e 49 64 2c 20 6e 54 6f 6b 65  sActionId, nToke
21c0: 6e 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  n).            i
21d0: 66 20 73 4d 73 67 5b 30 3a 31 5d 20 3d 3d 20 22  f sMsg[0:1] == "
21e0: 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  =":.            
21f0: 20 20 20 20 73 4d 73 67 20 3d 20 70 72 65 70 61      sMsg = prepa
2200: 72 65 46 75 6e 63 74 69 6f 6e 28 73 4d 73 67 5b  reFunction(sMsg[
2210: 31 3a 5d 2c 20 54 72 75 65 29 0a 20 20 20 20 20  1:], True).     
2220: 20 20 20 20 20 20 20 20 20 20 20 64 46 55 4e 43             dFUNC
2230: 54 49 4f 4e 53 5b 22 67 5f 6d 5f 22 2b 73 41 63  TIONS["g_m_"+sAc
2240: 74 69 6f 6e 49 64 5d 20 3d 20 73 4d 73 67 0a 20  tionId] = sMsg. 
2250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
2260: 4d 73 67 20 3d 20 22 3d 67 5f 6d 5f 22 2b 73 41  Msg = "=g_m_"+sA
2270: 63 74 69 6f 6e 49 64 0a 20 20 20 20 20 20 20 20  ctionId.        
2280: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
2290: 20 20 20 20 20 20 20 20 20 20 63 68 65 63 6b 49            checkI
22a0: 66 54 68 65 72 65 49 73 43 6f 64 65 28 73 4d 73  fThereIsCode(sMs
22b0: 67 2c 20 73 41 63 74 69 6f 6e 49 64 29 0a 0a 20  g, sActionId).. 
22c0: 20 20 20 23 20 63 68 65 63 6b 69 6e 67 20 63 6f     # checking co
22d0: 6e 73 69 73 74 61 6e 63 79 0a 20 20 20 20 63 68  nsistancy.    ch
22e0: 65 63 6b 54 6f 6b 65 6e 4e 75 6d 62 65 72 73 28  eckTokenNumbers(
22f0: 73 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e  sAction, sAction
2300: 49 64 2c 20 6e 54 6f 6b 65 6e 29 0a 0a 20 20 20  Id, nToken)..   
2310: 20 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22   if cAction == "
2320: 3e 22 3a 0a 20 20 20 20 20 20 20 20 23 23 20 6e  >":.        ## n
2330: 6f 20 61 63 74 69 6f 6e 2c 20 62 72 65 61 6b 20  o action, break 
2340: 6c 6f 6f 70 20 69 66 20 63 6f 6e 64 69 74 69 6f  loop if conditio
2350: 6e 20 69 73 20 46 61 6c 73 65 0a 20 20 20 20 20  n is False.     
2360: 20 20 20 72 65 74 75 72 6e 20 5b 73 4f 70 74 69     return [sOpti
2370: 6f 6e 2c 20 73 43 6f 6e 64 69 74 69 6f 6e 2c 20  on, sCondition, 
2380: 63 41 63 74 69 6f 6e 2c 20 22 22 5d 0a 0a 20 20  cAction, ""]..  
2390: 20 20 69 66 20 6e 6f 74 20 73 41 63 74 69 6f 6e    if not sAction
23a0: 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28  :.        print(
23b0: 22 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69  "# Error in acti
23c0: 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  on at line " + s
23d0: 41 63 74 69 6f 6e 49 64 20 2b 20 22 3a 20 20 54  ActionId + ":  T
23e0: 68 69 73 20 61 63 74 69 6f 6e 20 69 73 20 65 6d  his action is em
23f0: 70 74 79 2e 22 29 0a 0a 20 20 20 20 69 66 20 73  pty.")..    if s
2400: 41 63 74 69 6f 6e 5b 30 3a 31 5d 20 21 3d 20 22  Action[0:1] != "
2410: 3d 22 3a 0a 20 20 20 20 20 20 20 20 63 68 65 63  =":.        chec
2420: 6b 49 66 54 68 65 72 65 49 73 43 6f 64 65 28 73  kIfThereIsCode(s
2430: 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 49  Action, sActionI
2440: 64 29 0a 0a 20 20 20 20 69 66 20 63 41 63 74 69  d)..    if cActi
2450: 6f 6e 20 3d 3d 20 22 2d 22 3a 0a 20 20 20 20 20  on == "-":.     
2460: 20 20 20 23 23 20 65 72 72 6f 72 20 64 65 74 65     ## error dete
2470: 63 74 65 64 20 2d 2d 3e 20 73 75 67 67 65 73 74  cted --> suggest
2480: 69 6f 6e 0a 20 20 20 20 20 20 20 20 69 66 20 73  ion.        if s
2490: 41 63 74 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22  Action[0:1] == "
24a0: 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  =":.            
24b0: 73 41 63 74 69 6f 6e 20 3d 20 70 72 65 70 61 72  sAction = prepar
24c0: 65 46 75 6e 63 74 69 6f 6e 28 73 41 63 74 69 6f  eFunction(sActio
24d0: 6e 2c 20 54 72 75 65 29 0a 20 20 20 20 20 20 20  n, True).       
24e0: 20 20 20 20 20 64 46 55 4e 43 54 49 4f 4e 53 5b       dFUNCTIONS[
24f0: 22 5f 67 5f 73 5f 22 2b 73 41 63 74 69 6f 6e 49  "_g_s_"+sActionI
2500: 64 5d 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a 5d  d] = sAction[1:]
2510: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 41 63  .            sAc
2520: 74 69 6f 6e 20 3d 20 22 3d 5f 67 5f 73 5f 22 2b  tion = "=_g_s_"+
2530: 73 41 63 74 69 6f 6e 49 64 0a 20 20 20 20 20 20  sActionId.      
2540: 20 20 65 6c 69 66 20 73 41 63 74 69 6f 6e 2e 73    elif sAction.s
2550: 74 61 72 74 73 77 69 74 68 28 27 22 27 29 20 61  tartswith('"') a
2560: 6e 64 20 73 41 63 74 69 6f 6e 2e 65 6e 64 73 77  nd sAction.endsw
2570: 69 74 68 28 27 22 27 29 3a 0a 20 20 20 20 20 20  ith('"'):.      
2580: 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20        sAction = 
2590: 73 41 63 74 69 6f 6e 5b 31 3a 2d 31 5d 0a 20 20  sAction[1:-1].  
25a0: 20 20 20 20 20 20 69 66 20 6e 6f 74 20 73 4d 73        if not sMs
25b0: 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  g:.            p
25c0: 72 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69 6e  rint("# Error in
25d0: 20 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20   action at line 
25e0: 22 20 2b 20 73 41 63 74 69 6f 6e 49 64 20 2b 20  " + sActionId + 
25f0: 22 3a 20 20 54 68 65 20 6d 65 73 73 61 67 65 20  ":  The message 
2600: 69 73 20 65 6d 70 74 79 2e 22 29 0a 20 20 20 20  is empty.").    
2610: 20 20 20 20 72 65 74 75 72 6e 20 5b 73 4f 70 74      return [sOpt
2620: 69 6f 6e 2c 20 73 43 6f 6e 64 69 74 69 6f 6e 2c  ion, sCondition,
2630: 20 63 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f   cAction, sActio
2640: 6e 2c 20 69 53 74 61 72 74 41 63 74 69 6f 6e 2c  n, iStartAction,
2650: 20 69 45 6e 64 41 63 74 69 6f 6e 2c 20 6e 50 72   iEndAction, nPr
2660: 69 6f 72 69 74 79 2c 20 73 4d 73 67 2c 20 73 55  iority, sMsg, sU
2670: 52 4c 5d 0a 20 20 20 20 65 6c 69 66 20 63 41 63  RL].    elif cAc
2680: 74 69 6f 6e 20 3d 3d 20 22 7e 22 3a 0a 20 20 20  tion == "~":.   
2690: 20 20 20 20 20 23 23 20 74 65 78 74 20 70 72 6f       ## text pro
26a0: 63 65 73 73 6f 72 0a 20 20 20 20 20 20 20 20 69  cessor.        i
26b0: 66 20 73 41 63 74 69 6f 6e 5b 30 3a 31 5d 20 3d  f sAction[0:1] =
26c0: 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20  = "=":.         
26d0: 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 70 72 65     sAction = pre
26e0: 70 61 72 65 46 75 6e 63 74 69 6f 6e 28 73 41 63  pareFunction(sAc
26f0: 74 69 6f 6e 2c 20 54 72 75 65 29 0a 20 20 20 20  tion, True).    
2700: 20 20 20 20 20 20 20 20 64 46 55 4e 43 54 49 4f          dFUNCTIO
2710: 4e 53 5b 22 5f 67 5f 70 5f 22 2b 73 41 63 74 69  NS["_g_p_"+sActi
2720: 6f 6e 49 64 5d 20 3d 20 73 41 63 74 69 6f 6e 5b  onId] = sAction[
2730: 31 3a 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  1:].            
2740: 73 41 63 74 69 6f 6e 20 3d 20 22 3d 5f 67 5f 70  sAction = "=_g_p
2750: 5f 22 2b 73 41 63 74 69 6f 6e 49 64 0a 20 20 20  _"+sActionId.   
2760: 20 20 20 20 20 65 6c 69 66 20 73 41 63 74 69 6f       elif sActio
2770: 6e 2e 73 74 61 72 74 73 77 69 74 68 28 27 22 27  n.startswith('"'
2780: 29 20 61 6e 64 20 73 41 63 74 69 6f 6e 2e 65 6e  ) and sAction.en
2790: 64 73 77 69 74 68 28 27 22 27 29 3a 0a 20 20 20  dswith('"'):.   
27a0: 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e           sAction
27b0: 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a 2d 31 5d   = sAction[1:-1]
27c0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
27d0: 5b 73 4f 70 74 69 6f 6e 2c 20 73 43 6f 6e 64 69  [sOption, sCondi
27e0: 74 69 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73  tion, cAction, s
27f0: 41 63 74 69 6f 6e 2c 20 69 53 74 61 72 74 41 63  Action, iStartAc
2800: 74 69 6f 6e 2c 20 69 45 6e 64 41 63 74 69 6f 6e  tion, iEndAction
2810: 5d 0a 20 20 20 20 65 6c 69 66 20 63 41 63 74 69  ].    elif cActi
2820: 6f 6e 20 3d 3d 20 22 2f 22 3a 0a 20 20 20 20 20  on == "/":.     
2830: 20 20 20 23 23 20 74 61 67 73 0a 20 20 20 20 20     ## tags.     
2840: 20 20 20 72 65 74 75 72 6e 20 5b 73 4f 70 74 69     return [sOpti
2850: 6f 6e 2c 20 73 43 6f 6e 64 69 74 69 6f 6e 2c 20  on, sCondition, 
2860: 63 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e  cAction, sAction
2870: 2c 20 69 53 74 61 72 74 41 63 74 69 6f 6e 2c 20  , iStartAction, 
2880: 69 45 6e 64 41 63 74 69 6f 6e 5d 0a 20 20 20 20  iEndAction].    
2890: 65 6c 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d 20  elif cAction == 
28a0: 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 23 23 20  "=":.        ## 
28b0: 64 69 73 61 6d 62 69 67 75 61 74 6f 72 0a 20 20  disambiguator.  
28c0: 20 20 20 20 20 20 69 66 20 73 41 63 74 69 6f 6e        if sAction
28d0: 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20  [0:1] == "=":.  
28e0: 20 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f            sActio
28f0: 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a 5d 0a  n = sAction[1:].
2900: 20 20 20 20 20 20 20 20 69 66 20 22 64 65 66 69          if "defi
2910: 6e 65 22 20 69 6e 20 73 41 63 74 69 6f 6e 20 61  ne" in sAction a
2920: 6e 64 20 6e 6f 74 20 72 65 2e 73 65 61 72 63 68  nd not re.search
2930: 28 72 22 64 65 66 69 6e 65 5c 28 5c 5c 5c 64 2b  (r"define\(\\\d+
2940: 20 2a 2c 20 2a 5c 5b 2e 2a 5c 5d 20 2a 5c 29 22   *, *\[.*\] *\)"
2950: 2c 20 73 41 63 74 69 6f 6e 29 3a 0a 20 20 20 20  , sAction):.    
2960: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
2970: 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69 6f 6e   Error in action
2980: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 41 63   at line " + sAc
2990: 74 69 6f 6e 49 64 20 2b 20 22 3a 20 73 65 63 6f  tionId + ": seco
29a0: 6e 64 20 61 72 67 75 6d 65 6e 74 20 66 6f 72 20  nd argument for 
29b0: 3c 64 65 66 69 6e 65 3e 20 6d 75 73 74 20 62 65  <define> must be
29c0: 20 61 20 6c 69 73 74 20 6f 66 20 73 74 72 69 6e   a list of strin
29d0: 67 73 22 29 0a 20 20 20 20 20 20 20 20 73 41 63  gs").        sAc
29e0: 74 69 6f 6e 20 3d 20 70 72 65 70 61 72 65 46 75  tion = prepareFu
29f0: 6e 63 74 69 6f 6e 28 73 41 63 74 69 6f 6e 29 0a  nction(sAction).
2a00: 20 20 20 20 20 20 20 20 64 46 55 4e 43 54 49 4f          dFUNCTIO
2a10: 4e 53 5b 22 5f 67 5f 64 5f 22 2b 73 41 63 74 69  NS["_g_d_"+sActi
2a20: 6f 6e 49 64 5d 20 3d 20 73 41 63 74 69 6f 6e 0a  onId] = sAction.
2a30: 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20          sAction 
2a40: 3d 20 22 5f 67 5f 64 5f 22 2b 73 41 63 74 69 6f  = "_g_d_"+sActio
2a50: 6e 49 64 0a 20 20 20 20 20 20 20 20 72 65 74 75  nId.        retu
2a60: 72 6e 20 5b 73 4f 70 74 69 6f 6e 2c 20 73 43 6f  rn [sOption, sCo
2a70: 6e 64 69 74 69 6f 6e 2c 20 63 41 63 74 69 6f 6e  ndition, cAction
2a80: 2c 20 73 41 63 74 69 6f 6e 5d 0a 20 20 20 20 65  , sAction].    e
2a90: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 70 72 69  lse:.        pri
2aa0: 6e 74 28 22 23 20 55 6e 6b 6e 6f 77 6e 20 61 63  nt("# Unknown ac
2ab0: 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b  tion at line " +
2ac0: 20 73 41 63 74 69 6f 6e 49 64 29 0a 20 20 20 20   sActionId).    
2ad0: 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a      return None.
2ae0: 0a 0a 64 65 66 20 63 68 65 63 6b 52 65 67 65 78  ..def checkRegex
2af0: 65 73 20 28 64 41 6c 6c 47 72 61 70 68 29 3a 0a  es (dAllGraph):.
2b00: 20 20 20 20 22 63 68 65 63 6b 20 76 61 6c 69 64      "check valid
2b10: 69 74 79 20 6f 66 20 72 65 67 65 78 65 73 22 0a  ity of regexes".
2b20: 20 20 20 20 70 72 69 6e 74 28 22 20 20 63 68 65      print("  che
2b30: 63 6b 69 6e 67 20 72 65 67 65 78 65 73 2e 2e 2e  cking regexes...
2b40: 22 29 0a 20 20 20 20 66 6f 72 20 73 47 72 61 70  ").    for sGrap
2b50: 68 4e 61 6d 65 2c 20 64 47 72 61 70 68 20 69 6e  hName, dGraph in
2b60: 20 64 41 6c 6c 47 72 61 70 68 2e 69 74 65 6d 73   dAllGraph.items
2b70: 28 29 3a 0a 20 20 20 20 20 20 20 20 66 6f 72 20  ():.        for 
2b80: 6e 4b 65 79 2c 20 64 56 61 6c 20 69 6e 20 64 47  nKey, dVal in dG
2b90: 72 61 70 68 2e 69 74 65 6d 73 28 29 3a 0a 20 20  raph.items():.  
2ba0: 20 20 20 20 20 20 20 20 20 20 69 66 20 22 3c 72            if "<r
2bb0: 65 5f 76 61 6c 75 65 3e 22 20 69 6e 20 64 56 61  e_value>" in dVa
2bc0: 6c 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  l:.             
2bd0: 20 20 20 66 6f 72 20 73 52 65 67 65 78 20 69 6e     for sRegex in
2be0: 20 64 56 61 6c 5b 22 3c 72 65 5f 76 61 6c 75 65   dVal["<re_value
2bf0: 3e 22 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20  >"]:.           
2c00: 20 20 20 20 20 20 20 20 20 5f 63 68 65 63 6b 52           _checkR
2c10: 65 67 65 78 28 73 52 65 67 65 78 29 0a 20 20 20  egex(sRegex).   
2c20: 20 20 20 20 20 20 20 20 20 69 66 20 22 3c 72 65           if "<re
2c30: 5f 6d 6f 72 70 68 3e 22 20 69 6e 20 64 56 61 6c  _morph>" in dVal
2c40: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
2c50: 20 20 66 6f 72 20 73 52 65 67 65 78 20 69 6e 20    for sRegex in 
2c60: 64 56 61 6c 5b 22 3c 72 65 5f 6d 6f 72 70 68 3e  dVal["<re_morph>
2c70: 22 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "]:.            
2c80: 20 20 20 20 20 20 20 20 5f 63 68 65 63 6b 52 65          _checkRe
2c90: 67 65 78 28 73 52 65 67 65 78 29 0a 0a 64 65 66  gex(sRegex)..def
2ca0: 20 5f 63 68 65 63 6b 52 65 67 65 78 20 28 73 52   _checkRegex (sR
2cb0: 65 67 65 78 29 3a 0a 20 20 20 20 23 70 72 69 6e  egex):.    #prin
2cc0: 74 28 73 52 65 67 65 78 29 0a 20 20 20 20 69 66  t(sRegex).    if
2cd0: 20 22 c2 ac 22 20 69 6e 20 73 52 65 67 65 78 3a   ".." in sRegex:
2ce0: 0a 20 20 20 20 20 20 20 20 73 50 61 74 74 65 72  .        sPatter
2cf0: 6e 2c 20 73 4e 65 67 50 61 74 74 65 72 6e 20 3d  n, sNegPattern =
2d00: 20 73 52 65 67 65 78 2e 73 70 6c 69 74 28 22 c2   sRegex.split(".
2d10: ac 22 29 0a 20 20 20 20 20 20 20 20 74 72 79 3a  .").        try:
2d20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
2d30: 6e 6f 74 20 73 4e 65 67 50 61 74 74 65 72 6e 3a  not sNegPattern:
2d40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2d50: 20 70 72 69 6e 74 28 22 23 20 57 61 72 6e 69 6e   print("# Warnin
2d60: 67 21 20 45 6d 70 74 79 20 6e 65 67 70 61 74 74  g! Empty negpatt
2d70: 65 72 6e 3a 22 2c 20 73 52 65 67 65 78 29 0a 20  ern:", sRegex). 
2d80: 20 20 20 20 20 20 20 20 20 20 20 72 65 2e 63 6f             re.co
2d90: 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e 29 0a  mpile(sPattern).
2da0: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 2e 63              re.c
2db0: 6f 6d 70 69 6c 65 28 73 4e 65 67 50 61 74 74 65  ompile(sNegPatte
2dc0: 72 6e 29 0a 20 20 20 20 20 20 20 20 65 78 63 65  rn).        exce
2dd0: 70 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  pt:.            
2de0: 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 2e 20  print("# Error. 
2df0: 57 72 6f 6e 67 20 72 65 67 65 78 3a 22 2c 20 73  Wrong regex:", s
2e00: 52 65 67 65 78 29 0a 20 20 20 20 20 20 20 20 20  Regex).         
2e10: 20 20 20 74 72 61 63 65 62 61 63 6b 2e 70 72 69     traceback.pri
2e20: 6e 74 5f 65 78 63 28 29 0a 20 20 20 20 20 20 20  nt_exc().       
2e30: 20 20 20 20 20 65 78 69 74 28 29 0a 20 20 20 20       exit().    
2e40: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 74 72  else:.        tr
2e50: 79 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  y:.            i
2e60: 66 20 6e 6f 74 20 73 52 65 67 65 78 3a 0a 20 20  f not sRegex:.  
2e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
2e80: 69 6e 74 28 22 23 20 57 61 72 6e 69 6e 67 21 20  int("# Warning! 
2e90: 45 6d 70 74 79 20 70 61 74 74 65 72 6e 3a 22 2c  Empty pattern:",
2ea0: 20 73 52 65 67 65 78 29 0a 20 20 20 20 20 20 20   sRegex).       
2eb0: 20 20 20 20 20 72 65 2e 63 6f 6d 70 69 6c 65 28       re.compile(
2ec0: 73 52 65 67 65 78 29 0a 20 20 20 20 20 20 20 20  sRegex).        
2ed0: 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20  except:.        
2ee0: 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72      print("# Err
2ef0: 6f 72 2e 20 57 72 6f 6e 67 20 72 65 67 65 78 3a  or. Wrong regex:
2f00: 22 2c 20 73 52 65 67 65 78 29 0a 20 20 20 20 20  ", sRegex).     
2f10: 20 20 20 20 20 20 20 74 72 61 63 65 62 61 63 6b         traceback
2f20: 2e 70 72 69 6e 74 5f 65 78 63 28 29 0a 20 20 20  .print_exc().   
2f30: 20 20 20 20 20 20 20 20 20 65 78 69 74 28 29 0a           exit().
2f40: 0a 0a 64 65 66 20 6d 61 6b 65 20 28 6c 52 75 6c  ..def make (lRul
2f50: 65 2c 20 64 44 65 66 2c 20 73 4c 61 6e 67 2c 20  e, dDef, sLang, 
2f60: 62 4a 61 76 61 53 63 72 69 70 74 29 3a 0a 20 20  bJavaScript):.  
2f70: 20 20 22 63 6f 6d 70 69 6c 65 20 72 75 6c 65 73    "compile rules
2f80: 2c 20 72 65 74 75 72 6e 73 20 61 20 64 69 63 74  , returns a dict
2f90: 69 6f 6e 61 72 79 20 6f 66 20 76 61 6c 75 65 73  ionary of values
2fa0: 22 0a 20 20 20 20 23 20 66 6f 72 20 63 6c 61 72  ".    # for clar
2fb0: 69 74 79 20 70 75 72 70 6f 73 65 2c 20 64 6f 6e  ity purpose, don
2fc0: e2 80 99 74 20 63 72 65 61 74 65 20 61 6e 79 20  ...t create any 
2fd0: 66 69 6c 65 20 68 65 72 65 0a 0a 20 20 20 20 23  file here..    #
2fe0: 20 72 65 6d 6f 76 69 6e 67 20 63 6f 6d 6d 65 6e   removing commen
2ff0: 74 73 2c 20 7a 65 72 6f 69 6e 67 20 65 6d 70 74  ts, zeroing empt
3000: 79 20 6c 69 6e 65 73 2c 20 63 72 65 61 74 69 6e  y lines, creatin
3010: 67 20 64 65 66 69 6e 69 74 69 6f 6e 73 2c 20 73  g definitions, s
3020: 74 6f 72 69 6e 67 20 74 65 73 74 73 2c 20 6d 65  toring tests, me
3030: 72 67 69 6e 67 20 72 75 6c 65 20 6c 69 6e 65 73  rging rule lines
3040: 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 70 61  .    print("  pa
3050: 72 73 69 6e 67 20 72 75 6c 65 73 2e 2e 2e 22 29  rsing rules...")
3060: 0a 20 20 20 20 6c 54 6f 6b 65 6e 4c 69 6e 65 20  .    lTokenLine 
3070: 3d 20 5b 5d 0a 20 20 20 20 73 41 63 74 69 6f 6e  = [].    sAction
3080: 73 20 3d 20 22 22 0a 20 20 20 20 6e 50 72 69 6f  s = "".    nPrio
3090: 72 69 74 79 20 3d 20 34 0a 20 20 20 20 64 41 6c  rity = 4.    dAl
30a0: 6c 47 72 61 70 68 20 3d 20 7b 7d 0a 20 20 20 20  lGraph = {}.    
30b0: 73 47 72 61 70 68 4e 61 6d 65 20 3d 20 22 22 0a  sGraphName = "".
30c0: 20 20 20 20 69 41 63 74 69 6f 6e 42 6c 6f 63 6b      iActionBlock
30d0: 20 3d 20 30 0a 0a 20 20 20 20 66 6f 72 20 69 2c   = 0..    for i,
30e0: 20 73 4c 69 6e 65 20 69 6e 20 6c 52 75 6c 65 3a   sLine in lRule:
30f0: 0a 20 20 20 20 20 20 20 20 73 4c 69 6e 65 20 3d  .        sLine =
3100: 20 73 4c 69 6e 65 2e 72 73 74 72 69 70 28 29 0a   sLine.rstrip().
3110: 20 20 20 20 20 20 20 20 69 66 20 22 5c 74 22 20          if "\t" 
3120: 69 6e 20 73 4c 69 6e 65 3a 0a 20 20 20 20 20 20  in sLine:.      
3130: 20 20 20 20 20 20 23 20 74 61 62 75 6c 61 74 69        # tabulati
3140: 6f 6e 20 6e 6f 74 20 61 6c 6c 6f 77 65 64 0a 20  on not allowed. 
3150: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
3160: 28 22 45 72 72 6f 72 2e 20 54 61 62 75 6c 61 74  ("Error. Tabulat
3170: 69 6f 6e 20 61 74 20 6c 69 6e 65 3a 20 22 2c 20  ion at line: ", 
3180: 69 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 65  i).            e
3190: 78 69 74 28 29 0a 20 20 20 20 20 20 20 20 65 6c  xit().        el
31a0: 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77  if sLine.startsw
31b0: 69 74 68 28 22 40 40 40 40 47 52 41 50 48 3a 20  ith("@@@@GRAPH: 
31c0: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
31d0: 23 20 72 75 6c 65 73 20 67 72 61 70 68 20 63 61  # rules graph ca
31e0: 6c 6c 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d  ll.            m
31f0: 20 3d 20 72 65 2e 6d 61 74 63 68 28 72 22 40 40   = re.match(r"@@
3200: 40 40 47 52 41 50 48 3a 20 2a 28 5c 77 2b 29 22  @@GRAPH: *(\w+)"
3210: 2c 20 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 29  , sLine.strip())
3220: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
3230: 6d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  m:.             
3240: 20 20 20 73 47 72 61 70 68 4e 61 6d 65 20 3d 20     sGraphName = 
3250: 6d 2e 67 72 6f 75 70 28 31 29 0a 20 20 20 20 20  m.group(1).     
3260: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73 47             if sG
3270: 72 61 70 68 4e 61 6d 65 20 69 6e 20 64 41 6c 6c  raphName in dAll
3280: 47 72 61 70 68 3a 0a 20 20 20 20 20 20 20 20 20  Graph:.         
3290: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
32a0: 28 22 45 72 72 6f 72 2e 20 47 72 6f 75 70 20 6e  ("Error. Group n
32b0: 61 6d 65 20 22 20 2b 20 73 47 72 61 70 68 4e 61  ame " + sGraphNa
32c0: 6d 65 20 2b 20 22 20 61 6c 72 65 61 64 79 20 65  me + " already e
32d0: 78 69 73 74 73 2e 22 29 0a 20 20 20 20 20 20 20  xists.").       
32e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 78 69               exi
32f0: 74 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  t().            
3300: 20 20 20 20 64 41 6c 6c 47 72 61 70 68 5b 73 47      dAllGraph[sG
3310: 72 61 70 68 4e 61 6d 65 5d 20 3d 20 5b 5d 0a 20  raphName] = []. 
3320: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
3330: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3340: 20 70 72 69 6e 74 28 22 45 72 72 6f 72 2e 20 47   print("Error. G
3350: 72 61 70 68 20 6e 61 6d 65 20 6e 6f 74 20 66 6f  raph name not fo
3360: 75 6e 64 20 61 74 20 6c 69 6e 65 22 2c 20 69 29  und at line", i)
3370: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3380: 20 65 78 69 74 28 29 0a 20 20 20 20 20 20 20 20   exit().        
3390: 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74  elif sLine.start
33a0: 73 77 69 74 68 28 22 5f 5f 22 29 20 61 6e 64 20  swith("__") and 
33b0: 73 4c 69 6e 65 2e 65 6e 64 73 77 69 74 68 28 22  sLine.endswith("
33c0: 5f 5f 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  __"):.          
33d0: 20 20 23 20 6e 65 77 20 72 75 6c 65 20 67 72 6f    # new rule gro
33e0: 75 70 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d  up.            m
33f0: 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 5f 5f 28   = re.match("__(
3400: 5c 5c 77 2b 29 28 21 5c 5c 64 7c 29 5f 5f 22 2c  \\w+)(!\\d|)__",
3410: 20 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20   sLine).        
3420: 20 20 20 20 69 66 20 6d 3a 0a 20 20 20 20 20 20      if m:.      
3430: 20 20 20 20 20 20 20 20 20 20 73 52 75 6c 65 4e            sRuleN
3440: 61 6d 65 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29  ame = m.group(1)
3450: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3460: 20 69 41 63 74 69 6f 6e 42 6c 6f 63 6b 20 3d 20   iActionBlock = 
3470: 31 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  1.              
3480: 20 20 6e 50 72 69 6f 72 69 74 79 20 3d 20 69 6e    nPriority = in
3490: 74 28 6d 2e 67 72 6f 75 70 28 32 29 5b 31 3a 5d  t(m.group(2)[1:]
34a0: 29 20 69 66 20 6d 2e 67 72 6f 75 70 28 32 29 20  ) if m.group(2) 
34b0: 20 65 6c 73 65 20 34 0a 20 20 20 20 20 20 20 20   else 4.        
34c0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
34d0: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
34e0: 22 45 72 72 6f 72 20 61 74 20 72 75 6c 65 20 67  "Error at rule g
34f0: 72 6f 75 70 3a 20 22 2c 20 73 4c 69 6e 65 2c 20  roup: ", sLine, 
3500: 22 20 2d 2d 20 6c 69 6e 65 3a 22 2c 20 69 29 0a  " -- line:", i).
3510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3520: 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20 65 6c  break.        el
3530: 69 66 20 72 65 2e 73 65 61 72 63 68 28 22 5e 20  if re.search("^ 
3540: 20 20 20 2b 3c 3c 2d 20 22 2c 20 73 4c 69 6e 65     +<<- ", sLine
3550: 29 20 6f 72 20 73 4c 69 6e 65 2e 73 74 61 72 74  ) or sLine.start
3560: 73 77 69 74 68 28 22 20 20 20 20 20 20 20 20 22  swith("        "
3570: 29 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20  ) \.            
3580: 20 20 20 20 6f 72 20 72 65 2e 73 65 61 72 63 68      or re.search
3590: 28 22 5e 20 20 20 20 2b 23 22 2c 20 73 4c 69 6e  ("^    +#", sLin
35a0: 65 29 20 6f 72 20 72 65 2e 73 65 61 72 63 68 28  e) or re.search(
35b0: 72 22 5e 20 20 20 20 5b 2d 7e 3d 3e 2f 5d 28 3f  r"^    [-~=>/](?
35c0: 3a 5c 64 28 3f 3a 3a 5c 64 2b 7c 29 7c 29 3e 3e  :\d(?::\d+|)|)>>
35d0: 20 22 2c 20 73 4c 69 6e 65 29 20 3a 0a 20 20 20   ", sLine) :.   
35e0: 20 20 20 20 20 20 20 20 20 23 20 61 63 74 69 6f           # actio
35f0: 6e 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ns.            s
3600: 41 63 74 69 6f 6e 73 20 2b 3d 20 22 20 22 20 2b  Actions += " " +
3610: 20 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 0a 20   sLine.strip(). 
3620: 20 20 20 20 20 20 20 65 6c 69 66 20 72 65 2e 6d         elif re.m
3630: 61 74 63 68 28 22 5b 20 c2 a0 5d 2a 24 22 2c 20  atch("[ ..]*$", 
3640: 73 4c 69 6e 65 29 3a 0a 20 20 20 20 20 20 20 20  sLine):.        
3650: 20 20 20 20 23 20 65 6d 70 74 79 20 6c 69 6e 65      # empty line
3660: 20 74 6f 20 65 6e 64 20 6d 65 72 67 69 6e 67 0a   to end merging.
3670: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e              if n
3680: 6f 74 20 6c 54 6f 6b 65 6e 4c 69 6e 65 3a 0a 20  ot lTokenLine:. 
3690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63                 c
36a0: 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20 20 20 20  ontinue.        
36b0: 20 20 20 20 69 66 20 6e 6f 74 20 73 41 63 74 69      if not sActi
36c0: 6f 6e 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ons:.           
36d0: 20 20 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f       print("Erro
36e0: 72 2e 20 4e 6f 20 61 63 74 69 6f 6e 20 66 6f 75  r. No action fou
36f0: 6e 64 20 61 74 20 6c 69 6e 65 3a 22 2c 20 69 29  nd at line:", i)
3700: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3710: 20 65 78 69 74 28 29 0a 20 20 20 20 20 20 20 20   exit().        
3720: 20 20 20 20 69 66 20 6e 6f 74 20 73 47 72 61 70      if not sGrap
3730: 68 4e 61 6d 65 3a 0a 20 20 20 20 20 20 20 20 20  hName:.         
3740: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 45 72         print("Er
3750: 72 6f 72 2e 20 41 6c 6c 20 72 75 6c 65 73 20 6d  ror. All rules m
3760: 75 73 74 20 62 65 6c 6f 6e 67 20 74 6f 20 61 20  ust belong to a 
3770: 6e 61 6d 65 64 20 67 72 61 70 68 2e 20 4c 69 6e  named graph. Lin
3780: 65 3a 20 22 2c 20 69 29 0a 20 20 20 20 20 20 20  e: ", i).       
3790: 20 20 20 20 20 20 20 20 20 65 78 69 74 28 29 0a           exit().
37a0: 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20              for 
37b0: 6a 2c 20 73 54 6f 6b 65 6e 4c 69 6e 65 20 69 6e  j, sTokenLine in
37c0: 20 6c 54 6f 6b 65 6e 4c 69 6e 65 3a 0a 20 20 20   lTokenLine:.   
37d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 64 41 6c               dAl
37e0: 6c 47 72 61 70 68 5b 73 47 72 61 70 68 4e 61 6d  lGraph[sGraphNam
37f0: 65 5d 2e 61 70 70 65 6e 64 28 28 6a 2c 20 73 52  e].append((j, sR
3800: 75 6c 65 4e 61 6d 65 2c 20 73 54 6f 6b 65 6e 4c  uleName, sTokenL
3810: 69 6e 65 2c 20 69 41 63 74 69 6f 6e 42 6c 6f 63  ine, iActionBloc
3820: 6b 2c 20 73 41 63 74 69 6f 6e 73 2c 20 6e 50 72  k, sActions, nPr
3830: 69 6f 72 69 74 79 29 29 0a 20 20 20 20 20 20 20  iority)).       
3840: 20 20 20 20 20 6c 54 6f 6b 65 6e 4c 69 6e 65 2e       lTokenLine.
3850: 63 6c 65 61 72 28 29 0a 20 20 20 20 20 20 20 20  clear().        
3860: 20 20 20 20 73 41 63 74 69 6f 6e 73 20 3d 20 22      sActions = "
3870: 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 41  ".            iA
3880: 63 74 69 6f 6e 42 6c 6f 63 6b 20 2b 3d 20 31 0a  ctionBlock += 1.
3890: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69          elif sLi
38a0: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 28 22  ne.startswith(("
38b0: 20 20 20 20 22 29 29 3a 0a 20 20 20 20 20 20 20      ")):.       
38c0: 20 20 20 20 20 23 20 74 6f 6b 65 6e 73 0a 20 20       # tokens.  
38d0: 20 20 20 20 20 20 20 20 20 20 6c 54 6f 6b 65 6e            lToken
38e0: 4c 69 6e 65 2e 61 70 70 65 6e 64 28 5b 69 2c 20  Line.append([i, 
38f0: 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 5d 29 0a  sLine.strip()]).
3900: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
3910: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
3920: 22 55 6e 6b 6e 6f 77 6e 20 6c 69 6e 65 3a 22 29  "Unknown line:")
3930: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69  .            pri
3940: 6e 74 28 73 4c 69 6e 65 29 0a 0a 20 20 20 20 23  nt(sLine)..    #
3950: 20 70 72 6f 63 65 73 73 69 6e 67 20 72 75 6c 65   processing rule
3960: 73 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 70  s.    print("  p
3970: 72 65 70 61 72 69 6e 67 20 72 75 6c 65 73 2e 2e  reparing rules..
3980: 2e 22 29 0a 20 20 20 20 66 6f 72 20 73 47 72 61  .").    for sGra
3990: 70 68 4e 61 6d 65 2c 20 6c 52 75 6c 65 4c 69 6e  phName, lRuleLin
39a0: 65 20 69 6e 20 64 41 6c 6c 47 72 61 70 68 2e 69  e in dAllGraph.i
39b0: 74 65 6d 73 28 29 3a 0a 20 20 20 20 20 20 20 20  tems():.        
39c0: 6c 50 72 65 70 61 72 65 64 52 75 6c 65 20 3d 20  lPreparedRule = 
39d0: 5b 5d 0a 20 20 20 20 20 20 20 20 66 6f 72 20 69  [].        for i
39e0: 2c 20 73 52 75 6c 65 47 72 6f 75 70 2c 20 73 54  , sRuleGroup, sT
39f0: 6f 6b 65 6e 4c 69 6e 65 2c 20 69 41 63 74 69 6f  okenLine, iActio
3a00: 6e 42 6c 6f 63 6b 2c 20 73 41 63 74 69 6f 6e 73  nBlock, sActions
3a10: 2c 20 6e 50 72 69 6f 72 69 74 79 20 69 6e 20 6c  , nPriority in l
3a20: 52 75 6c 65 4c 69 6e 65 3a 0a 20 20 20 20 20 20  RuleLine:.      
3a30: 20 20 20 20 20 20 66 6f 72 20 6c 52 75 6c 65 20        for lRule 
3a40: 69 6e 20 63 72 65 61 74 65 52 75 6c 65 28 69 2c  in createRule(i,
3a50: 20 73 52 75 6c 65 47 72 6f 75 70 2c 20 73 54 6f   sRuleGroup, sTo
3a60: 6b 65 6e 4c 69 6e 65 2c 20 69 41 63 74 69 6f 6e  kenLine, iAction
3a70: 42 6c 6f 63 6b 2c 20 73 41 63 74 69 6f 6e 73 2c  Block, sActions,
3a80: 20 6e 50 72 69 6f 72 69 74 79 2c 20 64 44 65 66   nPriority, dDef
3a90: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
3aa0: 20 20 20 6c 50 72 65 70 61 72 65 64 52 75 6c 65     lPreparedRule
3ab0: 2e 61 70 70 65 6e 64 28 6c 52 75 6c 65 29 0a 20  .append(lRule). 
3ac0: 20 20 20 20 20 20 20 23 20 47 72 61 70 68 20 63         # Graph c
3ad0: 72 65 61 74 69 6f 6e 0a 20 20 20 20 20 20 20 20  reation.        
3ae0: 6f 44 41 52 47 20 3d 20 64 61 72 67 2e 44 41 52  oDARG = darg.DAR
3af0: 47 28 6c 50 72 65 70 61 72 65 64 52 75 6c 65 2c  G(lPreparedRule,
3b00: 20 73 4c 61 6e 67 29 0a 20 20 20 20 20 20 20 20   sLang).        
3b10: 64 41 6c 6c 47 72 61 70 68 5b 73 47 72 61 70 68  dAllGraph[sGraph
3b20: 4e 61 6d 65 5d 20 3d 20 6f 44 41 52 47 2e 63 72  Name] = oDARG.cr
3b30: 65 61 74 65 47 72 61 70 68 28 29 0a 20 20 20 20  eateGraph().    
3b40: 20 20 20 20 23 20 44 65 62 75 67 67 69 6e 67 0a      # Debugging.
3b50: 20 20 20 20 20 20 20 20 23 70 72 69 6e 74 28 22          #print("
3b60: 5c 6e 47 52 41 50 48 3a 22 2c 20 73 47 72 61 70  \nGRAPH:", sGrap
3b70: 68 4e 61 6d 65 29 0a 20 20 20 20 20 20 20 20 23  hName).        #
3b80: 66 6f 72 20 65 20 69 6e 20 6c 50 72 65 70 61 72  for e in lPrepar
3b90: 65 64 52 75 6c 65 3a 0a 20 20 20 20 20 20 20 20  edRule:.        
3ba0: 23 20 20 20 20 70 72 69 6e 74 28 65 29 0a 20 20  #    print(e).  
3bb0: 20 20 20 20 20 20 23 66 6f 72 20 6b 2c 20 76 20        #for k, v 
3bc0: 69 6e 20 64 41 6c 6c 47 72 61 70 68 5b 73 47 72  in dAllGraph[sGr
3bd0: 61 70 68 4e 61 6d 65 5d 2e 69 74 65 6d 73 28 29  aphName].items()
3be0: 3a 0a 20 20 20 20 20 20 20 20 23 20 20 20 20 70  :.        #    p
3bf0: 72 69 6e 74 28 6b 2c 20 22 5c 74 22 2c 20 76 29  rint(k, "\t", v)
3c00: 0a 0a 20 20 20 20 23 20 63 72 65 61 74 69 6e 67  ..    # creating
3c10: 20 66 69 6c 65 20 77 69 74 68 20 61 6c 6c 20 66   file with all f
3c20: 75 6e 63 74 69 6f 6e 73 20 63 61 6c 6c 61 62 6c  unctions callabl
3c30: 65 20 62 79 20 72 75 6c 65 73 0a 20 20 20 20 70  e by rules.    p
3c40: 72 69 6e 74 28 22 20 20 63 72 65 61 74 69 6e 67  rint("  creating
3c50: 20 63 61 6c 6c 61 62 6c 65 73 2e 2e 2e 22 29 0a   callables...").
3c60: 20 20 20 20 73 50 79 43 61 6c 6c 61 62 6c 65 73      sPyCallables
3c70: 20 3d 20 22 23 20 67 65 6e 65 72 61 74 65 64 20   = "# generated 
3c80: 63 6f 64 65 2c 20 64 6f 20 6e 6f 74 20 65 64 69  code, do not edi
3c90: 74 5c 6e 22 0a 20 20 20 20 23 73 4a 53 43 61 6c  t\n".    #sJSCal
3ca0: 6c 61 62 6c 65 73 20 3d 20 22 2f 2f 20 67 65 6e  lables = "// gen
3cb0: 65 72 61 74 65 64 20 63 6f 64 65 2c 20 64 6f 20  erated code, do 
3cc0: 6e 6f 74 20 65 64 69 74 5c 6e 63 6f 6e 73 74 20  not edit\nconst 
3cd0: 6f 45 76 61 6c 46 75 6e 63 20 3d 20 7b 5c 6e 22  oEvalFunc = {\n"
3ce0: 0a 20 20 20 20 66 6f 72 20 73 46 75 6e 63 4e 61  .    for sFuncNa
3cf0: 6d 65 2c 20 73 52 65 74 75 72 6e 20 69 6e 20 64  me, sReturn in d
3d00: 46 55 4e 43 54 49 4f 4e 53 2e 69 74 65 6d 73 28  FUNCTIONS.items(
3d10: 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73 46  ):.        if sF
3d20: 75 6e 63 4e 61 6d 65 2e 73 74 61 72 74 73 77 69  uncName.startswi
3d30: 74 68 28 22 5f 67 5f 63 5f 22 29 3a 20 23 20 63  th("_g_c_"): # c
3d40: 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 20 20 20  ondition.       
3d50: 20 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20 22       sParams = "
3d60: 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f 66  lToken, nTokenOf
3d70: 66 73 65 74 2c 20 6e 4c 61 73 74 54 6f 6b 65 6e  fset, nLastToken
3d80: 2c 20 73 43 6f 75 6e 74 72 79 2c 20 62 43 6f 6e  , sCountry, bCon
3d90: 64 4d 65 6d 6f 2c 20 64 54 61 67 73 2c 20 73 53  dMemo, dTags, sS
3da0: 65 6e 74 65 6e 63 65 2c 20 73 53 65 6e 74 65 6e  entence, sSenten
3db0: 63 65 30 22 0a 20 20 20 20 20 20 20 20 65 6c 69  ce0".        eli
3dc0: 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61 72  f sFuncName.star
3dd0: 74 73 77 69 74 68 28 22 67 5f 6d 5f 22 29 3a 20  tswith("g_m_"): 
3de0: 23 20 6d 65 73 73 61 67 65 0a 20 20 20 20 20 20  # message.      
3df0: 20 20 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20        sParams = 
3e00: 22 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f  "lToken, nTokenO
3e10: 66 66 73 65 74 22 0a 20 20 20 20 20 20 20 20 65  ffset".        e
3e20: 6c 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74  lif sFuncName.st
3e30: 61 72 74 73 77 69 74 68 28 22 5f 67 5f 73 5f 22  artswith("_g_s_"
3e40: 29 3a 20 23 20 73 75 67 67 65 73 74 69 6f 6e 0a  ): # suggestion.
3e50: 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61 72              sPar
3e60: 61 6d 73 20 3d 20 22 6c 54 6f 6b 65 6e 2c 20 6e  ams = "lToken, n
3e70: 54 6f 6b 65 6e 4f 66 66 73 65 74 22 0a 20 20 20  TokenOffset".   
3e80: 20 20 20 20 20 65 6c 69 66 20 73 46 75 6e 63 4e       elif sFuncN
3e90: 61 6d 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ame.startswith("
3ea0: 5f 67 5f 70 5f 22 29 3a 20 23 20 70 72 65 70 72  _g_p_"): # prepr
3eb0: 6f 63 65 73 73 6f 72 0a 20 20 20 20 20 20 20 20  ocessor.        
3ec0: 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20 22 6c      sParams = "l
3ed0: 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f 66 66  Token, nTokenOff
3ee0: 73 65 74 22 0a 20 20 20 20 20 20 20 20 65 6c 69  set".        eli
3ef0: 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61 72  f sFuncName.star
3f00: 74 73 77 69 74 68 28 22 5f 67 5f 64 5f 22 29 3a  tswith("_g_d_"):
3f10: 20 23 20 64 69 73 61 6d 62 69 67 75 61 74 6f 72   # disambiguator
3f20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61  .            sPa
3f30: 72 61 6d 73 20 3d 20 22 6c 54 6f 6b 65 6e 2c 20  rams = "lToken, 
3f40: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 22 0a 20 20  nTokenOffset".  
3f50: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
3f60: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
3f70: 20 55 6e 6b 6e 6f 77 6e 20 66 75 6e 63 74 69 6f   Unknown functio
3f80: 6e 20 74 79 70 65 20 69 6e 20 5b 22 20 2b 20 73  n type in [" + s
3f90: 46 75 6e 63 4e 61 6d 65 20 2b 20 22 5d 22 29 0a  FuncName + "]").
3fa0: 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 74              cont
3fb0: 69 6e 75 65 0a 20 20 20 20 20 20 20 20 73 50 79  inue.        sPy
3fc0: 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 64 65  Callables += "de
3fd0: 66 20 7b 7d 20 28 7b 7d 29 3a 5c 6e 22 2e 66 6f  f {} ({}):\n".fo
3fe0: 72 6d 61 74 28 73 46 75 6e 63 4e 61 6d 65 2c 20  rmat(sFuncName, 
3ff0: 73 50 61 72 61 6d 73 29 0a 20 20 20 20 20 20 20  sParams).       
4000: 20 73 50 79 43 61 6c 6c 61 62 6c 65 73 20 2b 3d   sPyCallables +=
4010: 20 22 20 20 20 20 72 65 74 75 72 6e 20 22 20 2b   "    return " +
4020: 20 73 52 65 74 75 72 6e 20 2b 20 22 5c 6e 22 0a   sReturn + "\n".
4030: 20 20 20 20 20 20 20 20 23 73 4a 53 43 61 6c 6c          #sJSCall
4040: 61 62 6c 65 73 20 2b 3d 20 22 20 20 20 20 7b 7d  ables += "    {}
4050: 3a 20 66 75 6e 63 74 69 6f 6e 20 28 7b 7d 29 22  : function ({})"
4060: 2e 66 6f 72 6d 61 74 28 73 46 75 6e 63 4e 61 6d  .format(sFuncNam
4070: 65 2c 20 73 50 61 72 61 6d 73 29 20 2b 20 22 20  e, sParams) + " 
4080: 7b 5c 6e 22 0a 20 20 20 20 20 20 20 20 23 73 4a  {\n".        #sJ
4090: 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 20  SCallables += " 
40a0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 20         return " 
40b0: 2b 20 6a 73 63 6f 6e 76 2e 70 79 32 6a 73 28 73  + jsconv.py2js(s
40c0: 52 65 74 75 72 6e 29 20 2b 20 22 3b 5c 6e 22 0a  Return) + ";\n".
40d0: 20 20 20 20 20 20 20 20 23 73 4a 53 43 61 6c 6c          #sJSCall
40e0: 61 62 6c 65 73 20 2b 3d 20 22 20 20 20 20 7d 2c  ables += "    },
40f0: 5c 6e 22 0a 20 20 20 20 23 73 4a 53 43 61 6c 6c  \n".    #sJSCall
4100: 61 62 6c 65 73 20 2b 3d 20 22 7d 5c 6e 22 0a 0a  ables += "}\n"..
4110: 20 20 20 20 23 20 44 65 62 75 67 67 69 6e 67 0a      # Debugging.
4120: 20 20 20 20 69 66 20 46 61 6c 73 65 3a 0a 20 20      if False:.  
4130: 20 20 20 20 20 20 70 72 69 6e 74 28 22 5c 6e 41        print("\nA
4140: 63 74 69 6f 6e 73 3a 22 29 0a 20 20 20 20 20 20  ctions:").      
4150: 20 20 66 6f 72 20 73 41 63 74 69 6f 6e 4e 61 6d    for sActionNam
4160: 65 2c 20 61 41 63 74 69 6f 6e 20 69 6e 20 64 41  e, aAction in dA
4170: 43 54 49 4f 4e 53 2e 69 74 65 6d 73 28 29 3a 0a  CTIONS.items():.
4180: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
4190: 74 28 73 41 63 74 69 6f 6e 4e 61 6d 65 2c 20 61  t(sActionName, a
41a0: 41 63 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20  Action).        
41b0: 70 72 69 6e 74 28 22 5c 6e 46 75 6e 63 74 69 6f  print("\nFunctio
41c0: 6e 73 3a 22 29 0a 20 20 20 20 20 20 20 20 70 72  ns:").        pr
41d0: 69 6e 74 28 73 50 79 43 61 6c 6c 61 62 6c 65 73  int(sPyCallables
41e0: 29 0a 0a 20 20 20 20 63 68 65 63 6b 52 65 67 65  )..    checkRege
41f0: 78 65 73 28 64 41 6c 6c 47 72 61 70 68 29 0a 0a  xes(dAllGraph)..
4200: 20 20 20 20 23 20 52 65 73 75 6c 74 0a 20 20 20      # Result.   
4210: 20 72 65 74 75 72 6e 20 7b 0a 20 20 20 20 20 20   return {.      
4220: 20 20 22 67 72 61 70 68 5f 63 61 6c 6c 61 62 6c    "graph_callabl
4230: 65 73 22 3a 20 73 50 79 43 61 6c 6c 61 62 6c 65  es": sPyCallable
4240: 73 2c 0a 20 20 20 20 20 20 20 20 22 72 75 6c 65  s,.        "rule
4250: 73 5f 67 72 61 70 68 73 22 3a 20 64 41 6c 6c 47  s_graphs": dAllG
4260: 72 61 70 68 2c 0a 20 20 20 20 20 20 20 20 22 72  raph,.        "r
4270: 75 6c 65 73 5f 61 63 74 69 6f 6e 73 22 3a 20 64  ules_actions": d
4280: 41 43 54 49 4f 4e 53 0a 20 20 20 20 7d 0a        ACTIONS.    }.