Grammalecte  Hex Artifact Content

Artifact b76ec26418ddfd0039fa89e0005ec61710698fe46425a3249b24aee46430ad31:


0000: 0a 69 6d 70 6f 72 74 20 72 65 0a 69 6d 70 6f 72  .import re.impor
0010: 74 20 73 79 73 0a 69 6d 70 6f 72 74 20 74 72 61  t sys.import tra
0020: 63 65 62 61 63 6b 0a 69 6d 70 6f 72 74 20 63 6f  ceback.import co
0030: 70 79 0a 69 6d 70 6f 72 74 20 6a 73 6f 6e 0a 66  py.import json.f
0040: 72 6f 6d 20 64 69 73 74 75 74 69 6c 73 20 69 6d  rom distutils im
0050: 70 6f 72 74 20 66 69 6c 65 5f 75 74 69 6c 0a 0a  port file_util..
0060: 0a 64 44 45 46 20 3d 20 7b 7d 0a 6c 46 55 4e 43  .dDEF = {}.lFUNC
0070: 54 49 4f 4e 53 20 3d 20 5b 5d 0a 0a 61 52 55 4c  TIONS = []..aRUL
0080: 45 53 45 54 20 3d 20 73 65 74 28 29 20 20 20 20  ESET = set()    
0090: 20 23 20 73 65 74 20 6f 66 20 72 75 6c 65 2d 69   # set of rule-i
00a0: 64 73 20 74 6f 20 63 68 65 63 6b 20 69 66 20 74  ds to check if t
00b0: 68 65 72 65 20 69 73 20 73 65 76 65 72 61 6c 20  here is several 
00c0: 72 75 6c 65 73 20 77 69 74 68 20 74 68 65 20 73  rules with the s
00d0: 61 6d 65 20 69 64 0a 6e 52 55 4c 45 57 49 54 48  ame id.nRULEWITH
00e0: 4f 55 54 4e 41 4d 45 20 3d 20 30 0a 0a 64 4a 53  OUTNAME = 0..dJS
00f0: 52 45 47 45 58 45 53 20 3d 20 7b 7d 0a 0a 73 57  REGEXES = {}..sW
0100: 4f 52 44 4c 49 4d 49 54 4c 45 46 54 20 20 3d 20  ORDLIMITLEFT  = 
0110: 72 22 28 3f 3c 21 5b 5c 77 2e 2c e2 80 93 2d 5d  r"(?<![\w.,...-]
0120: 29 22 20 20 20 23 20 72 22 28 3f 3c 21 5b 2d 2e  )"   # r"(?<![-.
0130: 2c e2 80 94 5d 29 5c 62 22 20 20 73 65 65 6d 73  ,...])\b"  seems
0140: 20 73 6c 6f 77 65 72 0a 73 57 4f 52 44 4c 49 4d   slower.sWORDLIM
0150: 49 54 52 49 47 48 54 20 3d 20 72 22 28 3f 21 5b  ITRIGHT = r"(?![
0160: 5c 77 e2 80 93 2d 5d 29 22 20 20 20 20 20 20 23  \w...-])"      #
0170: 20 72 22 5c 62 28 3f 21 2d e2 80 94 29 22 20 20   r"\b(?!-...)"  
0180: 20 20 20 20 20 73 65 65 6d 73 20 73 6c 6f 77 65       seems slowe
0190: 72 0a 0a 0a 64 65 66 20 70 72 65 70 61 72 65 46  r...def prepareF
01a0: 75 6e 63 74 69 6f 6e 20 28 73 29 3a 0a 20 20 20  unction (s):.   
01b0: 20 73 20 3d 20 73 2e 72 65 70 6c 61 63 65 28 22   s = s.replace("
01c0: 5f 5f 61 6c 73 6f 5f 5f 22 2c 20 22 62 43 6f 6e  __also__", "bCon
01d0: 64 4d 65 6d 6f 22 29 0a 20 20 20 20 73 20 3d 20  dMemo").    s = 
01e0: 73 2e 72 65 70 6c 61 63 65 28 22 5f 5f 65 6c 73  s.replace("__els
01f0: 65 5f 5f 22 2c 20 22 6e 6f 74 20 62 43 6f 6e 64  e__", "not bCond
0200: 4d 65 6d 6f 22 29 0a 20 20 20 20 73 20 3d 20 72  Memo").    s = r
0210: 65 2e 73 75 62 28 72 22 69 73 53 74 61 72 74 20  e.sub(r"isStart 
0220: 2a 5c 28 5c 29 22 2c 20 27 62 65 66 6f 72 65 28  *\(\)", 'before(
0230: 22 5e 20 2a 24 7c 2c 20 2a 24 22 29 27 2c 20 73  "^ *$|, *$")', s
0240: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0250: 28 72 22 69 73 52 65 61 6c 53 74 61 72 74 20 2a  (r"isRealStart *
0260: 5c 28 5c 29 22 2c 20 27 62 65 66 6f 72 65 28 22  \(\)", 'before("
0270: 5e 20 2a 24 22 29 27 2c 20 73 29 0a 20 20 20 20  ^ *$")', s).    
0280: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73 53  s = re.sub(r"isS
0290: 74 61 72 74 30 20 2a 5c 28 5c 29 22 2c 20 27 62  tart0 *\(\)", 'b
02a0: 65 66 6f 72 65 30 28 22 5e 20 2a 24 7c 2c 20 2a  efore0("^ *$|, *
02b0: 24 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d  $")', s).    s =
02c0: 20 72 65 2e 73 75 62 28 72 22 69 73 52 65 61 6c   re.sub(r"isReal
02d0: 53 74 61 72 74 30 20 2a 5c 28 5c 29 22 2c 20 27  Start0 *\(\)", '
02e0: 62 65 66 6f 72 65 30 28 22 5e 20 2a 24 22 29 27  before0("^ *$")'
02f0: 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  , s).    s = re.
0300: 73 75 62 28 72 22 69 73 45 6e 64 20 2a 5c 28 5c  sub(r"isEnd *\(\
0310: 29 22 2c 20 27 61 66 74 65 72 28 22 5e 20 2a 24  )", 'after("^ *$
0320: 7c 5e 2c 22 29 27 2c 20 73 29 0a 20 20 20 20 73  |^,")', s).    s
0330: 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73 52 65   = re.sub(r"isRe
0340: 61 6c 45 6e 64 20 2a 5c 28 5c 29 22 2c 20 27 61  alEnd *\(\)", 'a
0350: 66 74 65 72 28 22 5e 20 2a 24 22 29 27 2c 20 73  fter("^ *$")', s
0360: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0370: 28 72 22 69 73 45 6e 64 30 20 2a 5c 28 5c 29 22  (r"isEnd0 *\(\)"
0380: 2c 20 27 61 66 74 65 72 30 28 22 5e 20 2a 24 7c  , 'after0("^ *$|
0390: 5e 2c 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20  ^,")', s).    s 
03a0: 3d 20 72 65 2e 73 75 62 28 72 22 69 73 52 65 61  = re.sub(r"isRea
03b0: 6c 45 6e 64 30 20 2a 5c 28 5c 29 22 2c 20 27 61  lEnd0 *\(\)", 'a
03c0: 66 74 65 72 30 28 22 5e 20 2a 24 22 29 27 2c 20  fter0("^ *$")', 
03d0: 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75  s).    s = re.su
03e0: 62 28 72 22 28 73 65 6c 65 63 74 7c 65 78 63 6c  b(r"(select|excl
03f0: 75 64 65 29 5b 28 5d 5b 5c 5c 5d 28 5c 64 2b 29  ude)[(][\\](\d+)
0400: 22 2c 20 27 5c 5c 31 28 64 44 41 2c 20 6d 2e 73  ", '\\1(dDA, m.s
0410: 74 61 72 74 28 5c 5c 32 29 2c 20 6d 2e 67 72 6f  tart(\\2), m.gro
0420: 75 70 28 5c 5c 32 29 27 2c 20 73 29 0a 20 20 20  up(\\2)', s).   
0430: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 64 65   s = re.sub(r"de
0440: 66 69 6e 65 5b 28 5d 5b 5c 5c 5d 28 5c 64 2b 29  fine[(][\\](\d+)
0450: 22 2c 20 27 64 65 66 69 6e 65 28 64 44 41 2c 20  ", 'define(dDA, 
0460: 6d 2e 73 74 61 72 74 28 5c 5c 31 29 27 2c 20 73  m.start(\\1)', s
0470: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0480: 28 72 22 28 6d 6f 72 70 68 7c 6d 6f 72 70 68 65  (r"(morph|morphe
0490: 78 7c 64 69 73 70 6c 61 79 49 6e 66 6f 29 5b 28  x|displayInfo)[(
04a0: 5d 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27 5c 5c  ][\\](\d+)", '\\
04b0: 31 28 28 6d 2e 73 74 61 72 74 28 5c 5c 32 29 2c  1((m.start(\\2),
04c0: 20 6d 2e 67 72 6f 75 70 28 5c 5c 32 29 29 27 2c   m.group(\\2))',
04d0: 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73   s).    s = re.s
04e0: 75 62 28 72 22 28 6d 6f 72 70 68 7c 6d 6f 72 70  ub(r"(morph|morp
04f0: 68 65 78 7c 64 69 73 70 6c 61 79 49 6e 66 6f 29  hex|displayInfo)
0500: 5b 28 5d 22 2c 20 27 5c 5c 31 28 64 44 41 2c 20  [(]", '\\1(dDA, 
0510: 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65  ', s).    s = re
0520: 2e 73 75 62 28 72 22 28 73 75 67 67 5c 77 2b 7c  .sub(r"(sugg\w+|
0530: 73 77 69 74 63 68 5c 77 2b 29 5c 28 40 22 2c 20  switch\w+)\(@", 
0540: 27 5c 5c 31 28 6d 2e 67 72 6f 75 70 28 69 5b 34  '\\1(m.group(i[4
0550: 5d 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  ])', s).    s = 
0560: 72 65 2e 73 75 62 28 72 22 77 6f 72 64 5c 28 5c  re.sub(r"word\(\
0570: 73 2a 31 5c 62 22 2c 20 27 6e 65 78 74 77 6f 72  s*1\b", 'nextwor
0580: 64 31 28 73 2c 20 6d 2e 65 6e 64 28 29 27 2c 20  d1(s, m.end()', 
0590: 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s)              
05a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05b0: 20 20 20 20 23 20 77 6f 72 64 28 31 29 0a 20 20      # word(1).  
05c0: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 77    s = re.sub(r"w
05d0: 6f 72 64 5c 28 5c 73 2a 2d 31 5c 62 22 2c 20 27  ord\(\s*-1\b", '
05e0: 70 72 65 76 77 6f 72 64 31 28 73 2c 20 6d 2e 73  prevword1(s, m.s
05f0: 74 61 72 74 28 29 27 2c 20 73 29 20 20 20 20 20  tart()', s)     
0600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0610: 20 20 20 20 20 20 20 20 20 20 23 20 77 6f 72 64            # word
0620: 28 2d 31 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  (-1).    s = re.
0630: 73 75 62 28 72 22 77 6f 72 64 5c 28 5c 73 2a 28  sub(r"word\(\s*(
0640: 5c 64 29 22 2c 20 27 6e 65 78 74 77 6f 72 64 28  \d)", 'nextword(
0650: 73 2c 20 6d 2e 65 6e 64 28 29 2c 20 5c 5c 31 27  s, m.end(), \\1'
0660: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
0670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0680: 20 23 20 77 6f 72 64 28 6e 29 0a 20 20 20 20 73   # word(n).    s
0690: 20 3d 20 72 65 2e 73 75 62 28 72 22 77 6f 72 64   = re.sub(r"word
06a0: 5c 28 5c 73 2a 2d 28 5c 64 29 22 2c 20 27 70 72  \(\s*-(\d)", 'pr
06b0: 65 76 77 6f 72 64 28 73 2c 20 6d 2e 73 74 61 72  evword(s, m.star
06c0: 74 28 29 2c 20 5c 5c 31 27 2c 20 73 29 20 20 20  t(), \\1', s)   
06d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06e0: 20 20 20 20 20 20 20 23 20 77 6f 72 64 28 2d 6e         # word(-n
06f0: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0700: 28 72 22 62 65 66 6f 72 65 5c 28 5c 73 2a 22 2c  (r"before\(\s*",
0710: 20 27 6c 6f 6f 6b 28 73 5b 3a 6d 2e 73 74 61 72   'look(s[:m.star
0720: 74 28 29 5d 2c 20 27 2c 20 73 29 20 20 20 20 20  t()], ', s)     
0730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
0750: 62 65 66 6f 72 65 28 73 29 0a 20 20 20 20 73 20  before(s).    s 
0760: 3d 20 72 65 2e 73 75 62 28 72 22 61 66 74 65 72  = re.sub(r"after
0770: 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 5b  \(\s*", 'look(s[
0780: 6d 2e 65 6e 64 28 29 3a 5d 2c 20 27 2c 20 73 29  m.end():], ', s)
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07b0: 20 20 20 20 20 20 23 20 61 66 74 65 72 28 73 29        # after(s)
07c0: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
07d0: 72 22 74 65 78 74 61 72 65 61 5c 28 5c 73 2a 22  r"textarea\(\s*"
07e0: 2c 20 27 6c 6f 6f 6b 28 73 2c 20 27 2c 20 73 29  , 'look(s, ', s)
07f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0810: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 74               # t
0820: 65 78 74 61 72 65 61 28 73 29 0a 20 20 20 20 73  extarea(s).    s
0830: 20 3d 20 72 65 2e 73 75 62 28 72 22 62 65 66 6f   = re.sub(r"befo
0840: 72 65 5f 63 68 6b 31 5c 28 5c 73 2a 22 2c 20 27  re_chk1\(\s*", '
0850: 6c 6f 6f 6b 5f 63 68 6b 31 28 64 44 41 2c 20 73  look_chk1(dDA, s
0860: 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2c 20 30 2c  [:m.start()], 0,
0870: 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20   ', s)          
0880: 20 20 20 20 20 20 20 23 20 62 65 66 6f 72 65 5f         # before_
0890: 63 68 6b 31 28 73 29 0a 20 20 20 20 73 20 3d 20  chk1(s).    s = 
08a0: 72 65 2e 73 75 62 28 72 22 61 66 74 65 72 5f 63  re.sub(r"after_c
08b0: 68 6b 31 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b  hk1\(\s*", 'look
08c0: 5f 63 68 6b 31 28 64 44 41 2c 20 73 5b 6d 2e 65  _chk1(dDA, s[m.e
08d0: 6e 64 28 29 3a 5d 2c 20 6d 2e 65 6e 64 28 29 2c  nd():], m.end(),
08e0: 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20   ', s)          
08f0: 20 20 20 20 23 20 61 66 74 65 72 5f 63 68 6b 31      # after_chk1
0900: 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73  (s).    s = re.s
0910: 75 62 28 72 22 74 65 78 74 61 72 65 61 5f 63 68  ub(r"textarea_ch
0920: 6b 31 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 5f  k1\(\s*", 'look_
0930: 63 68 6b 31 28 64 44 41 2c 20 73 2c 20 30 2c 20  chk1(dDA, s, 0, 
0940: 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20  ', s)           
0950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0960: 23 20 74 65 78 74 61 72 65 61 5f 63 68 6b 31 28  # textarea_chk1(
0970: 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75  s).    s = re.su
0980: 62 28 72 22 2f 30 22 2c 20 27 73 78 5b 6d 2e 73  b(r"/0", 'sx[m.s
0990: 74 61 72 74 28 29 3a 6d 2e 65 6e 64 28 29 5d 27  tart():m.end()]'
09a0: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
09b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
09d0: 20 2f 30 0a 20 20 20 20 73 20 3d 20 72 65 2e 73   /0.    s = re.s
09e0: 75 62 28 72 22 62 65 66 6f 72 65 30 5c 28 5c 73  ub(r"before0\(\s
09f0: 2a 22 2c 20 27 6c 6f 6f 6b 28 73 78 5b 3a 6d 2e  *", 'look(sx[:m.
0a00: 73 74 61 72 74 28 29 5d 2c 20 27 2c 20 73 29 20  start()], ', s) 
0a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a30: 23 20 62 65 66 6f 72 65 30 28 73 29 0a 20 20 20  # before0(s).   
0a40: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 61 66   s = re.sub(r"af
0a50: 74 65 72 30 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f  ter0\(\s*", 'loo
0a60: 6b 28 73 78 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20  k(sx[m.end():], 
0a70: 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20  ', s)           
0a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a90: 20 20 20 20 20 20 20 20 20 23 20 61 66 74 65 72           # after
0aa0: 30 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  0(s).    s = re.
0ab0: 73 75 62 28 72 22 74 65 78 74 61 72 65 61 30 5c  sub(r"textarea0\
0ac0: 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 78 2c  (\s*", 'look(sx,
0ad0: 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20   ', s)          
0ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b00: 20 23 20 74 65 78 74 61 72 65 61 30 28 73 29 0a   # textarea0(s).
0b10: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
0b20: 22 62 65 66 6f 72 65 30 5f 63 68 6b 31 5c 28 5c  "before0_chk1\(\
0b30: 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63 68 6b 31 28  s*", 'look_chk1(
0b40: 64 44 41 2c 20 73 78 5b 3a 6d 2e 73 74 61 72 74  dDA, sx[:m.start
0b50: 28 29 5d 2c 20 30 2c 20 27 2c 20 73 29 20 20 20  ()], 0, ', s)   
0b60: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 62 65              # be
0b70: 66 6f 72 65 30 5f 63 68 6b 31 28 73 29 0a 20 20  fore0_chk1(s).  
0b80: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 61    s = re.sub(r"a
0b90: 66 74 65 72 30 5f 63 68 6b 31 5c 28 5c 73 2a 22  fter0_chk1\(\s*"
0ba0: 2c 20 27 6c 6f 6f 6b 5f 63 68 6b 31 28 64 44 41  , 'look_chk1(dDA
0bb0: 2c 20 73 78 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20  , sx[m.end():], 
0bc0: 6d 2e 65 6e 64 28 29 2c 20 27 2c 20 73 29 20 20  m.end(), ', s)  
0bd0: 20 20 20 20 20 20 20 20 20 20 23 20 61 66 74 65            # afte
0be0: 72 30 5f 63 68 6b 31 28 73 29 0a 20 20 20 20 73  r0_chk1(s).    s
0bf0: 20 3d 20 72 65 2e 73 75 62 28 72 22 74 65 78 74   = re.sub(r"text
0c00: 61 72 65 61 30 5f 63 68 6b 31 5c 28 5c 73 2a 22  area0_chk1\(\s*"
0c10: 2c 20 27 6c 6f 6f 6b 5f 63 68 6b 31 28 64 44 41  , 'look_chk1(dDA
0c20: 2c 20 73 78 2c 20 30 2c 20 27 2c 20 73 29 20 20  , sx, 0, ', s)  
0c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c40: 20 20 20 20 20 20 20 23 20 74 65 78 74 61 72 65         # textare
0c50: 61 30 5f 63 68 6b 31 28 73 29 0a 20 20 20 20 73  a0_chk1(s).    s
0c60: 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73 45 6e   = re.sub(r"isEn
0c70: 64 4f 66 4e 47 5c 28 5c 73 2a 5c 29 22 2c 20 27  dOfNG\(\s*\)", '
0c80: 69 73 45 6e 64 4f 66 4e 47 28 64 44 41 2c 20 73  isEndOfNG(dDA, s
0c90: 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20 6d 2e 65 6e  [m.end():], m.en
0ca0: 64 28 29 29 27 2c 20 73 29 20 20 20 20 20 20 20  d())', s)       
0cb0: 20 20 20 20 20 20 20 23 20 69 73 45 6e 64 4f 66         # isEndOf
0cc0: 4e 47 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65  NG(s).    s = re
0cd0: 2e 73 75 62 28 72 22 69 73 4e 65 78 74 4e 6f 74  .sub(r"isNextNot
0ce0: 43 4f 44 5c 28 5c 73 2a 5c 29 22 2c 20 27 69 73  COD\(\s*\)", 'is
0cf0: 4e 65 78 74 4e 6f 74 43 4f 44 28 64 44 41 2c 20  NextNotCOD(dDA, 
0d00: 73 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20 6d 2e 65  s[m.end():], m.e
0d10: 6e 64 28 29 29 27 2c 20 73 29 20 20 20 20 20 20  nd())', s)      
0d20: 20 20 23 20 69 73 4e 65 78 74 4e 6f 74 43 4f 44    # isNextNotCOD
0d30: 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73  (s).    s = re.s
0d40: 75 62 28 72 22 69 73 4e 65 78 74 56 65 72 62 5c  ub(r"isNextVerb\
0d50: 28 5c 73 2a 5c 29 22 2c 20 27 69 73 4e 65 78 74  (\s*\)", 'isNext
0d60: 56 65 72 62 28 64 44 41 2c 20 73 5b 6d 2e 65 6e  Verb(dDA, s[m.en
0d70: 64 28 29 3a 5d 2c 20 6d 2e 65 6e 64 28 29 29 27  d():], m.end())'
0d80: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
0d90: 23 20 69 73 4e 65 78 74 56 65 72 62 28 73 29 0a  # isNextVerb(s).
0da0: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
0db0: 22 5c 62 73 70 65 6c 6c 20 2a 5b 28 5d 22 2c 20  "\bspell *[(]", 
0dc0: 27 5f 6f 44 69 63 74 2e 69 73 56 61 6c 69 64 28  '_oDict.isValid(
0dd0: 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65  ', s).    s = re
0de0: 2e 73 75 62 28 72 22 5b 5c 5c 5d 28 5c 64 2b 29  .sub(r"[\\](\d+)
0df0: 22 2c 20 27 6d 2e 67 72 6f 75 70 28 5c 5c 31 29  ", 'm.group(\\1)
0e00: 27 2c 20 73 29 0a 20 20 20 20 72 65 74 75 72 6e  ', s).    return
0e10: 20 73 0a 0a 0a 64 65 66 20 70 79 32 6a 73 20 28   s...def py2js (
0e20: 73 43 6f 64 65 29 3a 0a 20 20 20 20 22 63 6f 6e  sCode):.    "con
0e30: 76 65 72 74 20 50 79 74 68 6f 6e 20 63 6f 64 65  vert Python code
0e40: 20 74 6f 20 4a 61 76 61 53 63 72 69 70 74 20 63   to JavaScript c
0e50: 6f 64 65 22 0a 20 20 20 20 23 20 50 79 74 68 6f  ode".    # Pytho
0e60: 6e 20 32 2e 78 20 75 6e 69 63 6f 64 65 20 73 74  n 2.x unicode st
0e70: 72 69 6e 67 73 0a 20 20 20 20 73 43 6f 64 65 20  rings.    sCode 
0e80: 3d 20 72 65 2e 73 75 62 28 27 5c 5c 62 5b 75 72  = re.sub('\\b[ur
0e90: 5d 22 27 2c 20 27 22 27 2c 20 73 43 6f 64 65 29  ]"', '"', sCode)
0ea0: 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 72 65 2e  .    sCode = re.
0eb0: 73 75 62 28 22 5c 5c 62 5b 75 72 5d 27 22 2c 20  sub("\\b[ur]'", 
0ec0: 22 27 22 2c 20 73 43 6f 64 65 29 0a 20 20 20 20  "'", sCode).    
0ed0: 23 20 6f 70 65 72 61 74 6f 72 73 0a 20 20 20 20  # operators.    
0ee0: 73 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65  sCode = sCode.re
0ef0: 70 6c 61 63 65 28 22 20 61 6e 64 20 22 2c 20 22  place(" and ", "
0f00: 20 26 26 20 22 29 0a 20 20 20 20 73 43 6f 64 65   && ").    sCode
0f10: 20 3d 20 73 43 6f 64 65 2e 72 65 70 6c 61 63 65   = sCode.replace
0f20: 28 22 20 6f 72 20 22 2c 20 22 20 7c 7c 20 22 29  (" or ", " || ")
0f30: 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 72 65 2e  .    sCode = re.
0f40: 73 75 62 28 22 5c 5c 62 6e 6f 74 5c 5c 62 22 2c  sub("\\bnot\\b",
0f50: 20 22 21 22 2c 20 73 43 6f 64 65 29 0a 20 20 20   "!", sCode).   
0f60: 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62 28   sCode = re.sub(
0f70: 22 28 2e 2b 29 20 69 66 20 28 2e 2b 29 20 65 6c  "(.+) if (.+) el
0f80: 73 65 20 28 2e 2b 29 22 2c 20 22 28 5c 5c 32 29  se (.+)", "(\\2)
0f90: 20 3f 20 5c 5c 31 20 3a 20 5c 5c 33 22 2c 20 73   ? \\1 : \\3", s
0fa0: 43 6f 64 65 29 0a 20 20 20 20 23 20 62 6f 6f 6c  Code).    # bool
0fb0: 65 61 6e 0a 20 20 20 20 73 43 6f 64 65 20 3d 20  ean.    sCode = 
0fc0: 73 43 6f 64 65 2e 72 65 70 6c 61 63 65 28 22 46  sCode.replace("F
0fd0: 61 6c 73 65 22 2c 20 22 66 61 6c 73 65 22 29 0a  alse", "false").
0fe0: 20 20 20 20 73 43 6f 64 65 20 3d 20 73 43 6f 64      sCode = sCod
0ff0: 65 2e 72 65 70 6c 61 63 65 28 22 54 72 75 65 22  e.replace("True"
1000: 2c 20 22 74 72 75 65 22 29 0a 20 20 20 20 73 43  , "true").    sC
1010: 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65 70 6c  ode = sCode.repl
1020: 61 63 65 28 22 62 6f 6f 6c 22 2c 20 22 42 6f 6f  ace("bool", "Boo
1030: 6c 65 61 6e 22 29 0a 20 20 20 20 23 20 6d 65 74  lean").    # met
1040: 68 6f 64 73 0a 20 20 20 20 73 43 6f 64 65 20 3d  hods.    sCode =
1050: 20 73 43 6f 64 65 2e 72 65 70 6c 61 63 65 28 22   sCode.replace("
1060: 2e 5f 5f 6c 65 6e 5f 5f 28 29 22 2c 20 22 2e 6c  .__len__()", ".l
1070: 65 6e 67 74 68 22 29 0a 20 20 20 20 73 43 6f 64  ength").    sCod
1080: 65 20 3d 20 73 43 6f 64 65 2e 72 65 70 6c 61 63  e = sCode.replac
1090: 65 28 22 2e 65 6e 64 73 77 69 74 68 22 2c 20 22  e(".endswith", "
10a0: 2e 65 6e 64 73 57 69 74 68 22 29 0a 20 20 20 20  .endsWith").    
10b0: 73 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65  sCode = sCode.re
10c0: 70 6c 61 63 65 28 22 2e 66 69 6e 64 22 2c 20 22  place(".find", "
10d0: 2e 69 6e 64 65 78 4f 66 22 29 0a 20 20 20 20 73  .indexOf").    s
10e0: 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65 70  Code = sCode.rep
10f0: 6c 61 63 65 28 22 2e 73 74 61 72 74 73 77 69 74  lace(".startswit
1100: 68 22 2c 20 22 2e 73 74 61 72 74 73 57 69 74 68  h", ".startsWith
1110: 22 29 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 73  ").    sCode = s
1120: 43 6f 64 65 2e 72 65 70 6c 61 63 65 28 22 2e 6c  Code.replace(".l
1130: 6f 77 65 72 22 2c 20 22 2e 74 6f 4c 6f 77 65 72  ower", ".toLower
1140: 43 61 73 65 22 29 0a 20 20 20 20 73 43 6f 64 65  Case").    sCode
1150: 20 3d 20 73 43 6f 64 65 2e 72 65 70 6c 61 63 65   = sCode.replace
1160: 28 22 2e 75 70 70 65 72 22 2c 20 22 2e 74 6f 55  (".upper", ".toU
1170: 70 70 65 72 43 61 73 65 22 29 0a 20 20 20 20 73  pperCase").    s
1180: 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65 70  Code = sCode.rep
1190: 6c 61 63 65 28 22 2e 69 73 64 69 67 69 74 22 2c  lace(".isdigit",
11a0: 20 22 2e 5f 69 73 44 69 67 69 74 22 29 0a 20 20   "._isDigit").  
11b0: 20 20 73 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e    sCode = sCode.
11c0: 72 65 70 6c 61 63 65 28 22 2e 69 73 75 70 70 65  replace(".isuppe
11d0: 72 22 2c 20 22 2e 5f 69 73 55 70 70 65 72 43 61  r", "._isUpperCa
11e0: 73 65 22 29 0a 20 20 20 20 73 43 6f 64 65 20 3d  se").    sCode =
11f0: 20 73 43 6f 64 65 2e 72 65 70 6c 61 63 65 28 22   sCode.replace("
1200: 2e 69 73 6c 6f 77 65 72 22 2c 20 22 2e 5f 69 73  .islower", "._is
1210: 4c 6f 77 65 72 43 61 73 65 22 29 0a 20 20 20 20  LowerCase").    
1220: 73 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65  sCode = sCode.re
1230: 70 6c 61 63 65 28 22 2e 69 73 74 69 74 6c 65 22  place(".istitle"
1240: 2c 20 22 2e 5f 69 73 54 69 74 6c 65 22 29 0a 20  , "._isTitle"). 
1250: 20 20 20 73 43 6f 64 65 20 3d 20 73 43 6f 64 65     sCode = sCode
1260: 2e 72 65 70 6c 61 63 65 28 22 2e 63 61 70 69 74  .replace(".capit
1270: 61 6c 69 7a 65 22 2c 20 22 2e 5f 74 6f 43 61 70  alize", "._toCap
1280: 69 74 61 6c 69 7a 65 22 29 0a 20 20 20 20 73 43  italize").    sC
1290: 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65 70 6c  ode = sCode.repl
12a0: 61 63 65 28 22 2e 73 74 72 69 70 22 2c 20 22 2e  ace(".strip", ".
12b0: 5f 74 72 69 6d 22 29 0a 20 20 20 20 73 43 6f 64  _trim").    sCod
12c0: 65 20 3d 20 73 43 6f 64 65 2e 72 65 70 6c 61 63  e = sCode.replac
12d0: 65 28 22 2e 6c 73 74 72 69 70 22 2c 20 22 2e 5f  e(".lstrip", "._
12e0: 74 72 69 6d 4c 65 66 74 22 29 0a 20 20 20 20 73  trimLeft").    s
12f0: 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65 70  Code = sCode.rep
1300: 6c 61 63 65 28 22 2e 72 73 74 72 69 70 22 2c 20  lace(".rstrip", 
1310: 22 2e 5f 74 72 69 6d 52 69 67 68 74 22 29 0a 20  "._trimRight"). 
1320: 20 20 20 73 43 6f 64 65 20 3d 20 73 43 6f 64 65     sCode = sCode
1330: 2e 72 65 70 6c 61 63 65 28 27 2e 72 65 70 6c 61  .replace('.repla
1340: 63 65 28 22 2e 22 27 2c 20 22 2e 72 65 70 6c 61  ce("."', ".repla
1350: 63 65 28 2f 5c 2e 2f 67 22 29 0a 20 20 20 20 73  ce(/\./g").    s
1360: 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65 70  Code = sCode.rep
1370: 6c 61 63 65 28 27 2e 72 65 70 6c 61 63 65 28 22  lace('.replace("
1380: 2e 2e 2e 22 27 2c 20 22 2e 72 65 70 6c 61 63 65  ..."', ".replace
1390: 28 2f 5c 2e 5c 2e 5c 2e 2f 67 22 29 0a 20 20 20  (/\.\.\./g").   
13a0: 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62 28   sCode = re.sub(
13b0: 27 2e 72 65 70 6c 61 63 65 5c 28 22 28 5b 5e 22  '.replace\("([^"
13c0: 5d 2b 29 22 20 3f 2c 27 2c 20 22 2e 72 65 70 6c  ]+)" ?,', ".repl
13d0: 61 63 65 28 2f 5c 5c 31 2f 67 2c 22 2c 20 73 43  ace(/\\1/g,", sC
13e0: 6f 64 65 29 0a 20 20 20 20 23 20 72 65 67 65 78  ode).    # regex
13f0: 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 72 65 2e  .    sCode = re.
1400: 73 75 62 28 27 72 65 2e 73 65 61 72 63 68 5c 28  sub('re.search\(
1410: 22 28 5b 5e 22 5d 2b 29 22 2c 20 2a 28 6d 2e 67  "([^"]+)", *(m.g
1420: 72 6f 75 70 5c 28 5c 5c 64 5c 29 29 5c 29 27 2c  roup\(\\d\))\)',
1430: 20 22 28 5c 5c 32 2e 73 65 61 72 63 68 28 2f 5c   "(\\2.search(/\
1440: 5c 31 2f 29 20 3e 3d 20 30 29 22 2c 20 73 43 6f  \1/) >= 0)", sCo
1450: 64 65 29 0a 20 20 20 20 73 43 6f 64 65 20 3d 20  de).    sCode = 
1460: 72 65 2e 73 75 62 28 22 2e 73 65 61 72 63 68 5c  re.sub(".search\
1470: 5c 28 2f 5c 5c 28 5c 5c 3f 69 5c 5c 29 28 5b 5e  \(/\\(\\?i\\)([^
1480: 2f 5d 2b 29 2f 5c 5c 29 20 3e 3d 20 30 5c 5c 29  /]+)/\\) >= 0\\)
1490: 22 2c 20 22 2e 73 65 61 72 63 68 28 2f 5c 5c 31  ", ".search(/\\1
14a0: 2f 69 29 20 3e 3d 20 30 29 22 2c 20 73 43 6f 64  /i) >= 0)", sCod
14b0: 65 29 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 72  e).    sCode = r
14c0: 65 2e 73 75 62 28 27 28 6c 6f 6f 6b 5c 5c 28 73  e.sub('(look\\(s
14d0: 78 3f 5b 5d 5b 2e 61 2d 7a 3a 28 29 5d 2a 29 2c  x?[][.a-z:()]*),
14e0: 20 22 5c 5c 28 5c 5c 3f 69 5c 5c 29 28 5b 5e 22   "\\(\\?i\\)([^"
14f0: 5d 2b 29 22 27 2c 20 22 5c 5c 31 2c 20 2f 5c 5c  ]+)"', "\\1, /\\
1500: 32 2f 69 22 2c 20 73 43 6f 64 65 29 0a 20 20 20  2/i", sCode).   
1510: 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62 28   sCode = re.sub(
1520: 27 28 6c 6f 6f 6b 5c 5c 28 73 78 3f 5b 5d 5b 2e  '(look\\(sx?[][.
1530: 61 2d 7a 3a 28 29 5d 2a 29 2c 20 22 28 5b 5e 22  a-z:()]*), "([^"
1540: 5d 2b 29 22 27 2c 20 22 5c 5c 31 2c 20 2f 5c 5c  ]+)"', "\\1, /\\
1550: 32 2f 22 2c 20 73 43 6f 64 65 29 0a 20 20 20 20  2/", sCode).    
1560: 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62 28 27  sCode = re.sub('
1570: 28 6c 6f 6f 6b 5f 63 68 6b 31 5c 5c 28 64 44 41  (look_chk1\\(dDA
1580: 2c 20 73 78 3f 5b 5d 5b 2e 61 2d 7a 3a 28 29 5d  , sx?[][.a-z:()]
1590: 2a 2c 20 5b 30 2d 39 61 2d 7a 2e 28 29 5d 2b 29  *, [0-9a-z.()]+)
15a0: 2c 20 22 5c 5c 28 5c 5c 3f 69 5c 5c 29 28 5b 5e  , "\\(\\?i\\)([^
15b0: 22 5d 2b 29 22 27 2c 20 22 5c 5c 31 2c 20 2f 5c  "]+)"', "\\1, /\
15c0: 5c 32 2f 69 22 2c 20 73 43 6f 64 65 29 0a 20 20  \2/i", sCode).  
15d0: 20 20 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62    sCode = re.sub
15e0: 28 27 28 6c 6f 6f 6b 5f 63 68 6b 31 5c 5c 28 64  ('(look_chk1\\(d
15f0: 44 41 2c 20 73 78 3f 5b 5d 5b 2e 61 2d 7a 3a 28  DA, sx?[][.a-z:(
1600: 29 5d 2a 2c 20 5b 30 2d 39 61 2d 7a 2e 28 29 5d  )]*, [0-9a-z.()]
1610: 2b 29 2c 20 22 28 5b 5e 22 5d 2b 29 22 27 2c 20  +), "([^"]+)"', 
1620: 22 5c 5c 31 2c 20 2f 5c 5c 32 2f 69 22 2c 20 73  "\\1, /\\2/i", s
1630: 43 6f 64 65 29 0a 20 20 20 20 73 43 6f 64 65 20  Code).    sCode 
1640: 3d 20 73 43 6f 64 65 2e 72 65 70 6c 61 63 65 28  = sCode.replace(
1650: 22 28 3f 3c 21 2d 29 22 2c 20 22 22 29 20 20 23  "(?<!-)", "")  #
1660: 20 74 6f 64 6f 0a 20 20 20 20 23 20 73 6c 69 63   todo.    # slic
1670: 65 73 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 73  es.    sCode = s
1680: 43 6f 64 65 2e 72 65 70 6c 61 63 65 28 22 5b 3a  Code.replace("[:
1690: 6d 2e 73 74 61 72 74 28 29 5d 22 2c 20 22 2e 73  m.start()]", ".s
16a0: 6c 69 63 65 28 30 2c 6d 2e 69 6e 64 65 78 29 22  lice(0,m.index)"
16b0: 29 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 73 43  ).    sCode = sC
16c0: 6f 64 65 2e 72 65 70 6c 61 63 65 28 22 5b 6d 2e  ode.replace("[m.
16d0: 65 6e 64 28 29 3a 5d 22 2c 20 22 2e 73 6c 69 63  end():]", ".slic
16e0: 65 28 6d 2e 65 6e 64 5b 30 5d 29 22 29 0a 20 20  e(m.end[0])").  
16f0: 20 20 73 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e    sCode = sCode.
1700: 72 65 70 6c 61 63 65 28 22 5b 6d 2e 73 74 61 72  replace("[m.star
1710: 74 28 29 3a 6d 2e 65 6e 64 28 29 5d 22 2c 20 22  t():m.end()]", "
1720: 2e 73 6c 69 63 65 28 6d 2e 69 6e 64 65 78 2c 20  .slice(m.index, 
1730: 6d 2e 65 6e 64 5b 30 5d 29 22 29 0a 20 20 20 20  m.end[0])").    
1740: 73 43 6f 64 65 20 3d 20 72 65 2e 73 75 62 28 22  sCode = re.sub("
1750: 5c 5c 5b 28 2d 3f 5c 5c 64 2b 29 3a 28 2d 3f 5c  \\[(-?\\d+):(-?\
1760: 5c 64 2b 29 5c 5c 5d 22 2c 20 22 2e 73 6c 69 63  \d+)\\]", ".slic
1770: 65 28 5c 5c 31 2c 5c 5c 32 29 22 2c 20 73 43 6f  e(\\1,\\2)", sCo
1780: 64 65 29 0a 20 20 20 20 73 43 6f 64 65 20 3d 20  de).    sCode = 
1790: 72 65 2e 73 75 62 28 22 5c 5c 5b 28 2d 3f 5c 5c  re.sub("\\[(-?\\
17a0: 64 2b 29 3a 5c 5c 5d 22 2c 20 22 2e 73 6c 69 63  d+):\\]", ".slic
17b0: 65 28 5c 5c 31 29 22 2c 20 73 43 6f 64 65 29 0a  e(\\1)", sCode).
17c0: 20 20 20 20 73 43 6f 64 65 20 3d 20 72 65 2e 73      sCode = re.s
17d0: 75 62 28 22 5c 5c 5b 3a 28 2d 3f 5c 5c 64 2b 29  ub("\\[:(-?\\d+)
17e0: 5c 5c 5d 22 2c 20 22 2e 73 6c 69 63 65 28 30 2c  \\]", ".slice(0,
17f0: 5c 5c 31 29 22 2c 20 73 43 6f 64 65 29 0a 20 20  \\1)", sCode).  
1800: 20 20 23 20 72 65 67 65 78 20 6d 61 74 63 68 65    # regex matche
1810: 73 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 73 43  s.    sCode = sC
1820: 6f 64 65 2e 72 65 70 6c 61 63 65 28 22 2e 65 6e  ode.replace(".en
1830: 64 28 29 22 2c 20 22 2e 65 6e 64 5b 30 5d 22 29  d()", ".end[0]")
1840: 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 73 43 6f  .    sCode = sCo
1850: 64 65 2e 72 65 70 6c 61 63 65 28 22 2e 73 74 61  de.replace(".sta
1860: 72 74 28 29 22 2c 20 22 2e 69 6e 64 65 78 22 29  rt()", ".index")
1870: 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 73 43 6f  .    sCode = sCo
1880: 64 65 2e 72 65 70 6c 61 63 65 28 22 6d 2e 67 72  de.replace("m.gr
1890: 6f 75 70 28 29 22 2c 20 22 6d 5b 30 5d 22 29 0a  oup()", "m[0]").
18a0: 20 20 20 20 73 43 6f 64 65 20 3d 20 72 65 2e 73      sCode = re.s
18b0: 75 62 28 22 5c 5c 2e 73 74 61 72 74 5c 5c 28 28  ub("\\.start\\((
18c0: 5c 5c 64 2b 29 5c 5c 29 22 2c 20 22 2e 73 74 61  \\d+)\\)", ".sta
18d0: 72 74 5b 5c 5c 31 5d 22 2c 20 73 43 6f 64 65 29  rt[\\1]", sCode)
18e0: 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 72 65 2e  .    sCode = re.
18f0: 73 75 62 28 22 6d 5c 5c 2e 67 72 6f 75 70 5c 5c  sub("m\\.group\\
1900: 28 28 5c 5c 64 2b 29 5c 5c 29 22 2c 20 22 6d 5b  ((\\d+)\\)", "m[
1910: 5c 5c 31 5d 22 2c 20 73 43 6f 64 65 29 0a 20 20  \\1]", sCode).  
1920: 20 20 23 20 74 75 70 6c 65 73 20 2d 3e 20 6c 69    # tuples -> li
1930: 73 74 73 0a 20 20 20 20 73 43 6f 64 65 20 3d 20  sts.    sCode = 
1940: 72 65 2e 73 75 62 28 22 5c 28 28 6d 5c 2e 73 74  re.sub("\((m\.st
1950: 61 72 74 5c 5b 5c 5c 64 2b 5c 5d 2c 20 6d 5c 5b  art\[\\d+\], m\[
1960: 5c 5c 64 2b 5c 5d 29 5c 29 22 2c 20 22 5b 5c 5c  \\d+\])\)", "[\\
1970: 31 5d 22 2c 20 73 43 6f 64 65 29 0a 20 20 20 20  1]", sCode).    
1980: 23 20 72 65 67 65 78 0a 20 20 20 20 73 43 6f 64  # regex.    sCod
1990: 65 20 3d 20 73 43 6f 64 65 2e 72 65 70 6c 61 63  e = sCode.replac
19a0: 65 28 22 5c 77 5b 5c 77 2d 5d 2b 22 2c 20 22 5b  e("\w[\w-]+", "[
19b0: 61 2d 7a 41 2d 5a c3 a0 2d c3 b6 c3 80 2d c3 96  a-zA-Z..-....-..
19c0: 30 2d 39 5f c3 b8 2d c3 bf c3 98 2d c3 9f c4 80  0-9_..-....-....
19d0: 2d ca af ef ac 81 2d ef ac 86 5d 5b 61 2d 7a 41  -.....-...][a-zA
19e0: 2d 5a c3 a0 2d c3 b6 c3 80 2d c3 96 30 2d 39 5f  -Z..-....-..0-9_
19f0: c3 b8 2d c3 bf c3 98 2d c3 9f c4 80 2d ca af ef  ..-....-....-...
1a00: ac 81 2d ef ac 86 2d 5d 2b 22 29 0a 20 20 20 20  ..-...-]+").    
1a10: 73 43 6f 64 65 20 3d 20 73 43 6f 64 65 2e 72 65  sCode = sCode.re
1a20: 70 6c 61 63 65 28 72 22 2f 5c 77 2f 22 2c 20 22  place(r"/\w/", "
1a30: 2f 5b 61 2d 7a 41 2d 5a c3 a0 2d c3 b6 c3 80 2d  /[a-zA-Z..-....-
1a40: c3 96 30 2d 39 5f c3 b8 2d c3 bf c3 98 2d c3 9f  ..0-9_..-....-..
1a50: c4 80 2d ca af ef ac 81 2d ef ac 86 5d 2f 22 29  ..-.....-...]/")
1a60: 0a 20 20 20 20 73 43 6f 64 65 20 3d 20 73 43 6f  .    sCode = sCo
1a70: 64 65 2e 72 65 70 6c 61 63 65 28 72 22 5b 5c 77  de.replace(r"[\w
1a80: 2d 5d 22 2c 20 22 5b 61 2d 7a 41 2d 5a c3 a0 2d  -]", "[a-zA-Z..-
1a90: c3 b6 c3 80 2d c3 96 30 2d 39 5f c3 b8 2d c3 bf  ....-..0-9_..-..
1aa0: c3 98 2d c3 9f c4 80 2d ca af ef ac 81 2d ef ac  ..-....-.....-..
1ab0: 86 2d 5d 22 29 0a 20 20 20 20 73 43 6f 64 65 20  .-]").    sCode 
1ac0: 3d 20 73 43 6f 64 65 2e 72 65 70 6c 61 63 65 28  = sCode.replace(
1ad0: 72 22 5b 5c 77 2c 5d 22 2c 20 22 5b 61 2d 7a 41  r"[\w,]", "[a-zA
1ae0: 2d 5a c3 a0 2d c3 b6 c3 80 2d c3 96 30 2d 39 5f  -Z..-....-..0-9_
1af0: c3 b8 2d c3 bf c3 98 2d c3 9f c4 80 2d ca af ef  ..-....-....-...
1b00: ac 81 2d ef ac 86 2c 5d 22 29 0a 20 20 20 20 72  ..-...,]").    r
1b10: 65 74 75 72 6e 20 73 43 6f 64 65 0a 0a 0a 64 65  eturn sCode...de
1b20: 66 20 75 70 70 65 72 63 61 73 65 20 28 73 2c 20  f uppercase (s, 
1b30: 73 4c 61 6e 67 29 3a 0a 20 20 20 20 22 28 66 6c  sLang):.    "(fl
1b40: 61 67 20 69 20 69 73 20 6e 6f 74 20 65 6e 6f 75  ag i is not enou
1b50: 67 68 29 3a 20 63 6f 6e 76 65 72 74 73 20 72 65  gh): converts re
1b60: 67 65 78 20 74 6f 20 75 70 70 65 72 63 61 73 65  gex to uppercase
1b70: 20 72 65 67 65 78 3a 20 27 66 6f 6f 27 20 62 65   regex: 'foo' be
1b80: 63 6f 6d 65 73 20 27 5b 46 66 5d 5b 4f 6f 5d 5b  comes '[Ff][Oo][
1b90: 4f 6f 5d 27 2c 20 62 75 74 20 27 42 61 72 27 20  Oo]', but 'Bar' 
1ba0: 62 65 63 6f 6d 65 73 20 27 42 5b 41 61 5d 5b 52  becomes 'B[Aa][R
1bb0: 72 5d 27 2e 22 0a 20 20 20 20 73 55 70 20 3d 20  r]'.".    sUp = 
1bc0: 22 22 0a 20 20 20 20 6e 53 74 61 74 65 20 3d 20  "".    nState = 
1bd0: 30 0a 20 20 20 20 66 6f 72 20 69 20 69 6e 20 72  0.    for i in r
1be0: 61 6e 67 65 28 30 2c 20 6c 65 6e 28 73 29 29 3a  ange(0, len(s)):
1bf0: 0a 20 20 20 20 20 20 20 20 63 20 3d 20 73 5b 69  .        c = s[i
1c00: 5d 0a 20 20 20 20 20 20 20 20 69 66 20 63 20 3d  ].        if c =
1c10: 3d 20 22 5b 22 3a 0a 20 20 20 20 20 20 20 20 20  = "[":.         
1c20: 20 20 20 6e 53 74 61 74 65 20 3d 20 31 0a 20 20     nState = 1.  
1c30: 20 20 20 20 20 20 69 66 20 6e 53 74 61 74 65 20        if nState 
1c40: 3d 3d 20 31 20 61 6e 64 20 63 20 3d 3d 20 22 5d  == 1 and c == "]
1c50: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e  ":.            n
1c60: 53 74 61 74 65 20 3d 20 30 0a 20 20 20 20 20 20  State = 0.      
1c70: 20 20 69 66 20 63 20 3d 3d 20 22 3c 22 20 61 6e    if c == "<" an
1c80: 64 20 69 20 3e 20 33 20 61 6e 64 20 73 5b 69 2d  d i > 3 and s[i-
1c90: 33 3a 69 5d 20 3d 3d 20 22 28 3f 50 22 3a 0a 20  3:i] == "(?P":. 
1ca0: 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61 74             nStat
1cb0: 65 20 3d 20 32 0a 20 20 20 20 20 20 20 20 69 66  e = 2.        if
1cc0: 20 6e 53 74 61 74 65 20 3d 3d 20 32 20 61 6e 64   nState == 2 and
1cd0: 20 63 20 3d 3d 20 22 3e 22 3a 0a 20 20 20 20 20   c == ">":.     
1ce0: 20 20 20 20 20 20 20 6e 53 74 61 74 65 20 3d 20         nState = 
1cf0: 30 0a 20 20 20 20 20 20 20 20 69 66 20 63 20 3d  0.        if c =
1d00: 3d 20 22 3f 22 20 61 6e 64 20 69 20 3e 20 30 20  = "?" and i > 0 
1d10: 61 6e 64 20 73 5b 69 2d 31 3a 69 5d 20 3d 3d 20  and s[i-1:i] == 
1d20: 22 28 22 20 61 6e 64 20 73 5b 69 2b 31 3a 69 2b  "(" and s[i+1:i+
1d30: 32 5d 20 21 3d 20 22 3a 22 3a 0a 20 20 20 20 20  2] != ":":.     
1d40: 20 20 20 20 20 20 20 6e 53 74 61 74 65 20 3d 20         nState = 
1d50: 35 0a 20 20 20 20 20 20 20 20 69 66 20 6e 53 74  5.        if nSt
1d60: 61 74 65 20 3d 3d 20 35 20 61 6e 64 20 63 20 3d  ate == 5 and c =
1d70: 3d 20 22 29 22 3a 0a 20 20 20 20 20 20 20 20 20  = ")":.         
1d80: 20 20 20 6e 53 74 61 74 65 20 3d 20 30 0a 20 20     nState = 0.  
1d90: 20 20 20 20 20 20 69 66 20 63 2e 69 73 61 6c 70        if c.isalp
1da0: 68 61 28 29 20 61 6e 64 20 63 2e 69 73 6c 6f 77  ha() and c.islow
1db0: 65 72 28 29 20 61 6e 64 20 6e 53 74 61 74 65 20  er() and nState 
1dc0: 3d 3d 20 30 3a 0a 20 20 20 20 20 20 20 20 20 20  == 0:.          
1dd0: 20 20 69 66 20 63 20 3d 3d 20 22 69 22 20 61 6e    if c == "i" an
1de0: 64 20 28 73 4c 61 6e 67 20 3d 3d 20 22 74 72 22  d (sLang == "tr"
1df0: 20 6f 72 20 73 4c 61 6e 67 20 3d 3d 20 22 61 7a   or sLang == "az
1e00: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
1e10: 20 20 20 20 73 55 70 20 2b 3d 20 22 5b c4 b0 22      sUp += "[.."
1e20: 20 2b 20 63 20 2b 20 22 5d 22 0a 20 20 20 20 20   + c + "]".     
1e30: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
1e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 55 70               sUp
1e50: 20 2b 3d 20 22 5b 22 20 2b 20 63 2e 75 70 70 65   += "[" + c.uppe
1e60: 72 28 29 20 2b 20 63 20 2b 20 22 5d 22 0a 20 20  r() + c + "]".  
1e70: 20 20 20 20 20 20 65 6c 69 66 20 63 2e 69 73 61        elif c.isa
1e80: 6c 70 68 61 28 29 20 61 6e 64 20 63 2e 69 73 6c  lpha() and c.isl
1e90: 6f 77 65 72 28 29 20 61 6e 64 20 6e 53 74 61 74  ower() and nStat
1ea0: 65 20 3d 3d 20 31 20 61 6e 64 20 73 5b 69 2b 31  e == 1 and s[i+1
1eb0: 3a 69 2b 32 5d 20 21 3d 20 22 2d 22 3a 0a 20 20  :i+2] != "-":.  
1ec0: 20 20 20 20 20 20 20 20 20 20 69 66 20 73 5b 69            if s[i
1ed0: 2d 31 3a 69 5d 20 3d 3d 20 22 2d 22 20 61 6e 64  -1:i] == "-" and
1ee0: 20 73 5b 69 2d 32 3a 69 2d 31 5d 2e 69 73 6c 6f   s[i-2:i-1].islo
1ef0: 77 65 72 28 29 3a 20 20 23 20 5b 61 2d 7a 5d 20  wer():  # [a-z] 
1f00: 2d 3e 20 5b 61 2d 7a 41 2d 5a 5d 0a 20 20 20 20  -> [a-zA-Z].    
1f10: 20 20 20 20 20 20 20 20 20 20 20 20 73 55 70 20              sUp 
1f20: 2b 3d 20 63 20 2b 20 73 5b 69 2d 32 3a 69 2d 31  += c + s[i-2:i-1
1f30: 5d 2e 75 70 70 65 72 28 29 20 2b 20 22 2d 22 20  ].upper() + "-" 
1f40: 2b 20 63 2e 75 70 70 65 72 28 29 0a 20 20 20 20  + c.upper().    
1f50: 20 20 20 20 20 20 20 20 65 6c 69 66 20 63 20 3d          elif c =
1f60: 3d 20 22 69 22 20 61 6e 64 20 28 73 4c 61 6e 67  = "i" and (sLang
1f70: 20 3d 3d 20 22 74 72 22 20 6f 72 20 73 4c 61 6e   == "tr" or sLan
1f80: 67 20 3d 3d 20 22 61 7a 22 29 3a 0a 20 20 20 20  g == "az"):.    
1f90: 20 20 20 20 20 20 20 20 20 20 20 20 73 55 70 20              sUp 
1fa0: 2b 3d 20 22 c4 b0 22 20 2b 20 63 0a 20 20 20 20  += ".." + c.    
1fb0: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
1fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 55                sU
1fd0: 70 20 2b 3d 20 63 2e 75 70 70 65 72 28 29 20 2b  p += c.upper() +
1fe0: 20 63 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a   c.        else:
1ff0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 55 70  .            sUp
2000: 20 2b 3d 20 63 0a 20 20 20 20 20 20 20 20 69 66   += c.        if
2010: 20 63 20 3d 3d 20 22 5c 5c 22 3a 0a 20 20 20 20   c == "\\":.    
2020: 20 20 20 20 20 20 20 20 6e 53 74 61 74 65 20 3d          nState =
2030: 20 34 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20   4.        elif 
2040: 6e 53 74 61 74 65 20 3d 3d 20 34 3a 0a 20 20 20  nState == 4:.   
2050: 20 20 20 20 20 20 20 20 20 6e 53 74 61 74 65 20           nState 
2060: 3d 20 30 0a 20 20 20 20 72 65 74 75 72 6e 20 73  = 0.    return s
2070: 55 70 0a 0a 0a 64 65 66 20 63 6f 75 6e 74 47 72  Up...def countGr
2080: 6f 75 70 49 6e 52 65 67 65 78 20 28 73 52 65 67  oupInRegex (sReg
2090: 65 78 29 3a 0a 20 20 20 20 74 72 79 3a 0a 20 20  ex):.    try:.  
20a0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 65 2e        return re.
20b0: 63 6f 6d 70 69 6c 65 28 73 52 65 67 65 78 29 2e  compile(sRegex).
20c0: 67 72 6f 75 70 73 0a 20 20 20 20 65 78 63 65 70  groups.    excep
20d0: 74 3a 0a 20 20 20 20 20 20 20 20 74 72 61 63 65  t:.        trace
20e0: 62 61 63 6b 2e 70 72 69 6e 74 5f 65 78 63 28 29  back.print_exc()
20f0: 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 73  .        print(s
2100: 52 65 67 65 78 29 0a 20 20 20 20 72 65 74 75 72  Regex).    retur
2110: 6e 20 30 0a 0a 0a 64 65 66 20 63 72 65 61 74 65  n 0...def create
2120: 52 75 6c 65 20 28 73 2c 20 6e 49 64 4c 69 6e 65  Rule (s, nIdLine
2130: 2c 20 73 4c 61 6e 67 2c 20 62 50 61 72 61 67 72  , sLang, bParagr
2140: 61 70 68 2c 20 64 4f 70 74 50 72 69 6f 72 69 74  aph, dOptPriorit
2150: 79 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73  y):.    "returns
2160: 20 72 75 6c 65 20 61 73 20 6c 69 73 74 20 5b 6f   rule as list [o
2170: 70 74 69 6f 6e 20 6e 61 6d 65 2c 20 72 65 67 65  ption name, rege
2180: 78 2c 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74  x, bCaseInsensit
2190: 69 76 65 2c 20 69 64 65 6e 74 69 66 69 65 72 2c  ive, identifier,
21a0: 20 6c 69 73 74 20 6f 66 20 61 63 74 69 6f 6e 73   list of actions
21b0: 5d 22 0a 20 20 20 20 67 6c 6f 62 61 6c 20 64 4a  ]".    global dJ
21c0: 53 52 45 47 45 58 45 53 0a 20 20 20 20 67 6c 6f  SREGEXES.    glo
21d0: 62 61 6c 20 6e 52 55 4c 45 57 49 54 48 4f 55 54  bal nRULEWITHOUT
21e0: 4e 41 4d 45 0a 0a 20 20 20 20 23 23 23 23 20 4f  NAME..    #### O
21f0: 50 54 49 4f 4e 53 0a 20 20 20 20 73 4c 69 6e 65  PTIONS.    sLine
2200: 49 64 20 3d 20 73 74 72 28 6e 49 64 4c 69 6e 65  Id = str(nIdLine
2210: 29 20 2b 20 28 22 70 22 20 69 66 20 62 50 61 72  ) + ("p" if bPar
2220: 61 67 72 61 70 68 20 65 6c 73 65 20 22 73 22 29  agraph else "s")
2230: 0a 20 20 20 20 73 52 75 6c 65 49 64 20 3d 20 73  .    sRuleId = s
2240: 4c 69 6e 65 49 64 0a 20 20 20 20 73 4f 70 74 69  LineId.    sOpti
2250: 6f 6e 20 3d 20 46 61 6c 73 65 20 20 20 20 20 20  on = False      
2260: 20 20 20 23 20 46 61 6c 73 65 20 6f 72 20 5b 61     # False or [a
2270: 2d 7a 30 2d 39 5d 2b 20 6e 61 6d 65 0a 20 20 20  -z0-9]+ name.   
2280: 20 6e 50 72 69 6f 72 69 74 79 20 3d 20 34 20 20   nPriority = 4  
2290: 20 20 20 20 20 20 20 20 20 23 20 44 65 66 61 75           # Defau
22a0: 6c 74 20 69 73 20 34 2c 20 76 61 6c 75 65 20 6d  lt is 4, value m
22b0: 75 73 74 20 62 65 20 62 65 74 77 65 65 6e 20 30  ust be between 0
22c0: 20 61 6e 64 20 39 0a 20 20 20 20 74 47 72 6f 75   and 9.    tGrou
22d0: 70 73 20 3d 20 4e 6f 6e 65 20 20 20 20 20 20 20  ps = None       
22e0: 20 20 20 23 20 63 6f 64 65 20 66 6f 72 20 67 72     # code for gr
22f0: 6f 75 70 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67  oups positioning
2300: 20 28 6f 6e 6c 79 20 75 73 65 66 75 6c 20 66 6f   (only useful fo
2310: 72 20 4a 61 76 61 53 63 72 69 70 74 29 0a 20 20  r JavaScript).  
2320: 20 20 63 43 61 73 65 4d 6f 64 65 20 3d 20 27 69    cCaseMode = 'i
2330: 27 20 20 20 20 20 20 20 20 20 23 20 69 3a 20 63  '         # i: c
2340: 61 73 65 20 69 6e 73 65 6e 73 69 74 69 76 65 2c  ase insensitive,
2350: 20 20 73 3a 20 63 61 73 65 20 73 65 6e 73 69 74    s: case sensit
2360: 69 76 65 2c 20 20 75 3a 20 75 70 70 65 72 63 61  ive,  u: upperca
2370: 73 69 6e 67 20 61 6c 6c 6f 77 65 64 0a 20 20 20  sing allowed.   
2380: 20 63 57 6f 72 64 4c 69 6d 69 74 4c 65 66 74 20   cWordLimitLeft 
2390: 3d 20 27 5b 27 20 20 20 20 23 20 5b 3a 20 77 6f  = '['    # [: wo
23a0: 72 64 20 6c 69 6d 69 74 2c 20 3c 3a 20 6e 6f 20  rd limit, <: no 
23b0: 73 70 65 63 69 66 69 63 20 6c 69 6d 69 74 0a 20  specific limit. 
23c0: 20 20 20 63 57 6f 72 64 4c 69 6d 69 74 52 69 67     cWordLimitRig
23d0: 68 74 20 3d 20 27 5d 27 20 20 20 23 20 5d 3a 20  ht = ']'   # ]: 
23e0: 77 6f 72 64 20 6c 69 6d 69 74 2c 20 3e 3a 20 6e  word limit, >: n
23f0: 6f 20 73 70 65 63 69 66 69 63 20 6c 69 6d 69 74  o specific limit
2400: 0a 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63  .    m = re.matc
2410: 68 28 22 5e 5f 5f 28 3f 50 3c 62 6f 72 64 65 72  h("^__(?P<border
2420: 73 5f 61 6e 64 5f 63 61 73 65 3e 5b 5b 3c 5d 5c  s_and_case>[[<]\
2430: 5c 77 5b 5d 3e 5d 29 28 3f 50 3c 6f 70 74 69 6f  \w[]>])(?P<optio
2440: 6e 3e 2f 5b 61 2d 7a 41 2d 5a 30 2d 39 5d 2b 7c  n>/[a-zA-Z0-9]+|
2450: 29 28 3f 50 3c 72 75 6c 65 69 64 3e 5c 5c 28 5c  )(?P<ruleid>\\(\
2460: 5c 77 2b 5c 5c 29 7c 29 28 3f 50 3c 70 72 69 6f  \w+\\)|)(?P<prio
2470: 72 69 74 79 3e 21 5b 30 2d 39 5d 7c 29 5f 5f 20  rity>![0-9]|)__ 
2480: 2a 22 2c 20 73 29 0a 20 20 20 20 69 66 20 6d 3a  *", s).    if m:
2490: 0a 20 20 20 20 20 20 20 20 63 57 6f 72 64 4c 69  .        cWordLi
24a0: 6d 69 74 4c 65 66 74 20 3d 20 6d 2e 67 72 6f 75  mitLeft = m.grou
24b0: 70 28 27 62 6f 72 64 65 72 73 5f 61 6e 64 5f 63  p('borders_and_c
24c0: 61 73 65 27 29 5b 30 5d 0a 20 20 20 20 20 20 20  ase')[0].       
24d0: 20 63 43 61 73 65 4d 6f 64 65 20 3d 20 6d 2e 67   cCaseMode = m.g
24e0: 72 6f 75 70 28 27 62 6f 72 64 65 72 73 5f 61 6e  roup('borders_an
24f0: 64 5f 63 61 73 65 27 29 5b 31 5d 0a 20 20 20 20  d_case')[1].    
2500: 20 20 20 20 63 57 6f 72 64 4c 69 6d 69 74 52 69      cWordLimitRi
2510: 67 68 74 20 3d 20 6d 2e 67 72 6f 75 70 28 27 62  ght = m.group('b
2520: 6f 72 64 65 72 73 5f 61 6e 64 5f 63 61 73 65 27  orders_and_case'
2530: 29 5b 32 5d 0a 20 20 20 20 20 20 20 20 73 4f 70  )[2].        sOp
2540: 74 69 6f 6e 20 3d 20 6d 2e 67 72 6f 75 70 28 27  tion = m.group('
2550: 6f 70 74 69 6f 6e 27 29 5b 31 3a 5d 20 20 69 66  option')[1:]  if
2560: 20 6d 2e 67 72 6f 75 70 28 27 6f 70 74 69 6f 6e   m.group('option
2570: 27 29 20 20 65 6c 73 65 20 46 61 6c 73 65 0a 20  ')  else False. 
2580: 20 20 20 20 20 20 20 69 66 20 6d 2e 67 72 6f 75         if m.grou
2590: 70 28 27 72 75 6c 65 69 64 27 29 3a 0a 20 20 20  p('ruleid'):.   
25a0: 20 20 20 20 20 20 20 20 20 73 52 75 6c 65 49 64           sRuleId
25b0: 20 3d 20 20 6d 2e 67 72 6f 75 70 28 27 72 75 6c   =  m.group('rul
25c0: 65 69 64 27 29 5b 31 3a 2d 31 5d 0a 20 20 20 20  eid')[1:-1].    
25d0: 20 20 20 20 20 20 20 20 69 66 20 73 52 75 6c 65          if sRule
25e0: 49 64 20 69 6e 20 61 52 55 4c 45 53 45 54 3a 0a  Id in aRULESET:.
25f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2600: 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 2e 20  print("# Error. 
2610: 53 65 76 65 72 61 6c 20 72 75 6c 65 73 20 68 61  Several rules ha
2620: 76 65 20 74 68 65 20 73 61 6d 65 20 69 64 3a 20  ve the same id: 
2630: 22 20 2b 20 73 52 75 6c 65 49 64 29 0a 20 20 20  " + sRuleId).   
2640: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 78 69               exi
2650: 74 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  t().            
2660: 61 52 55 4c 45 53 45 54 2e 61 64 64 28 73 52 75  aRULESET.add(sRu
2670: 6c 65 49 64 29 0a 20 20 20 20 20 20 20 20 65 6c  leId).        el
2680: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
2690: 6e 52 55 4c 45 57 49 54 48 4f 55 54 4e 41 4d 45  nRULEWITHOUTNAME
26a0: 20 2b 3d 20 31 0a 20 20 20 20 20 20 20 20 6e 50   += 1.        nP
26b0: 72 69 6f 72 69 74 79 20 3d 20 64 4f 70 74 50 72  riority = dOptPr
26c0: 69 6f 72 69 74 79 2e 67 65 74 28 73 4f 70 74 69  iority.get(sOpti
26d0: 6f 6e 2c 20 34 29 0a 20 20 20 20 20 20 20 20 69  on, 4).        i
26e0: 66 20 6d 2e 67 72 6f 75 70 28 27 70 72 69 6f 72  f m.group('prior
26f0: 69 74 79 27 29 3a 0a 20 20 20 20 20 20 20 20 20  ity'):.         
2700: 20 20 20 6e 50 72 69 6f 72 69 74 79 20 3d 20 69     nPriority = i
2710: 6e 74 28 6d 2e 67 72 6f 75 70 28 27 70 72 69 6f  nt(m.group('prio
2720: 72 69 74 79 27 29 5b 31 3a 5d 29 0a 20 20 20 20  rity')[1:]).    
2730: 20 20 20 20 73 20 3d 20 73 5b 6d 2e 65 6e 64 28      s = s[m.end(
2740: 30 29 3a 5d 0a 20 20 20 20 65 6c 73 65 3a 0a 20  0):].    else:. 
2750: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20         print("# 
2760: 57 61 72 6e 69 6e 67 2e 20 4e 6f 20 6f 70 74 69  Warning. No opti
2770: 6f 6e 20 64 65 66 69 6e 65 64 20 61 74 20 6c 69  on defined at li
2780: 6e 65 3a 20 22 20 2b 20 73 4c 69 6e 65 49 64 29  ne: " + sLineId)
2790: 0a 0a 20 20 20 20 23 23 23 23 20 52 45 47 45 58  ..    #### REGEX
27a0: 20 54 52 49 47 47 45 52 0a 20 20 20 20 69 20 3d   TRIGGER.    i =
27b0: 20 73 2e 66 69 6e 64 28 22 20 3c 3c 2d 22 29 0a   s.find(" <<-").
27c0: 20 20 20 20 69 66 20 69 20 3d 3d 20 2d 31 3a 0a      if i == -1:.
27d0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
27e0: 20 45 72 72 6f 72 3a 20 6e 6f 20 63 6f 6e 64 69   Error: no condi
27f0: 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b  tion at line " +
2800: 20 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20   sLineId).      
2810: 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20    return None.  
2820: 20 20 73 52 65 67 65 78 20 3d 20 73 5b 3a 69 5d    sRegex = s[:i]
2830: 2e 73 74 72 69 70 28 29 0a 20 20 20 20 73 20 3d  .strip().    s =
2840: 20 73 5b 69 2b 34 3a 5d 0a 20 20 20 20 0a 20 20   s[i+4:].    .  
2850: 20 20 23 20 4a 53 20 67 72 6f 75 70 73 20 70 6f    # JS groups po
2860: 73 69 74 69 6f 6e 69 6e 67 20 63 6f 64 65 73 0a  sitioning codes.
2870: 20 20 20 20 6d 20 3d 20 72 65 2e 73 65 61 72 63      m = re.searc
2880: 68 28 22 40 40 5c 5c 53 2b 22 2c 20 73 52 65 67  h("@@\\S+", sReg
2890: 65 78 29 0a 20 20 20 20 69 66 20 6d 3a 0a 20 20  ex).    if m:.  
28a0: 20 20 20 20 20 20 74 47 72 6f 75 70 73 20 3d 20        tGroups = 
28b0: 67 72 6f 75 70 73 50 6f 73 69 74 69 6f 6e 69 6e  groupsPositionin
28c0: 67 43 6f 64 65 54 6f 4c 69 73 74 28 73 52 65 67  gCodeToList(sReg
28d0: 65 78 5b 6d 2e 73 74 61 72 74 28 29 2b 32 3a 5d  ex[m.start()+2:]
28e0: 29 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78  ).        sRegex
28f0: 20 3d 20 73 52 65 67 65 78 5b 3a 6d 2e 73 74 61   = sRegex[:m.sta
2900: 72 74 28 29 5d 2e 73 74 72 69 70 28 29 0a 20 20  rt()].strip().  
2910: 20 20 23 20 4a 53 20 72 65 67 65 78 0a 20 20 20    # JS regex.   
2920: 20 6d 20 3d 20 72 65 2e 73 65 61 72 63 68 28 22   m = re.search("
2930: 3c 6a 73 3e 2e 2b 3c 2f 6a 73 3e 69 3f 22 2c 20  <js>.+</js>i?", 
2940: 73 52 65 67 65 78 29 0a 20 20 20 20 69 66 20 6d  sRegex).    if m
2950: 3a 0a 20 20 20 20 20 20 20 20 64 4a 53 52 45 47  :.        dJSREG
2960: 45 58 45 53 5b 73 4c 69 6e 65 49 64 5d 20 3d 20  EXES[sLineId] = 
2970: 6d 2e 67 72 6f 75 70 28 30 29 0a 20 20 20 20 20  m.group(0).     
2980: 20 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67     sRegex = sReg
2990: 65 78 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2e 73  ex[:m.start()].s
29a0: 74 72 69 70 28 29 0a 20 20 20 20 69 66 20 22 3c  trip().    if "<
29b0: 6a 73 3e 22 20 69 6e 20 73 52 65 67 65 78 20 6f  js>" in sRegex o
29c0: 72 20 22 3c 2f 6a 73 3e 22 20 69 6e 20 73 52 65  r "</js>" in sRe
29d0: 67 65 78 3a 0a 20 20 20 20 20 20 20 20 70 72 69  gex:.        pri
29e0: 6e 74 28 22 23 20 45 72 72 6f 72 3a 20 4a 61 76  nt("# Error: Jav
29f0: 61 53 63 72 69 70 74 20 72 65 67 65 78 20 6e 6f  aScript regex no
2a00: 74 20 64 65 6c 69 6d 69 74 65 64 20 61 74 20 6c  t delimited at l
2a10: 69 6e 65 20 22 20 2b 20 73 4c 69 6e 65 49 64 29  ine " + sLineId)
2a20: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
2a30: 4e 6f 6e 65 0a 0a 20 20 20 20 23 20 71 75 6f 74  None..    # quot
2a40: 65 73 20 3f 0a 20 20 20 20 69 66 20 73 52 65 67  es ?.    if sReg
2a50: 65 78 2e 73 74 61 72 74 73 77 69 74 68 28 27 22  ex.startswith('"
2a60: 27 29 20 61 6e 64 20 73 52 65 67 65 78 2e 65 6e  ') and sRegex.en
2a70: 64 73 77 69 74 68 28 27 22 27 29 3a 0a 20 20 20  dswith('"'):.   
2a80: 20 20 20 20 20 73 52 65 67 65 78 20 3d 20 73 52       sRegex = sR
2a90: 65 67 65 78 5b 31 3a 2d 31 5d 0a 0a 20 20 20 20  egex[1:-1]..    
2aa0: 23 23 20 64 65 66 69 6e 69 74 69 6f 6e 73 0a 20  ## definitions. 
2ab0: 20 20 20 66 6f 72 20 73 44 65 66 2c 20 73 52 65     for sDef, sRe
2ac0: 70 6c 20 69 6e 20 64 44 45 46 2e 69 74 65 6d 73  pl in dDEF.items
2ad0: 28 29 3a 0a 20 20 20 20 20 20 20 20 73 52 65 67  ():.        sReg
2ae0: 65 78 20 3d 20 73 52 65 67 65 78 2e 72 65 70 6c  ex = sRegex.repl
2af0: 61 63 65 28 73 44 65 66 2c 20 73 52 65 70 6c 29  ace(sDef, sRepl)
2b00: 0a 0a 20 20 20 20 23 23 20 63 6f 75 6e 74 20 6e  ..    ## count n
2b10: 75 6d 62 65 72 20 6f 66 20 67 72 6f 75 70 73 20  umber of groups 
2b20: 28 6d 75 73 74 20 62 65 20 64 6f 6e 65 20 62 65  (must be done be
2b30: 66 6f 72 65 20 6d 6f 64 69 66 79 69 6e 67 20 74  fore modifying t
2b40: 68 65 20 72 65 67 65 78 29 0a 20 20 20 20 6e 47  he regex).    nG
2b50: 72 6f 75 70 20 3d 20 63 6f 75 6e 74 47 72 6f 75  roup = countGrou
2b60: 70 49 6e 52 65 67 65 78 28 73 52 65 67 65 78 29  pInRegex(sRegex)
2b70: 0a 20 20 20 20 69 66 20 6e 47 72 6f 75 70 20 3e  .    if nGroup >
2b80: 20 30 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6e   0:.        if n
2b90: 6f 74 20 74 47 72 6f 75 70 73 3a 0a 20 20 20 20  ot tGroups:.    
2ba0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
2bb0: 20 57 61 72 6e 69 6e 67 3a 20 67 72 6f 75 70 73   Warning: groups
2bc0: 20 70 6f 73 69 74 69 6f 6e 69 6e 67 20 63 6f 64   positioning cod
2bd0: 65 20 66 6f 72 20 4a 61 76 61 53 63 72 69 70 74  e for JavaScript
2be0: 20 73 68 6f 75 6c 64 20 62 65 20 64 65 66 69 6e   should be defin
2bf0: 65 64 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  ed at line " + s
2c00: 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20 20  LineId).        
2c10: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
2c20: 20 20 69 66 20 6e 47 72 6f 75 70 20 21 3d 20 6c    if nGroup != l
2c30: 65 6e 28 74 47 72 6f 75 70 73 29 3a 0a 20 20 20  en(tGroups):.   
2c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
2c50: 6e 74 28 22 23 20 45 72 72 6f 72 3a 20 67 72 6f  nt("# Error: gro
2c60: 75 70 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67 20  ups positioning 
2c70: 63 6f 64 65 20 69 72 72 65 6c 65 76 61 6e 74 20  code irrelevant 
2c80: 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 4c 69 6e  at line " + sLin
2c90: 65 49 64 29 0a 0a 20 20 20 20 23 23 20 77 6f 72  eId)..    ## wor
2ca0: 64 20 6c 69 6d 69 74 0a 20 20 20 20 69 66 20 63  d limit.    if c
2cb0: 57 6f 72 64 4c 69 6d 69 74 4c 65 66 74 20 3d 3d  WordLimitLeft ==
2cc0: 20 27 5b 27 20 61 6e 64 20 6e 6f 74 20 73 52 65   '[' and not sRe
2cd0: 67 65 78 2e 73 74 61 72 74 73 77 69 74 68 28 28  gex.startswith((
2ce0: 22 5e 22 2c 20 27 e2 80 99 27 2c 20 22 27 22 2c  "^", '...', "'",
2cf0: 20 22 2c 22 29 29 3a 0a 20 20 20 20 20 20 20 20   ",")):.        
2d00: 73 52 65 67 65 78 20 3d 20 73 57 4f 52 44 4c 49  sRegex = sWORDLI
2d10: 4d 49 54 4c 45 46 54 20 2b 20 73 52 65 67 65 78  MITLEFT + sRegex
2d20: 0a 20 20 20 20 69 66 20 63 57 6f 72 64 4c 69 6d  .    if cWordLim
2d30: 69 74 52 69 67 68 74 20 3d 3d 20 27 5d 27 20 61  itRight == ']' a
2d40: 6e 64 20 6e 6f 74 20 73 52 65 67 65 78 2e 65 6e  nd not sRegex.en
2d50: 64 73 77 69 74 68 28 28 22 24 22 2c 20 27 e2 80  dswith(("$", '..
2d60: 99 27 2c 20 22 27 22 2c 20 22 2c 22 29 29 3a 0a  .', "'", ",")):.
2d70: 20 20 20 20 20 20 20 20 73 52 65 67 65 78 20 3d          sRegex =
2d80: 20 73 52 65 67 65 78 20 2b 20 73 57 4f 52 44 4c   sRegex + sWORDL
2d90: 49 4d 49 54 52 49 47 48 54 0a 0a 20 20 20 20 23  IMITRIGHT..    #
2da0: 23 20 63 61 73 69 6e 67 20 6d 6f 64 65 0a 20 20  # casing mode.  
2db0: 20 20 69 66 20 63 43 61 73 65 4d 6f 64 65 20 3d    if cCaseMode =
2dc0: 3d 20 22 69 22 3a 0a 20 20 20 20 20 20 20 20 62  = "i":.        b
2dd0: 43 61 73 65 49 6e 73 65 6e 73 69 74 69 76 65 20  CaseInsensitive 
2de0: 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20 20 69  = True.        i
2df0: 66 20 6e 6f 74 20 73 52 65 67 65 78 2e 73 74 61  f not sRegex.sta
2e00: 72 74 73 77 69 74 68 28 22 28 3f 69 29 22 29 3a  rtswith("(?i)"):
2e10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 52 65  .            sRe
2e20: 67 65 78 20 3d 20 22 28 3f 69 29 22 20 2b 20 73  gex = "(?i)" + s
2e30: 52 65 67 65 78 0a 20 20 20 20 65 6c 69 66 20 63  Regex.    elif c
2e40: 43 61 73 65 4d 6f 64 65 20 3d 3d 20 22 73 22 3a  CaseMode == "s":
2e50: 0a 20 20 20 20 20 20 20 20 62 43 61 73 65 49 6e  .        bCaseIn
2e60: 73 65 6e 73 69 74 69 76 65 20 3d 20 46 61 6c 73  sensitive = Fals
2e70: 65 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78  e.        sRegex
2e80: 20 3d 20 73 52 65 67 65 78 2e 72 65 70 6c 61 63   = sRegex.replac
2e90: 65 28 22 28 3f 69 29 22 2c 20 22 22 29 0a 20 20  e("(?i)", "").  
2ea0: 20 20 65 6c 69 66 20 63 43 61 73 65 4d 6f 64 65    elif cCaseMode
2eb0: 20 3d 3d 20 22 75 22 3a 0a 20 20 20 20 20 20 20   == "u":.       
2ec0: 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69 76   bCaseInsensitiv
2ed0: 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20  e = False.      
2ee0: 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67 65    sRegex = sRege
2ef0: 78 2e 72 65 70 6c 61 63 65 28 22 28 3f 69 29 22  x.replace("(?i)"
2f00: 2c 20 22 22 29 0a 20 20 20 20 20 20 20 20 73 52  , "").        sR
2f10: 65 67 65 78 20 3d 20 75 70 70 65 72 63 61 73 65  egex = uppercase
2f20: 28 73 52 65 67 65 78 2c 20 73 4c 61 6e 67 29 0a  (sRegex, sLang).
2f30: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
2f40: 20 20 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e 6f    print("# Unkno
2f50: 77 6e 20 63 61 73 65 20 6d 6f 64 65 20 5b 22 20  wn case mode [" 
2f60: 2b 20 63 43 61 73 65 4d 6f 64 65 20 2b 20 22 5d  + cCaseMode + "]
2f70: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 4c 69   at line " + sLi
2f80: 6e 65 49 64 29 0a 0a 20 20 20 20 23 23 20 63 68  neId)..    ## ch
2f90: 65 63 6b 20 72 65 67 65 78 0a 20 20 20 20 74 72  eck regex.    tr
2fa0: 79 3a 0a 20 20 20 20 20 20 20 20 7a 20 3d 20 72  y:.        z = r
2fb0: 65 2e 63 6f 6d 70 69 6c 65 28 73 52 65 67 65 78  e.compile(sRegex
2fc0: 29 0a 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20  ).    except:.  
2fd0: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 52        print("# R
2fe0: 65 67 65 78 20 65 72 72 6f 72 20 61 74 20 6c 69  egex error at li
2ff0: 6e 65 20 22 2c 20 6e 49 64 4c 69 6e 65 29 0a 20  ne ", nIdLine). 
3000: 20 20 20 20 20 20 20 70 72 69 6e 74 28 73 52 65         print(sRe
3010: 67 65 78 29 0a 20 20 20 20 20 20 20 20 74 72 61  gex).        tra
3020: 63 65 62 61 63 6b 2e 70 72 69 6e 74 5f 65 78 63  ceback.print_exc
3030: 28 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ().        retur
3040: 6e 20 4e 6f 6e 65 0a 20 20 20 20 23 23 20 67 72  n None.    ## gr
3050: 6f 75 70 73 20 69 6e 20 6e 6f 6e 20 67 72 6f 75  oups in non grou
3060: 70 69 6e 67 20 70 61 72 65 6e 74 68 65 73 69 73  ping parenthesis
3070: 0a 20 20 20 20 66 6f 72 20 78 20 69 6e 20 72 65  .    for x in re
3080: 2e 66 69 6e 64 69 74 65 72 28 22 5c 28 5c 3f 3a  .finditer("\(\?:
3090: 5b 5e 29 5d 2a 5c 28 5b 5b 5c 77 20 2d 5d 22 2c  [^)]*\([[\w -]",
30a0: 20 73 52 65 67 65 78 29 3a 0a 20 20 20 20 20 20   sRegex):.      
30b0: 20 20 70 72 69 6e 74 28 22 23 20 57 61 72 6e 69    print("# Warni
30c0: 6e 67 3a 20 67 72 6f 75 70 73 20 69 6e 73 69 64  ng: groups insid
30d0: 65 20 6e 6f 6e 20 67 72 6f 75 70 69 6e 67 20 70  e non grouping p
30e0: 61 72 65 6e 74 68 65 73 69 73 20 69 6e 20 72 65  arenthesis in re
30f0: 67 65 78 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  gex at line " + 
3100: 73 4c 69 6e 65 49 64 29 0a 0a 20 20 20 20 23 23  sLineId)..    ##
3110: 23 23 20 50 41 52 53 45 20 41 43 54 49 4f 4e 53  ## PARSE ACTIONS
3120: 0a 20 20 20 20 6c 41 63 74 69 6f 6e 73 20 3d 20  .    lActions = 
3130: 5b 5d 0a 20 20 20 20 6e 41 63 74 69 6f 6e 20 3d  [].    nAction =
3140: 20 31 0a 20 20 20 20 66 6f 72 20 73 41 63 74 69   1.    for sActi
3150: 6f 6e 20 69 6e 20 73 2e 73 70 6c 69 74 28 22 20  on in s.split(" 
3160: 3c 3c 2d 20 22 29 3a 0a 20 20 20 20 20 20 20 20  <<- "):.        
3170: 74 20 3d 20 63 72 65 61 74 65 41 63 74 69 6f 6e  t = createAction
3180: 28 73 52 75 6c 65 49 64 20 2b 20 22 5f 22 20 2b  (sRuleId + "_" +
3190: 20 73 74 72 28 6e 41 63 74 69 6f 6e 29 2c 20 73   str(nAction), s
31a0: 41 63 74 69 6f 6e 2c 20 6e 47 72 6f 75 70 29 0a  Action, nGroup).
31b0: 20 20 20 20 20 20 20 20 6e 41 63 74 69 6f 6e 20          nAction 
31c0: 2b 3d 20 31 0a 20 20 20 20 20 20 20 20 69 66 20  += 1.        if 
31d0: 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c  t:.            l
31e0: 41 63 74 69 6f 6e 73 2e 61 70 70 65 6e 64 28 74  Actions.append(t
31f0: 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c 41 63  ).    if not lAc
3200: 74 69 6f 6e 73 3a 0a 20 20 20 20 20 20 20 20 72  tions:.        r
3210: 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a 20 20 20 20  eturn None..    
3220: 72 65 74 75 72 6e 20 5b 73 4f 70 74 69 6f 6e 2c  return [sOption,
3230: 20 73 52 65 67 65 78 2c 20 62 43 61 73 65 49 6e   sRegex, bCaseIn
3240: 73 65 6e 73 69 74 69 76 65 2c 20 73 4c 69 6e 65  sensitive, sLine
3250: 49 64 2c 20 73 52 75 6c 65 49 64 2c 20 6e 50 72  Id, sRuleId, nPr
3260: 69 6f 72 69 74 79 2c 20 6c 41 63 74 69 6f 6e 73  iority, lActions
3270: 2c 20 74 47 72 6f 75 70 73 5d 0a 0a 0a 64 65 66  , tGroups]...def
3280: 20 63 72 65 61 74 65 41 63 74 69 6f 6e 20 28 73   createAction (s
3290: 49 64 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f  IdAction, sActio
32a0: 6e 2c 20 6e 47 72 6f 75 70 29 3a 0a 20 20 20 20  n, nGroup):.    
32b0: 22 72 65 74 75 72 6e 73 20 61 6e 20 61 63 74 69  "returns an acti
32c0: 6f 6e 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 73  on to perform as
32d0: 20 61 20 74 75 70 6c 65 20 28 63 6f 6e 64 69 74   a tuple (condit
32e0: 69 6f 6e 2c 20 61 63 74 69 6f 6e 20 74 79 70 65  ion, action type
32f0: 2c 20 61 63 74 69 6f 6e 5b 2c 20 69 47 72 6f 75  , action[, iGrou
3300: 70 20 5b 2c 20 6d 65 73 73 61 67 65 2c 20 55 52  p [, message, UR
3310: 4c 20 5d 5d 29 22 0a 20 20 20 20 67 6c 6f 62 61  L ]])".    globa
3320: 6c 20 6c 46 55 4e 43 54 49 4f 4e 53 0a 0a 20 20  l lFUNCTIONS..  
3330: 20 20 6d 20 3d 20 72 65 2e 73 65 61 72 63 68 28    m = re.search(
3340: 72 22 28 5b 2d 7e 3d 3e 5d 29 28 5c 64 2a 7c 29  r"([-~=>])(\d*|)
3350: 3e 3e 22 2c 20 73 41 63 74 69 6f 6e 29 0a 20 20  >>", sAction).  
3360: 20 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20    if not m:.    
3370: 20 20 20 20 70 72 69 6e 74 28 22 23 20 4e 6f 20      print("# No 
3380: 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22  action at line "
3390: 20 2b 20 73 49 64 41 63 74 69 6f 6e 29 0a 20 20   + sIdAction).  
33a0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e        return Non
33b0: 65 0a 0a 20 20 20 20 23 23 23 23 20 43 4f 4e 44  e..    #### COND
33c0: 49 54 49 4f 4e 0a 20 20 20 20 73 43 6f 6e 64 69  ITION.    sCondi
33d0: 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 3a  tion = sAction[:
33e0: 6d 2e 73 74 61 72 74 28 29 5d 2e 73 74 72 69 70  m.start()].strip
33f0: 28 29 0a 20 20 20 20 69 66 20 73 43 6f 6e 64 69  ().    if sCondi
3400: 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 73 43  tion:.        sC
3410: 6f 6e 64 69 74 69 6f 6e 20 3d 20 70 72 65 70 61  ondition = prepa
3420: 72 65 46 75 6e 63 74 69 6f 6e 28 73 43 6f 6e 64  reFunction(sCond
3430: 69 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 6c  ition).        l
3440: 46 55 4e 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64  FUNCTIONS.append
3450: 28 28 22 63 5f 22 2b 73 49 64 41 63 74 69 6f 6e  (("c_"+sIdAction
3460: 2c 20 73 43 6f 6e 64 69 74 69 6f 6e 29 29 0a 20  , sCondition)). 
3470: 20 20 20 20 20 20 20 66 6f 72 20 78 20 69 6e 20         for x in 
3480: 72 65 2e 66 69 6e 64 69 74 65 72 28 22 5b 2e 5d  re.finditer("[.]
3490: 28 3f 3a 67 72 6f 75 70 7c 73 74 61 72 74 7c 65  (?:group|start|e
34a0: 6e 64 29 5b 28 5d 28 5c 64 2b 29 5b 29 5d 22 2c  nd)[(](\d+)[)]",
34b0: 20 73 43 6f 6e 64 69 74 69 6f 6e 29 3a 0a 20 20   sCondition):.  
34c0: 20 20 20 20 20 20 20 20 20 20 69 66 20 69 6e 74            if int
34d0: 28 78 2e 67 72 6f 75 70 28 31 29 29 20 3e 20 6e  (x.group(1)) > n
34e0: 47 72 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20  Group:.         
34f0: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20         print("# 
3500: 45 72 72 6f 72 20 69 6e 20 67 72 6f 75 70 73 20  Error in groups 
3510: 69 6e 20 63 6f 6e 64 69 74 69 6f 6e 20 61 74 20  in condition at 
3520: 6c 69 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69  line " + sIdActi
3530: 6f 6e 20 2b 20 22 20 28 22 2b 73 74 72 28 6e 47  on + " ("+str(nG
3540: 72 6f 75 70 29 2b 22 20 67 72 6f 75 70 73 20 6f  roup)+" groups o
3550: 6e 6c 79 29 22 29 0a 20 20 20 20 20 20 20 20 69  nly)").        i
3560: 66 20 22 2e 6d 61 74 63 68 22 20 69 6e 20 73 43  f ".match" in sC
3570: 6f 6e 64 69 74 69 6f 6e 3a 0a 20 20 20 20 20 20  ondition:.      
3580: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45        print("# E
3590: 72 72 6f 72 2e 20 4a 53 20 63 6f 6d 70 61 74 69  rror. JS compati
35a0: 62 69 6c 69 74 79 2e 20 44 6f 6e 27 74 20 75 73  bility. Don't us
35b0: 65 20 2e 6d 61 74 63 68 28 29 20 69 6e 20 63 6f  e .match() in co
35c0: 6e 64 69 74 69 6f 6e 2c 20 75 73 65 20 2e 73 65  ndition, use .se
35d0: 61 72 63 68 28 29 22 29 0a 20 20 20 20 20 20 20  arch()").       
35e0: 20 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 22 63   sCondition = "c
35f0: 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a 20 20 20  _"+sIdAction.   
3600: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 73   else:.        s
3610: 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 4e 6f 6e 65  Condition = None
3620: 0a 0a 20 20 20 20 23 23 23 23 20 69 47 72 6f 75  ..    #### iGrou
3630: 70 20 2f 20 70 6f 73 69 74 69 6f 6e 69 6e 67 0a  p / positioning.
3640: 20 20 20 20 69 47 72 6f 75 70 20 3d 20 69 6e 74      iGroup = int
3650: 28 6d 2e 67 72 6f 75 70 28 32 29 29 20 69 66 20  (m.group(2)) if 
3660: 6d 2e 67 72 6f 75 70 28 32 29 20 65 6c 73 65 20  m.group(2) else 
3670: 30 0a 20 20 20 20 69 66 20 69 47 72 6f 75 70 20  0.    if iGroup 
3680: 3e 20 6e 47 72 6f 75 70 3a 0a 20 20 20 20 20 20  > nGroup:.      
3690: 20 20 70 72 69 6e 74 28 22 23 20 53 65 6c 65 63    print("# Selec
36a0: 74 65 64 20 67 72 6f 75 70 20 3e 20 67 72 6f 75  ted group > grou
36b0: 70 20 6e 75 6d 62 65 72 20 69 6e 20 72 65 67 65  p number in rege
36c0: 78 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49  x at line " + sI
36d0: 64 41 63 74 69 6f 6e 29 0a 20 20 20 20 0a 20 20  dAction).    .  
36e0: 20 20 23 23 23 23 20 41 43 54 49 4f 4e 0a 20 20    #### ACTION.  
36f0: 20 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74    sAction = sAct
3700: 69 6f 6e 5b 6d 2e 65 6e 64 28 29 3a 5d 2e 73 74  ion[m.end():].st
3710: 72 69 70 28 29 0a 20 20 20 20 63 41 63 74 69 6f  rip().    cActio
3720: 6e 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29 0a 20  n = m.group(1). 
3730: 20 20 20 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d     if cAction ==
3740: 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 23 23   "-":.        ##
3750: 20 65 72 72 6f 72 0a 20 20 20 20 20 20 20 20 69   error.        i
3760: 4d 73 67 20 3d 20 73 41 63 74 69 6f 6e 2e 66 69  Msg = sAction.fi
3770: 6e 64 28 22 20 23 20 22 29 0a 20 20 20 20 20 20  nd(" # ").      
3780: 20 20 73 4d 73 67 20 3d 20 73 41 63 74 69 6f 6e    sMsg = sAction
3790: 5b 69 4d 73 67 2b 33 3a 5d 2e 73 74 72 69 70 28  [iMsg+3:].strip(
37a0: 29 0a 20 20 20 20 20 20 20 20 73 41 63 74 69 6f  ).        sActio
37b0: 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 3a 69 4d 73  n = sAction[:iMs
37c0: 67 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20  g].strip().     
37d0: 20 20 20 73 55 52 4c 20 3d 20 22 22 0a 20 20 20     sURL = "".   
37e0: 20 20 20 20 20 6d 55 52 4c 20 3d 20 72 65 2e 73       mURL = re.s
37f0: 65 61 72 63 68 28 22 5b 7c 5d 20 2a 28 68 74 74  earch("[|] *(htt
3800: 70 73 3f 3a 2f 2f 2e 2a 29 22 2c 20 73 4d 73 67  ps?://.*)", sMsg
3810: 29 0a 20 20 20 20 20 20 20 20 69 66 20 6d 55 52  ).        if mUR
3820: 4c 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  L:.            s
3830: 55 52 4c 20 3d 20 6d 55 52 4c 2e 67 72 6f 75 70  URL = mURL.group
3840: 28 31 29 2e 73 74 72 69 70 28 29 0a 20 20 20 20  (1).strip().    
3850: 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 73          sMsg = s
3860: 4d 73 67 5b 3a 6d 55 52 4c 2e 73 74 61 72 74 28  Msg[:mURL.start(
3870: 30 29 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20  0)].strip().    
3880: 20 20 20 20 69 66 20 73 4d 73 67 5b 30 3a 31 5d      if sMsg[0:1]
3890: 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20   == "=":.       
38a0: 20 20 20 20 20 73 4d 73 67 20 3d 20 70 72 65 70       sMsg = prep
38b0: 61 72 65 46 75 6e 63 74 69 6f 6e 28 73 4d 73 67  areFunction(sMsg
38c0: 5b 31 3a 5d 29 0a 20 20 20 20 20 20 20 20 20 20  [1:]).          
38d0: 20 20 6c 46 55 4e 43 54 49 4f 4e 53 2e 61 70 70    lFUNCTIONS.app
38e0: 65 6e 64 28 28 22 6d 5f 22 2b 73 49 64 41 63 74  end(("m_"+sIdAct
38f0: 69 6f 6e 2c 20 73 4d 73 67 29 29 0a 20 20 20 20  ion, sMsg)).    
3900: 20 20 20 20 20 20 20 20 66 6f 72 20 78 20 69 6e          for x in
3910: 20 72 65 2e 66 69 6e 64 69 74 65 72 28 22 67 72   re.finditer("gr
3920: 6f 75 70 5b 28 5d 28 5c 64 2b 29 5b 29 5d 22 2c  oup[(](\d+)[)]",
3930: 20 73 4d 73 67 29 3a 0a 20 20 20 20 20 20 20 20   sMsg):.        
3940: 20 20 20 20 20 20 20 20 69 66 20 69 6e 74 28 78          if int(x
3950: 2e 67 72 6f 75 70 28 31 29 29 20 3e 20 6e 47 72  .group(1)) > nGr
3960: 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20 20 20  oup:.           
3970: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
3980: 23 20 45 72 72 6f 72 20 69 6e 20 67 72 6f 75 70  # Error in group
3990: 73 20 69 6e 20 6d 65 73 73 61 67 65 20 61 74 20  s in message at 
39a0: 6c 69 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69  line " + sIdActi
39b0: 6f 6e 20 2b 20 22 20 28 22 2b 73 74 72 28 6e 47  on + " ("+str(nG
39c0: 72 6f 75 70 29 2b 22 20 67 72 6f 75 70 73 20 6f  roup)+" groups o
39d0: 6e 6c 79 29 22 29 0a 20 20 20 20 20 20 20 20 20  nly)").         
39e0: 20 20 20 73 4d 73 67 20 3d 20 22 3d 6d 5f 22 2b     sMsg = "=m_"+
39f0: 73 49 64 41 63 74 69 6f 6e 0a 20 20 20 20 20 20  sIdAction.      
3a00: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
3a10: 20 20 20 20 66 6f 72 20 78 20 69 6e 20 72 65 2e      for x in re.
3a20: 66 69 6e 64 69 74 65 72 28 72 22 5c 5c 28 5c 64  finditer(r"\\(\d
3a30: 2b 29 22 2c 20 73 4d 73 67 29 3a 0a 20 20 20 20  +)", sMsg):.    
3a40: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 69              if i
3a50: 6e 74 28 78 2e 67 72 6f 75 70 28 31 29 29 20 3e  nt(x.group(1)) >
3a60: 20 6e 47 72 6f 75 70 3a 0a 20 20 20 20 20 20 20   nGroup:.       
3a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
3a80: 6e 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20 67  nt("# Error in g
3a90: 72 6f 75 70 73 20 69 6e 20 6d 65 73 73 61 67 65  roups in message
3aa0: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64   at line " + sId
3ab0: 41 63 74 69 6f 6e 20 2b 20 22 20 28 22 2b 73 74  Action + " ("+st
3ac0: 72 28 6e 47 72 6f 75 70 29 2b 22 20 67 72 6f 75  r(nGroup)+" grou
3ad0: 70 73 20 6f 6e 6c 79 29 22 29 0a 20 20 20 20 20  ps only)").     
3ae0: 20 20 20 20 20 20 20 69 66 20 72 65 2e 73 65 61         if re.sea
3af0: 72 63 68 28 22 5b 2e 5d 5c 5c 77 2b 5b 28 5d 22  rch("[.]\\w+[(]"
3b00: 2c 20 73 4d 73 67 29 3a 0a 20 20 20 20 20 20 20  , sMsg):.       
3b10: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
3b20: 23 20 45 72 72 6f 72 20 69 6e 20 6d 65 73 73 61  # Error in messa
3b30: 67 65 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  ge at line " + s
3b40: 49 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 20 54  IdAction + ":  T
3b50: 68 69 73 20 6d 65 73 73 61 67 65 20 6c 6f 6f 6b  his message look
3b60: 73 20 6c 69 6b 65 20 63 6f 64 65 2e 20 4c 69 6e  s like code. Lin
3b70: 65 20 73 68 6f 75 6c 64 20 62 65 67 69 6e 20 77  e should begin w
3b80: 69 74 68 20 3d 22 29 0a 20 20 20 20 20 20 20 20  ith =").        
3b90: 20 20 20 20 0a 20 20 20 20 69 66 20 73 41 63 74      .    if sAct
3ba0: 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 20  ion[0:1] == "=" 
3bb0: 6f 72 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3d  or cAction == "=
3bc0: 22 3a 0a 20 20 20 20 20 20 20 20 69 66 20 22 64  ":.        if "d
3bd0: 65 66 69 6e 65 22 20 69 6e 20 73 41 63 74 69 6f  efine" in sActio
3be0: 6e 20 61 6e 64 20 6e 6f 74 20 72 65 2e 73 65 61  n and not re.sea
3bf0: 72 63 68 28 72 22 64 65 66 69 6e 65 5c 28 5c 5c  rch(r"define\(\\
3c00: 5c 64 2b 20 2a 2c 20 2a 5c 5b 2e 2a 5c 5d 20 2a  \d+ *, *\[.*\] *
3c10: 5c 29 22 2c 20 73 41 63 74 69 6f 6e 29 3a 0a 20  \)", sAction):. 
3c20: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
3c30: 28 22 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74  ("# Error in act
3c40: 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ion at line " + 
3c50: 73 49 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 73  sIdAction + ": s
3c60: 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 66  econd argument f
3c70: 6f 72 20 64 65 66 69 6e 65 20 6d 75 73 74 20 62  or define must b
3c80: 65 20 61 20 6c 69 73 74 20 6f 66 20 73 74 72 69  e a list of stri
3c90: 6e 67 73 22 29 0a 20 20 20 20 20 20 20 20 73 41  ngs").        sA
3ca0: 63 74 69 6f 6e 20 3d 20 70 72 65 70 61 72 65 46  ction = prepareF
3cb0: 75 6e 63 74 69 6f 6e 28 73 41 63 74 69 6f 6e 29  unction(sAction)
3cc0: 0a 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e  .        sAction
3cd0: 20 3d 20 73 41 63 74 69 6f 6e 2e 72 65 70 6c 61   = sAction.repla
3ce0: 63 65 28 22 6d 2e 67 72 6f 75 70 28 69 5b 34 5d  ce("m.group(i[4]
3cf0: 29 22 2c 20 22 6d 2e 67 72 6f 75 70 28 22 2b 73  )", "m.group("+s
3d00: 74 72 28 69 47 72 6f 75 70 29 2b 22 29 22 29 0a  tr(iGroup)+")").
3d10: 20 20 20 20 20 20 20 20 66 6f 72 20 78 20 69 6e          for x in
3d20: 20 72 65 2e 66 69 6e 64 69 74 65 72 28 22 67 72   re.finditer("gr
3d30: 6f 75 70 5b 28 5d 28 5c 64 2b 29 5b 29 5d 22 2c  oup[(](\d+)[)]",
3d40: 20 73 41 63 74 69 6f 6e 29 3a 0a 20 20 20 20 20   sAction):.     
3d50: 20 20 20 20 20 20 20 69 66 20 69 6e 74 28 78 2e         if int(x.
3d60: 67 72 6f 75 70 28 31 29 29 20 3e 20 6e 47 72 6f  group(1)) > nGro
3d70: 75 70 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  up:.            
3d80: 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72      print("# Err
3d90: 6f 72 20 69 6e 20 67 72 6f 75 70 73 20 69 6e 20  or in groups in 
3da0: 72 65 70 6c 61 63 65 6d 65 6e 74 20 61 74 20 6c  replacement at l
3db0: 69 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f  ine " + sIdActio
3dc0: 6e 20 2b 20 22 20 28 22 2b 73 74 72 28 6e 47 72  n + " ("+str(nGr
3dd0: 6f 75 70 29 2b 22 20 67 72 6f 75 70 73 20 6f 6e  oup)+" groups on
3de0: 6c 79 29 22 29 0a 20 20 20 20 65 6c 73 65 3a 0a  ly)").    else:.
3df0: 20 20 20 20 20 20 20 20 66 6f 72 20 78 20 69 6e          for x in
3e00: 20 72 65 2e 66 69 6e 64 69 74 65 72 28 72 22 5c   re.finditer(r"\
3e10: 5c 28 5c 64 2b 29 22 2c 20 73 41 63 74 69 6f 6e  \(\d+)", sAction
3e20: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  ):.            i
3e30: 66 20 69 6e 74 28 78 2e 67 72 6f 75 70 28 31 29  f int(x.group(1)
3e40: 29 20 3e 20 6e 47 72 6f 75 70 3a 0a 20 20 20 20  ) > nGroup:.    
3e50: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
3e60: 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20 67 72  t("# Error in gr
3e70: 6f 75 70 73 20 69 6e 20 72 65 70 6c 61 63 65 6d  oups in replacem
3e80: 65 6e 74 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ent at line " + 
3e90: 73 49 64 41 63 74 69 6f 6e 20 2b 20 22 20 28 22  sIdAction + " ("
3ea0: 2b 73 74 72 28 6e 47 72 6f 75 70 29 2b 22 20 67  +str(nGroup)+" g
3eb0: 72 6f 75 70 73 20 6f 6e 6c 79 29 22 29 0a 20 20  roups only)").  
3ec0: 20 20 20 20 20 20 69 66 20 72 65 2e 73 65 61 72        if re.sear
3ed0: 63 68 28 22 5b 2e 5d 5c 5c 77 2b 5b 28 5d 22 2c  ch("[.]\\w+[(]",
3ee0: 20 73 41 63 74 69 6f 6e 29 3a 0a 20 20 20 20 20   sAction):.     
3ef0: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20         print("# 
3f00: 45 72 72 6f 72 20 69 6e 20 61 63 74 69 6f 6e 20  Error in action 
3f10: 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64 41  at line " + sIdA
3f20: 63 74 69 6f 6e 20 2b 20 22 3a 20 20 54 68 69 73  ction + ":  This
3f30: 20 61 63 74 69 6f 6e 20 6c 6f 6f 6b 73 20 6c 69   action looks li
3f40: 6b 65 20 63 6f 64 65 2e 20 4c 69 6e 65 20 73 68  ke code. Line sh
3f50: 6f 75 6c 64 20 62 65 67 69 6e 20 77 69 74 68 20  ould begin with 
3f60: 3d 22 29 0a 0a 20 20 20 20 69 66 20 63 41 63 74  =")..    if cAct
3f70: 69 6f 6e 20 3d 3d 20 22 2d 22 3a 0a 20 20 20 20  ion == "-":.    
3f80: 20 20 20 20 23 23 20 65 72 72 6f 72 20 64 65 74      ## error det
3f90: 65 63 74 65 64 20 2d 2d 3e 20 73 75 67 67 65 73  ected --> sugges
3fa0: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 69 66 20  tion.        if 
3fb0: 6e 6f 74 20 73 41 63 74 69 6f 6e 3a 0a 20 20 20  not sAction:.   
3fc0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
3fd0: 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69 6f  # Error in actio
3fe0: 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49  n at line " + sI
3ff0: 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 20 54 68  dAction + ":  Th
4000: 69 73 20 61 63 74 69 6f 6e 20 69 73 20 65 6d 70  is action is emp
4010: 74 79 2e 22 29 0a 20 20 20 20 20 20 20 20 69 66  ty.").        if
4020: 20 73 41 63 74 69 6f 6e 5b 30 3a 31 5d 20 3d 3d   sAction[0:1] ==
4030: 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20   "=":.          
4040: 20 20 6c 46 55 4e 43 54 49 4f 4e 53 2e 61 70 70    lFUNCTIONS.app
4050: 65 6e 64 28 28 22 73 5f 22 2b 73 49 64 41 63 74  end(("s_"+sIdAct
4060: 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 5b 31 3a 5d  ion, sAction[1:]
4070: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  )).            s
4080: 41 63 74 69 6f 6e 20 3d 20 22 3d 73 5f 22 2b 73  Action = "=s_"+s
4090: 49 64 41 63 74 69 6f 6e 0a 20 20 20 20 20 20 20  IdAction.       
40a0: 20 65 6c 69 66 20 73 41 63 74 69 6f 6e 2e 73 74   elif sAction.st
40b0: 61 72 74 73 77 69 74 68 28 27 22 27 29 20 61 6e  artswith('"') an
40c0: 64 20 73 41 63 74 69 6f 6e 2e 65 6e 64 73 77 69  d sAction.endswi
40d0: 74 68 28 27 22 27 29 3a 0a 20 20 20 20 20 20 20  th('"'):.       
40e0: 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 73       sAction = s
40f0: 41 63 74 69 6f 6e 5b 31 3a 2d 31 5d 0a 20 20 20  Action[1:-1].   
4100: 20 20 20 20 20 69 66 20 6e 6f 74 20 73 4d 73 67       if not sMsg
4110: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72  :.            pr
4120: 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20  int("# Error in 
4130: 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22  action at line "
4140: 20 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b 20 22   + sIdAction + "
4150: 3a 20 20 74 68 65 20 6d 65 73 73 61 67 65 20 69  :  the message i
4160: 73 20 65 6d 70 74 79 2e 22 29 0a 20 20 20 20 20  s empty.").     
4170: 20 20 20 72 65 74 75 72 6e 20 5b 73 43 6f 6e 64     return [sCond
4180: 69 74 69 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20  ition, cAction, 
4190: 73 41 63 74 69 6f 6e 2c 20 69 47 72 6f 75 70 2c  sAction, iGroup,
41a0: 20 73 4d 73 67 2c 20 73 55 52 4c 5d 0a 20 20 20   sMsg, sURL].   
41b0: 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d   elif cAction ==
41c0: 20 22 7e 22 3a 0a 20 20 20 20 20 20 20 20 23 23   "~":.        ##
41d0: 20 74 65 78 74 20 70 72 6f 63 65 73 73 6f 72 0a   text processor.
41e0: 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 73          if not s
41f0: 41 63 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20  Action:.        
4200: 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72      print("# Err
4210: 6f 72 20 69 6e 20 61 63 74 69 6f 6e 20 61 74 20  or in action at 
4220: 6c 69 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69  line " + sIdActi
4230: 6f 6e 20 2b 20 22 3a 20 20 54 68 69 73 20 61 63  on + ":  This ac
4240: 74 69 6f 6e 20 69 73 20 65 6d 70 74 79 2e 22 29  tion is empty.")
4250: 0a 20 20 20 20 20 20 20 20 69 66 20 73 41 63 74  .        if sAct
4260: 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a  ion[0:1] == "=":
4270: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 46 55  .            lFU
4280: 4e 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28 28  NCTIONS.append((
4290: 22 70 5f 22 2b 73 49 64 41 63 74 69 6f 6e 2c 20  "p_"+sIdAction, 
42a0: 73 41 63 74 69 6f 6e 5b 31 3a 5d 29 29 0a 20 20  sAction[1:])).  
42b0: 20 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f            sActio
42c0: 6e 20 3d 20 22 3d 70 5f 22 2b 73 49 64 41 63 74  n = "=p_"+sIdAct
42d0: 69 6f 6e 0a 20 20 20 20 20 20 20 20 65 6c 69 66  ion.        elif
42e0: 20 73 41 63 74 69 6f 6e 2e 73 74 61 72 74 73 77   sAction.startsw
42f0: 69 74 68 28 27 22 27 29 20 61 6e 64 20 73 41 63  ith('"') and sAc
4300: 74 69 6f 6e 2e 65 6e 64 73 77 69 74 68 28 27 22  tion.endswith('"
4310: 27 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  '):.            
4320: 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f  sAction = sActio
4330: 6e 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20 20 20  n[1:-1].        
4340: 72 65 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69  return [sConditi
4350: 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41 63  on, cAction, sAc
4360: 74 69 6f 6e 2c 20 69 47 72 6f 75 70 5d 0a 20 20  tion, iGroup].  
4370: 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 20 3d    elif cAction =
4380: 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 23  = "=":.        #
4390: 23 20 64 69 73 61 6d 62 69 67 75 61 74 6f 72 0a  # disambiguator.
43a0: 20 20 20 20 20 20 20 20 69 66 20 73 41 63 74 69          if sActi
43b0: 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a  on[0:1] == "=":.
43c0: 20 20 20 20 20 20 20 20 20 20 20 20 73 41 63 74              sAct
43d0: 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a  ion = sAction[1:
43e0: 5d 0a 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74  ].        if not
43f0: 20 73 41 63 74 69 6f 6e 3a 0a 20 20 20 20 20 20   sAction:.      
4400: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45        print("# E
4410: 72 72 6f 72 20 69 6e 20 61 63 74 69 6f 6e 20 61  rror in action a
4420: 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64 41 63  t line " + sIdAc
4430: 74 69 6f 6e 20 2b 20 22 3a 20 20 54 68 69 73 20  tion + ":  This 
4440: 61 63 74 69 6f 6e 20 69 73 20 65 6d 70 74 79 2e  action is empty.
4450: 22 29 0a 20 20 20 20 20 20 20 20 6c 46 55 4e 43  ").        lFUNC
4460: 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28 28 22 64  TIONS.append(("d
4470: 5f 22 2b 73 49 64 41 63 74 69 6f 6e 2c 20 73 41  _"+sIdAction, sA
4480: 63 74 69 6f 6e 29 29 0a 20 20 20 20 20 20 20 20  ction)).        
4490: 73 41 63 74 69 6f 6e 20 3d 20 22 64 5f 22 2b 73  sAction = "d_"+s
44a0: 49 64 41 63 74 69 6f 6e 0a 20 20 20 20 20 20 20  IdAction.       
44b0: 20 72 65 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74   return [sCondit
44c0: 69 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41  ion, cAction, sA
44d0: 63 74 69 6f 6e 5d 0a 20 20 20 20 65 6c 69 66 20  ction].    elif 
44e0: 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3e 22 3a 0a  cAction == ">":.
44f0: 20 20 20 20 20 20 20 20 23 23 20 6e 6f 20 61 63          ## no ac
4500: 74 69 6f 6e 2c 20 62 72 65 61 6b 20 6c 6f 6f 70  tion, break loop
4510: 20 69 66 20 63 6f 6e 64 69 74 69 6f 6e 20 69 73   if condition is
4520: 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20 72   False.        r
4530: 65 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69 6f  eturn [sConditio
4540: 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 22 22 5d 0a  n, cAction, ""].
4550: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
4560: 20 20 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e 6f    print("# Unkno
4570: 77 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e  wn action at lin
4580: 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 29  e " + sIdAction)
4590: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
45a0: 4e 6f 6e 65 0a 0a 0a 64 65 66 20 72 65 67 65 78  None...def regex
45b0: 32 6a 73 20 28 73 52 65 67 65 78 29 3a 0a 20 20  2js (sRegex):.  
45c0: 20 20 22 63 6f 6e 76 65 72 74 73 20 50 79 74 68    "converts Pyth
45d0: 6f 6e 20 72 65 67 65 78 20 74 6f 20 4a 53 20 72  on regex to JS r
45e0: 65 67 65 78 20 61 6e 64 20 72 65 74 75 72 6e 73  egex and returns
45f0: 20 4a 53 20 72 65 67 65 78 20 61 6e 64 20 6c 69   JS regex and li
4600: 73 74 20 6f 66 20 6e 65 67 61 74 69 76 65 20 6c  st of negative l
4610: 6f 6f 6b 62 65 66 6f 72 65 20 61 73 73 65 72 74  ookbefore assert
4620: 69 6f 6e 73 22 0a 20 20 20 20 23 20 20 20 4c 61  ions".    #   La
4630: 74 69 6e 20 6c 65 74 74 65 72 73 3a 20 68 74 74  tin letters: htt
4640: 70 3a 2f 2f 75 6e 69 63 6f 64 65 2d 74 61 62 6c  p://unicode-tabl
4650: 65 2e 63 6f 6d 2f 66 72 2f 0a 20 20 20 20 23 20  e.com/fr/.    # 
4660: 20 20 30 2d 39 20 20 61 6e 64 20 20 5f 0a 20 20    0-9  and  _.  
4670: 20 20 23 20 20 20 41 2d 5a 0a 20 20 20 20 23 20    #   A-Z.    # 
4680: 20 20 61 2d 7a 0a 20 20 20 20 23 20 20 20 c3 80    a-z.    #   ..
4690: 2d c3 96 20 20 20 20 20 30 30 43 30 2d 30 30 44  -..     00C0-00D
46a0: 36 20 20 20 28 75 70 70 65 72 20 63 61 73 65 29  6   (upper case)
46b0: 0a 20 20 20 20 23 20 20 20 c3 98 2d c3 9f 20 20  .    #   ..-..  
46c0: 20 20 20 30 30 44 38 2d 30 30 44 46 20 20 20 28     00D8-00DF   (
46d0: 75 70 70 65 72 20 63 61 73 65 29 0a 20 20 20 20  upper case).    
46e0: 23 20 20 20 c3 a0 2d c3 b6 20 20 20 20 20 30 30  #   ..-..     00
46f0: 45 30 2d 30 30 46 36 20 20 20 28 6c 6f 77 65 72  E0-00F6   (lower
4700: 20 63 61 73 65 29 0a 20 20 20 20 23 20 20 20 c3   case).    #   .
4710: b8 2d c3 bf 20 20 20 20 20 30 30 46 38 2d 30 30  .-..     00F8-00
4720: 46 46 20 20 20 28 6c 6f 77 65 72 20 63 61 73 65  FF   (lower case
4730: 29 0a 20 20 20 20 23 20 20 20 c4 80 2d ca af 20  ).    #   ..-.. 
4740: 20 20 20 20 30 31 30 30 2d 30 32 41 46 20 20 20      0100-02AF   
4750: 28 6d 69 78 65 64 29 0a 20 20 20 20 23 20 20 20  (mixed).    #   
4760: 2d 3e 20 61 2d 7a 41 2d 5a c3 a0 2d c3 b6 c3 80  -> a-zA-Z..-....
4770: 2d c3 96 30 2d 39 5f c3 b8 2d c3 bf c3 98 2d c3  -..0-9_..-....-.
4780: 9f c4 80 2d ca af 0a 20 20 20 20 62 43 61 73 65  ...-...    bCase
4790: 49 6e 73 65 6e 73 69 74 69 76 65 20 3d 20 46 61  Insensitive = Fa
47a0: 6c 73 65 0a 20 20 20 20 69 66 20 22 28 3f 69 29  lse.    if "(?i)
47b0: 22 20 69 6e 20 73 52 65 67 65 78 3a 0a 20 20 20  " in sRegex:.   
47c0: 20 20 20 20 20 73 52 65 67 65 78 20 3d 20 73 52       sRegex = sR
47d0: 65 67 65 78 2e 72 65 70 6c 61 63 65 28 22 28 3f  egex.replace("(?
47e0: 69 29 22 2c 20 22 22 29 0a 20 20 20 20 20 20 20  i)", "").       
47f0: 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69 76   bCaseInsensitiv
4800: 65 20 3d 20 54 72 75 65 0a 20 20 20 20 6c 4e 65  e = True.    lNe
4810: 67 4c 6f 6f 6b 42 65 66 6f 72 65 52 65 67 65 78  gLookBeforeRegex
4820: 20 3d 20 5b 5d 0a 20 20 20 20 69 66 20 73 57 4f   = [].    if sWO
4830: 52 44 4c 49 4d 49 54 4c 45 46 54 20 69 6e 20 73  RDLIMITLEFT in s
4840: 52 65 67 65 78 3a 0a 20 20 20 20 20 20 20 20 73  Regex:.        s
4850: 52 65 67 65 78 20 3d 20 73 52 65 67 65 78 2e 72  Regex = sRegex.r
4860: 65 70 6c 61 63 65 28 73 57 4f 52 44 4c 49 4d 49  eplace(sWORDLIMI
4870: 54 4c 45 46 54 2c 20 22 22 29 0a 20 20 20 20 20  TLEFT, "").     
4880: 20 20 20 6c 4e 65 67 4c 6f 6f 6b 42 65 66 6f 72     lNegLookBefor
4890: 65 52 65 67 65 78 20 3d 20 5b 22 5b 61 2d 7a 41  eRegex = ["[a-zA
48a0: 2d 5a c3 a0 2d c3 b6 c3 80 2d c3 96 30 2d 39 5f  -Z..-....-..0-9_
48b0: c3 b8 2d c3 bf c3 98 2d c3 9f c4 80 2d ca af 2e  ..-....-....-...
48c0: 2c e2 80 93 2d 5d 24 22 5d 0a 20 20 20 20 73 52  ,...-]$"].    sR
48d0: 65 67 65 78 20 3d 20 73 52 65 67 65 78 2e 72 65  egex = sRegex.re
48e0: 70 6c 61 63 65 28 22 5b 5c 5c 77 22 2c 20 22 5b  place("[\\w", "[
48f0: 61 2d 7a 41 2d 5a c3 a0 2d c3 b6 c3 80 2d c3 96  a-zA-Z..-....-..
4900: 30 2d 39 5f c3 b8 2d c3 bf c3 98 2d c3 9f c4 80  0-9_..-....-....
4910: 2d ca af 22 29 0a 20 20 20 20 73 52 65 67 65 78  -..").    sRegex
4920: 20 3d 20 73 52 65 67 65 78 2e 72 65 70 6c 61 63   = sRegex.replac
4930: 65 28 22 5c 5c 77 22 2c 20 22 5b 61 2d 7a 41 2d  e("\\w", "[a-zA-
4940: 5a c3 a0 2d c3 b6 c3 80 2d c3 96 30 2d 39 5f c3  Z..-....-..0-9_.
4950: b8 2d c3 bf c3 98 2d c3 9f c4 80 2d ca af 5d 22  .-....-....-..]"
4960: 29 0a 20 20 20 20 73 52 65 67 65 78 20 3d 20 73  ).    sRegex = s
4970: 52 65 67 65 78 2e 72 65 70 6c 61 63 65 28 22 5b  Regex.replace("[
4980: 2e 5d 22 2c 20 72 22 5c 2e 22 29 0a 20 20 20 20  .]", r"\.").    
4990: 69 66 20 6e 6f 74 20 73 52 65 67 65 78 2e 73 74  if not sRegex.st
49a0: 61 72 74 73 77 69 74 68 28 22 3c 6a 73 3e 22 29  artswith("<js>")
49b0: 3a 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78  :.        sRegex
49c0: 20 3d 20 73 52 65 67 65 78 2e 72 65 70 6c 61 63   = sRegex.replac
49d0: 65 28 22 2f 22 2c 20 72 22 5c 2f 22 29 0a 20 20  e("/", r"\/").  
49e0: 20 20 6d 20 3d 20 72 65 2e 73 65 61 72 63 68 28    m = re.search(
49f0: 72 22 5c 28 5c 3f 3c 21 28 5b 5e 28 29 5d 2b 29  r"\(\?<!([^()]+)
4a00: 5c 29 22 2c 20 73 52 65 67 65 78 29 20 20 23 20  \)", sRegex)  # 
4a10: 4e 65 67 61 74 69 76 65 20 6c 6f 6f 6b 62 65 66  Negative lookbef
4a20: 6f 72 65 20 61 73 73 65 72 74 69 6f 6e 20 73 68  ore assertion sh
4a30: 6f 75 6c 64 20 61 6c 77 61 79 73 20 62 65 20 61  ould always be a
4a40: 74 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20  t the beginning 
4a50: 6f 66 20 72 65 67 65 78 0a 20 20 20 20 69 66 20  of regex.    if 
4a60: 6d 3a 0a 20 20 20 20 20 20 20 20 6c 4e 65 67 4c  m:.        lNegL
4a70: 6f 6f 6b 42 65 66 6f 72 65 52 65 67 65 78 2e 61  ookBeforeRegex.a
4a80: 70 70 65 6e 64 28 6d 2e 67 72 6f 75 70 28 31 29  ppend(m.group(1)
4a90: 2b 22 24 22 29 0a 20 20 20 20 20 20 20 20 73 52  +"$").        sR
4aa0: 65 67 65 78 20 3d 20 73 52 65 67 65 78 2e 72 65  egex = sRegex.re
4ab0: 70 6c 61 63 65 28 6d 2e 67 72 6f 75 70 28 30 29  place(m.group(0)
4ac0: 2c 20 22 22 29 0a 20 20 20 20 69 66 20 22 28 3f  , "").    if "(?
4ad0: 3c 22 20 69 6e 20 73 52 65 67 65 78 3a 0a 20 20  <" in sRegex:.  
4ae0: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 57        print("# W
4af0: 61 72 6e 69 6e 67 2e 20 4c 6f 6f 6b 62 65 66 6f  arning. Lookbefo
4b00: 72 65 20 61 73 73 65 72 74 69 6f 6e 20 6e 6f 74  re assertion not
4b10: 20 63 68 61 6e 67 65 64 20 69 6e 3a 5c 6e 20 20   changed in:\n  
4b20: 22 29 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  ").        print
4b30: 28 73 52 65 67 65 78 29 0a 20 20 20 20 69 66 20  (sRegex).    if 
4b40: 73 52 65 67 65 78 2e 73 74 61 72 74 73 77 69 74  sRegex.startswit
4b50: 68 28 22 3c 6a 73 3e 22 29 3a 0a 20 20 20 20 20  h("<js>"):.     
4b60: 20 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67     sRegex = sReg
4b70: 65 78 2e 72 65 70 6c 61 63 65 28 27 3c 6a 73 3e  ex.replace('<js>
4b80: 27 2c 20 27 2f 27 29 2e 72 65 70 6c 61 63 65 28  ', '/').replace(
4b90: 27 3c 2f 6a 73 3e 69 27 2c 20 27 2f 69 67 27 29  '</js>i', '/ig')
4ba0: 2e 72 65 70 6c 61 63 65 28 27 3c 2f 6a 73 3e 27  .replace('</js>'
4bb0: 2c 20 27 2f 67 27 29 0a 20 20 20 20 65 6c 73 65  , '/g').    else
4bc0: 3a 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78  :.        sRegex
4bd0: 20 3d 20 22 2f 22 20 2b 20 73 52 65 67 65 78 20   = "/" + sRegex 
4be0: 2b 20 22 2f 67 22 0a 20 20 20 20 69 66 20 62 43  + "/g".    if bC
4bf0: 61 73 65 49 6e 73 65 6e 73 69 74 69 76 65 20 61  aseInsensitive a
4c00: 6e 64 20 6e 6f 74 20 73 52 65 67 65 78 2e 65 6e  nd not sRegex.en
4c10: 64 73 77 69 74 68 28 22 2f 69 67 22 29 3a 0a 20  dswith("/ig"):. 
4c20: 20 20 20 20 20 20 20 73 52 65 67 65 78 20 3d 20         sRegex = 
4c30: 73 52 65 67 65 78 20 2b 20 22 69 22 0a 20 20 20  sRegex + "i".   
4c40: 20 69 66 20 6e 6f 74 20 6c 4e 65 67 4c 6f 6f 6b   if not lNegLook
4c50: 42 65 66 6f 72 65 52 65 67 65 78 3a 0a 20 20 20  BeforeRegex:.   
4c60: 20 20 20 20 20 6c 4e 65 67 4c 6f 6f 6b 42 65 66       lNegLookBef
4c70: 6f 72 65 52 65 67 65 78 20 3d 20 4e 6f 6e 65 0a  oreRegex = None.
4c80: 20 20 20 20 72 65 74 75 72 6e 20 28 73 52 65 67      return (sReg
4c90: 65 78 2c 20 6c 4e 65 67 4c 6f 6f 6b 42 65 66 6f  ex, lNegLookBefo
4ca0: 72 65 52 65 67 65 78 29 0a 0a 0a 64 65 66 20 70  reRegex)...def p
4cb0: 79 52 75 6c 65 54 6f 4a 53 20 28 6c 52 75 6c 65  yRuleToJS (lRule
4cc0: 29 3a 0a 20 20 20 20 6c 52 75 6c 65 4a 53 20 3d  ):.    lRuleJS =
4cd0: 20 63 6f 70 79 2e 64 65 65 70 63 6f 70 79 28 6c   copy.deepcopy(l
4ce0: 52 75 6c 65 29 0a 20 20 20 20 64 65 6c 20 6c 52  Rule).    del lR
4cf0: 75 6c 65 5b 2d 31 5d 20 23 20 74 47 72 6f 75 70  ule[-1] # tGroup
4d00: 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67 20 63 6f  s positioning co
4d10: 64 65 73 20 61 72 65 20 75 73 65 6c 65 73 73 20  des are useless 
4d20: 66 6f 72 20 50 79 74 68 6f 6e 0a 20 20 20 20 23  for Python.    #
4d30: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 73 0a   error messages.
4d40: 20 20 20 20 66 6f 72 20 61 41 63 74 69 6f 6e 20      for aAction 
4d50: 69 6e 20 6c 52 75 6c 65 4a 53 5b 36 5d 3a 0a 20  in lRuleJS[6]:. 
4d60: 20 20 20 20 20 20 20 69 66 20 61 41 63 74 69 6f         if aActio
4d70: 6e 5b 31 5d 20 3d 3d 20 22 2d 22 3a 0a 20 20 20  n[1] == "-":.   
4d80: 20 20 20 20 20 20 20 20 20 61 41 63 74 69 6f 6e           aAction
4d90: 5b 32 5d 20 3d 20 61 41 63 74 69 6f 6e 5b 32 5d  [2] = aAction[2]
4da0: 2e 72 65 70 6c 61 63 65 28 22 c2 a0 22 2c 20 22  .replace("..", "
4db0: e2 80 af 22 29 20 23 20 6e 62 73 70 20 2d 2d 3e  ...") # nbsp -->
4dc0: 20 6e 6e 62 73 70 0a 20 20 20 20 20 20 20 20 20   nnbsp.         
4dd0: 20 20 20 61 41 63 74 69 6f 6e 5b 34 5d 20 3d 20     aAction[4] = 
4de0: 61 41 63 74 69 6f 6e 5b 34 5d 2e 72 65 70 6c 61  aAction[4].repla
4df0: 63 65 28 22 c2 ab 20 22 2c 20 22 c2 ab 26 6e 62  ce(".. ", "..&nb
4e00: 73 70 3b 22 29 2e 72 65 70 6c 61 63 65 28 22 20  sp;").replace(" 
4e10: c2 bb 22 2c 20 22 26 6e 62 73 70 3b c2 bb 22 29  ..", "&nbsp;..")
4e20: 0a 20 20 20 20 23 20 6a 73 20 72 65 67 65 78 65  .    # js regexe
4e30: 73 0a 20 20 20 20 6c 52 75 6c 65 4a 53 5b 31 5d  s.    lRuleJS[1]
4e40: 2c 20 6c 4e 65 67 4c 6f 6f 6b 42 65 68 69 6e 64  , lNegLookBehind
4e50: 52 65 67 65 78 20 3d 20 72 65 67 65 78 32 6a 73  Regex = regex2js
4e60: 28 20 64 4a 53 52 45 47 45 58 45 53 2e 67 65 74  ( dJSREGEXES.get
4e70: 28 6c 52 75 6c 65 4a 53 5b 33 5d 2c 20 6c 52 75  (lRuleJS[3], lRu
4e80: 6c 65 4a 53 5b 31 5d 29 20 29 0a 20 20 20 20 6c  leJS[1]) ).    l
4e90: 52 75 6c 65 4a 53 2e 61 70 70 65 6e 64 28 6c 4e  RuleJS.append(lN
4ea0: 65 67 4c 6f 6f 6b 42 65 68 69 6e 64 52 65 67 65  egLookBehindRege
4eb0: 78 29 0a 20 20 20 20 72 65 74 75 72 6e 20 6c 52  x).    return lR
4ec0: 75 6c 65 4a 53 0a 0a 0a 64 65 66 20 77 72 69 74  uleJS...def writ
4ed0: 65 52 75 6c 65 73 54 6f 4a 53 41 72 72 61 79 20  eRulesToJSArray 
4ee0: 28 6c 52 75 6c 65 73 29 3a 0a 20 20 20 20 73 41  (lRules):.    sA
4ef0: 72 72 61 79 20 3d 20 22 5b 5c 6e 22 0a 20 20 20  rray = "[\n".   
4f00: 20 66 6f 72 20 73 4f 70 74 69 6f 6e 2c 20 61 52   for sOption, aR
4f10: 75 6c 65 47 72 6f 75 70 20 69 6e 20 6c 52 75 6c  uleGroup in lRul
4f20: 65 73 3a 0a 20 20 20 20 20 20 20 20 73 41 72 72  es:.        sArr
4f30: 61 79 20 2b 3d 20 27 20 20 5b 22 27 20 2b 20 73  ay += '  ["' + s
4f40: 4f 70 74 69 6f 6e 20 2b 20 27 22 2c 20 5b 5c 6e  Option + '", [\n
4f50: 27 20 20 69 66 20 73 4f 70 74 69 6f 6e 20 20 65  '  if sOption  e
4f60: 6c 73 65 20 20 22 20 20 5b 66 61 6c 73 65 2c 20  lse  "  [false, 
4f70: 5b 5c 6e 22 0a 20 20 20 20 20 20 20 20 66 6f 72  [\n".        for
4f80: 20 73 52 65 67 65 78 2c 20 62 43 61 73 65 49 6e   sRegex, bCaseIn
4f90: 73 65 6e 73 69 74 69 76 65 2c 20 73 4c 69 6e 65  sensitive, sLine
4fa0: 49 64 2c 20 73 52 75 6c 65 49 64 2c 20 6e 50 72  Id, sRuleId, nPr
4fb0: 69 6f 72 69 74 79 2c 20 6c 41 63 74 69 6f 6e 73  iority, lActions
4fc0: 2c 20 61 47 72 6f 75 70 73 2c 20 61 4e 65 67 4c  , aGroups, aNegL
4fd0: 6f 6f 6b 42 65 68 69 6e 64 52 65 67 65 78 20 69  ookBehindRegex i
4fe0: 6e 20 61 52 75 6c 65 47 72 6f 75 70 3a 0a 20 20  n aRuleGroup:.  
4ff0: 20 20 20 20 20 20 20 20 20 20 73 41 72 72 61 79            sArray
5000: 20 2b 3d 20 27 20 20 20 20 5b 27 20 2b 20 73 52   += '    [' + sR
5010: 65 67 65 78 20 2b 20 22 2c 20 22 0a 20 20 20 20  egex + ", ".    
5020: 20 20 20 20 20 20 20 20 73 41 72 72 61 79 20 2b          sArray +
5030: 3d 20 22 74 72 75 65 2c 20 22 20 69 66 20 62 43  = "true, " if bC
5040: 61 73 65 49 6e 73 65 6e 73 69 74 69 76 65 20 20  aseInsensitive  
5050: 65 6c 73 65 20 22 66 61 6c 73 65 2c 20 22 0a 20  else "false, ". 
5060: 20 20 20 20 20 20 20 20 20 20 20 73 41 72 72 61             sArra
5070: 79 20 2b 3d 20 27 22 27 20 2b 20 73 4c 69 6e 65  y += '"' + sLine
5080: 49 64 20 2b 20 27 22 2c 20 27 0a 20 20 20 20 20  Id + '", '.     
5090: 20 20 20 20 20 20 20 73 41 72 72 61 79 20 2b 3d         sArray +=
50a0: 20 27 22 27 20 2b 20 73 52 75 6c 65 49 64 20 2b   '"' + sRuleId +
50b0: 20 27 22 2c 20 27 0a 20 20 20 20 20 20 20 20 20   '", '.         
50c0: 20 20 20 73 41 72 72 61 79 20 2b 3d 20 73 74 72     sArray += str
50d0: 28 6e 50 72 69 6f 72 69 74 79 29 20 2b 20 22 2c  (nPriority) + ",
50e0: 20 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 73   ".            s
50f0: 41 72 72 61 79 20 2b 3d 20 6a 73 6f 6e 2e 64 75  Array += json.du
5100: 6d 70 73 28 6c 41 63 74 69 6f 6e 73 2c 20 65 6e  mps(lActions, en
5110: 73 75 72 65 5f 61 73 63 69 69 3d 46 61 6c 73 65  sure_ascii=False
5120: 29 20 2b 20 22 2c 20 22 0a 20 20 20 20 20 20 20  ) + ", ".       
5130: 20 20 20 20 20 73 41 72 72 61 79 20 2b 3d 20 6a       sArray += j
5140: 73 6f 6e 2e 64 75 6d 70 73 28 61 47 72 6f 75 70  son.dumps(aGroup
5150: 73 2c 20 65 6e 73 75 72 65 5f 61 73 63 69 69 3d  s, ensure_ascii=
5160: 46 61 6c 73 65 29 20 2b 20 22 2c 20 22 0a 20 20  False) + ", ".  
5170: 20 20 20 20 20 20 20 20 20 20 73 41 72 72 61 79            sArray
5180: 20 2b 3d 20 6a 73 6f 6e 2e 64 75 6d 70 73 28 61   += json.dumps(a
5190: 4e 65 67 4c 6f 6f 6b 42 65 68 69 6e 64 52 65 67  NegLookBehindReg
51a0: 65 78 2c 20 65 6e 73 75 72 65 5f 61 73 63 69 69  ex, ensure_ascii
51b0: 3d 46 61 6c 73 65 29 20 2b 20 22 5d 2c 5c 6e 22  =False) + "],\n"
51c0: 0a 20 20 20 20 20 20 20 20 73 41 72 72 61 79 20  .        sArray 
51d0: 2b 3d 20 22 20 20 5d 5d 2c 5c 6e 22 0a 20 20 20  += "  ]],\n".   
51e0: 20 73 41 72 72 61 79 20 2b 3d 20 22 5d 22 0a 20   sArray += "]". 
51f0: 20 20 20 72 65 74 75 72 6e 20 73 41 72 72 61 79     return sArray
5200: 0a 0a 0a 64 65 66 20 67 72 6f 75 70 73 50 6f 73  ...def groupsPos
5210: 69 74 69 6f 6e 69 6e 67 43 6f 64 65 54 6f 4c 69  itioningCodeToLi
5220: 73 74 20 28 73 47 72 6f 75 70 73 50 6f 73 69 74  st (sGroupsPosit
5230: 69 6f 6e 69 6e 67 43 6f 64 65 29 3a 0a 20 20 20  ioningCode):.   
5240: 20 69 66 20 6e 6f 74 20 73 47 72 6f 75 70 73 50   if not sGroupsP
5250: 6f 73 69 74 69 6f 6e 69 6e 67 43 6f 64 65 3a 0a  ositioningCode:.
5260: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e          return N
5270: 6f 6e 65 0a 20 20 20 20 72 65 74 75 72 6e 20 5b  one.    return [
5280: 20 69 6e 74 28 73 43 6f 64 65 29 20 20 69 66 20   int(sCode)  if 
5290: 73 43 6f 64 65 2e 69 73 64 69 67 69 74 28 29 20  sCode.isdigit() 
52a0: 6f 72 20 28 73 43 6f 64 65 5b 30 3a 31 5d 20 3d  or (sCode[0:1] =
52b0: 3d 20 22 2d 22 20 61 6e 64 20 73 43 6f 64 65 5b  = "-" and sCode[
52c0: 31 3a 5d 2e 69 73 64 69 67 69 74 28 29 29 20 20  1:].isdigit())  
52d0: 65 6c 73 65 20 73 43 6f 64 65 20 5c 0a 20 20 20  else sCode \.   
52e0: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 73 43            for sC
52f0: 6f 64 65 20 69 6e 20 73 47 72 6f 75 70 73 50 6f  ode in sGroupsPo
5300: 73 69 74 69 6f 6e 69 6e 67 43 6f 64 65 2e 73 70  sitioningCode.sp
5310: 6c 69 74 28 22 2c 22 29 20 5d 0a 0a 0a 64 65 66  lit(",") ]...def
5320: 20 5f 63 61 6c 63 52 75 6c 65 73 53 74 61 74 73   _calcRulesStats
5330: 20 28 6c 52 75 6c 65 73 29 3a 0a 20 20 20 20 64   (lRules):.    d
5340: 20 3d 20 7b 27 3d 27 3a 30 2c 20 27 7e 27 3a 20   = {'=':0, '~': 
5350: 30 2c 20 27 2d 27 3a 20 30 2c 20 27 3e 27 3a 20  0, '-': 0, '>': 
5360: 30 7d 0a 20 20 20 20 66 6f 72 20 61 52 75 6c 65  0}.    for aRule
5370: 20 69 6e 20 6c 52 75 6c 65 73 3a 0a 20 20 20 20   in lRules:.    
5380: 20 20 20 20 66 6f 72 20 61 41 63 74 69 6f 6e 20      for aAction 
5390: 69 6e 20 61 52 75 6c 65 5b 36 5d 3a 0a 20 20 20  in aRule[6]:.   
53a0: 20 20 20 20 20 20 20 20 20 64 5b 61 41 63 74 69           d[aActi
53b0: 6f 6e 5b 31 5d 5d 20 3d 20 64 5b 61 41 63 74 69  on[1]] = d[aActi
53c0: 6f 6e 5b 31 5d 5d 20 2b 20 31 0a 20 20 20 20 72  on[1]] + 1.    r
53d0: 65 74 75 72 6e 20 28 64 2c 20 6c 65 6e 28 6c 52  eturn (d, len(lR
53e0: 75 6c 65 73 29 29 0a 0a 0a 64 65 66 20 64 69 73  ules))...def dis
53f0: 70 6c 61 79 53 74 61 74 73 20 28 6c 50 61 72 61  playStats (lPara
5400: 67 72 61 70 68 52 75 6c 65 73 2c 20 6c 53 65 6e  graphRules, lSen
5410: 74 65 6e 63 65 52 75 6c 65 73 29 3a 0a 20 20 20  tenceRules):.   
5420: 20 70 72 69 6e 74 28 22 20 20 7b 3a 3e 31 38 7d   print("  {:>18}
5430: 20 7b 3a 3e 31 38 7d 20 7b 3a 3e 31 38 7d 20 7b   {:>18} {:>18} {
5440: 3a 3e 31 38 7d 22 2e 66 6f 72 6d 61 74 28 22 44  :>18}".format("D
5450: 49 53 41 4d 42 49 47 55 41 54 4f 52 22 2c 20 22  ISAMBIGUATOR", "
5460: 54 45 58 54 20 50 52 4f 43 45 53 53 4f 52 22 2c  TEXT PROCESSOR",
5470: 20 22 47 52 41 4d 4d 41 52 20 43 48 45 43 4b 49   "GRAMMAR CHECKI
5480: 4e 47 22 2c 20 22 52 45 47 45 58 22 29 29 0a 20  NG", "REGEX")). 
5490: 20 20 20 64 2c 20 6e 52 75 6c 65 20 3d 20 5f 63     d, nRule = _c
54a0: 61 6c 63 52 75 6c 65 73 53 74 61 74 73 28 6c 50  alcRulesStats(lP
54b0: 61 72 61 67 72 61 70 68 52 75 6c 65 73 29 0a 20  aragraphRules). 
54c0: 20 20 20 70 72 69 6e 74 28 22 c2 a7 20 7b 3a 3e     print(".. {:>
54d0: 31 30 7d 20 61 63 74 69 6f 6e 73 20 7b 3a 3e 31  10} actions {:>1
54e0: 30 7d 20 61 63 74 69 6f 6e 73 20 7b 3a 3e 31 30  0} actions {:>10
54f0: 7d 20 61 63 74 69 6f 6e 73 20 20 69 6e 20 7b 3a  } actions  in {:
5500: 3e 38 7d 20 72 75 6c 65 73 22 2e 66 6f 72 6d 61  >8} rules".forma
5510: 74 28 64 5b 27 3d 27 5d 2c 20 64 5b 27 7e 27 5d  t(d['='], d['~']
5520: 2c 20 64 5b 27 2d 27 5d 2c 20 6e 52 75 6c 65 29  , d['-'], nRule)
5530: 29 0a 20 20 20 20 64 2c 20 6e 52 75 6c 65 20 3d  ).    d, nRule =
5540: 20 5f 63 61 6c 63 52 75 6c 65 73 53 74 61 74 73   _calcRulesStats
5550: 28 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 29  (lSentenceRules)
5560: 0a 20 20 20 20 70 72 69 6e 74 28 22 73 20 7b 3a  .    print("s {:
5570: 3e 31 30 7d 20 61 63 74 69 6f 6e 73 20 7b 3a 3e  >10} actions {:>
5580: 31 30 7d 20 61 63 74 69 6f 6e 73 20 7b 3a 3e 31  10} actions {:>1
5590: 30 7d 20 61 63 74 69 6f 6e 73 20 20 69 6e 20 7b  0} actions  in {
55a0: 3a 3e 38 7d 20 72 75 6c 65 73 22 2e 66 6f 72 6d  :>8} rules".form
55b0: 61 74 28 64 5b 27 3d 27 5d 2c 20 64 5b 27 7e 27  at(d['='], d['~'
55c0: 5d 2c 20 64 5b 27 2d 27 5d 2c 20 6e 52 75 6c 65  ], d['-'], nRule
55d0: 29 29 0a 0a 0a 64 65 66 20 6d 65 72 67 65 52 75  ))...def mergeRu
55e0: 6c 65 73 42 79 4f 70 74 69 6f 6e 20 28 6c 52 75  lesByOption (lRu
55f0: 6c 65 73 29 3a 0a 20 20 20 20 22 72 65 74 75 72  les):.    "retur
5600: 6e 73 20 61 20 6c 69 73 74 20 6f 66 20 74 75 70  ns a list of tup
5610: 6c 65 73 20 5b 6f 70 74 69 6f 6e 2c 20 6c 69 73  les [option, lis
5620: 74 20 6f 66 20 72 75 6c 65 73 5d 20 6b 65 65 70  t of rules] keep
5630: 69 6e 67 20 74 68 65 20 72 75 6c 65 73 20 6f 72  ing the rules or
5640: 64 65 72 22 0a 20 20 20 20 6c 46 69 6e 61 6c 20  der".    lFinal 
5650: 3d 20 5b 5d 0a 20 20 20 20 6c 54 65 6d 70 20 3d  = [].    lTemp =
5660: 20 5b 5d 0a 20 20 20 20 73 4f 70 74 69 6f 6e 20   [].    sOption 
5670: 3d 20 4e 6f 6e 65 0a 20 20 20 20 66 6f 72 20 61  = None.    for a
5680: 52 75 6c 65 20 69 6e 20 6c 52 75 6c 65 73 3a 0a  Rule in lRules:.
5690: 20 20 20 20 20 20 20 20 69 66 20 61 52 75 6c 65          if aRule
56a0: 5b 30 5d 20 21 3d 20 73 4f 70 74 69 6f 6e 3a 0a  [0] != sOption:.
56b0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73              if s
56c0: 4f 70 74 69 6f 6e 20 21 3d 20 4e 6f 6e 65 3a 0a  Option != None:.
56d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
56e0: 6c 46 69 6e 61 6c 2e 61 70 70 65 6e 64 28 5b 73  lFinal.append([s
56f0: 4f 70 74 69 6f 6e 2c 20 6c 54 65 6d 70 5d 29 0a  Option, lTemp]).
5700: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 6e 65              # ne
5710: 77 20 74 75 70 6c 65 0a 20 20 20 20 20 20 20 20  w tuple.        
5720: 20 20 20 20 73 4f 70 74 69 6f 6e 20 3d 20 61 52      sOption = aR
5730: 75 6c 65 5b 30 5d 0a 20 20 20 20 20 20 20 20 20  ule[0].         
5740: 20 20 20 6c 54 65 6d 70 20 3d 20 5b 5d 0a 20 20     lTemp = [].  
5750: 20 20 20 20 20 20 6c 54 65 6d 70 2e 61 70 70 65        lTemp.appe
5760: 6e 64 28 61 52 75 6c 65 5b 31 3a 5d 29 0a 20 20  nd(aRule[1:]).  
5770: 20 20 6c 46 69 6e 61 6c 2e 61 70 70 65 6e 64 28    lFinal.append(
5780: 5b 73 4f 70 74 69 6f 6e 2c 20 6c 54 65 6d 70 5d  [sOption, lTemp]
5790: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 6c 46 69  ).    return lFi
57a0: 6e 61 6c 0a 0a 0a 64 65 66 20 70 72 65 70 61 72  nal...def prepar
57b0: 65 4f 70 74 69 6f 6e 73 20 28 6c 4f 70 74 69 6f  eOptions (lOptio
57c0: 6e 4c 69 6e 65 73 29 3a 0a 20 20 20 20 22 72 65  nLines):.    "re
57d0: 74 75 72 6e 73 20 61 20 64 69 63 74 69 6f 6e 61  turns a dictiona
57e0: 72 79 20 77 69 74 68 20 64 61 74 61 20 61 62 6f  ry with data abo
57f0: 75 74 20 6f 70 74 69 6f 6e 73 22 0a 20 20 20 20  ut options".    
5800: 73 4c 61 6e 67 20 3d 20 22 22 0a 20 20 20 20 6c  sLang = "".    l
5810: 53 74 72 75 63 74 4f 70 74 20 3d 20 5b 5d 0a 20  StructOpt = []. 
5820: 20 20 20 6c 4f 70 74 20 3d 20 5b 5d 0a 20 20 20     lOpt = [].   
5830: 20 64 4f 70 74 4c 61 62 65 6c 20 3d 20 7b 7d 0a   dOptLabel = {}.
5840: 20 20 20 20 64 4f 70 74 50 72 69 6f 72 69 74 79      dOptPriority
5850: 20 3d 20 7b 7d 0a 20 20 20 20 66 6f 72 20 73 4c   = {}.    for sL
5860: 69 6e 65 20 69 6e 20 6c 4f 70 74 69 6f 6e 4c 69  ine in lOptionLi
5870: 6e 65 73 3a 0a 20 20 20 20 20 20 20 20 73 4c 69  nes:.        sLi
5880: 6e 65 20 3d 20 73 4c 69 6e 65 2e 73 74 72 69 70  ne = sLine.strip
5890: 28 29 0a 20 20 20 20 20 20 20 20 69 66 20 73 4c  ().        if sL
58a0: 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ine.startswith("
58b0: 4f 50 54 47 52 4f 55 50 2f 22 29 3a 0a 20 20 20  OPTGROUP/"):.   
58c0: 20 20 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e           m = re.
58d0: 6d 61 74 63 68 28 22 4f 50 54 47 52 4f 55 50 2f  match("OPTGROUP/
58e0: 28 5b 61 2d 7a 30 2d 39 5d 2b 29 3a 28 2e 2b 29  ([a-z0-9]+):(.+)
58f0: 24 22 2c 20 73 4c 69 6e 65 29 0a 20 20 20 20 20  $", sLine).     
5900: 20 20 20 20 20 20 20 6c 53 74 72 75 63 74 4f 70         lStructOp
5910: 74 2e 61 70 70 65 6e 64 28 20 28 6d 2e 67 72 6f  t.append( (m.gro
5920: 75 70 28 31 29 2c 20 6c 69 73 74 28 6d 61 70 28  up(1), list(map(
5930: 73 74 72 2e 73 70 6c 69 74 2c 20 6d 2e 67 72 6f  str.split, m.gro
5940: 75 70 28 32 29 2e 73 70 6c 69 74 28 22 2c 22 29  up(2).split(",")
5950: 29 29 29 20 29 0a 20 20 20 20 20 20 20 20 65 6c  ))) ).        el
5960: 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77  if sLine.startsw
5970: 69 74 68 28 22 4f 50 54 53 4f 46 54 57 41 52 45  ith("OPTSOFTWARE
5980: 3a 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  :"):.           
5990: 20 6c 4f 70 74 20 3d 20 5b 20 5b 73 2c 20 7b 7d   lOpt = [ [s, {}
59a0: 5d 20 20 66 6f 72 20 73 20 69 6e 20 73 4c 69 6e  ]  for s in sLin
59b0: 65 5b 31 32 3a 5d 2e 73 74 72 69 70 28 29 2e 73  e[12:].strip().s
59c0: 70 6c 69 74 28 29 20 5d 20 20 23 20 64 6f 6e e2  plit() ]  # don.
59d0: 80 99 74 20 75 73 65 20 74 75 70 6c 65 73 20 28  ..t use tuples (
59e0: 73 2c 20 7b 7d 29 2c 20 62 65 63 61 75 73 65 20  s, {}), because 
59f0: 75 6e 6b 6e 6f 77 6e 20 74 6f 20 4a 53 0a 20 20  unknown to JS.  
5a00: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
5a10: 2e 73 74 61 72 74 73 77 69 74 68 28 22 4f 50 54  .startswith("OPT
5a20: 2f 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  /"):.           
5a30: 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f   m = re.match("O
5a40: 50 54 2f 28 5b 61 2d 7a 30 2d 39 5d 2b 29 3a 28  PT/([a-z0-9]+):(
5a50: 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29 0a 20 20  .+)$", sLine).  
5a60: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 69 2c            for i,
5a70: 20 73 4f 70 74 20 69 6e 20 65 6e 75 6d 65 72 61   sOpt in enumera
5a80: 74 65 28 6d 2e 67 72 6f 75 70 28 32 29 2e 73 70  te(m.group(2).sp
5a90: 6c 69 74 28 29 29 3a 0a 20 20 20 20 20 20 20 20  lit()):.        
5aa0: 20 20 20 20 20 20 20 20 6c 4f 70 74 5b 69 5d 5b          lOpt[i][
5ab0: 31 5d 5b 6d 2e 67 72 6f 75 70 28 31 29 5d 20 3d  1][m.group(1)] =
5ac0: 20 20 65 76 61 6c 28 73 4f 70 74 29 0a 20 20 20    eval(sOpt).   
5ad0: 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e       elif sLine.
5ae0: 73 74 61 72 74 73 77 69 74 68 28 22 4f 50 54 50  startswith("OPTP
5af0: 52 49 4f 52 49 54 59 2f 22 29 3a 0a 20 20 20 20  RIORITY/"):.    
5b00: 20 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d          m = re.m
5b10: 61 74 63 68 28 22 4f 50 54 50 52 49 4f 52 49 54  atch("OPTPRIORIT
5b20: 59 2f 28 5b 61 2d 7a 30 2d 39 5d 2b 29 3a 20 2a  Y/([a-z0-9]+): *
5b30: 28 5b 30 2d 39 5d 29 24 22 2c 20 73 4c 69 6e 65  ([0-9])$", sLine
5b40: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 4f  ).            dO
5b50: 70 74 50 72 69 6f 72 69 74 79 5b 6d 2e 67 72 6f  ptPriority[m.gro
5b60: 75 70 28 31 29 5d 20 3d 20 69 6e 74 28 6d 2e 67  up(1)] = int(m.g
5b70: 72 6f 75 70 28 32 29 29 0a 20 20 20 20 20 20 20  roup(2)).       
5b80: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
5b90: 74 73 77 69 74 68 28 22 4f 50 54 4c 41 4e 47 2f  tswith("OPTLANG/
5ba0: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
5bb0: 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f 50  m = re.match("OP
5bc0: 54 4c 41 4e 47 2f 28 5b 61 2d 7a 5d 5b 61 2d 7a  TLANG/([a-z][a-z
5bd0: 5d 28 3f 3a 5f 5b 41 2d 5a 5d 5b 41 2d 5a 5d 7c  ](?:_[A-Z][A-Z]|
5be0: 29 29 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65  )):(.+)$", sLine
5bf0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 4c  ).            sL
5c00: 61 6e 67 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29  ang = m.group(1)
5c10: 5b 3a 32 5d 0a 20 20 20 20 20 20 20 20 20 20 20  [:2].           
5c20: 20 64 4f 70 74 4c 61 62 65 6c 5b 73 4c 61 6e 67   dOptLabel[sLang
5c30: 5d 20 3d 20 7b 20 22 5f 5f 6f 70 74 69 6f 6e 74  ] = { "__optiont
5c40: 69 74 6c 65 5f 5f 22 3a 20 6d 2e 67 72 6f 75 70  itle__": m.group
5c50: 28 32 29 2e 73 74 72 69 70 28 29 20 7d 0a 20 20  (2).strip() }.  
5c60: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
5c70: 2e 73 74 61 72 74 73 77 69 74 68 28 22 4f 50 54  .startswith("OPT
5c80: 4c 41 42 45 4c 2f 22 29 3a 0a 20 20 20 20 20 20  LABEL/"):.      
5c90: 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74        m = re.mat
5ca0: 63 68 28 22 4f 50 54 4c 41 42 45 4c 2f 28 5b 61  ch("OPTLABEL/([a
5cb0: 2d 7a 30 2d 39 5d 2b 29 3a 28 2e 2b 29 24 22 2c  -z0-9]+):(.+)$",
5cc0: 20 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20   sLine).        
5cd0: 20 20 20 20 64 4f 70 74 4c 61 62 65 6c 5b 73 4c      dOptLabel[sL
5ce0: 61 6e 67 5d 5b 6d 2e 67 72 6f 75 70 28 31 29 5d  ang][m.group(1)]
5cf0: 20 3d 20 6c 69 73 74 28 6d 61 70 28 73 74 72 2e   = list(map(str.
5d00: 73 74 72 69 70 2c 20 6d 2e 67 72 6f 75 70 28 32  strip, m.group(2
5d10: 29 2e 73 70 6c 69 74 28 22 7c 22 29 29 29 20 20  ).split("|")))  
5d20: 69 66 20 22 7c 22 20 69 6e 20 6d 2e 67 72 6f 75  if "|" in m.grou
5d30: 70 28 32 29 20 20 65 6c 73 65 20 20 5b 6d 2e 67  p(2)  else  [m.g
5d40: 72 6f 75 70 28 32 29 2e 73 74 72 69 70 28 29 2c  roup(2).strip(),
5d50: 20 22 22 5d 0a 20 20 20 20 20 20 20 20 65 6c 73   ""].        els
5d60: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  e:.            p
5d70: 72 69 6e 74 28 22 23 20 45 72 72 6f 72 2e 20 57  rint("# Error. W
5d80: 72 6f 6e 67 20 6f 70 74 69 6f 6e 20 6c 69 6e 65  rong option line
5d90: 20 69 6e 3a 5c 6e 20 20 22 29 0a 20 20 20 20 20   in:\n  ").     
5da0: 20 20 20 20 20 20 20 70 72 69 6e 74 28 73 4c 69         print(sLi
5db0: 6e 65 29 0a 20 20 20 20 70 72 69 6e 74 28 22 20  ne).    print(" 
5dc0: 20 6f 70 74 69 6f 6e 73 20 64 65 66 69 6e 65 64   options defined
5dd0: 20 66 6f 72 3a 20 22 20 2b 20 22 2c 20 22 2e 6a   for: " + ", ".j
5de0: 6f 69 6e 28 5b 20 74 5b 30 5d 20 66 6f 72 20 74  oin([ t[0] for t
5df0: 20 69 6e 20 6c 4f 70 74 20 5d 29 29 0a 20 20 20   in lOpt ])).   
5e00: 20 64 4f 70 74 69 6f 6e 73 20 3d 20 7b 20 22 6c   dOptions = { "l
5e10: 53 74 72 75 63 74 4f 70 74 22 3a 20 6c 53 74 72  StructOpt": lStr
5e20: 75 63 74 4f 70 74 2c 20 22 64 4f 70 74 4c 61 62  uctOpt, "dOptLab
5e30: 65 6c 22 3a 20 64 4f 70 74 4c 61 62 65 6c 20 7d  el": dOptLabel }
5e40: 0a 20 20 20 20 64 4f 70 74 69 6f 6e 73 2e 75 70  .    dOptions.up
5e50: 64 61 74 65 28 7b 20 22 64 4f 70 74 22 2b 6b 3a  date({ "dOpt"+k:
5e60: 20 76 20 20 66 6f 72 20 6b 2c 20 76 20 69 6e 20   v  for k, v in 
5e70: 6c 4f 70 74 20 7d 29 0a 20 20 20 20 72 65 74 75  lOpt }).    retu
5e80: 72 6e 20 64 4f 70 74 69 6f 6e 73 2c 20 64 4f 70  rn dOptions, dOp
5e90: 74 50 72 69 6f 72 69 74 79 0a 0a 0a 64 65 66 20  tPriority...def 
5ea0: 70 72 69 6e 74 42 6f 6f 6b 6d 61 72 6b 20 28 6e  printBookmark (n
5eb0: 4c 65 76 65 6c 2c 20 73 43 6f 6d 6d 65 6e 74 2c  Level, sComment,
5ec0: 20 6e 4c 69 6e 65 29 3a 0a 20 20 20 20 70 72 69   nLine):.    pri
5ed0: 6e 74 28 22 20 20 7b 3a 3e 36 7d 3a 20 20 7b 7d  nt("  {:>6}:  {}
5ee0: 22 2e 66 6f 72 6d 61 74 28 6e 4c 69 6e 65 2c 20  ".format(nLine, 
5ef0: 22 20 20 22 20 2a 20 6e 4c 65 76 65 6c 20 2b 20  "  " * nLevel + 
5f00: 73 43 6f 6d 6d 65 6e 74 29 29 0a 0a 0a 64 65 66  sComment))...def
5f10: 20 6d 61 6b 65 20 28 6c 52 75 6c 65 73 2c 20 73   make (lRules, s
5f20: 4c 61 6e 67 2c 20 62 4a 61 76 61 53 63 72 69 70  Lang, bJavaScrip
5f30: 74 29 3a 0a 20 20 20 20 22 63 6f 6d 70 69 6c 65  t):.    "compile
5f40: 20 72 75 6c 65 73 2c 20 72 65 74 75 72 6e 73 20   rules, returns 
5f50: 61 20 64 69 63 74 69 6f 6e 61 72 79 20 6f 66 20  a dictionary of 
5f60: 76 61 6c 75 65 73 22 0a 20 20 20 20 23 20 66 6f  values".    # fo
5f70: 72 20 63 6c 61 72 69 74 79 20 70 75 72 70 6f 73  r clarity purpos
5f80: 65 2c 20 64 6f 6e e2 80 99 74 20 63 72 65 61 74  e, don...t creat
5f90: 65 20 61 6e 79 20 66 69 6c 65 20 68 65 72 65 0a  e any file here.
5fa0: 0a 20 20 20 20 23 20 72 65 6d 6f 76 69 6e 67 20  .    # removing 
5fb0: 63 6f 6d 6d 65 6e 74 73 2c 20 7a 65 72 6f 69 6e  comments, zeroin
5fc0: 67 20 65 6d 70 74 79 20 6c 69 6e 65 73 2c 20 63  g empty lines, c
5fd0: 72 65 61 74 69 6e 67 20 64 65 66 69 6e 69 74 69  reating definiti
5fe0: 6f 6e 73 2c 20 73 74 6f 72 69 6e 67 20 74 65 73  ons, storing tes
5ff0: 74 73 2c 20 6d 65 72 67 69 6e 67 20 72 75 6c 65  ts, merging rule
6000: 20 6c 69 6e 65 73 0a 20 20 20 20 70 72 69 6e 74   lines.    print
6010: 28 22 20 20 70 61 72 73 69 6e 67 20 72 75 6c 65  ("  parsing rule
6020: 73 2e 2e 2e 22 29 0a 20 20 20 20 67 6c 6f 62 61  s...").    globa
6030: 6c 20 64 44 45 46 0a 20 20 20 20 6c 4c 69 6e 65  l dDEF.    lLine
6040: 20 3d 20 5b 5d 0a 20 20 20 20 6c 52 75 6c 65 4c   = [].    lRuleL
6050: 69 6e 65 20 3d 20 5b 5d 0a 20 20 20 20 6c 54 65  ine = [].    lTe
6060: 73 74 20 3d 20 5b 5d 0a 20 20 20 20 6c 4f 70 74  st = [].    lOpt
6070: 20 3d 20 5b 5d 0a 20 20 20 20 7a 42 6f 6f 6b 6d   = [].    zBookm
6080: 61 72 6b 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65  ark = re.compile
6090: 28 22 5e 21 21 2b 22 29 0a 0a 20 20 20 20 66 6f  ("^!!+")..    fo
60a0: 72 20 69 2c 20 73 4c 69 6e 65 20 69 6e 20 65 6e  r i, sLine in en
60b0: 75 6d 65 72 61 74 65 28 6c 52 75 6c 65 73 2c 20  umerate(lRules, 
60c0: 31 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73  1):.        if s
60d0: 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28  Line.startswith(
60e0: 27 23 45 4e 44 27 29 3a 0a 20 20 20 20 20 20 20  '#END'):.       
60f0: 20 20 20 20 20 70 72 69 6e 74 42 6f 6f 6b 6d 61       printBookma
6100: 72 6b 28 30 2c 20 22 42 52 45 41 4b 20 42 59 20  rk(0, "BREAK BY 
6110: 23 45 4e 44 22 2c 20 69 29 0a 20 20 20 20 20 20  #END", i).      
6120: 20 20 20 20 20 20 62 72 65 61 6b 0a 20 20 20 20        break.    
6130: 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73      elif sLine.s
6140: 74 61 72 74 73 77 69 74 68 28 22 23 22 29 3a 0a  tartswith("#"):.
6150: 20 20 20 20 20 20 20 20 20 20 20 20 70 61 73 73              pass
6160: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c  .        elif sL
6170: 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ine.startswith("
6180: 44 45 46 3a 22 29 3a 0a 20 20 20 20 20 20 20 20  DEF:"):.        
6190: 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68      m = re.match
61a0: 28 22 44 45 46 3a 20 2b 28 5b 61 2d 7a 41 2d 5a  ("DEF: +([a-zA-Z
61b0: 5f 5d 5b 61 2d 7a 41 2d 5a 5f 30 2d 39 5d 2a 29  _][a-zA-Z_0-9]*)
61c0: 20 2b 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 2e   +(.+)$", sLine.
61d0: 73 74 72 69 70 28 29 29 0a 20 20 20 20 20 20 20  strip()).       
61e0: 20 20 20 20 20 69 66 20 6d 3a 0a 20 20 20 20 20       if m:.     
61f0: 20 20 20 20 20 20 20 20 20 20 20 64 44 45 46 5b             dDEF[
6200: 22 7b 22 2b 6d 2e 67 72 6f 75 70 28 31 29 2b 22  "{"+m.group(1)+"
6210: 7d 22 5d 20 3d 20 6d 2e 67 72 6f 75 70 28 32 29  }"] = m.group(2)
6220: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
6230: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
6240: 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f 72 20     print("Error 
6250: 69 6e 20 64 65 66 69 6e 69 74 69 6f 6e 3a 20 22  in definition: "
6260: 2c 20 65 6e 64 3d 22 22 29 0a 20 20 20 20 20 20  , end="").      
6270: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
6280: 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 29 0a 20  sLine.strip()). 
6290: 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e         elif sLin
62a0: 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 54 45  e.startswith("TE
62b0: 53 54 3a 22 29 3a 0a 20 20 20 20 20 20 20 20 20  ST:"):.         
62c0: 20 20 20 6c 54 65 73 74 2e 61 70 70 65 6e 64 28     lTest.append(
62d0: 22 7b 3a 3c 38 7d 22 2e 66 6f 72 6d 61 74 28 69  "{:<8}".format(i
62e0: 29 20 2b 20 22 20 20 22 20 2b 20 73 4c 69 6e 65  ) + "  " + sLine
62f0: 5b 35 3a 5d 2e 73 74 72 69 70 28 29 29 0a 20 20  [5:].strip()).  
6300: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
6310: 2e 73 74 61 72 74 73 77 69 74 68 28 22 54 4f 44  .startswith("TOD
6320: 4f 3a 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  O:"):.          
6330: 20 20 70 61 73 73 0a 20 20 20 20 20 20 20 20 65    pass.        e
6340: 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73  lif sLine.starts
6350: 77 69 74 68 28 28 22 4f 50 54 47 52 4f 55 50 2f  with(("OPTGROUP/
6360: 22 2c 20 22 4f 50 54 53 4f 46 54 57 41 52 45 3a  ", "OPTSOFTWARE:
6370: 22 2c 20 22 4f 50 54 2f 22 2c 20 22 4f 50 54 4c  ", "OPT/", "OPTL
6380: 41 4e 47 2f 22 2c 20 22 4f 50 54 4c 41 42 45 4c  ANG/", "OPTLABEL
6390: 2f 22 2c 20 22 4f 50 54 50 52 49 4f 52 49 54 59  /", "OPTPRIORITY
63a0: 2f 22 29 29 3a 0a 20 20 20 20 20 20 20 20 20 20  /")):.          
63b0: 20 20 6c 4f 70 74 2e 61 70 70 65 6e 64 28 73 4c    lOpt.append(sL
63c0: 69 6e 65 29 0a 20 20 20 20 20 20 20 20 65 6c 69  ine).        eli
63d0: 66 20 72 65 2e 6d 61 74 63 68 28 22 5b 20 c2 a0  f re.match("[ ..
63e0: 5c 74 5d 2a 24 22 2c 20 73 4c 69 6e 65 29 3a 0a  \t]*$", sLine):.
63f0: 20 20 20 20 20 20 20 20 20 20 20 20 70 61 73 73              pass
6400: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c  .        elif sL
6410: 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ine.startswith("
6420: 21 21 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  !!"):.          
6430: 20 20 6d 20 3d 20 7a 42 6f 6f 6b 6d 61 72 6b 2e    m = zBookmark.
6440: 73 65 61 72 63 68 28 73 4c 69 6e 65 29 0a 20 20  search(sLine).  
6450: 20 20 20 20 20 20 20 20 20 20 6e 45 78 4d 6b 20            nExMk 
6460: 3d 20 6c 65 6e 28 6d 2e 67 72 6f 75 70 28 30 29  = len(m.group(0)
6470: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  ).            if
6480: 20 73 4c 69 6e 65 5b 6e 45 78 4d 6b 3a 5d 2e 73   sLine[nExMk:].s
6490: 74 72 69 70 28 29 3a 0a 20 20 20 20 20 20 20 20  trip():.        
64a0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 42 6f 6f          printBoo
64b0: 6b 6d 61 72 6b 28 6e 45 78 4d 6b 2d 32 2c 20 73  kmark(nExMk-2, s
64c0: 4c 69 6e 65 5b 6e 45 78 4d 6b 3a 5d 2e 73 74 72  Line[nExMk:].str
64d0: 69 70 28 29 2c 20 69 29 0a 20 20 20 20 20 20 20  ip(), i).       
64e0: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
64f0: 74 73 77 69 74 68 28 28 22 20 20 20 20 22 2c 20  tswith(("    ", 
6500: 22 5c 74 22 29 29 3a 0a 20 20 20 20 20 20 20 20  "\t")):.        
6510: 20 20 20 20 6c 52 75 6c 65 4c 69 6e 65 5b 6c 65      lRuleLine[le
6520: 6e 28 6c 52 75 6c 65 4c 69 6e 65 29 2d 31 5d 5b  n(lRuleLine)-1][
6530: 31 5d 20 2b 3d 20 22 20 22 20 2b 20 73 4c 69 6e  1] += " " + sLin
6540: 65 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20 20  e.strip().      
6550: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
6560: 20 20 20 20 6c 52 75 6c 65 4c 69 6e 65 2e 61 70      lRuleLine.ap
6570: 70 65 6e 64 28 5b 69 2c 20 73 4c 69 6e 65 2e 73  pend([i, sLine.s
6580: 74 72 69 70 28 29 5d 29 0a 0a 20 20 20 20 23 20  trip()])..    # 
6590: 67 65 6e 65 72 61 74 69 6e 67 20 6f 70 74 69 6f  generating optio
65a0: 6e 73 20 66 69 6c 65 73 0a 20 20 20 20 70 72 69  ns files.    pri
65b0: 6e 74 28 22 20 20 70 61 72 73 69 6e 67 20 6f 70  nt("  parsing op
65c0: 74 69 6f 6e 73 2e 2e 2e 22 29 0a 20 20 20 20 74  tions...").    t
65d0: 72 79 3a 0a 20 20 20 20 20 20 20 20 64 4f 70 74  ry:.        dOpt
65e0: 69 6f 6e 73 2c 20 64 4f 70 74 50 72 69 6f 72 69  ions, dOptPriori
65f0: 74 79 20 3d 20 70 72 65 70 61 72 65 4f 70 74 69  ty = prepareOpti
6600: 6f 6e 73 28 6c 4f 70 74 29 0a 20 20 20 20 65 78  ons(lOpt).    ex
6610: 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20 74 72  cept:.        tr
6620: 61 63 65 62 61 63 6b 2e 70 72 69 6e 74 5f 65 78  aceback.print_ex
6630: 63 28 29 0a 20 20 20 20 20 20 20 20 65 78 69 74  c().        exit
6640: 28 29 0a 0a 20 20 20 20 23 20 74 65 73 74 73 0a  ()..    # tests.
6650: 20 20 20 20 70 72 69 6e 74 28 22 20 20 6c 69 73      print("  lis
6660: 74 20 74 65 73 74 73 2e 2e 2e 22 29 0a 20 20 20  t tests...").   
6670: 20 73 47 43 54 65 73 74 73 20 3d 20 22 5c 6e 22   sGCTests = "\n"
6680: 2e 6a 6f 69 6e 28 6c 54 65 73 74 29 0a 20 20 20  .join(lTest).   
6690: 20 73 47 43 54 65 73 74 73 4a 53 20 3d 20 27 7b   sGCTestsJS = '{
66a0: 20 22 61 44 61 74 61 22 3a 20 27 20 2b 20 6a 73   "aData": ' + js
66b0: 6f 6e 2e 64 75 6d 70 73 28 6c 54 65 73 74 2c 20  on.dumps(lTest, 
66c0: 65 6e 73 75 72 65 5f 61 73 63 69 69 3d 46 61 6c  ensure_ascii=Fal
66d0: 73 65 29 20 2b 20 22 20 7d 5c 6e 22 0a 0a 20 20  se) + " }\n"..  
66e0: 20 20 23 20 70 72 6f 63 65 73 73 69 6e 67 0a 20    # processing. 
66f0: 20 20 20 70 72 69 6e 74 28 22 20 20 70 72 65 70     print("  prep
6700: 61 72 69 6e 67 20 72 75 6c 65 73 2e 2e 2e 22 29  aring rules...")
6710: 0a 20 20 20 20 62 50 61 72 61 67 72 61 70 68 20  .    bParagraph 
6720: 3d 20 54 72 75 65 0a 20 20 20 20 6c 50 61 72 61  = True.    lPara
6730: 67 72 61 70 68 52 75 6c 65 73 20 3d 20 5b 5d 0a  graphRules = [].
6740: 20 20 20 20 6c 53 65 6e 74 65 6e 63 65 52 75 6c      lSentenceRul
6750: 65 73 20 3d 20 5b 5d 0a 20 20 20 20 6c 50 61 72  es = [].    lPar
6760: 61 67 72 61 70 68 52 75 6c 65 73 4a 53 20 3d 20  agraphRulesJS = 
6770: 5b 5d 0a 20 20 20 20 6c 53 65 6e 74 65 6e 63 65  [].    lSentence
6780: 52 75 6c 65 73 4a 53 20 3d 20 5b 5d 0a 0a 20 20  RulesJS = []..  
6790: 20 20 66 6f 72 20 6e 4c 69 6e 65 2c 20 73 4c 69    for nLine, sLi
67a0: 6e 65 20 69 6e 20 6c 52 75 6c 65 4c 69 6e 65 3a  ne in lRuleLine:
67b0: 0a 20 20 20 20 20 20 20 20 69 66 20 73 4c 69 6e  .        if sLin
67c0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  e:.            i
67d0: 66 20 73 4c 69 6e 65 20 3d 3d 20 22 5b 2b 2b 5d  f sLine == "[++]
67e0: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ":.             
67f0: 20 20 20 62 50 61 72 61 67 72 61 70 68 20 3d 20     bParagraph = 
6800: 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20 20 20  False.          
6810: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
6820: 20 20 20 20 20 20 20 20 61 52 75 6c 65 20 3d 20          aRule = 
6830: 63 72 65 61 74 65 52 75 6c 65 28 73 4c 69 6e 65  createRule(sLine
6840: 2c 20 6e 4c 69 6e 65 2c 20 73 4c 61 6e 67 2c 20  , nLine, sLang, 
6850: 62 50 61 72 61 67 72 61 70 68 2c 20 64 4f 70 74  bParagraph, dOpt
6860: 50 72 69 6f 72 69 74 79 29 0a 20 20 20 20 20 20  Priority).      
6870: 20 20 20 20 20 20 20 20 20 20 69 66 20 61 52 75            if aRu
6880: 6c 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  le:.            
6890: 20 20 20 20 20 20 20 20 69 66 20 62 50 61 72 61          if bPara
68a0: 67 72 61 70 68 3a 0a 20 20 20 20 20 20 20 20 20  graph:.         
68b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
68c0: 50 61 72 61 67 72 61 70 68 52 75 6c 65 73 2e 61  ParagraphRules.a
68d0: 70 70 65 6e 64 28 61 52 75 6c 65 29 0a 20 20 20  ppend(aRule).   
68e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
68f0: 20 20 20 20 20 6c 50 61 72 61 67 72 61 70 68 52       lParagraphR
6900: 75 6c 65 73 4a 53 2e 61 70 70 65 6e 64 28 70 79  ulesJS.append(py
6910: 52 75 6c 65 54 6f 4a 53 28 61 52 75 6c 65 29 29  RuleToJS(aRule))
6920: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6930: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
6940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6950: 20 20 20 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65     lSentenceRule
6960: 73 2e 61 70 70 65 6e 64 28 61 52 75 6c 65 29 0a  s.append(aRule).
6970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6980: 20 20 20 20 20 20 20 20 6c 53 65 6e 74 65 6e 63          lSentenc
6990: 65 52 75 6c 65 73 4a 53 2e 61 70 70 65 6e 64 28  eRulesJS.append(
69a0: 70 79 52 75 6c 65 54 6f 4a 53 28 61 52 75 6c 65  pyRuleToJS(aRule
69b0: 29 29 0a 0a 20 20 20 20 23 20 63 72 65 61 74 69  ))..    # creati
69c0: 6e 67 20 66 69 6c 65 20 77 69 74 68 20 61 6c 6c  ng file with all
69d0: 20 66 75 6e 63 74 69 6f 6e 73 20 63 61 6c 6c 61   functions calla
69e0: 62 6c 65 20 62 79 20 72 75 6c 65 73 0a 20 20 20  ble by rules.   
69f0: 20 70 72 69 6e 74 28 22 20 20 63 72 65 61 74 69   print("  creati
6a00: 6e 67 20 63 61 6c 6c 61 62 6c 65 73 2e 2e 2e 22  ng callables..."
6a10: 29 0a 20 20 20 20 73 50 79 43 61 6c 6c 61 62 6c  ).    sPyCallabl
6a20: 65 73 20 3d 20 22 23 20 67 65 6e 65 72 61 74 65  es = "# generate
6a30: 64 20 63 6f 64 65 2c 20 64 6f 20 6e 6f 74 20 65  d code, do not e
6a40: 64 69 74 5c 6e 22 0a 20 20 20 20 73 4a 53 43 61  dit\n".    sJSCa
6a50: 6c 6c 61 62 6c 65 73 20 3d 20 22 2f 2f 20 67 65  llables = "// ge
6a60: 6e 65 72 61 74 65 64 20 63 6f 64 65 2c 20 64 6f  nerated code, do
6a70: 20 6e 6f 74 20 65 64 69 74 5c 6e 63 6f 6e 73 74   not edit\nconst
6a80: 20 6f 45 76 61 6c 46 75 6e 63 20 3d 20 7b 5c 6e   oEvalFunc = {\n
6a90: 22 0a 20 20 20 20 66 6f 72 20 73 46 75 6e 63 4e  ".    for sFuncN
6aa0: 61 6d 65 2c 20 73 52 65 74 75 72 6e 20 69 6e 20  ame, sReturn in 
6ab0: 6c 46 55 4e 43 54 49 4f 4e 53 3a 0a 20 20 20 20  lFUNCTIONS:.    
6ac0: 20 20 20 20 63 54 79 70 65 20 3d 20 73 46 75 6e      cType = sFun
6ad0: 63 4e 61 6d 65 5b 30 3a 31 5d 0a 20 20 20 20 20  cName[0:1].     
6ae0: 20 20 20 69 66 20 63 54 79 70 65 20 3d 3d 20 22     if cType == "
6af0: 63 22 3a 20 23 20 63 6f 6e 64 69 74 69 6f 6e 0a  c": # condition.
6b00: 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61 72              sPar
6b10: 61 6d 73 20 3d 20 22 73 2c 20 73 78 2c 20 6d 2c  ams = "s, sx, m,
6b20: 20 64 44 41 2c 20 73 43 6f 75 6e 74 72 79 2c 20   dDA, sCountry, 
6b30: 62 43 6f 6e 64 4d 65 6d 6f 22 0a 20 20 20 20 20  bCondMemo".     
6b40: 20 20 20 65 6c 69 66 20 63 54 79 70 65 20 3d 3d     elif cType ==
6b50: 20 22 6d 22 3a 20 23 20 6d 65 73 73 61 67 65 0a   "m": # message.
6b60: 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61 72              sPar
6b70: 61 6d 73 20 3d 20 22 73 2c 20 6d 22 0a 20 20 20  ams = "s, m".   
6b80: 20 20 20 20 20 65 6c 69 66 20 63 54 79 70 65 20       elif cType 
6b90: 3d 3d 20 22 73 22 3a 20 23 20 73 75 67 67 65 73  == "s": # sugges
6ba0: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20  tion.           
6bb0: 20 73 50 61 72 61 6d 73 20 3d 20 22 73 2c 20 6d   sParams = "s, m
6bc0: 22 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 63  ".        elif c
6bd0: 54 79 70 65 20 3d 3d 20 22 70 22 3a 20 23 20 70  Type == "p": # p
6be0: 72 65 70 72 6f 63 65 73 73 6f 72 0a 20 20 20 20  reprocessor.    
6bf0: 20 20 20 20 20 20 20 20 73 50 61 72 61 6d 73 20          sParams 
6c00: 3d 20 22 73 2c 20 6d 22 0a 20 20 20 20 20 20 20  = "s, m".       
6c10: 20 65 6c 69 66 20 63 54 79 70 65 20 3d 3d 20 22   elif cType == "
6c20: 64 22 3a 20 23 20 64 69 73 61 6d 62 69 67 75 61  d": # disambigua
6c30: 74 6f 72 0a 20 20 20 20 20 20 20 20 20 20 20 20  tor.            
6c40: 73 50 61 72 61 6d 73 20 3d 20 22 73 2c 20 6d 2c  sParams = "s, m,
6c50: 20 64 44 41 22 0a 20 20 20 20 20 20 20 20 65 6c   dDA".        el
6c60: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
6c70: 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e 6f 77 6e  print("# Unknown
6c80: 20 66 75 6e 63 74 69 6f 6e 20 74 79 70 65 20 69   function type i
6c90: 6e 20 5b 22 20 2b 20 73 46 75 6e 63 4e 61 6d 65  n [" + sFuncName
6ca0: 20 2b 20 22 5d 22 29 0a 20 20 20 20 20 20 20 20   + "]").        
6cb0: 20 20 20 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20      continue.   
6cc0: 20 20 20 20 20 73 50 79 43 61 6c 6c 61 62 6c 65       sPyCallable
6cd0: 73 20 2b 3d 20 22 64 65 66 20 7b 7d 20 28 7b 7d  s += "def {} ({}
6ce0: 29 3a 5c 6e 22 2e 66 6f 72 6d 61 74 28 73 46 75  ):\n".format(sFu
6cf0: 6e 63 4e 61 6d 65 2c 20 73 50 61 72 61 6d 73 29  ncName, sParams)
6d00: 0a 20 20 20 20 20 20 20 20 73 50 79 43 61 6c 6c  .        sPyCall
6d10: 61 62 6c 65 73 20 2b 3d 20 22 20 20 20 20 72 65  ables += "    re
6d20: 74 75 72 6e 20 22 20 2b 20 73 52 65 74 75 72 6e  turn " + sReturn
6d30: 20 2b 20 22 5c 6e 22 0a 20 20 20 20 20 20 20 20   + "\n".        
6d40: 73 4a 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20  sJSCallables += 
6d50: 22 20 20 20 20 7b 7d 3a 20 66 75 6e 63 74 69 6f  "    {}: functio
6d60: 6e 20 28 7b 7d 29 22 2e 66 6f 72 6d 61 74 28 73  n ({})".format(s
6d70: 46 75 6e 63 4e 61 6d 65 2c 20 73 50 61 72 61 6d  FuncName, sParam
6d80: 73 29 20 2b 20 22 20 7b 5c 6e 22 0a 20 20 20 20  s) + " {\n".    
6d90: 20 20 20 20 73 4a 53 43 61 6c 6c 61 62 6c 65 73      sJSCallables
6da0: 20 2b 3d 20 22 20 20 20 20 20 20 20 20 72 65 74   += "        ret
6db0: 75 72 6e 20 22 20 2b 20 70 79 32 6a 73 28 73 52  urn " + py2js(sR
6dc0: 65 74 75 72 6e 29 20 2b 20 22 3b 5c 6e 22 0a 20  eturn) + ";\n". 
6dd0: 20 20 20 20 20 20 20 73 4a 53 43 61 6c 6c 61 62         sJSCallab
6de0: 6c 65 73 20 2b 3d 20 22 20 20 20 20 7d 2c 5c 6e  les += "    },\n
6df0: 22 0a 20 20 20 20 73 4a 53 43 61 6c 6c 61 62 6c  ".    sJSCallabl
6e00: 65 73 20 2b 3d 20 22 7d 5c 6e 22 0a 0a 20 20 20  es += "}\n"..   
6e10: 20 64 69 73 70 6c 61 79 53 74 61 74 73 28 6c 50   displayStats(lP
6e20: 61 72 61 67 72 61 70 68 52 75 6c 65 73 2c 20 6c  aragraphRules, l
6e30: 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 29 0a 0a  SentenceRules)..
6e40: 20 20 20 20 70 72 69 6e 74 28 22 55 6e 6e 61 6d      print("Unnam
6e50: 65 64 20 72 75 6c 65 73 3a 20 22 20 2b 20 73 74  ed rules: " + st
6e60: 72 28 6e 52 55 4c 45 57 49 54 48 4f 55 54 4e 41  r(nRULEWITHOUTNA
6e70: 4d 45 29 29 0a 0a 20 20 20 20 64 20 3d 20 7b 20  ME))..    d = { 
6e80: 22 63 61 6c 6c 61 62 6c 65 73 22 3a 20 73 50 79  "callables": sPy
6e90: 43 61 6c 6c 61 62 6c 65 73 2c 0a 20 20 20 20 20  Callables,.     
6ea0: 20 20 20 20 20 22 63 61 6c 6c 61 62 6c 65 73 4a       "callablesJ
6eb0: 53 22 3a 20 73 4a 53 43 61 6c 6c 61 62 6c 65 73  S": sJSCallables
6ec0: 2c 0a 20 20 20 20 20 20 20 20 20 20 22 67 63 74  ,.          "gct
6ed0: 65 73 74 73 22 3a 20 73 47 43 54 65 73 74 73 2c  ests": sGCTests,
6ee0: 0a 20 20 20 20 20 20 20 20 20 20 22 67 63 74 65  .          "gcte
6ef0: 73 74 73 4a 53 22 3a 20 73 47 43 54 65 73 74 73  stsJS": sGCTests
6f00: 4a 53 2c 0a 20 20 20 20 20 20 20 20 20 20 22 70  JS,.          "p
6f10: 61 72 61 67 72 61 70 68 5f 72 75 6c 65 73 22 3a  aragraph_rules":
6f20: 20 6d 65 72 67 65 52 75 6c 65 73 42 79 4f 70 74   mergeRulesByOpt
6f30: 69 6f 6e 28 6c 50 61 72 61 67 72 61 70 68 52 75  ion(lParagraphRu
6f40: 6c 65 73 29 2c 0a 20 20 20 20 20 20 20 20 20 20  les),.          
6f50: 22 73 65 6e 74 65 6e 63 65 5f 72 75 6c 65 73 22  "sentence_rules"
6f60: 3a 20 6d 65 72 67 65 52 75 6c 65 73 42 79 4f 70  : mergeRulesByOp
6f70: 74 69 6f 6e 28 6c 53 65 6e 74 65 6e 63 65 52 75  tion(lSentenceRu
6f80: 6c 65 73 29 2c 0a 20 20 20 20 20 20 20 20 20 20  les),.          
6f90: 22 70 61 72 61 67 72 61 70 68 5f 72 75 6c 65 73  "paragraph_rules
6fa0: 5f 4a 53 22 3a 20 77 72 69 74 65 52 75 6c 65 73  _JS": writeRules
6fb0: 54 6f 4a 53 41 72 72 61 79 28 6d 65 72 67 65 52  ToJSArray(mergeR
6fc0: 75 6c 65 73 42 79 4f 70 74 69 6f 6e 28 6c 50 61  ulesByOption(lPa
6fd0: 72 61 67 72 61 70 68 52 75 6c 65 73 4a 53 29 29  ragraphRulesJS))
6fe0: 2c 0a 20 20 20 20 20 20 20 20 20 20 22 73 65 6e  ,.          "sen
6ff0: 74 65 6e 63 65 5f 72 75 6c 65 73 5f 4a 53 22 3a  tence_rules_JS":
7000: 20 77 72 69 74 65 52 75 6c 65 73 54 6f 4a 53 41   writeRulesToJSA
7010: 72 72 61 79 28 6d 65 72 67 65 52 75 6c 65 73 42  rray(mergeRulesB
7020: 79 4f 70 74 69 6f 6e 28 6c 53 65 6e 74 65 6e 63  yOption(lSentenc
7030: 65 52 75 6c 65 73 4a 53 29 29 20 7d 0a 20 20 20  eRulesJS)) }.   
7040: 20 64 2e 75 70 64 61 74 65 28 64 4f 70 74 69 6f   d.update(dOptio
7050: 6e 73 29 0a 0a 20 20 20 20 72 65 74 75 72 6e 20  ns)..    return 
7060: 64 0a                                            d.