Grammalecte  Hex Artifact Content

Artifact 856372255beeaca2b2eb1073ad47171af8f5ba68b295780f9e7303133b501d98:


0000: 0a 69 6d 70 6f 72 74 20 72 65 0a 69 6d 70 6f 72  .import re.impor
0010: 74 20 74 72 61 63 65 62 61 63 6b 0a 69 6d 70 6f  t traceback.impo
0020: 72 74 20 6a 73 6f 6e 0a 0a 69 6d 70 6f 72 74 20  rt json..import 
0030: 63 6f 6d 70 69 6c 65 5f 72 75 6c 65 73 5f 6a 73  compile_rules_js
0040: 5f 63 6f 6e 76 65 72 74 20 61 73 20 6a 73 63 6f  _convert as jsco
0050: 6e 76 0a 69 6d 70 6f 72 74 20 63 6f 6d 70 69 6c  nv.import compil
0060: 65 5f 72 75 6c 65 73 5f 67 72 61 70 68 20 61 73  e_rules_graph as
0070: 20 63 72 67 0a 0a 0a 64 44 45 46 20 3d 20 7b 7d   crg...dDEF = {}
0080: 0a 6c 46 55 4e 43 54 49 4f 4e 53 20 3d 20 5b 5d  .lFUNCTIONS = []
0090: 0a 0a 61 52 55 4c 45 53 45 54 20 3d 20 73 65 74  ..aRULESET = set
00a0: 28 29 20 20 20 20 20 23 20 73 65 74 20 6f 66 20  ()     # set of 
00b0: 72 75 6c 65 2d 69 64 73 20 74 6f 20 63 68 65 63  rule-ids to chec
00c0: 6b 20 69 66 20 74 68 65 72 65 20 69 73 20 73 65  k if there is se
00d0: 76 65 72 61 6c 20 72 75 6c 65 73 20 77 69 74 68  veral rules with
00e0: 20 74 68 65 20 73 61 6d 65 20 69 64 0a 6e 52 55   the same id.nRU
00f0: 4c 45 57 49 54 48 4f 55 54 4e 41 4d 45 20 3d 20  LEWITHOUTNAME = 
0100: 30 0a 0a 64 4a 53 52 45 47 45 58 45 53 20 3d 20  0..dJSREGEXES = 
0110: 7b 7d 0a 0a 73 57 4f 52 44 4c 49 4d 49 54 4c 45  {}..sWORDLIMITLE
0120: 46 54 20 20 3d 20 72 22 28 3f 3c 21 5b 5c 77 2e  FT  = r"(?<![\w.
0130: 2c e2 80 93 2d 5d 29 22 20 20 20 23 20 72 22 28  ,...-])"   # r"(
0140: 3f 3c 21 5b 2d 2e 2c e2 80 94 5d 29 5c 62 22 20  ?<![-.,...])\b" 
0150: 20 73 65 65 6d 73 20 73 6c 6f 77 65 72 0a 73 57   seems slower.sW
0160: 4f 52 44 4c 49 4d 49 54 52 49 47 48 54 20 3d 20  ORDLIMITRIGHT = 
0170: 72 22 28 3f 21 5b 5c 77 e2 80 93 2d 5d 29 22 20  r"(?![\w...-])" 
0180: 20 20 20 20 20 23 20 72 22 5c 62 28 3f 21 2d e2       # r"\b(?!-.
0190: 80 94 29 22 20 20 20 20 20 20 20 73 65 65 6d 73  ..)"       seems
01a0: 20 73 6c 6f 77 65 72 0a 0a 0a 64 65 66 20 70 72   slower...def pr
01b0: 65 70 61 72 65 46 75 6e 63 74 69 6f 6e 20 28 73  epareFunction (s
01c0: 29 3a 0a 20 20 20 20 73 20 3d 20 73 2e 72 65 70  ):.    s = s.rep
01d0: 6c 61 63 65 28 22 5f 5f 61 6c 73 6f 5f 5f 22 2c  lace("__also__",
01e0: 20 22 62 43 6f 6e 64 4d 65 6d 6f 22 29 0a 20 20   "bCondMemo").  
01f0: 20 20 73 20 3d 20 73 2e 72 65 70 6c 61 63 65 28    s = s.replace(
0200: 22 5f 5f 65 6c 73 65 5f 5f 22 2c 20 22 6e 6f 74  "__else__", "not
0210: 20 62 43 6f 6e 64 4d 65 6d 6f 22 29 0a 20 20 20   bCondMemo").   
0220: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73   s = re.sub(r"is
0230: 53 74 61 72 74 20 2a 5c 28 5c 29 22 2c 20 27 62  Start *\(\)", 'b
0240: 65 66 6f 72 65 28 22 5e 20 2a 24 7c 2c 20 2a 24  efore("^ *$|, *$
0250: 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  ")', s).    s = 
0260: 72 65 2e 73 75 62 28 72 22 69 73 52 65 61 6c 53  re.sub(r"isRealS
0270: 74 61 72 74 20 2a 5c 28 5c 29 22 2c 20 27 62 65  tart *\(\)", 'be
0280: 66 6f 72 65 28 22 5e 20 2a 24 22 29 27 2c 20 73  fore("^ *$")', s
0290: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
02a0: 28 72 22 69 73 53 74 61 72 74 30 20 2a 5c 28 5c  (r"isStart0 *\(\
02b0: 29 22 2c 20 27 62 65 66 6f 72 65 30 28 22 5e 20  )", 'before0("^ 
02c0: 2a 24 7c 2c 20 2a 24 22 29 27 2c 20 73 29 0a 20  *$|, *$")', s). 
02d0: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
02e0: 69 73 52 65 61 6c 53 74 61 72 74 30 20 2a 5c 28  isRealStart0 *\(
02f0: 5c 29 22 2c 20 27 62 65 66 6f 72 65 30 28 22 5e  \)", 'before0("^
0300: 20 2a 24 22 29 27 2c 20 73 29 0a 20 20 20 20 73   *$")', s).    s
0310: 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73 45 6e   = re.sub(r"isEn
0320: 64 20 2a 5c 28 5c 29 22 2c 20 27 61 66 74 65 72  d *\(\)", 'after
0330: 28 22 5e 20 2a 24 7c 5e 2c 22 29 27 2c 20 73 29  ("^ *$|^,")', s)
0340: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
0350: 72 22 69 73 52 65 61 6c 45 6e 64 20 2a 5c 28 5c  r"isRealEnd *\(\
0360: 29 22 2c 20 27 61 66 74 65 72 28 22 5e 20 2a 24  )", 'after("^ *$
0370: 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  ")', s).    s = 
0380: 72 65 2e 73 75 62 28 72 22 69 73 45 6e 64 30 20  re.sub(r"isEnd0 
0390: 2a 5c 28 5c 29 22 2c 20 27 61 66 74 65 72 30 28  *\(\)", 'after0(
03a0: 22 5e 20 2a 24 7c 5e 2c 22 29 27 2c 20 73 29 0a  "^ *$|^,")', s).
03b0: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
03c0: 22 69 73 52 65 61 6c 45 6e 64 30 20 2a 5c 28 5c  "isRealEnd0 *\(\
03d0: 29 22 2c 20 27 61 66 74 65 72 30 28 22 5e 20 2a  )", 'after0("^ *
03e0: 24 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d  $")', s).    s =
03f0: 20 72 65 2e 73 75 62 28 72 22 28 73 65 6c 65 63   re.sub(r"(selec
0400: 74 7c 65 78 63 6c 75 64 65 29 5b 28 5d 5b 5c 5c  t|exclude)[(][\\
0410: 5d 28 5c 64 2b 29 22 2c 20 27 5c 5c 31 28 64 44  ](\d+)", '\\1(dD
0420: 41 2c 20 6d 2e 73 74 61 72 74 28 5c 5c 32 29 2c  A, m.start(\\2),
0430: 20 6d 2e 67 72 6f 75 70 28 5c 5c 32 29 27 2c 20   m.group(\\2)', 
0440: 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75  s).    s = re.su
0450: 62 28 72 22 64 65 66 69 6e 65 5b 28 5d 5b 5c 5c  b(r"define[(][\\
0460: 5d 28 5c 64 2b 29 22 2c 20 27 64 65 66 69 6e 65  ](\d+)", 'define
0470: 28 64 44 41 2c 20 6d 2e 73 74 61 72 74 28 5c 5c  (dDA, m.start(\\
0480: 31 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  1)', s).    s = 
0490: 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70 68 7c  re.sub(r"(morph|
04a0: 6d 6f 72 70 68 65 78 7c 64 69 73 70 6c 61 79 49  morphex|displayI
04b0: 6e 66 6f 29 5b 28 5d 5b 5c 5c 5d 28 5c 64 2b 29  nfo)[(][\\](\d+)
04c0: 22 2c 20 27 5c 5c 31 28 28 6d 2e 73 74 61 72 74  ", '\\1((m.start
04d0: 28 5c 5c 32 29 2c 20 6d 2e 67 72 6f 75 70 28 5c  (\\2), m.group(\
04e0: 5c 32 29 29 27 2c 20 73 29 0a 20 20 20 20 73 20  \2))', s).    s 
04f0: 3d 20 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70  = re.sub(r"(morp
0500: 68 7c 6d 6f 72 70 68 65 78 7c 64 69 73 70 6c 61  h|morphex|displa
0510: 79 49 6e 66 6f 29 5b 28 5d 22 2c 20 27 5c 5c 31  yInfo)[(]", '\\1
0520: 28 64 44 41 2c 20 27 2c 20 73 29 0a 20 20 20 20  (dDA, ', s).    
0530: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 28 73 75  s = re.sub(r"(su
0540: 67 67 5c 77 2b 7c 73 77 69 74 63 68 5c 77 2b 29  gg\w+|switch\w+)
0550: 5c 28 40 22 2c 20 27 5c 5c 31 28 6d 2e 67 72 6f  \(@", '\\1(m.gro
0560: 75 70 28 69 5b 34 5d 29 27 2c 20 73 29 0a 20 20  up(i[4])', s).  
0570: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 77    s = re.sub(r"w
0580: 6f 72 64 5c 28 5c 73 2a 31 5c 62 22 2c 20 27 6e  ord\(\s*1\b", 'n
0590: 65 78 74 77 6f 72 64 31 28 73 2c 20 6d 2e 65 6e  extword1(s, m.en
05a0: 64 28 29 27 2c 20 73 29 20 20 20 20 20 20 20 20  d()', s)        
05b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05c0: 20 20 20 20 20 20 20 20 20 20 23 20 77 6f 72 64            # word
05d0: 28 31 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73  (1).    s = re.s
05e0: 75 62 28 72 22 77 6f 72 64 5c 28 5c 73 2a 2d 31  ub(r"word\(\s*-1
05f0: 5c 62 22 2c 20 27 70 72 65 76 77 6f 72 64 31 28  \b", 'prevword1(
0600: 73 2c 20 6d 2e 73 74 61 72 74 28 29 27 2c 20 73  s, m.start()', s
0610: 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  )               
0620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0630: 23 20 77 6f 72 64 28 2d 31 29 0a 20 20 20 20 73  # word(-1).    s
0640: 20 3d 20 72 65 2e 73 75 62 28 72 22 77 6f 72 64   = re.sub(r"word
0650: 5c 28 5c 73 2a 28 5c 64 29 22 2c 20 27 6e 65 78  \(\s*(\d)", 'nex
0660: 74 77 6f 72 64 28 73 2c 20 6d 2e 65 6e 64 28 29  tword(s, m.end()
0670: 2c 20 5c 5c 31 27 2c 20 73 29 20 20 20 20 20 20  , \\1', s)      
0680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0690: 20 20 20 20 20 20 20 23 20 77 6f 72 64 28 6e 29         # word(n)
06a0: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
06b0: 72 22 77 6f 72 64 5c 28 5c 73 2a 2d 28 5c 64 29  r"word\(\s*-(\d)
06c0: 22 2c 20 27 70 72 65 76 77 6f 72 64 28 73 2c 20  ", 'prevword(s, 
06d0: 6d 2e 73 74 61 72 74 28 29 2c 20 5c 5c 31 27 2c  m.start(), \\1',
06e0: 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20   s)             
06f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 77               # w
0700: 6f 72 64 28 2d 6e 29 0a 20 20 20 20 73 20 3d 20  ord(-n).    s = 
0710: 72 65 2e 73 75 62 28 72 22 62 65 66 6f 72 65 5c  re.sub(r"before\
0720: 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 5b 3a  (\s*", 'look(s[:
0730: 6d 2e 73 74 61 72 74 28 29 5d 2c 20 27 2c 20 73  m.start()], ', s
0740: 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  )               
0750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0760: 20 20 20 20 23 20 62 65 66 6f 72 65 28 73 29 0a      # before(s).
0770: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
0780: 22 61 66 74 65 72 5c 28 5c 73 2a 22 2c 20 27 6c  "after\(\s*", 'l
0790: 6f 6f 6b 28 73 5b 6d 2e 65 6e 64 28 29 3a 5d 2c  ook(s[m.end():],
07a0: 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20   ', s)          
07b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07c0: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61 66              # af
07d0: 74 65 72 28 73 29 0a 20 20 20 20 73 20 3d 20 72  ter(s).    s = r
07e0: 65 2e 73 75 62 28 72 22 74 65 78 74 61 72 65 61  e.sub(r"textarea
07f0: 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 2c  \(\s*", 'look(s,
0800: 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20   ', s)          
0810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0830: 20 20 20 23 20 74 65 78 74 61 72 65 61 28 73 29     # textarea(s)
0840: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
0850: 72 22 62 65 66 6f 72 65 5f 63 68 6b 31 5c 28 5c  r"before_chk1\(\
0860: 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63 68 6b 31 28  s*", 'look_chk1(
0870: 64 44 41 2c 20 73 5b 3a 6d 2e 73 74 61 72 74 28  dDA, s[:m.start(
0880: 29 5d 2c 20 30 2c 20 27 2c 20 73 29 20 20 20 20  )], 0, ', s)    
0890: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 62               # b
08a0: 65 66 6f 72 65 5f 63 68 6b 31 28 73 29 0a 20 20  efore_chk1(s).  
08b0: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 61    s = re.sub(r"a
08c0: 66 74 65 72 5f 63 68 6b 31 5c 28 5c 73 2a 22 2c  fter_chk1\(\s*",
08d0: 20 27 6c 6f 6f 6b 5f 63 68 6b 31 28 64 44 41 2c   'look_chk1(dDA,
08e0: 20 73 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20 6d 2e   s[m.end():], m.
08f0: 65 6e 64 28 29 2c 20 27 2c 20 73 29 20 20 20 20  end(), ', s)    
0900: 20 20 20 20 20 20 20 20 20 20 23 20 61 66 74 65            # afte
0910: 72 5f 63 68 6b 31 28 73 29 0a 20 20 20 20 73 20  r_chk1(s).    s 
0920: 3d 20 72 65 2e 73 75 62 28 72 22 74 65 78 74 61  = re.sub(r"texta
0930: 72 65 61 5f 63 68 6b 31 5c 28 5c 73 2a 22 2c 20  rea_chk1\(\s*", 
0940: 27 6c 6f 6f 6b 5f 63 68 6b 31 28 64 44 41 2c 20  'look_chk1(dDA, 
0950: 73 2c 20 30 2c 20 27 2c 20 73 29 20 20 20 20 20  s, 0, ', s)     
0960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0970: 20 20 20 20 20 20 23 20 74 65 78 74 61 72 65 61        # textarea
0980: 5f 63 68 6b 31 28 73 29 0a 20 20 20 20 73 20 3d  _chk1(s).    s =
0990: 20 72 65 2e 73 75 62 28 72 22 2f 30 22 2c 20 27   re.sub(r"/0", '
09a0: 73 78 5b 6d 2e 73 74 61 72 74 28 29 3a 6d 2e 65  sx[m.start():m.e
09b0: 6e 64 28 29 5d 27 2c 20 73 29 20 20 20 20 20 20  nd()]', s)      
09c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09e0: 20 20 20 20 20 23 20 2f 30 0a 20 20 20 20 73 20       # /0.    s 
09f0: 3d 20 72 65 2e 73 75 62 28 72 22 62 65 66 6f 72  = re.sub(r"befor
0a00: 65 30 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28  e0\(\s*", 'look(
0a10: 73 78 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2c 20  sx[:m.start()], 
0a20: 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20  ', s)           
0a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a40: 20 20 20 20 20 20 23 20 62 65 66 6f 72 65 30 28        # before0(
0a50: 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75  s).    s = re.su
0a60: 62 28 72 22 61 66 74 65 72 30 5c 28 5c 73 2a 22  b(r"after0\(\s*"
0a70: 2c 20 27 6c 6f 6f 6b 28 73 78 5b 6d 2e 65 6e 64  , 'look(sx[m.end
0a80: 28 29 3a 5d 2c 20 27 2c 20 73 29 20 20 20 20 20  ():], ', s)     
0a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
0ab0: 20 61 66 74 65 72 30 28 73 29 0a 20 20 20 20 73   after0(s).    s
0ac0: 20 3d 20 72 65 2e 73 75 62 28 72 22 74 65 78 74   = re.sub(r"text
0ad0: 61 72 65 61 30 5c 28 5c 73 2a 22 2c 20 27 6c 6f  area0\(\s*", 'lo
0ae0: 6f 6b 28 73 78 2c 20 27 2c 20 73 29 20 20 20 20  ok(sx, ', s)    
0af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b10: 20 20 20 20 20 20 20 23 20 74 65 78 74 61 72 65         # textare
0b20: 61 30 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65  a0(s).    s = re
0b30: 2e 73 75 62 28 72 22 62 65 66 6f 72 65 30 5f 63  .sub(r"before0_c
0b40: 68 6b 31 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b  hk1\(\s*", 'look
0b50: 5f 63 68 6b 31 28 64 44 41 2c 20 73 78 5b 3a 6d  _chk1(dDA, sx[:m
0b60: 2e 73 74 61 72 74 28 29 5d 2c 20 30 2c 20 27 2c  .start()], 0, ',
0b70: 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20   s)             
0b80: 20 20 23 20 62 65 66 6f 72 65 30 5f 63 68 6b 31    # before0_chk1
0b90: 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73  (s).    s = re.s
0ba0: 75 62 28 72 22 61 66 74 65 72 30 5f 63 68 6b 31  ub(r"after0_chk1
0bb0: 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63 68  \(\s*", 'look_ch
0bc0: 6b 31 28 64 44 41 2c 20 73 78 5b 6d 2e 65 6e 64  k1(dDA, sx[m.end
0bd0: 28 29 3a 5d 2c 20 6d 2e 65 6e 64 28 29 2c 20 27  ():], m.end(), '
0be0: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
0bf0: 23 20 61 66 74 65 72 30 5f 63 68 6b 31 28 73 29  # after0_chk1(s)
0c00: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
0c10: 72 22 74 65 78 74 61 72 65 61 30 5f 63 68 6b 31  r"textarea0_chk1
0c20: 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63 68  \(\s*", 'look_ch
0c30: 6b 31 28 64 44 41 2c 20 73 78 2c 20 30 2c 20 27  k1(dDA, sx, 0, '
0c40: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
0c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 74               # t
0c60: 65 78 74 61 72 65 61 30 5f 63 68 6b 31 28 73 29  extarea0_chk1(s)
0c70: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
0c80: 72 22 69 73 45 6e 64 4f 66 4e 47 5c 28 5c 73 2a  r"isEndOfNG\(\s*
0c90: 5c 29 22 2c 20 27 69 73 45 6e 64 4f 66 4e 47 28  \)", 'isEndOfNG(
0ca0: 64 44 41 2c 20 73 5b 6d 2e 65 6e 64 28 29 3a 5d  dDA, s[m.end():]
0cb0: 2c 20 6d 2e 65 6e 64 28 29 29 27 2c 20 73 29 20  , m.end())', s) 
0cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 69               # i
0cd0: 73 45 6e 64 4f 66 4e 47 28 73 29 0a 20 20 20 20  sEndOfNG(s).    
0ce0: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73 4e  s = re.sub(r"isN
0cf0: 65 78 74 4e 6f 74 43 4f 44 5c 28 5c 73 2a 5c 29  extNotCOD\(\s*\)
0d00: 22 2c 20 27 69 73 4e 65 78 74 4e 6f 74 43 4f 44  ", 'isNextNotCOD
0d10: 28 64 44 41 2c 20 73 5b 6d 2e 65 6e 64 28 29 3a  (dDA, s[m.end():
0d20: 5d 2c 20 6d 2e 65 6e 64 28 29 29 27 2c 20 73 29  ], m.end())', s)
0d30: 20 20 20 20 20 20 20 20 23 20 69 73 4e 65 78 74          # isNext
0d40: 4e 6f 74 43 4f 44 28 73 29 0a 20 20 20 20 73 20  NotCOD(s).    s 
0d50: 3d 20 72 65 2e 73 75 62 28 72 22 69 73 4e 65 78  = re.sub(r"isNex
0d60: 74 56 65 72 62 5c 28 5c 73 2a 5c 29 22 2c 20 27  tVerb\(\s*\)", '
0d70: 69 73 4e 65 78 74 56 65 72 62 28 64 44 41 2c 20  isNextVerb(dDA, 
0d80: 73 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20 6d 2e 65  s[m.end():], m.e
0d90: 6e 64 28 29 29 27 2c 20 73 29 20 20 20 20 20 20  nd())', s)      
0da0: 20 20 20 20 20 20 23 20 69 73 4e 65 78 74 56 65        # isNextVe
0db0: 72 62 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65  rb(s).    s = re
0dc0: 2e 73 75 62 28 72 22 5c 62 73 70 65 6c 6c 20 2a  .sub(r"\bspell *
0dd0: 5b 28 5d 22 2c 20 27 5f 6f 53 70 65 6c 6c 43 68  [(]", '_oSpellCh
0de0: 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 27 2c  ecker.isValid(',
0df0: 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73   s).    s = re.s
0e00: 75 62 28 72 22 5b 5c 5c 5d 28 5c 64 2b 29 22 2c  ub(r"[\\](\d+)",
0e10: 20 27 6d 2e 67 72 6f 75 70 28 5c 5c 31 29 27 2c   'm.group(\\1)',
0e20: 20 73 29 0a 20 20 20 20 72 65 74 75 72 6e 20 73   s).    return s
0e30: 0a 0a 0a 64 65 66 20 75 70 70 65 72 63 61 73 65  ...def uppercase
0e40: 20 28 73 2c 20 73 4c 61 6e 67 29 3a 0a 20 20 20   (s, sLang):.   
0e50: 20 22 28 66 6c 61 67 20 69 20 69 73 20 6e 6f 74   "(flag i is not
0e60: 20 65 6e 6f 75 67 68 29 3a 20 63 6f 6e 76 65 72   enough): conver
0e70: 74 73 20 72 65 67 65 78 20 74 6f 20 75 70 70 65  ts regex to uppe
0e80: 72 63 61 73 65 20 72 65 67 65 78 3a 20 27 66 6f  rcase regex: 'fo
0e90: 6f 27 20 62 65 63 6f 6d 65 73 20 27 5b 46 66 5d  o' becomes '[Ff]
0ea0: 5b 4f 6f 5d 5b 4f 6f 5d 27 2c 20 62 75 74 20 27  [Oo][Oo]', but '
0eb0: 42 61 72 27 20 62 65 63 6f 6d 65 73 20 27 42 5b  Bar' becomes 'B[
0ec0: 41 61 5d 5b 52 72 5d 27 2e 22 0a 20 20 20 20 73  Aa][Rr]'.".    s
0ed0: 55 70 20 3d 20 22 22 0a 20 20 20 20 6e 53 74 61  Up = "".    nSta
0ee0: 74 65 20 3d 20 30 0a 20 20 20 20 66 6f 72 20 69  te = 0.    for i
0ef0: 20 69 6e 20 72 61 6e 67 65 28 30 2c 20 6c 65 6e   in range(0, len
0f00: 28 73 29 29 3a 0a 20 20 20 20 20 20 20 20 63 20  (s)):.        c 
0f10: 3d 20 73 5b 69 5d 0a 20 20 20 20 20 20 20 20 69  = s[i].        i
0f20: 66 20 63 20 3d 3d 20 22 5b 22 3a 0a 20 20 20 20  f c == "[":.    
0f30: 20 20 20 20 20 20 20 20 6e 53 74 61 74 65 20 3d          nState =
0f40: 20 31 0a 20 20 20 20 20 20 20 20 69 66 20 6e 53   1.        if nS
0f50: 74 61 74 65 20 3d 3d 20 31 20 61 6e 64 20 63 20  tate == 1 and c 
0f60: 3d 3d 20 22 5d 22 3a 0a 20 20 20 20 20 20 20 20  == "]":.        
0f70: 20 20 20 20 6e 53 74 61 74 65 20 3d 20 30 0a 20      nState = 0. 
0f80: 20 20 20 20 20 20 20 69 66 20 63 20 3d 3d 20 22         if c == "
0f90: 3c 22 20 61 6e 64 20 69 20 3e 20 33 20 61 6e 64  <" and i > 3 and
0fa0: 20 73 5b 69 2d 33 3a 69 5d 20 3d 3d 20 22 28 3f   s[i-3:i] == "(?
0fb0: 50 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  P":.            
0fc0: 6e 53 74 61 74 65 20 3d 20 32 0a 20 20 20 20 20  nState = 2.     
0fd0: 20 20 20 69 66 20 6e 53 74 61 74 65 20 3d 3d 20     if nState == 
0fe0: 32 20 61 6e 64 20 63 20 3d 3d 20 22 3e 22 3a 0a  2 and c == ">":.
0ff0: 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61              nSta
1000: 74 65 20 3d 20 30 0a 20 20 20 20 20 20 20 20 69  te = 0.        i
1010: 66 20 63 20 3d 3d 20 22 3f 22 20 61 6e 64 20 69  f c == "?" and i
1020: 20 3e 20 30 20 61 6e 64 20 73 5b 69 2d 31 3a 69   > 0 and s[i-1:i
1030: 5d 20 3d 3d 20 22 28 22 20 61 6e 64 20 73 5b 69  ] == "(" and s[i
1040: 2b 31 3a 69 2b 32 5d 20 21 3d 20 22 3a 22 3a 0a  +1:i+2] != ":":.
1050: 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61              nSta
1060: 74 65 20 3d 20 35 0a 20 20 20 20 20 20 20 20 69  te = 5.        i
1070: 66 20 6e 53 74 61 74 65 20 3d 3d 20 35 20 61 6e  f nState == 5 an
1080: 64 20 63 20 3d 3d 20 22 29 22 3a 0a 20 20 20 20  d c == ")":.    
1090: 20 20 20 20 20 20 20 20 6e 53 74 61 74 65 20 3d          nState =
10a0: 20 30 0a 20 20 20 20 20 20 20 20 69 66 20 63 2e   0.        if c.
10b0: 69 73 61 6c 70 68 61 28 29 20 61 6e 64 20 63 2e  isalpha() and c.
10c0: 69 73 6c 6f 77 65 72 28 29 20 61 6e 64 20 6e 53  islower() and nS
10d0: 74 61 74 65 20 3d 3d 20 30 3a 0a 20 20 20 20 20  tate == 0:.     
10e0: 20 20 20 20 20 20 20 69 66 20 63 20 3d 3d 20 22         if c == "
10f0: 69 22 20 61 6e 64 20 28 73 4c 61 6e 67 20 3d 3d  i" and (sLang ==
1100: 20 22 74 72 22 20 6f 72 20 73 4c 61 6e 67 20 3d   "tr" or sLang =
1110: 3d 20 22 61 7a 22 29 3a 0a 20 20 20 20 20 20 20  = "az"):.       
1120: 20 20 20 20 20 20 20 20 20 73 55 70 20 2b 3d 20           sUp += 
1130: 22 5b c4 b0 22 20 2b 20 63 20 2b 20 22 5d 22 0a  "[.." + c + "]".
1140: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65              else
1150: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
1160: 20 20 73 55 70 20 2b 3d 20 22 5b 22 20 2b 20 63    sUp += "[" + c
1170: 2e 75 70 70 65 72 28 29 20 2b 20 63 20 2b 20 22  .upper() + c + "
1180: 5d 22 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  ]".        elif 
1190: 63 2e 69 73 61 6c 70 68 61 28 29 20 61 6e 64 20  c.isalpha() and 
11a0: 63 2e 69 73 6c 6f 77 65 72 28 29 20 61 6e 64 20  c.islower() and 
11b0: 6e 53 74 61 74 65 20 3d 3d 20 31 20 61 6e 64 20  nState == 1 and 
11c0: 73 5b 69 2b 31 3a 69 2b 32 5d 20 21 3d 20 22 2d  s[i+1:i+2] != "-
11d0: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  ":.            i
11e0: 66 20 73 5b 69 2d 31 3a 69 5d 20 3d 3d 20 22 2d  f s[i-1:i] == "-
11f0: 22 20 61 6e 64 20 73 5b 69 2d 32 3a 69 2d 31 5d  " and s[i-2:i-1]
1200: 2e 69 73 6c 6f 77 65 72 28 29 3a 20 20 23 20 5b  .islower():  # [
1210: 61 2d 7a 5d 20 2d 3e 20 5b 61 2d 7a 41 2d 5a 5d  a-z] -> [a-zA-Z]
1220: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1230: 20 73 55 70 20 2b 3d 20 63 20 2b 20 73 5b 69 2d   sUp += c + s[i-
1240: 32 3a 69 2d 31 5d 2e 75 70 70 65 72 28 29 20 2b  2:i-1].upper() +
1250: 20 22 2d 22 20 2b 20 63 2e 75 70 70 65 72 28 29   "-" + c.upper()
1260: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69  .            eli
1270: 66 20 63 20 3d 3d 20 22 69 22 20 61 6e 64 20 28  f c == "i" and (
1280: 73 4c 61 6e 67 20 3d 3d 20 22 74 72 22 20 6f 72  sLang == "tr" or
1290: 20 73 4c 61 6e 67 20 3d 3d 20 22 61 7a 22 29 3a   sLang == "az"):
12a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
12b0: 20 73 55 70 20 2b 3d 20 22 c4 b0 22 20 2b 20 63   sUp += ".." + c
12c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
12d0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
12e0: 20 20 20 73 55 70 20 2b 3d 20 63 2e 75 70 70 65     sUp += c.uppe
12f0: 72 28 29 20 2b 20 63 0a 20 20 20 20 20 20 20 20  r() + c.        
1300: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
1310: 20 20 73 55 70 20 2b 3d 20 63 0a 20 20 20 20 20    sUp += c.     
1320: 20 20 20 69 66 20 63 20 3d 3d 20 22 5c 5c 22 3a     if c == "\\":
1330: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74  .            nSt
1340: 61 74 65 20 3d 20 34 0a 20 20 20 20 20 20 20 20  ate = 4.        
1350: 65 6c 69 66 20 6e 53 74 61 74 65 20 3d 3d 20 34  elif nState == 4
1360: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 53  :.            nS
1370: 74 61 74 65 20 3d 20 30 0a 20 20 20 20 72 65 74  tate = 0.    ret
1380: 75 72 6e 20 73 55 70 0a 0a 0a 64 65 66 20 63 6f  urn sUp...def co
1390: 75 6e 74 47 72 6f 75 70 49 6e 52 65 67 65 78 20  untGroupInRegex 
13a0: 28 73 52 65 67 65 78 29 3a 0a 20 20 20 20 74 72  (sRegex):.    tr
13b0: 79 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  y:.        retur
13c0: 6e 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 52 65  n re.compile(sRe
13d0: 67 65 78 29 2e 67 72 6f 75 70 73 0a 20 20 20 20  gex).groups.    
13e0: 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20  except:.        
13f0: 74 72 61 63 65 62 61 63 6b 2e 70 72 69 6e 74 5f  traceback.print_
1400: 65 78 63 28 29 0a 20 20 20 20 20 20 20 20 70 72  exc().        pr
1410: 69 6e 74 28 73 52 65 67 65 78 29 0a 20 20 20 20  int(sRegex).    
1420: 72 65 74 75 72 6e 20 30 0a 0a 0a 64 65 66 20 63  return 0...def c
1430: 72 65 61 74 65 52 75 6c 65 20 28 73 2c 20 6e 49  reateRule (s, nI
1440: 64 4c 69 6e 65 2c 20 73 4c 61 6e 67 2c 20 62 50  dLine, sLang, bP
1450: 61 72 61 67 72 61 70 68 2c 20 64 4f 70 74 50 72  aragraph, dOptPr
1460: 69 6f 72 69 74 79 29 3a 0a 20 20 20 20 22 72 65  iority):.    "re
1470: 74 75 72 6e 73 20 72 75 6c 65 20 61 73 20 6c 69  turns rule as li
1480: 73 74 20 5b 6f 70 74 69 6f 6e 20 6e 61 6d 65 2c  st [option name,
1490: 20 72 65 67 65 78 2c 20 62 43 61 73 65 49 6e 73   regex, bCaseIns
14a0: 65 6e 73 69 74 69 76 65 2c 20 69 64 65 6e 74 69  ensitive, identi
14b0: 66 69 65 72 2c 20 6c 69 73 74 20 6f 66 20 61 63  fier, list of ac
14c0: 74 69 6f 6e 73 5d 22 0a 20 20 20 20 67 6c 6f 62  tions]".    glob
14d0: 61 6c 20 64 4a 53 52 45 47 45 58 45 53 0a 20 20  al dJSREGEXES.  
14e0: 20 20 67 6c 6f 62 61 6c 20 6e 52 55 4c 45 57 49    global nRULEWI
14f0: 54 48 4f 55 54 4e 41 4d 45 0a 0a 20 20 20 20 73  THOUTNAME..    s
1500: 4c 69 6e 65 49 64 20 3d 20 73 74 72 28 6e 49 64  LineId = str(nId
1510: 4c 69 6e 65 29 20 2b 20 28 22 70 22 20 69 66 20  Line) + ("p" if 
1520: 62 50 61 72 61 67 72 61 70 68 20 65 6c 73 65 20  bParagraph else 
1530: 22 73 22 29 0a 20 20 20 20 73 52 75 6c 65 49 64  "s").    sRuleId
1540: 20 3d 20 73 4c 69 6e 65 49 64 0a 0a 20 20 20 20   = sLineId..    
1550: 23 23 23 23 20 47 52 41 50 48 20 43 41 4c 4c 0a  #### GRAPH CALL.
1560: 20 20 20 20 69 66 20 73 2e 73 74 61 72 74 73 77      if s.startsw
1570: 69 74 68 28 22 40 40 40 40 22 29 3a 0a 20 20 20  ith("@@@@"):.   
1580: 20 20 20 20 20 69 66 20 62 50 61 72 61 67 72 61       if bParagra
1590: 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ph:.            
15a0: 70 72 69 6e 74 28 22 45 72 72 6f 72 2e 20 47 72  print("Error. Gr
15b0: 61 70 68 20 63 61 6c 6c 20 63 61 6e e2 80 99 74  aph call can...t
15c0: 20 62 65 20 6d 61 64 65 20 6f 6e 6c 79 20 61 66   be made only af
15d0: 74 65 72 20 74 68 65 20 66 69 72 73 74 20 70 61  ter the first pa
15e0: 73 73 20 28 73 65 6e 74 65 6e 63 65 20 62 79 20  ss (sentence by 
15f0: 73 65 6e 74 65 6e 63 65 29 22 29 0a 20 20 20 20  sentence)").    
1600: 20 20 20 20 20 20 20 20 65 78 69 74 28 29 0a 20          exit(). 
1610: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b 22         return ["
1620: 40 40 40 40 22 2c 20 73 5b 34 3a 5d 2c 20 73 4c  @@@@", s[4:], sL
1630: 69 6e 65 49 64 5d 0a 0a 20 20 20 20 23 23 23 23  ineId]..    ####
1640: 20 4f 50 54 49 4f 4e 53 0a 20 20 20 20 73 4f 70   OPTIONS.    sOp
1650: 74 69 6f 6e 20 3d 20 46 61 6c 73 65 20 20 20 20  tion = False    
1660: 20 20 20 20 20 23 20 46 61 6c 73 65 20 6f 72 20       # False or 
1670: 5b 61 2d 7a 30 2d 39 5d 2b 20 6e 61 6d 65 0a 20  [a-z0-9]+ name. 
1680: 20 20 20 6e 50 72 69 6f 72 69 74 79 20 3d 20 34     nPriority = 4
1690: 20 20 20 20 20 20 20 20 20 20 20 23 20 44 65 66             # Def
16a0: 61 75 6c 74 20 69 73 20 34 2c 20 76 61 6c 75 65  ault is 4, value
16b0: 20 6d 75 73 74 20 62 65 20 62 65 74 77 65 65 6e   must be between
16c0: 20 30 20 61 6e 64 20 39 0a 20 20 20 20 74 47 72   0 and 9.    tGr
16d0: 6f 75 70 73 20 3d 20 4e 6f 6e 65 20 20 20 20 20  oups = None     
16e0: 20 20 20 20 20 23 20 63 6f 64 65 20 66 6f 72 20       # code for 
16f0: 67 72 6f 75 70 73 20 70 6f 73 69 74 69 6f 6e 69  groups positioni
1700: 6e 67 20 28 6f 6e 6c 79 20 75 73 65 66 75 6c 20  ng (only useful 
1710: 66 6f 72 20 4a 61 76 61 53 63 72 69 70 74 29 0a  for JavaScript).
1720: 20 20 20 20 63 43 61 73 65 4d 6f 64 65 20 3d 20      cCaseMode = 
1730: 27 69 27 20 20 20 20 20 20 20 20 20 23 20 69 3a  'i'         # i:
1740: 20 63 61 73 65 20 69 6e 73 65 6e 73 69 74 69 76   case insensitiv
1750: 65 2c 20 20 73 3a 20 63 61 73 65 20 73 65 6e 73  e,  s: case sens
1760: 69 74 69 76 65 2c 20 20 75 3a 20 75 70 70 65 72  itive,  u: upper
1770: 63 61 73 69 6e 67 20 61 6c 6c 6f 77 65 64 0a 20  casing allowed. 
1780: 20 20 20 63 57 6f 72 64 4c 69 6d 69 74 4c 65 66     cWordLimitLef
1790: 74 20 3d 20 27 5b 27 20 20 20 20 23 20 5b 3a 20  t = '['    # [: 
17a0: 77 6f 72 64 20 6c 69 6d 69 74 2c 20 3c 3a 20 6e  word limit, <: n
17b0: 6f 20 73 70 65 63 69 66 69 63 20 6c 69 6d 69 74  o specific limit
17c0: 0a 20 20 20 20 63 57 6f 72 64 4c 69 6d 69 74 52  .    cWordLimitR
17d0: 69 67 68 74 20 3d 20 27 5d 27 20 20 20 23 20 5d  ight = ']'   # ]
17e0: 3a 20 77 6f 72 64 20 6c 69 6d 69 74 2c 20 3e 3a  : word limit, >:
17f0: 20 6e 6f 20 73 70 65 63 69 66 69 63 20 6c 69 6d   no specific lim
1800: 69 74 0a 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61  it.    m = re.ma
1810: 74 63 68 28 22 5e 5f 5f 28 3f 50 3c 62 6f 72 64  tch("^__(?P<bord
1820: 65 72 73 5f 61 6e 64 5f 63 61 73 65 3e 5b 5b 3c  ers_and_case>[[<
1830: 5d 5c 5c 77 5b 5d 3e 5d 29 28 3f 50 3c 6f 70 74  ]\\w[]>])(?P<opt
1840: 69 6f 6e 3e 2f 5b 61 2d 7a 41 2d 5a 30 2d 39 5d  ion>/[a-zA-Z0-9]
1850: 2b 7c 29 28 3f 50 3c 72 75 6c 65 69 64 3e 5c 5c  +|)(?P<ruleid>\\
1860: 28 5c 5c 77 2b 5c 5c 29 7c 29 28 3f 50 3c 70 72  (\\w+\\)|)(?P<pr
1870: 69 6f 72 69 74 79 3e 21 5b 30 2d 39 5d 7c 29 5f  iority>![0-9]|)_
1880: 5f 20 2a 22 2c 20 73 29 0a 20 20 20 20 69 66 20  _ *", s).    if 
1890: 6d 3a 0a 20 20 20 20 20 20 20 20 63 57 6f 72 64  m:.        cWord
18a0: 4c 69 6d 69 74 4c 65 66 74 20 3d 20 6d 2e 67 72  LimitLeft = m.gr
18b0: 6f 75 70 28 27 62 6f 72 64 65 72 73 5f 61 6e 64  oup('borders_and
18c0: 5f 63 61 73 65 27 29 5b 30 5d 0a 20 20 20 20 20  _case')[0].     
18d0: 20 20 20 63 43 61 73 65 4d 6f 64 65 20 3d 20 6d     cCaseMode = m
18e0: 2e 67 72 6f 75 70 28 27 62 6f 72 64 65 72 73 5f  .group('borders_
18f0: 61 6e 64 5f 63 61 73 65 27 29 5b 31 5d 0a 20 20  and_case')[1].  
1900: 20 20 20 20 20 20 63 57 6f 72 64 4c 69 6d 69 74        cWordLimit
1910: 52 69 67 68 74 20 3d 20 6d 2e 67 72 6f 75 70 28  Right = m.group(
1920: 27 62 6f 72 64 65 72 73 5f 61 6e 64 5f 63 61 73  'borders_and_cas
1930: 65 27 29 5b 32 5d 0a 20 20 20 20 20 20 20 20 73  e')[2].        s
1940: 4f 70 74 69 6f 6e 20 3d 20 6d 2e 67 72 6f 75 70  Option = m.group
1950: 28 27 6f 70 74 69 6f 6e 27 29 5b 31 3a 5d 20 20  ('option')[1:]  
1960: 69 66 20 6d 2e 67 72 6f 75 70 28 27 6f 70 74 69  if m.group('opti
1970: 6f 6e 27 29 20 20 65 6c 73 65 20 46 61 6c 73 65  on')  else False
1980: 0a 20 20 20 20 20 20 20 20 69 66 20 6d 2e 67 72  .        if m.gr
1990: 6f 75 70 28 27 72 75 6c 65 69 64 27 29 3a 0a 20  oup('ruleid'):. 
19a0: 20 20 20 20 20 20 20 20 20 20 20 73 52 75 6c 65             sRule
19b0: 49 64 20 3d 20 20 6d 2e 67 72 6f 75 70 28 27 72  Id =  m.group('r
19c0: 75 6c 65 69 64 27 29 5b 31 3a 2d 31 5d 0a 20 20  uleid')[1:-1].  
19d0: 20 20 20 20 20 20 20 20 20 20 69 66 20 73 52 75            if sRu
19e0: 6c 65 49 64 20 69 6e 20 61 52 55 4c 45 53 45 54  leId in aRULESET
19f0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
1a00: 20 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72    print("# Error
1a10: 2e 20 53 65 76 65 72 61 6c 20 72 75 6c 65 73 20  . Several rules 
1a20: 68 61 76 65 20 74 68 65 20 73 61 6d 65 20 69 64  have the same id
1a30: 3a 20 22 20 2b 20 73 52 75 6c 65 49 64 29 0a 20  : " + sRuleId). 
1a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65                 e
1a50: 78 69 74 28 29 0a 20 20 20 20 20 20 20 20 20 20  xit().          
1a60: 20 20 61 52 55 4c 45 53 45 54 2e 61 64 64 28 73    aRULESET.add(s
1a70: 52 75 6c 65 49 64 29 0a 20 20 20 20 20 20 20 20  RuleId).        
1a80: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
1a90: 20 20 6e 52 55 4c 45 57 49 54 48 4f 55 54 4e 41    nRULEWITHOUTNA
1aa0: 4d 45 20 2b 3d 20 31 0a 20 20 20 20 20 20 20 20  ME += 1.        
1ab0: 6e 50 72 69 6f 72 69 74 79 20 3d 20 64 4f 70 74  nPriority = dOpt
1ac0: 50 72 69 6f 72 69 74 79 2e 67 65 74 28 73 4f 70  Priority.get(sOp
1ad0: 74 69 6f 6e 2c 20 34 29 0a 20 20 20 20 20 20 20  tion, 4).       
1ae0: 20 69 66 20 6d 2e 67 72 6f 75 70 28 27 70 72 69   if m.group('pri
1af0: 6f 72 69 74 79 27 29 3a 0a 20 20 20 20 20 20 20  ority'):.       
1b00: 20 20 20 20 20 6e 50 72 69 6f 72 69 74 79 20 3d       nPriority =
1b10: 20 69 6e 74 28 6d 2e 67 72 6f 75 70 28 27 70 72   int(m.group('pr
1b20: 69 6f 72 69 74 79 27 29 5b 31 3a 5d 29 0a 20 20  iority')[1:]).  
1b30: 20 20 20 20 20 20 73 20 3d 20 73 5b 6d 2e 65 6e        s = s[m.en
1b40: 64 28 30 29 3a 5d 0a 20 20 20 20 65 6c 73 65 3a  d(0):].    else:
1b50: 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22  .        print("
1b60: 23 20 57 61 72 6e 69 6e 67 2e 20 4e 6f 20 6f 70  # Warning. No op
1b70: 74 69 6f 6e 20 64 65 66 69 6e 65 64 20 61 74 20  tion defined at 
1b80: 6c 69 6e 65 3a 20 22 20 2b 20 73 4c 69 6e 65 49  line: " + sLineI
1b90: 64 29 0a 0a 20 20 20 20 23 23 23 23 20 52 45 47  d)..    #### REG
1ba0: 45 58 20 54 52 49 47 47 45 52 0a 20 20 20 20 69  EX TRIGGER.    i
1bb0: 20 3d 20 73 2e 66 69 6e 64 28 22 20 3c 3c 2d 22   = s.find(" <<-"
1bc0: 29 0a 20 20 20 20 69 66 20 69 20 3d 3d 20 2d 31  ).    if i == -1
1bd0: 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28  :.        print(
1be0: 22 23 20 45 72 72 6f 72 3a 20 6e 6f 20 63 6f 6e  "# Error: no con
1bf0: 64 69 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22  dition at line "
1c00: 20 2b 20 73 4c 69 6e 65 49 64 29 0a 20 20 20 20   + sLineId).    
1c10: 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a      return None.
1c20: 20 20 20 20 73 52 65 67 65 78 20 3d 20 73 5b 3a      sRegex = s[:
1c30: 69 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20 73  i].strip().    s
1c40: 20 3d 20 73 5b 69 2b 34 3a 5d 0a 20 20 20 20 0a   = s[i+4:].    .
1c50: 20 20 20 20 23 20 4a 53 20 67 72 6f 75 70 73 20      # JS groups 
1c60: 70 6f 73 69 74 69 6f 6e 69 6e 67 20 63 6f 64 65  positioning code
1c70: 73 0a 20 20 20 20 6d 20 3d 20 72 65 2e 73 65 61  s.    m = re.sea
1c80: 72 63 68 28 22 40 40 5c 5c 53 2b 22 2c 20 73 52  rch("@@\\S+", sR
1c90: 65 67 65 78 29 0a 20 20 20 20 69 66 20 6d 3a 0a  egex).    if m:.
1ca0: 20 20 20 20 20 20 20 20 74 47 72 6f 75 70 73 20          tGroups 
1cb0: 3d 20 6a 73 63 6f 6e 76 2e 67 72 6f 75 70 73 50  = jsconv.groupsP
1cc0: 6f 73 69 74 69 6f 6e 69 6e 67 43 6f 64 65 54 6f  ositioningCodeTo
1cd0: 4c 69 73 74 28 73 52 65 67 65 78 5b 6d 2e 73 74  List(sRegex[m.st
1ce0: 61 72 74 28 29 2b 32 3a 5d 29 0a 20 20 20 20 20  art()+2:]).     
1cf0: 20 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67     sRegex = sReg
1d00: 65 78 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2e 73  ex[:m.start()].s
1d10: 74 72 69 70 28 29 0a 20 20 20 20 23 20 4a 53 20  trip().    # JS 
1d20: 72 65 67 65 78 0a 20 20 20 20 6d 20 3d 20 72 65  regex.    m = re
1d30: 2e 73 65 61 72 63 68 28 22 3c 6a 73 3e 2e 2b 3c  .search("<js>.+<
1d40: 2f 6a 73 3e 69 3f 22 2c 20 73 52 65 67 65 78 29  /js>i?", sRegex)
1d50: 0a 20 20 20 20 69 66 20 6d 3a 0a 20 20 20 20 20  .    if m:.     
1d60: 20 20 20 64 4a 53 52 45 47 45 58 45 53 5b 73 4c     dJSREGEXES[sL
1d70: 69 6e 65 49 64 5d 20 3d 20 6d 2e 67 72 6f 75 70  ineId] = m.group
1d80: 28 30 29 0a 20 20 20 20 20 20 20 20 73 52 65 67  (0).        sReg
1d90: 65 78 20 3d 20 73 52 65 67 65 78 5b 3a 6d 2e 73  ex = sRegex[:m.s
1da0: 74 61 72 74 28 29 5d 2e 73 74 72 69 70 28 29 0a  tart()].strip().
1db0: 20 20 20 20 69 66 20 22 3c 6a 73 3e 22 20 69 6e      if "<js>" in
1dc0: 20 73 52 65 67 65 78 20 6f 72 20 22 3c 2f 6a 73   sRegex or "</js
1dd0: 3e 22 20 69 6e 20 73 52 65 67 65 78 3a 0a 20 20  >" in sRegex:.  
1de0: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45        print("# E
1df0: 72 72 6f 72 3a 20 4a 61 76 61 53 63 72 69 70 74  rror: JavaScript
1e00: 20 72 65 67 65 78 20 6e 6f 74 20 64 65 6c 69 6d   regex not delim
1e10: 69 74 65 64 20 61 74 20 6c 69 6e 65 20 22 20 2b  ited at line " +
1e20: 20 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20   sLineId).      
1e30: 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a 20    return None.. 
1e40: 20 20 20 23 20 71 75 6f 74 65 73 20 3f 0a 20 20     # quotes ?.  
1e50: 20 20 69 66 20 73 52 65 67 65 78 2e 73 74 61 72    if sRegex.star
1e60: 74 73 77 69 74 68 28 27 22 27 29 20 61 6e 64 20  tswith('"') and 
1e70: 73 52 65 67 65 78 2e 65 6e 64 73 77 69 74 68 28  sRegex.endswith(
1e80: 27 22 27 29 3a 0a 20 20 20 20 20 20 20 20 73 52  '"'):.        sR
1e90: 65 67 65 78 20 3d 20 73 52 65 67 65 78 5b 31 3a  egex = sRegex[1:
1ea0: 2d 31 5d 0a 0a 20 20 20 20 23 23 20 64 65 66 69  -1]..    ## defi
1eb0: 6e 69 74 69 6f 6e 73 0a 20 20 20 20 66 6f 72 20  nitions.    for 
1ec0: 73 44 65 66 2c 20 73 52 65 70 6c 20 69 6e 20 64  sDef, sRepl in d
1ed0: 44 45 46 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20  DEF.items():.   
1ee0: 20 20 20 20 20 73 52 65 67 65 78 20 3d 20 73 52       sRegex = sR
1ef0: 65 67 65 78 2e 72 65 70 6c 61 63 65 28 73 44 65  egex.replace(sDe
1f00: 66 2c 20 73 52 65 70 6c 29 0a 0a 20 20 20 20 23  f, sRepl)..    #
1f10: 23 20 63 6f 75 6e 74 20 6e 75 6d 62 65 72 20 6f  # count number o
1f20: 66 20 67 72 6f 75 70 73 20 28 6d 75 73 74 20 62  f groups (must b
1f30: 65 20 64 6f 6e 65 20 62 65 66 6f 72 65 20 6d 6f  e done before mo
1f40: 64 69 66 79 69 6e 67 20 74 68 65 20 72 65 67 65  difying the rege
1f50: 78 29 0a 20 20 20 20 6e 47 72 6f 75 70 20 3d 20  x).    nGroup = 
1f60: 63 6f 75 6e 74 47 72 6f 75 70 49 6e 52 65 67 65  countGroupInRege
1f70: 78 28 73 52 65 67 65 78 29 0a 20 20 20 20 69 66  x(sRegex).    if
1f80: 20 6e 47 72 6f 75 70 20 3e 20 30 3a 0a 20 20 20   nGroup > 0:.   
1f90: 20 20 20 20 20 69 66 20 6e 6f 74 20 74 47 72 6f       if not tGro
1fa0: 75 70 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ups:.           
1fb0: 20 70 72 69 6e 74 28 22 23 20 57 61 72 6e 69 6e   print("# Warnin
1fc0: 67 3a 20 67 72 6f 75 70 73 20 70 6f 73 69 74 69  g: groups positi
1fd0: 6f 6e 69 6e 67 20 63 6f 64 65 20 66 6f 72 20 4a  oning code for J
1fe0: 61 76 61 53 63 72 69 70 74 20 73 68 6f 75 6c 64  avaScript should
1ff0: 20 62 65 20 64 65 66 69 6e 65 64 20 61 74 20 6c   be defined at l
2000: 69 6e 65 20 22 20 2b 20 73 4c 69 6e 65 49 64 29  ine " + sLineId)
2010: 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20  .        else:. 
2020: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e 47             if nG
2030: 72 6f 75 70 20 21 3d 20 6c 65 6e 28 74 47 72 6f  roup != len(tGro
2040: 75 70 73 29 3a 0a 20 20 20 20 20 20 20 20 20 20  ups):.          
2050: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45        print("# E
2060: 72 72 6f 72 3a 20 67 72 6f 75 70 73 20 70 6f 73  rror: groups pos
2070: 69 74 69 6f 6e 69 6e 67 20 63 6f 64 65 20 69 72  itioning code ir
2080: 72 65 6c 65 76 61 6e 74 20 61 74 20 6c 69 6e 65  relevant at line
2090: 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a 0a 20   " + sLineId).. 
20a0: 20 20 20 23 23 20 77 6f 72 64 20 6c 69 6d 69 74     ## word limit
20b0: 0a 20 20 20 20 69 66 20 63 57 6f 72 64 4c 69 6d  .    if cWordLim
20c0: 69 74 4c 65 66 74 20 3d 3d 20 27 5b 27 20 61 6e  itLeft == '[' an
20d0: 64 20 6e 6f 74 20 73 52 65 67 65 78 2e 73 74 61  d not sRegex.sta
20e0: 72 74 73 77 69 74 68 28 28 22 5e 22 2c 20 27 e2  rtswith(("^", '.
20f0: 80 99 27 2c 20 22 27 22 2c 20 22 2c 22 29 29 3a  ..', "'", ",")):
2100: 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78 20  .        sRegex 
2110: 3d 20 73 57 4f 52 44 4c 49 4d 49 54 4c 45 46 54  = sWORDLIMITLEFT
2120: 20 2b 20 73 52 65 67 65 78 0a 20 20 20 20 69 66   + sRegex.    if
2130: 20 63 57 6f 72 64 4c 69 6d 69 74 52 69 67 68 74   cWordLimitRight
2140: 20 3d 3d 20 27 5d 27 20 61 6e 64 20 6e 6f 74 20   == ']' and not 
2150: 73 52 65 67 65 78 2e 65 6e 64 73 77 69 74 68 28  sRegex.endswith(
2160: 28 22 24 22 2c 20 27 e2 80 99 27 2c 20 22 27 22  ("$", '...', "'"
2170: 2c 20 22 2c 22 29 29 3a 0a 20 20 20 20 20 20 20  , ",")):.       
2180: 20 73 52 65 67 65 78 20 3d 20 73 52 65 67 65 78   sRegex = sRegex
2190: 20 2b 20 73 57 4f 52 44 4c 49 4d 49 54 52 49 47   + sWORDLIMITRIG
21a0: 48 54 0a 0a 20 20 20 20 23 23 20 63 61 73 69 6e  HT..    ## casin
21b0: 67 20 6d 6f 64 65 0a 20 20 20 20 69 66 20 63 43  g mode.    if cC
21c0: 61 73 65 4d 6f 64 65 20 3d 3d 20 22 69 22 3a 0a  aseMode == "i":.
21d0: 20 20 20 20 20 20 20 20 62 43 61 73 65 49 6e 73          bCaseIns
21e0: 65 6e 73 69 74 69 76 65 20 3d 20 54 72 75 65 0a  ensitive = True.
21f0: 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 73          if not s
2200: 52 65 67 65 78 2e 73 74 61 72 74 73 77 69 74 68  Regex.startswith
2210: 28 22 28 3f 69 29 22 29 3a 0a 20 20 20 20 20 20  ("(?i)"):.      
2220: 20 20 20 20 20 20 73 52 65 67 65 78 20 3d 20 22        sRegex = "
2230: 28 3f 69 29 22 20 2b 20 73 52 65 67 65 78 0a 20  (?i)" + sRegex. 
2240: 20 20 20 65 6c 69 66 20 63 43 61 73 65 4d 6f 64     elif cCaseMod
2250: 65 20 3d 3d 20 22 73 22 3a 0a 20 20 20 20 20 20  e == "s":.      
2260: 20 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69    bCaseInsensiti
2270: 76 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20  ve = False.     
2280: 20 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67     sRegex = sReg
2290: 65 78 2e 72 65 70 6c 61 63 65 28 22 28 3f 69 29  ex.replace("(?i)
22a0: 22 2c 20 22 22 29 0a 20 20 20 20 65 6c 69 66 20  ", "").    elif 
22b0: 63 43 61 73 65 4d 6f 64 65 20 3d 3d 20 22 75 22  cCaseMode == "u"
22c0: 3a 0a 20 20 20 20 20 20 20 20 62 43 61 73 65 49  :.        bCaseI
22d0: 6e 73 65 6e 73 69 74 69 76 65 20 3d 20 46 61 6c  nsensitive = Fal
22e0: 73 65 0a 20 20 20 20 20 20 20 20 73 52 65 67 65  se.        sRege
22f0: 78 20 3d 20 73 52 65 67 65 78 2e 72 65 70 6c 61  x = sRegex.repla
2300: 63 65 28 22 28 3f 69 29 22 2c 20 22 22 29 0a 20  ce("(?i)", ""). 
2310: 20 20 20 20 20 20 20 73 52 65 67 65 78 20 3d 20         sRegex = 
2320: 75 70 70 65 72 63 61 73 65 28 73 52 65 67 65 78  uppercase(sRegex
2330: 2c 20 73 4c 61 6e 67 29 0a 20 20 20 20 65 6c 73  , sLang).    els
2340: 65 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  e:.        print
2350: 28 22 23 20 55 6e 6b 6e 6f 77 6e 20 63 61 73 65  ("# Unknown case
2360: 20 6d 6f 64 65 20 5b 22 20 2b 20 63 43 61 73 65   mode [" + cCase
2370: 4d 6f 64 65 20 2b 20 22 5d 20 61 74 20 6c 69 6e  Mode + "] at lin
2380: 65 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a 0a  e " + sLineId)..
2390: 20 20 20 20 23 23 20 63 68 65 63 6b 20 72 65 67      ## check reg
23a0: 65 78 0a 20 20 20 20 74 72 79 3a 0a 20 20 20 20  ex.    try:.    
23b0: 20 20 20 20 7a 20 3d 20 72 65 2e 63 6f 6d 70 69      z = re.compi
23c0: 6c 65 28 73 52 65 67 65 78 29 0a 20 20 20 20 65  le(sRegex).    e
23d0: 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20 70  xcept:.        p
23e0: 72 69 6e 74 28 22 23 20 52 65 67 65 78 20 65 72  rint("# Regex er
23f0: 72 6f 72 20 61 74 20 6c 69 6e 65 20 22 2c 20 6e  ror at line ", n
2400: 49 64 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20  IdLine).        
2410: 70 72 69 6e 74 28 73 52 65 67 65 78 29 0a 20 20  print(sRegex).  
2420: 20 20 20 20 20 20 74 72 61 63 65 62 61 63 6b 2e        traceback.
2430: 70 72 69 6e 74 5f 65 78 63 28 29 0a 20 20 20 20  print_exc().    
2440: 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a      return None.
2450: 20 20 20 20 23 23 20 67 72 6f 75 70 73 20 69 6e      ## groups in
2460: 20 6e 6f 6e 20 67 72 6f 75 70 69 6e 67 20 70 61   non grouping pa
2470: 72 65 6e 74 68 65 73 69 73 0a 20 20 20 20 66 6f  renthesis.    fo
2480: 72 20 78 20 69 6e 20 72 65 2e 66 69 6e 64 69 74  r x in re.findit
2490: 65 72 28 22 5c 28 5c 3f 3a 5b 5e 29 5d 2a 5c 28  er("\(\?:[^)]*\(
24a0: 5b 5b 5c 77 20 2d 5d 22 2c 20 73 52 65 67 65 78  [[\w -]", sRegex
24b0: 29 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  ):.        print
24c0: 28 22 23 20 57 61 72 6e 69 6e 67 3a 20 67 72 6f  ("# Warning: gro
24d0: 75 70 73 20 69 6e 73 69 64 65 20 6e 6f 6e 20 67  ups inside non g
24e0: 72 6f 75 70 69 6e 67 20 70 61 72 65 6e 74 68 65  rouping parenthe
24f0: 73 69 73 20 69 6e 20 72 65 67 65 78 20 61 74 20  sis in regex at 
2500: 6c 69 6e 65 20 22 20 2b 20 73 4c 69 6e 65 49 64  line " + sLineId
2510: 29 0a 0a 20 20 20 20 23 23 23 23 20 50 41 52 53  )..    #### PARS
2520: 45 20 41 43 54 49 4f 4e 53 0a 20 20 20 20 6c 41  E ACTIONS.    lA
2530: 63 74 69 6f 6e 73 20 3d 20 5b 5d 0a 20 20 20 20  ctions = [].    
2540: 6e 41 63 74 69 6f 6e 20 3d 20 31 0a 20 20 20 20  nAction = 1.    
2550: 66 6f 72 20 73 41 63 74 69 6f 6e 20 69 6e 20 73  for sAction in s
2560: 2e 73 70 6c 69 74 28 22 20 3c 3c 2d 20 22 29 3a  .split(" <<- "):
2570: 0a 20 20 20 20 20 20 20 20 74 20 3d 20 63 72 65  .        t = cre
2580: 61 74 65 41 63 74 69 6f 6e 28 73 52 75 6c 65 49  ateAction(sRuleI
2590: 64 20 2b 20 22 5f 22 20 2b 20 73 74 72 28 6e 41  d + "_" + str(nA
25a0: 63 74 69 6f 6e 29 2c 20 73 41 63 74 69 6f 6e 2c  ction), sAction,
25b0: 20 6e 47 72 6f 75 70 29 0a 20 20 20 20 20 20 20   nGroup).       
25c0: 20 6e 41 63 74 69 6f 6e 20 2b 3d 20 31 0a 20 20   nAction += 1.  
25d0: 20 20 20 20 20 20 69 66 20 74 3a 0a 20 20 20 20        if t:.    
25e0: 20 20 20 20 20 20 20 20 6c 41 63 74 69 6f 6e 73          lActions
25f0: 2e 61 70 70 65 6e 64 28 74 29 0a 20 20 20 20 69  .append(t).    i
2600: 66 20 6e 6f 74 20 6c 41 63 74 69 6f 6e 73 3a 0a  f not lActions:.
2610: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e          return N
2620: 6f 6e 65 0a 0a 20 20 20 20 72 65 74 75 72 6e 20  one..    return 
2630: 5b 73 4f 70 74 69 6f 6e 2c 20 73 52 65 67 65 78  [sOption, sRegex
2640: 2c 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69  , bCaseInsensiti
2650: 76 65 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75  ve, sLineId, sRu
2660: 6c 65 49 64 2c 20 6e 50 72 69 6f 72 69 74 79 2c  leId, nPriority,
2670: 20 6c 41 63 74 69 6f 6e 73 2c 20 74 47 72 6f 75   lActions, tGrou
2680: 70 73 5d 0a 0a 0a 64 65 66 20 63 72 65 61 74 65  ps]...def create
2690: 41 63 74 69 6f 6e 20 28 73 49 64 41 63 74 69 6f  Action (sIdActio
26a0: 6e 2c 20 73 41 63 74 69 6f 6e 2c 20 6e 47 72 6f  n, sAction, nGro
26b0: 75 70 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e  up):.    "return
26c0: 73 20 61 6e 20 61 63 74 69 6f 6e 20 74 6f 20 70  s an action to p
26d0: 65 72 66 6f 72 6d 20 61 73 20 61 20 74 75 70 6c  erform as a tupl
26e0: 65 20 28 63 6f 6e 64 69 74 69 6f 6e 2c 20 61 63  e (condition, ac
26f0: 74 69 6f 6e 20 74 79 70 65 2c 20 61 63 74 69 6f  tion type, actio
2700: 6e 5b 2c 20 69 47 72 6f 75 70 20 5b 2c 20 6d 65  n[, iGroup [, me
2710: 73 73 61 67 65 2c 20 55 52 4c 20 5d 5d 29 22 0a  ssage, URL ]])".
2720: 20 20 20 20 67 6c 6f 62 61 6c 20 6c 46 55 4e 43      global lFUNC
2730: 54 49 4f 4e 53 0a 0a 20 20 20 20 6d 20 3d 20 72  TIONS..    m = r
2740: 65 2e 73 65 61 72 63 68 28 72 22 28 5b 2d 7e 3d  e.search(r"([-~=
2750: 3e 5d 29 28 5c 64 2a 7c 29 3e 3e 22 2c 20 73 41  >])(\d*|)>>", sA
2760: 63 74 69 6f 6e 29 0a 20 20 20 20 69 66 20 6e 6f  ction).    if no
2770: 74 20 6d 3a 0a 20 20 20 20 20 20 20 20 70 72 69  t m:.        pri
2780: 6e 74 28 22 23 20 4e 6f 20 61 63 74 69 6f 6e 20  nt("# No action 
2790: 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64 41  at line " + sIdA
27a0: 63 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 72  ction).        r
27b0: 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a 20 20 20 20  eturn None..    
27c0: 23 23 23 23 20 43 4f 4e 44 49 54 49 4f 4e 0a 20  #### CONDITION. 
27d0: 20 20 20 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20     sCondition = 
27e0: 73 41 63 74 69 6f 6e 5b 3a 6d 2e 73 74 61 72 74  sAction[:m.start
27f0: 28 29 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20  ()].strip().    
2800: 69 66 20 73 43 6f 6e 64 69 74 69 6f 6e 3a 0a 20  if sCondition:. 
2810: 20 20 20 20 20 20 20 73 43 6f 6e 64 69 74 69 6f         sConditio
2820: 6e 20 3d 20 70 72 65 70 61 72 65 46 75 6e 63 74  n = prepareFunct
2830: 69 6f 6e 28 73 43 6f 6e 64 69 74 69 6f 6e 29 0a  ion(sCondition).
2840: 20 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f          lFUNCTIO
2850: 4e 53 2e 61 70 70 65 6e 64 28 28 22 63 5f 22 2b  NS.append(("c_"+
2860: 73 49 64 41 63 74 69 6f 6e 2c 20 73 43 6f 6e 64  sIdAction, sCond
2870: 69 74 69 6f 6e 29 29 0a 20 20 20 20 20 20 20 20  ition)).        
2880: 66 6f 72 20 78 20 69 6e 20 72 65 2e 66 69 6e 64  for x in re.find
2890: 69 74 65 72 28 22 5b 2e 5d 28 3f 3a 67 72 6f 75  iter("[.](?:grou
28a0: 70 7c 73 74 61 72 74 7c 65 6e 64 29 5b 28 5d 28  p|start|end)[(](
28b0: 5c 64 2b 29 5b 29 5d 22 2c 20 73 43 6f 6e 64 69  \d+)[)]", sCondi
28c0: 74 69 6f 6e 29 3a 0a 20 20 20 20 20 20 20 20 20  tion):.         
28d0: 20 20 20 69 66 20 69 6e 74 28 78 2e 67 72 6f 75     if int(x.grou
28e0: 70 28 31 29 29 20 3e 20 6e 47 72 6f 75 70 3a 0a  p(1)) > nGroup:.
28f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2900: 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69  print("# Error i
2910: 6e 20 67 72 6f 75 70 73 20 69 6e 20 63 6f 6e 64  n groups in cond
2920: 69 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20  ition at line " 
2930: 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b 20 22 20  + sIdAction + " 
2940: 28 22 2b 73 74 72 28 6e 47 72 6f 75 70 29 2b 22  ("+str(nGroup)+"
2950: 20 67 72 6f 75 70 73 20 6f 6e 6c 79 29 22 29 0a   groups only)").
2960: 20 20 20 20 20 20 20 20 69 66 20 22 2e 6d 61 74          if ".mat
2970: 63 68 22 20 69 6e 20 73 43 6f 6e 64 69 74 69 6f  ch" in sConditio
2980: 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  n:.            p
2990: 72 69 6e 74 28 22 23 20 45 72 72 6f 72 2e 20 4a  rint("# Error. J
29a0: 53 20 63 6f 6d 70 61 74 69 62 69 6c 69 74 79 2e  S compatibility.
29b0: 20 44 6f 6e 27 74 20 75 73 65 20 2e 6d 61 74 63   Don't use .matc
29c0: 68 28 29 20 69 6e 20 63 6f 6e 64 69 74 69 6f 6e  h() in condition
29d0: 2c 20 75 73 65 20 2e 73 65 61 72 63 68 28 29 22  , use .search()"
29e0: 29 0a 20 20 20 20 20 20 20 20 73 43 6f 6e 64 69  ).        sCondi
29f0: 74 69 6f 6e 20 3d 20 22 63 5f 22 2b 73 49 64 41  tion = "c_"+sIdA
2a00: 63 74 69 6f 6e 0a 20 20 20 20 65 6c 73 65 3a 0a  ction.    else:.
2a10: 20 20 20 20 20 20 20 20 73 43 6f 6e 64 69 74 69          sConditi
2a20: 6f 6e 20 3d 20 4e 6f 6e 65 0a 0a 20 20 20 20 23  on = None..    #
2a30: 23 23 23 20 69 47 72 6f 75 70 20 2f 20 70 6f 73  ### iGroup / pos
2a40: 69 74 69 6f 6e 69 6e 67 0a 20 20 20 20 69 47 72  itioning.    iGr
2a50: 6f 75 70 20 3d 20 69 6e 74 28 6d 2e 67 72 6f 75  oup = int(m.grou
2a60: 70 28 32 29 29 20 69 66 20 6d 2e 67 72 6f 75 70  p(2)) if m.group
2a70: 28 32 29 20 65 6c 73 65 20 30 0a 20 20 20 20 69  (2) else 0.    i
2a80: 66 20 69 47 72 6f 75 70 20 3e 20 6e 47 72 6f 75  f iGroup > nGrou
2a90: 70 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  p:.        print
2aa0: 28 22 23 20 53 65 6c 65 63 74 65 64 20 67 72 6f  ("# Selected gro
2ab0: 75 70 20 3e 20 67 72 6f 75 70 20 6e 75 6d 62 65  up > group numbe
2ac0: 72 20 69 6e 20 72 65 67 65 78 20 61 74 20 6c 69  r in regex at li
2ad0: 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e  ne " + sIdAction
2ae0: 29 0a 20 20 20 20 0a 20 20 20 20 23 23 23 23 20  ).    .    #### 
2af0: 41 43 54 49 4f 4e 0a 20 20 20 20 73 41 63 74 69  ACTION.    sActi
2b00: 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 6d 2e 65  on = sAction[m.e
2b10: 6e 64 28 29 3a 5d 2e 73 74 72 69 70 28 29 0a 20  nd():].strip(). 
2b20: 20 20 20 63 41 63 74 69 6f 6e 20 3d 20 6d 2e 67     cAction = m.g
2b30: 72 6f 75 70 28 31 29 0a 20 20 20 20 69 66 20 63  roup(1).    if c
2b40: 41 63 74 69 6f 6e 20 3d 3d 20 22 2d 22 3a 0a 20  Action == "-":. 
2b50: 20 20 20 20 20 20 20 23 23 20 65 72 72 6f 72 0a         ## error.
2b60: 20 20 20 20 20 20 20 20 69 4d 73 67 20 3d 20 73          iMsg = s
2b70: 41 63 74 69 6f 6e 2e 66 69 6e 64 28 22 20 23 20  Action.find(" # 
2b80: 22 29 0a 20 20 20 20 20 20 20 20 69 66 20 69 4d  ").        if iM
2b90: 73 67 20 3d 3d 20 2d 31 3a 0a 20 20 20 20 20 20  sg == -1:.      
2ba0: 20 20 20 20 20 20 73 4d 73 67 20 3d 20 22 23 20        sMsg = "# 
2bb0: 45 72 72 6f 72 2e 20 45 72 72 6f 72 20 6d 65 73  Error. Error mes
2bc0: 73 61 67 65 20 6e 6f 74 20 66 6f 75 6e 64 2e 22  sage not found."
2bd0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 55 52  .            sUR
2be0: 4c 20 3d 20 22 22 0a 20 20 20 20 20 20 20 20 20  L = "".         
2bf0: 20 20 20 70 72 69 6e 74 28 73 4d 73 67 20 2b 20     print(sMsg + 
2c00: 22 20 41 63 74 69 6f 6e 20 69 64 3a 20 22 20 2b  " Action id: " +
2c10: 20 73 49 64 41 63 74 69 6f 6e 29 0a 20 20 20 20   sIdAction).    
2c20: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
2c30: 20 20 20 20 20 20 73 4d 73 67 20 3d 20 73 41 63        sMsg = sAc
2c40: 74 69 6f 6e 5b 69 4d 73 67 2b 33 3a 5d 2e 73 74  tion[iMsg+3:].st
2c50: 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 20 20  rip().          
2c60: 20 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74    sAction = sAct
2c70: 69 6f 6e 5b 3a 69 4d 73 67 5d 2e 73 74 72 69 70  ion[:iMsg].strip
2c80: 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ().            s
2c90: 55 52 4c 20 3d 20 22 22 0a 20 20 20 20 20 20 20  URL = "".       
2ca0: 20 20 20 20 20 6d 55 52 4c 20 3d 20 72 65 2e 73       mURL = re.s
2cb0: 65 61 72 63 68 28 22 5b 7c 5d 20 2a 28 68 74 74  earch("[|] *(htt
2cc0: 70 73 3f 3a 2f 2f 2e 2a 29 22 2c 20 73 4d 73 67  ps?://.*)", sMsg
2cd0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  ).            if
2ce0: 20 6d 55 52 4c 3a 0a 20 20 20 20 20 20 20 20 20   mURL:.         
2cf0: 20 20 20 20 20 20 20 73 55 52 4c 20 3d 20 6d 55         sURL = mU
2d00: 52 4c 2e 67 72 6f 75 70 28 31 29 2e 73 74 72 69  RL.group(1).stri
2d10: 70 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  p().            
2d20: 20 20 20 20 73 4d 73 67 20 3d 20 73 4d 73 67 5b      sMsg = sMsg[
2d30: 3a 6d 55 52 4c 2e 73 74 61 72 74 28 30 29 5d 2e  :mURL.start(0)].
2d40: 73 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20  strip().        
2d50: 20 20 20 20 69 66 20 73 4d 73 67 5b 30 3a 31 5d      if sMsg[0:1]
2d60: 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20   == "=":.       
2d70: 20 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20           sMsg = 
2d80: 70 72 65 70 61 72 65 46 75 6e 63 74 69 6f 6e 28  prepareFunction(
2d90: 73 4d 73 67 5b 31 3a 5d 29 0a 20 20 20 20 20 20  sMsg[1:]).      
2da0: 20 20 20 20 20 20 20 20 20 20 6c 46 55 4e 43 54            lFUNCT
2db0: 49 4f 4e 53 2e 61 70 70 65 6e 64 28 28 22 6d 5f  IONS.append(("m_
2dc0: 22 2b 73 49 64 41 63 74 69 6f 6e 2c 20 73 4d 73  "+sIdAction, sMs
2dd0: 67 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  g)).            
2de0: 20 20 20 20 66 6f 72 20 78 20 69 6e 20 72 65 2e      for x in re.
2df0: 66 69 6e 64 69 74 65 72 28 22 67 72 6f 75 70 5b  finditer("group[
2e00: 28 5d 28 5c 64 2b 29 5b 29 5d 22 2c 20 73 4d 73  (](\d+)[)]", sMs
2e10: 67 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  g):.            
2e20: 20 20 20 20 20 20 20 20 69 66 20 69 6e 74 28 78          if int(x
2e30: 2e 67 72 6f 75 70 28 31 29 29 20 3e 20 6e 47 72  .group(1)) > nGr
2e40: 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20 20 20  oup:.           
2e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
2e60: 6e 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20 67  nt("# Error in g
2e70: 72 6f 75 70 73 20 69 6e 20 6d 65 73 73 61 67 65  roups in message
2e80: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64   at line " + sId
2e90: 41 63 74 69 6f 6e 20 2b 20 22 20 28 22 2b 73 74  Action + " ("+st
2ea0: 72 28 6e 47 72 6f 75 70 29 2b 22 20 67 72 6f 75  r(nGroup)+" grou
2eb0: 70 73 20 6f 6e 6c 79 29 22 29 0a 20 20 20 20 20  ps only)").     
2ec0: 20 20 20 20 20 20 20 20 20 20 20 73 4d 73 67 20             sMsg 
2ed0: 3d 20 22 3d 6d 5f 22 2b 73 49 64 41 63 74 69 6f  = "=m_"+sIdActio
2ee0: 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c  n.            el
2ef0: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
2f00: 20 20 20 20 66 6f 72 20 78 20 69 6e 20 72 65 2e      for x in re.
2f10: 66 69 6e 64 69 74 65 72 28 72 22 5c 5c 28 5c 64  finditer(r"\\(\d
2f20: 2b 29 22 2c 20 73 4d 73 67 29 3a 0a 20 20 20 20  +)", sMsg):.    
2f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f40: 69 66 20 69 6e 74 28 78 2e 67 72 6f 75 70 28 31  if int(x.group(1
2f50: 29 29 20 3e 20 6e 47 72 6f 75 70 3a 0a 20 20 20  )) > nGroup:.   
2f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f70: 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72       print("# Er
2f80: 72 6f 72 20 69 6e 20 67 72 6f 75 70 73 20 69 6e  ror in groups in
2f90: 20 6d 65 73 73 61 67 65 20 61 74 20 6c 69 6e 65   message at line
2fa0: 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b   " + sIdAction +
2fb0: 20 22 20 28 22 2b 73 74 72 28 6e 47 72 6f 75 70   " ("+str(nGroup
2fc0: 29 2b 22 20 67 72 6f 75 70 73 20 6f 6e 6c 79 29  )+" groups only)
2fd0: 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ").             
2fe0: 20 20 20 69 66 20 72 65 2e 73 65 61 72 63 68 28     if re.search(
2ff0: 22 5b 2e 5d 5c 5c 77 2b 5b 28 5d 22 2c 20 73 4d  "[.]\\w+[(]", sM
3000: 73 67 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  sg):.           
3010: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
3020: 23 20 45 72 72 6f 72 20 69 6e 20 6d 65 73 73 61  # Error in messa
3030: 67 65 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  ge at line " + s
3040: 49 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 20 54  IdAction + ":  T
3050: 68 69 73 20 6d 65 73 73 61 67 65 20 6c 6f 6f 6b  his message look
3060: 73 20 6c 69 6b 65 20 63 6f 64 65 2e 20 4c 69 6e  s like code. Lin
3070: 65 20 73 68 6f 75 6c 64 20 62 65 67 69 6e 20 77  e should begin w
3080: 69 74 68 20 3d 22 29 0a 20 20 20 20 20 20 20 20  ith =").        
3090: 20 20 20 20 0a 20 20 20 20 69 66 20 73 41 63 74      .    if sAct
30a0: 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 20  ion[0:1] == "=" 
30b0: 6f 72 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3d  or cAction == "=
30c0: 22 3a 0a 20 20 20 20 20 20 20 20 69 66 20 22 64  ":.        if "d
30d0: 65 66 69 6e 65 22 20 69 6e 20 73 41 63 74 69 6f  efine" in sActio
30e0: 6e 20 61 6e 64 20 6e 6f 74 20 72 65 2e 73 65 61  n and not re.sea
30f0: 72 63 68 28 72 22 64 65 66 69 6e 65 5c 28 5c 5c  rch(r"define\(\\
3100: 5c 64 2b 20 2a 2c 20 2a 5c 5b 2e 2a 5c 5d 20 2a  \d+ *, *\[.*\] *
3110: 5c 29 22 2c 20 73 41 63 74 69 6f 6e 29 3a 0a 20  \)", sAction):. 
3120: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
3130: 28 22 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74  ("# Error in act
3140: 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ion at line " + 
3150: 73 49 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 73  sIdAction + ": s
3160: 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 66  econd argument f
3170: 6f 72 20 64 65 66 69 6e 65 20 6d 75 73 74 20 62  or define must b
3180: 65 20 61 20 6c 69 73 74 20 6f 66 20 73 74 72 69  e a list of stri
3190: 6e 67 73 22 29 0a 20 20 20 20 20 20 20 20 73 41  ngs").        sA
31a0: 63 74 69 6f 6e 20 3d 20 70 72 65 70 61 72 65 46  ction = prepareF
31b0: 75 6e 63 74 69 6f 6e 28 73 41 63 74 69 6f 6e 29  unction(sAction)
31c0: 0a 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e  .        sAction
31d0: 20 3d 20 73 41 63 74 69 6f 6e 2e 72 65 70 6c 61   = sAction.repla
31e0: 63 65 28 22 6d 2e 67 72 6f 75 70 28 69 5b 34 5d  ce("m.group(i[4]
31f0: 29 22 2c 20 22 6d 2e 67 72 6f 75 70 28 22 2b 73  )", "m.group("+s
3200: 74 72 28 69 47 72 6f 75 70 29 2b 22 29 22 29 0a  tr(iGroup)+")").
3210: 20 20 20 20 20 20 20 20 66 6f 72 20 78 20 69 6e          for x in
3220: 20 72 65 2e 66 69 6e 64 69 74 65 72 28 22 67 72   re.finditer("gr
3230: 6f 75 70 5b 28 5d 28 5c 64 2b 29 5b 29 5d 22 2c  oup[(](\d+)[)]",
3240: 20 73 41 63 74 69 6f 6e 29 3a 0a 20 20 20 20 20   sAction):.     
3250: 20 20 20 20 20 20 20 69 66 20 69 6e 74 28 78 2e         if int(x.
3260: 67 72 6f 75 70 28 31 29 29 20 3e 20 6e 47 72 6f  group(1)) > nGro
3270: 75 70 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  up:.            
3280: 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72      print("# Err
3290: 6f 72 20 69 6e 20 67 72 6f 75 70 73 20 69 6e 20  or in groups in 
32a0: 72 65 70 6c 61 63 65 6d 65 6e 74 20 61 74 20 6c  replacement at l
32b0: 69 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f  ine " + sIdActio
32c0: 6e 20 2b 20 22 20 28 22 2b 73 74 72 28 6e 47 72  n + " ("+str(nGr
32d0: 6f 75 70 29 2b 22 20 67 72 6f 75 70 73 20 6f 6e  oup)+" groups on
32e0: 6c 79 29 22 29 0a 20 20 20 20 65 6c 73 65 3a 0a  ly)").    else:.
32f0: 20 20 20 20 20 20 20 20 66 6f 72 20 78 20 69 6e          for x in
3300: 20 72 65 2e 66 69 6e 64 69 74 65 72 28 72 22 5c   re.finditer(r"\
3310: 5c 28 5c 64 2b 29 22 2c 20 73 41 63 74 69 6f 6e  \(\d+)", sAction
3320: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  ):.            i
3330: 66 20 69 6e 74 28 78 2e 67 72 6f 75 70 28 31 29  f int(x.group(1)
3340: 29 20 3e 20 6e 47 72 6f 75 70 3a 0a 20 20 20 20  ) > nGroup:.    
3350: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
3360: 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20 67 72  t("# Error in gr
3370: 6f 75 70 73 20 69 6e 20 72 65 70 6c 61 63 65 6d  oups in replacem
3380: 65 6e 74 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ent at line " + 
3390: 73 49 64 41 63 74 69 6f 6e 20 2b 20 22 20 28 22  sIdAction + " ("
33a0: 2b 73 74 72 28 6e 47 72 6f 75 70 29 2b 22 20 67  +str(nGroup)+" g
33b0: 72 6f 75 70 73 20 6f 6e 6c 79 29 22 29 0a 20 20  roups only)").  
33c0: 20 20 20 20 20 20 69 66 20 72 65 2e 73 65 61 72        if re.sear
33d0: 63 68 28 22 5b 2e 5d 5c 5c 77 2b 5b 28 5d 7c 73  ch("[.]\\w+[(]|s
33e0: 75 67 67 5c 5c 77 2b 5b 28 5d 22 2c 20 73 41 63  ugg\\w+[(]", sAc
33f0: 74 69 6f 6e 29 3a 0a 20 20 20 20 20 20 20 20 20  tion):.         
3400: 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f     print("# Erro
3410: 72 20 69 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c  r in action at l
3420: 69 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f  ine " + sIdActio
3430: 6e 20 2b 20 22 3a 20 20 54 68 69 73 20 61 63 74  n + ":  This act
3440: 69 6f 6e 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20 63  ion looks like c
3450: 6f 64 65 2e 20 4c 69 6e 65 20 73 68 6f 75 6c 64  ode. Line should
3460: 20 62 65 67 69 6e 20 77 69 74 68 20 3d 22 29 0a   begin with =").
3470: 0a 20 20 20 20 69 66 20 63 41 63 74 69 6f 6e 20  .    if cAction 
3480: 3d 3d 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20  == "-":.        
3490: 23 23 20 65 72 72 6f 72 20 64 65 74 65 63 74 65  ## error detecte
34a0: 64 20 2d 2d 3e 20 73 75 67 67 65 73 74 69 6f 6e  d --> suggestion
34b0: 0a 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20  .        if not 
34c0: 73 41 63 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20  sAction:.       
34d0: 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72       print("# Er
34e0: 72 6f 72 20 69 6e 20 61 63 74 69 6f 6e 20 61 74  ror in action at
34f0: 20 6c 69 6e 65 20 22 20 2b 20 73 49 64 41 63 74   line " + sIdAct
3500: 69 6f 6e 20 2b 20 22 3a 20 20 54 68 69 73 20 61  ion + ":  This a
3510: 63 74 69 6f 6e 20 69 73 20 65 6d 70 74 79 2e 22  ction is empty."
3520: 29 0a 20 20 20 20 20 20 20 20 69 66 20 73 41 63  ).        if sAc
3530: 74 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22  tion[0:1] == "="
3540: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 46  :.            lF
3550: 55 4e 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28  UNCTIONS.append(
3560: 28 22 73 5f 22 2b 73 49 64 41 63 74 69 6f 6e 2c  ("s_"+sIdAction,
3570: 20 73 41 63 74 69 6f 6e 5b 31 3a 5d 29 29 0a 20   sAction[1:])). 
3580: 20 20 20 20 20 20 20 20 20 20 20 73 41 63 74 69             sActi
3590: 6f 6e 20 3d 20 22 3d 73 5f 22 2b 73 49 64 41 63  on = "=s_"+sIdAc
35a0: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 65 6c 69  tion.        eli
35b0: 66 20 73 41 63 74 69 6f 6e 2e 73 74 61 72 74 73  f sAction.starts
35c0: 77 69 74 68 28 27 22 27 29 20 61 6e 64 20 73 41  with('"') and sA
35d0: 63 74 69 6f 6e 2e 65 6e 64 73 77 69 74 68 28 27  ction.endswith('
35e0: 22 27 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "'):.           
35f0: 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69   sAction = sActi
3600: 6f 6e 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20 20  on[1:-1].       
3610: 20 69 66 20 6e 6f 74 20 73 4d 73 67 3a 0a 20 20   if not sMsg:.  
3620: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
3630: 22 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69  "# Error in acti
3640: 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  on at line " + s
3650: 49 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 20 74  IdAction + ":  t
3660: 68 65 20 6d 65 73 73 61 67 65 20 69 73 20 65 6d  he message is em
3670: 70 74 79 2e 22 29 0a 20 20 20 20 20 20 20 20 72  pty.").        r
3680: 65 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69 6f  eturn [sConditio
3690: 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41 63 74  n, cAction, sAct
36a0: 69 6f 6e 2c 20 69 47 72 6f 75 70 2c 20 73 4d 73  ion, iGroup, sMs
36b0: 67 2c 20 73 55 52 4c 5d 0a 20 20 20 20 65 6c 69  g, sURL].    eli
36c0: 66 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 7e 22  f cAction == "~"
36d0: 3a 0a 20 20 20 20 20 20 20 20 23 23 20 74 65 78  :.        ## tex
36e0: 74 20 70 72 6f 63 65 73 73 6f 72 0a 20 20 20 20  t processor.    
36f0: 20 20 20 20 69 66 20 6e 6f 74 20 73 41 63 74 69      if not sActi
3700: 6f 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  on:.            
3710: 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69  print("# Error i
3720: 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65  n action at line
3730: 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b   " + sIdAction +
3740: 20 22 3a 20 20 54 68 69 73 20 61 63 74 69 6f 6e   ":  This action
3750: 20 69 73 20 65 6d 70 74 79 2e 22 29 0a 20 20 20   is empty.").   
3760: 20 20 20 20 20 69 66 20 73 41 63 74 69 6f 6e 5b       if sAction[
3770: 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20  0:1] == "=":.   
3780: 20 20 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49           lFUNCTI
3790: 4f 4e 53 2e 61 70 70 65 6e 64 28 28 22 70 5f 22  ONS.append(("p_"
37a0: 2b 73 49 64 41 63 74 69 6f 6e 2c 20 73 41 63 74  +sIdAction, sAct
37b0: 69 6f 6e 5b 31 3a 5d 29 29 0a 20 20 20 20 20 20  ion[1:])).      
37c0: 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20        sAction = 
37d0: 22 3d 70 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a  "=p_"+sIdAction.
37e0: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 41 63          elif sAc
37f0: 74 69 6f 6e 2e 73 74 61 72 74 73 77 69 74 68 28  tion.startswith(
3800: 27 22 27 29 20 61 6e 64 20 73 41 63 74 69 6f 6e  '"') and sAction
3810: 2e 65 6e 64 73 77 69 74 68 28 27 22 27 29 3a 0a  .endswith('"'):.
3820: 20 20 20 20 20 20 20 20 20 20 20 20 73 41 63 74              sAct
3830: 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a  ion = sAction[1:
3840: 2d 31 5d 0a 20 20 20 20 20 20 20 20 72 65 74 75  -1].        retu
3850: 72 6e 20 5b 73 43 6f 6e 64 69 74 69 6f 6e 2c 20  rn [sCondition, 
3860: 63 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e  cAction, sAction
3870: 2c 20 69 47 72 6f 75 70 5d 0a 20 20 20 20 65 6c  , iGroup].    el
3880: 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3d  if cAction == "=
3890: 22 3a 0a 20 20 20 20 20 20 20 20 23 23 20 64 69  ":.        ## di
38a0: 73 61 6d 62 69 67 75 61 74 6f 72 0a 20 20 20 20  sambiguator.    
38b0: 20 20 20 20 69 66 20 73 41 63 74 69 6f 6e 5b 30      if sAction[0
38c0: 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20  :1] == "=":.    
38d0: 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20          sAction 
38e0: 3d 20 73 41 63 74 69 6f 6e 5b 31 3a 5d 0a 20 20  = sAction[1:].  
38f0: 20 20 20 20 20 20 69 66 20 6e 6f 74 20 73 41 63        if not sAc
3900: 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 20 20  tion:.          
3910: 20 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72    print("# Error
3920: 20 69 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c 69   in action at li
3930: 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e  ne " + sIdAction
3940: 20 2b 20 22 3a 20 20 54 68 69 73 20 61 63 74 69   + ":  This acti
3950: 6f 6e 20 69 73 20 65 6d 70 74 79 2e 22 29 0a 20  on is empty."). 
3960: 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f 4e         lFUNCTION
3970: 53 2e 61 70 70 65 6e 64 28 28 22 64 5f 22 2b 73  S.append(("d_"+s
3980: 49 64 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f  IdAction, sActio
3990: 6e 29 29 0a 20 20 20 20 20 20 20 20 73 41 63 74  n)).        sAct
39a0: 69 6f 6e 20 3d 20 22 64 5f 22 2b 73 49 64 41 63  ion = "d_"+sIdAc
39b0: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 72 65 74  tion.        ret
39c0: 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69 6f 6e 2c  urn [sCondition,
39d0: 20 63 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f   cAction, sActio
39e0: 6e 5d 0a 20 20 20 20 65 6c 69 66 20 63 41 63 74  n].    elif cAct
39f0: 69 6f 6e 20 3d 3d 20 22 3e 22 3a 0a 20 20 20 20  ion == ">":.    
3a00: 20 20 20 20 23 23 20 6e 6f 20 61 63 74 69 6f 6e      ## no action
3a10: 2c 20 62 72 65 61 6b 20 6c 6f 6f 70 20 69 66 20  , break loop if 
3a20: 63 6f 6e 64 69 74 69 6f 6e 20 69 73 20 46 61 6c  condition is Fal
3a30: 73 65 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  se.        retur
3a40: 6e 20 5b 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 63  n [sCondition, c
3a50: 41 63 74 69 6f 6e 2c 20 22 22 5d 0a 20 20 20 20  Action, ""].    
3a60: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 70 72  else:.        pr
3a70: 69 6e 74 28 22 23 20 55 6e 6b 6e 6f 77 6e 20 61  int("# Unknown a
3a80: 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20  ction at line " 
3a90: 2b 20 73 49 64 41 63 74 69 6f 6e 29 0a 20 20 20  + sIdAction).   
3aa0: 20 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65       return None
3ab0: 0a 0a 0a 64 65 66 20 5f 63 61 6c 63 52 75 6c 65  ...def _calcRule
3ac0: 73 53 74 61 74 73 20 28 6c 52 75 6c 65 73 29 3a  sStats (lRules):
3ad0: 0a 20 20 20 20 64 20 3d 20 7b 27 3d 27 3a 30 2c  .    d = {'=':0,
3ae0: 20 27 7e 27 3a 20 30 2c 20 27 2d 27 3a 20 30 2c   '~': 0, '-': 0,
3af0: 20 27 3e 27 3a 20 30 7d 0a 20 20 20 20 66 6f 72   '>': 0}.    for
3b00: 20 61 52 75 6c 65 20 69 6e 20 6c 52 75 6c 65 73   aRule in lRules
3b10: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 61 52 75  :.        if aRu
3b20: 6c 65 5b 30 5d 20 21 3d 20 22 40 40 40 40 22 3a  le[0] != "@@@@":
3b30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72  .            for
3b40: 20 61 41 63 74 69 6f 6e 20 69 6e 20 61 52 75 6c   aAction in aRul
3b50: 65 5b 36 5d 3a 0a 20 20 20 20 20 20 20 20 20 20  e[6]:.          
3b60: 20 20 20 20 20 20 64 5b 61 41 63 74 69 6f 6e 5b        d[aAction[
3b70: 31 5d 5d 20 3d 20 64 5b 61 41 63 74 69 6f 6e 5b  1]] = d[aAction[
3b80: 31 5d 5d 20 2b 20 31 0a 20 20 20 20 72 65 74 75  1]] + 1.    retu
3b90: 72 6e 20 28 64 2c 20 6c 65 6e 28 6c 52 75 6c 65  rn (d, len(lRule
3ba0: 73 29 29 0a 0a 0a 64 65 66 20 64 69 73 70 6c 61  s))...def displa
3bb0: 79 53 74 61 74 73 20 28 6c 50 61 72 61 67 72 61  yStats (lParagra
3bc0: 70 68 52 75 6c 65 73 2c 20 6c 53 65 6e 74 65 6e  phRules, lSenten
3bd0: 63 65 52 75 6c 65 73 29 3a 0a 20 20 20 20 70 72  ceRules):.    pr
3be0: 69 6e 74 28 22 20 20 7b 3a 3e 31 38 7d 20 7b 3a  int("  {:>18} {:
3bf0: 3e 31 38 7d 20 7b 3a 3e 31 38 7d 20 7b 3a 3e 31  >18} {:>18} {:>1
3c00: 38 7d 22 2e 66 6f 72 6d 61 74 28 22 44 49 53 41  8}".format("DISA
3c10: 4d 42 49 47 55 41 54 4f 52 22 2c 20 22 54 45 58  MBIGUATOR", "TEX
3c20: 54 20 50 52 4f 43 45 53 53 4f 52 22 2c 20 22 47  T PROCESSOR", "G
3c30: 52 41 4d 4d 41 52 20 43 48 45 43 4b 49 4e 47 22  RAMMAR CHECKING"
3c40: 2c 20 22 52 45 47 45 58 22 29 29 0a 20 20 20 20  , "REGEX")).    
3c50: 64 2c 20 6e 52 75 6c 65 20 3d 20 5f 63 61 6c 63  d, nRule = _calc
3c60: 52 75 6c 65 73 53 74 61 74 73 28 6c 50 61 72 61  RulesStats(lPara
3c70: 67 72 61 70 68 52 75 6c 65 73 29 0a 20 20 20 20  graphRules).    
3c80: 70 72 69 6e 74 28 22 c2 a7 20 7b 3a 3e 31 30 7d  print(".. {:>10}
3c90: 20 61 63 74 69 6f 6e 73 20 7b 3a 3e 31 30 7d 20   actions {:>10} 
3ca0: 61 63 74 69 6f 6e 73 20 7b 3a 3e 31 30 7d 20 61  actions {:>10} a
3cb0: 63 74 69 6f 6e 73 20 20 69 6e 20 7b 3a 3e 38 7d  ctions  in {:>8}
3cc0: 20 72 75 6c 65 73 22 2e 66 6f 72 6d 61 74 28 64   rules".format(d
3cd0: 5b 27 3d 27 5d 2c 20 64 5b 27 7e 27 5d 2c 20 64  ['='], d['~'], d
3ce0: 5b 27 2d 27 5d 2c 20 6e 52 75 6c 65 29 29 0a 20  ['-'], nRule)). 
3cf0: 20 20 20 64 2c 20 6e 52 75 6c 65 20 3d 20 5f 63     d, nRule = _c
3d00: 61 6c 63 52 75 6c 65 73 53 74 61 74 73 28 6c 53  alcRulesStats(lS
3d10: 65 6e 74 65 6e 63 65 52 75 6c 65 73 29 0a 20 20  entenceRules).  
3d20: 20 20 70 72 69 6e 74 28 22 73 20 7b 3a 3e 31 30    print("s {:>10
3d30: 7d 20 61 63 74 69 6f 6e 73 20 7b 3a 3e 31 30 7d  } actions {:>10}
3d40: 20 61 63 74 69 6f 6e 73 20 7b 3a 3e 31 30 7d 20   actions {:>10} 
3d50: 61 63 74 69 6f 6e 73 20 20 69 6e 20 7b 3a 3e 38  actions  in {:>8
3d60: 7d 20 72 75 6c 65 73 22 2e 66 6f 72 6d 61 74 28  } rules".format(
3d70: 64 5b 27 3d 27 5d 2c 20 64 5b 27 7e 27 5d 2c 20  d['='], d['~'], 
3d80: 64 5b 27 2d 27 5d 2c 20 6e 52 75 6c 65 29 29 0a  d['-'], nRule)).
3d90: 0a 0a 64 65 66 20 6d 65 72 67 65 52 75 6c 65 73  ..def mergeRules
3da0: 42 79 4f 70 74 69 6f 6e 20 28 6c 52 75 6c 65 73  ByOption (lRules
3db0: 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20  ):.    "returns 
3dc0: 61 20 6c 69 73 74 20 6f 66 20 74 75 70 6c 65 73  a list of tuples
3dd0: 20 5b 6f 70 74 69 6f 6e 2c 20 6c 69 73 74 20 6f   [option, list o
3de0: 66 20 72 75 6c 65 73 5d 20 6b 65 65 70 69 6e 67  f rules] keeping
3df0: 20 74 68 65 20 72 75 6c 65 73 20 6f 72 64 65 72   the rules order
3e00: 22 0a 20 20 20 20 6c 46 69 6e 61 6c 20 3d 20 5b  ".    lFinal = [
3e10: 5d 0a 20 20 20 20 6c 54 65 6d 70 20 3d 20 5b 5d  ].    lTemp = []
3e20: 0a 20 20 20 20 73 4f 70 74 69 6f 6e 20 3d 20 4e  .    sOption = N
3e30: 6f 6e 65 0a 20 20 20 20 66 6f 72 20 61 52 75 6c  one.    for aRul
3e40: 65 20 69 6e 20 6c 52 75 6c 65 73 3a 0a 20 20 20  e in lRules:.   
3e50: 20 20 20 20 20 69 66 20 61 52 75 6c 65 5b 30 5d       if aRule[0]
3e60: 20 21 3d 20 73 4f 70 74 69 6f 6e 3a 0a 20 20 20   != sOption:.   
3e70: 20 20 20 20 20 20 20 20 20 69 66 20 73 4f 70 74           if sOpt
3e80: 69 6f 6e 20 21 3d 20 4e 6f 6e 65 3a 0a 20 20 20  ion != None:.   
3e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 46 69               lFi
3ea0: 6e 61 6c 2e 61 70 70 65 6e 64 28 5b 73 4f 70 74  nal.append([sOpt
3eb0: 69 6f 6e 2c 20 6c 54 65 6d 70 5d 29 0a 20 20 20  ion, lTemp]).   
3ec0: 20 20 20 20 20 20 20 20 20 23 20 6e 65 77 20 74           # new t
3ed0: 75 70 6c 65 0a 20 20 20 20 20 20 20 20 20 20 20  uple.           
3ee0: 20 73 4f 70 74 69 6f 6e 20 3d 20 61 52 75 6c 65   sOption = aRule
3ef0: 5b 30 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  [0].            
3f00: 6c 54 65 6d 70 20 3d 20 5b 5d 0a 20 20 20 20 20  lTemp = [].     
3f10: 20 20 20 6c 54 65 6d 70 2e 61 70 70 65 6e 64 28     lTemp.append(
3f20: 61 52 75 6c 65 5b 31 3a 5d 29 0a 20 20 20 20 6c  aRule[1:]).    l
3f30: 46 69 6e 61 6c 2e 61 70 70 65 6e 64 28 5b 73 4f  Final.append([sO
3f40: 70 74 69 6f 6e 2c 20 6c 54 65 6d 70 5d 29 0a 20  ption, lTemp]). 
3f50: 20 20 20 72 65 74 75 72 6e 20 6c 46 69 6e 61 6c     return lFinal
3f60: 0a 0a 0a 64 65 66 20 70 72 65 70 61 72 65 4f 70  ...def prepareOp
3f70: 74 69 6f 6e 73 20 28 6c 4f 70 74 69 6f 6e 4c 69  tions (lOptionLi
3f80: 6e 65 73 29 3a 0a 20 20 20 20 22 72 65 74 75 72  nes):.    "retur
3f90: 6e 73 20 61 20 64 69 63 74 69 6f 6e 61 72 79 20  ns a dictionary 
3fa0: 77 69 74 68 20 64 61 74 61 20 61 62 6f 75 74 20  with data about 
3fb0: 6f 70 74 69 6f 6e 73 22 0a 20 20 20 20 73 4c 61  options".    sLa
3fc0: 6e 67 20 3d 20 22 22 0a 20 20 20 20 73 44 65 66  ng = "".    sDef
3fd0: 61 75 6c 74 55 49 4c 61 6e 67 20 3d 20 22 22 0a  aultUILang = "".
3fe0: 20 20 20 20 6c 53 74 72 75 63 74 4f 70 74 20 3d      lStructOpt =
3ff0: 20 5b 5d 0a 20 20 20 20 6c 4f 70 74 20 3d 20 5b   [].    lOpt = [
4000: 5d 0a 20 20 20 20 64 4f 70 74 4c 61 62 65 6c 20  ].    dOptLabel 
4010: 3d 20 7b 7d 0a 20 20 20 20 64 4f 70 74 50 72 69  = {}.    dOptPri
4020: 6f 72 69 74 79 20 3d 20 7b 7d 0a 20 20 20 20 66  ority = {}.    f
4030: 6f 72 20 73 4c 69 6e 65 20 69 6e 20 6c 4f 70 74  or sLine in lOpt
4040: 69 6f 6e 4c 69 6e 65 73 3a 0a 20 20 20 20 20 20  ionLines:.      
4050: 20 20 73 4c 69 6e 65 20 3d 20 73 4c 69 6e 65 2e    sLine = sLine.
4060: 73 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20  strip().        
4070: 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77  if sLine.startsw
4080: 69 74 68 28 22 4f 50 54 47 52 4f 55 50 2f 22 29  ith("OPTGROUP/")
4090: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 20  :.            m 
40a0: 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54 47  = re.match("OPTG
40b0: 52 4f 55 50 2f 28 5b 61 2d 7a 30 2d 39 5d 2b 29  ROUP/([a-z0-9]+)
40c0: 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29 0a  :(.+)$", sLine).
40d0: 20 20 20 20 20 20 20 20 20 20 20 20 6c 53 74 72              lStr
40e0: 75 63 74 4f 70 74 2e 61 70 70 65 6e 64 28 20 28  uctOpt.append( (
40f0: 6d 2e 67 72 6f 75 70 28 31 29 2c 20 6c 69 73 74  m.group(1), list
4100: 28 6d 61 70 28 73 74 72 2e 73 70 6c 69 74 2c 20  (map(str.split, 
4110: 6d 2e 67 72 6f 75 70 28 32 29 2e 73 70 6c 69 74  m.group(2).split
4120: 28 22 2c 22 29 29 29 29 20 29 0a 20 20 20 20 20  (",")))) ).     
4130: 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74     elif sLine.st
4140: 61 72 74 73 77 69 74 68 28 22 4f 50 54 53 4f 46  artswith("OPTSOF
4150: 54 57 41 52 45 3a 22 29 3a 0a 20 20 20 20 20 20  TWARE:"):.      
4160: 20 20 20 20 20 20 6c 4f 70 74 20 3d 20 5b 20 5b        lOpt = [ [
4170: 73 2c 20 7b 7d 5d 20 20 66 6f 72 20 73 20 69 6e  s, {}]  for s in
4180: 20 73 4c 69 6e 65 5b 31 32 3a 5d 2e 73 74 72 69   sLine[12:].stri
4190: 70 28 29 2e 73 70 6c 69 74 28 29 20 5d 20 20 23  p().split() ]  #
41a0: 20 64 6f 6e e2 80 99 74 20 75 73 65 20 74 75 70   don...t use tup
41b0: 6c 65 73 20 28 73 2c 20 7b 7d 29 2c 20 62 65 63  les (s, {}), bec
41c0: 61 75 73 65 20 75 6e 6b 6e 6f 77 6e 20 74 6f 20  ause unknown to 
41d0: 4a 53 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  JS.        elif 
41e0: 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68  sLine.startswith
41f0: 28 22 4f 50 54 2f 22 29 3a 0a 20 20 20 20 20 20  ("OPT/"):.      
4200: 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74        m = re.mat
4210: 63 68 28 22 4f 50 54 2f 28 5b 61 2d 7a 30 2d 39  ch("OPT/([a-z0-9
4220: 5d 2b 29 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e  ]+):(.+)$", sLin
4230: 65 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  e).            f
4240: 6f 72 20 69 2c 20 73 4f 70 74 20 69 6e 20 65 6e  or i, sOpt in en
4250: 75 6d 65 72 61 74 65 28 6d 2e 67 72 6f 75 70 28  umerate(m.group(
4260: 32 29 2e 73 70 6c 69 74 28 29 29 3a 0a 20 20 20  2).split()):.   
4270: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 4f 70               lOp
4280: 74 5b 69 5d 5b 31 5d 5b 6d 2e 67 72 6f 75 70 28  t[i][1][m.group(
4290: 31 29 5d 20 3d 20 20 65 76 61 6c 28 73 4f 70 74  1)] =  eval(sOpt
42a0: 29 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73  ).        elif s
42b0: 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28  Line.startswith(
42c0: 22 4f 50 54 50 52 49 4f 52 49 54 59 2f 22 29 3a  "OPTPRIORITY/"):
42d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d  .            m =
42e0: 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54 50 52   re.match("OPTPR
42f0: 49 4f 52 49 54 59 2f 28 5b 61 2d 7a 30 2d 39 5d  IORITY/([a-z0-9]
4300: 2b 29 3a 20 2a 28 5b 30 2d 39 5d 29 24 22 2c 20  +): *([0-9])$", 
4310: 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20  sLine).         
4320: 20 20 20 64 4f 70 74 50 72 69 6f 72 69 74 79 5b     dOptPriority[
4330: 6d 2e 67 72 6f 75 70 28 31 29 5d 20 3d 20 69 6e  m.group(1)] = in
4340: 74 28 6d 2e 67 72 6f 75 70 28 32 29 29 0a 20 20  t(m.group(2)).  
4350: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
4360: 2e 73 74 61 72 74 73 77 69 74 68 28 22 4f 50 54  .startswith("OPT
4370: 4c 41 4e 47 2f 22 29 3a 0a 20 20 20 20 20 20 20  LANG/"):.       
4380: 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63       m = re.matc
4390: 68 28 22 4f 50 54 4c 41 4e 47 2f 28 5b 61 2d 7a  h("OPTLANG/([a-z
43a0: 5d 5b 61 2d 7a 5d 28 3f 3a 5f 5b 41 2d 5a 5d 5b  ][a-z](?:_[A-Z][
43b0: 41 2d 5a 5d 7c 29 29 3a 28 2e 2b 29 24 22 2c 20  A-Z]|)):(.+)$", 
43c0: 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20  sLine).         
43d0: 20 20 20 73 4c 61 6e 67 20 3d 20 6d 2e 67 72 6f     sLang = m.gro
43e0: 75 70 28 31 29 5b 3a 32 5d 0a 20 20 20 20 20 20  up(1)[:2].      
43f0: 20 20 20 20 20 20 64 4f 70 74 4c 61 62 65 6c 5b        dOptLabel[
4400: 73 4c 61 6e 67 5d 20 3d 20 7b 20 22 5f 5f 6f 70  sLang] = { "__op
4410: 74 69 6f 6e 74 69 74 6c 65 5f 5f 22 3a 20 6d 2e  tiontitle__": m.
4420: 67 72 6f 75 70 28 32 29 2e 73 74 72 69 70 28 29  group(2).strip()
4430: 20 7d 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20   }.        elif 
4440: 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68  sLine.startswith
4450: 28 22 4f 50 54 44 45 46 41 55 4c 54 55 49 4c 41  ("OPTDEFAULTUILA
4460: 4e 47 3a 22 29 3a 0a 20 20 20 20 20 20 20 20 20  NG:"):.         
4470: 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28     m = re.match(
4480: 22 4f 50 54 44 45 46 41 55 4c 54 55 49 4c 41 4e  "OPTDEFAULTUILAN
4490: 47 3a 20 2a 28 5b 61 2d 7a 5d 5b 61 2d 7a 5d 28  G: *([a-z][a-z](
44a0: 3f 3a 5f 5b 41 2d 5a 5d 5b 41 2d 5a 5d 7c 29 29  ?:_[A-Z][A-Z]|))
44b0: 24 22 2c 20 73 4c 69 6e 65 29 0a 20 20 20 20 20  $", sLine).     
44c0: 20 20 20 20 20 20 20 73 44 65 66 61 75 6c 74 55         sDefaultU
44d0: 49 4c 61 6e 67 20 3d 20 6d 2e 67 72 6f 75 70 28  ILang = m.group(
44e0: 31 29 5b 3a 32 5d 0a 20 20 20 20 20 20 20 20 65  1)[:2].        e
44f0: 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73  lif sLine.starts
4500: 77 69 74 68 28 22 4f 50 54 4c 41 42 45 4c 2f 22  with("OPTLABEL/"
4510: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d  ):.            m
4520: 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54   = re.match("OPT
4530: 4c 41 42 45 4c 2f 28 5b 61 2d 7a 30 2d 39 5d 2b  LABEL/([a-z0-9]+
4540: 29 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29  ):(.+)$", sLine)
4550: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 4f 70  .            dOp
4560: 74 4c 61 62 65 6c 5b 73 4c 61 6e 67 5d 5b 6d 2e  tLabel[sLang][m.
4570: 67 72 6f 75 70 28 31 29 5d 20 3d 20 6c 69 73 74  group(1)] = list
4580: 28 6d 61 70 28 73 74 72 2e 73 74 72 69 70 2c 20  (map(str.strip, 
4590: 6d 2e 67 72 6f 75 70 28 32 29 2e 73 70 6c 69 74  m.group(2).split
45a0: 28 22 7c 22 29 29 29 20 20 69 66 20 22 7c 22 20  ("|")))  if "|" 
45b0: 69 6e 20 6d 2e 67 72 6f 75 70 28 32 29 20 20 65  in m.group(2)  e
45c0: 6c 73 65 20 20 5b 6d 2e 67 72 6f 75 70 28 32 29  lse  [m.group(2)
45d0: 2e 73 74 72 69 70 28 29 2c 20 22 22 5d 0a 20 20  .strip(), ""].  
45e0: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
45f0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
4600: 20 45 72 72 6f 72 2e 20 57 72 6f 6e 67 20 6f 70   Error. Wrong op
4610: 74 69 6f 6e 20 6c 69 6e 65 20 69 6e 3a 5c 6e 20  tion line in:\n 
4620: 20 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20   ").            
4630: 70 72 69 6e 74 28 73 4c 69 6e 65 29 0a 20 20 20  print(sLine).   
4640: 20 70 72 69 6e 74 28 22 20 20 6f 70 74 69 6f 6e   print("  option
4650: 73 20 64 65 66 69 6e 65 64 20 66 6f 72 3a 20 22  s defined for: "
4660: 20 2b 20 22 2c 20 22 2e 6a 6f 69 6e 28 5b 20 74   + ", ".join([ t
4670: 5b 30 5d 20 66 6f 72 20 74 20 69 6e 20 6c 4f 70  [0] for t in lOp
4680: 74 20 5d 29 29 0a 20 20 20 20 64 4f 70 74 69 6f  t ])).    dOptio
4690: 6e 73 20 3d 20 7b 20 22 6c 53 74 72 75 63 74 4f  ns = { "lStructO
46a0: 70 74 22 3a 20 6c 53 74 72 75 63 74 4f 70 74 2c  pt": lStructOpt,
46b0: 20 22 64 4f 70 74 4c 61 62 65 6c 22 3a 20 64 4f   "dOptLabel": dO
46c0: 70 74 4c 61 62 65 6c 2c 20 22 73 44 65 66 61 75  ptLabel, "sDefau
46d0: 6c 74 55 49 4c 61 6e 67 22 3a 20 73 44 65 66 61  ltUILang": sDefa
46e0: 75 6c 74 55 49 4c 61 6e 67 20 7d 0a 20 20 20 20  ultUILang }.    
46f0: 64 4f 70 74 69 6f 6e 73 2e 75 70 64 61 74 65 28  dOptions.update(
4700: 7b 20 22 64 4f 70 74 22 2b 6b 3a 20 76 20 20 66  { "dOpt"+k: v  f
4710: 6f 72 20 6b 2c 20 76 20 69 6e 20 6c 4f 70 74 20  or k, v in lOpt 
4720: 7d 29 0a 20 20 20 20 72 65 74 75 72 6e 20 64 4f  }).    return dO
4730: 70 74 69 6f 6e 73 2c 20 64 4f 70 74 50 72 69 6f  ptions, dOptPrio
4740: 72 69 74 79 0a 0a 0a 64 65 66 20 70 72 69 6e 74  rity...def print
4750: 42 6f 6f 6b 6d 61 72 6b 20 28 6e 4c 65 76 65 6c  Bookmark (nLevel
4760: 2c 20 73 43 6f 6d 6d 65 6e 74 2c 20 6e 4c 69 6e  , sComment, nLin
4770: 65 29 3a 0a 20 20 20 20 70 72 69 6e 74 28 22 20  e):.    print(" 
4780: 20 7b 3a 3e 36 7d 3a 20 20 7b 7d 22 2e 66 6f 72   {:>6}:  {}".for
4790: 6d 61 74 28 6e 4c 69 6e 65 2c 20 22 20 20 22 20  mat(nLine, "  " 
47a0: 2a 20 6e 4c 65 76 65 6c 20 2b 20 73 43 6f 6d 6d  * nLevel + sComm
47b0: 65 6e 74 29 29 0a 0a 0a 64 65 66 20 6d 61 6b 65  ent))...def make
47c0: 20 28 73 70 4c 61 6e 67 2c 20 73 4c 61 6e 67 2c   (spLang, sLang,
47d0: 20 62 4a 61 76 61 53 63 72 69 70 74 29 3a 0a 20   bJavaScript):. 
47e0: 20 20 20 22 63 6f 6d 70 69 6c 65 20 72 75 6c 65     "compile rule
47f0: 73 2c 20 72 65 74 75 72 6e 73 20 61 20 64 69 63  s, returns a dic
4800: 74 69 6f 6e 61 72 79 20 6f 66 20 76 61 6c 75 65  tionary of value
4810: 73 22 0a 20 20 20 20 23 20 66 6f 72 20 63 6c 61  s".    # for cla
4820: 72 69 74 79 20 70 75 72 70 6f 73 65 2c 20 64 6f  rity purpose, do
4830: 6e e2 80 99 74 20 63 72 65 61 74 65 20 61 6e 79  n...t create any
4840: 20 66 69 6c 65 20 68 65 72 65 0a 0a 20 20 20 20   file here..    
4850: 70 72 69 6e 74 28 22 3e 20 72 65 61 64 20 72 75  print("> read ru
4860: 6c 65 73 20 66 69 6c 65 2e 2e 2e 22 29 0a 20 20  les file...").  
4870: 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 6c    try:.        l
4880: 52 75 6c 65 73 20 3d 20 6f 70 65 6e 28 73 70 4c  Rules = open(spL
4890: 61 6e 67 20 2b 20 22 2f 72 75 6c 65 73 2e 67 72  ang + "/rules.gr
48a0: 78 22 2c 20 27 72 27 2c 20 65 6e 63 6f 64 69 6e  x", 'r', encodin
48b0: 67 3d 22 75 74 66 2d 38 22 29 2e 72 65 61 64 6c  g="utf-8").readl
48c0: 69 6e 65 73 28 29 0a 20 20 20 20 65 78 63 65 70  ines().    excep
48d0: 74 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  t:.        print
48e0: 28 22 45 72 72 6f 72 2e 20 52 75 6c 65 73 20 66  ("Error. Rules f
48f0: 69 6c 65 20 69 6e 20 70 72 6f 6a 65 63 74 20 5b  ile in project [
4900: 22 20 2b 20 73 4c 61 6e 67 20 2b 20 22 5d 20 6e  " + sLang + "] n
4910: 6f 74 20 66 6f 75 6e 64 2e 22 29 0a 20 20 20 20  ot found.").    
4920: 20 20 20 20 65 78 69 74 28 29 0a 0a 20 20 20 20      exit()..    
4930: 23 20 72 65 6d 6f 76 69 6e 67 20 63 6f 6d 6d 65  # removing comme
4940: 6e 74 73 2c 20 7a 65 72 6f 69 6e 67 20 65 6d 70  nts, zeroing emp
4950: 74 79 20 6c 69 6e 65 73 2c 20 63 72 65 61 74 69  ty lines, creati
4960: 6e 67 20 64 65 66 69 6e 69 74 69 6f 6e 73 2c 20  ng definitions, 
4970: 73 74 6f 72 69 6e 67 20 74 65 73 74 73 2c 20 6d  storing tests, m
4980: 65 72 67 69 6e 67 20 72 75 6c 65 20 6c 69 6e 65  erging rule line
4990: 73 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 70  s.    print("  p
49a0: 61 72 73 69 6e 67 20 72 75 6c 65 73 2e 2e 2e 22  arsing rules..."
49b0: 29 0a 20 20 20 20 67 6c 6f 62 61 6c 20 64 44 45  ).    global dDE
49c0: 46 0a 20 20 20 20 6c 52 75 6c 65 4c 69 6e 65 20  F.    lRuleLine 
49d0: 3d 20 5b 5d 0a 20 20 20 20 6c 54 65 73 74 20 3d  = [].    lTest =
49e0: 20 5b 5d 0a 20 20 20 20 6c 4f 70 74 20 3d 20 5b   [].    lOpt = [
49f0: 5d 0a 20 20 20 20 62 47 72 61 70 68 20 3d 20 46  ].    bGraph = F
4a00: 61 6c 73 65 0a 20 20 20 20 6c 47 72 61 70 68 52  alse.    lGraphR
4a10: 75 6c 65 20 3d 20 5b 5d 0a 0a 20 20 20 20 66 6f  ule = []..    fo
4a20: 72 20 69 2c 20 73 4c 69 6e 65 20 69 6e 20 65 6e  r i, sLine in en
4a30: 75 6d 65 72 61 74 65 28 6c 52 75 6c 65 73 2c 20  umerate(lRules, 
4a40: 31 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73  1):.        if s
4a50: 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28  Line.startswith(
4a60: 27 23 45 4e 44 27 29 3a 0a 20 20 20 20 20 20 20  '#END'):.       
4a70: 20 20 20 20 20 23 20 61 72 62 69 74 72 61 72 79       # arbitrary
4a80: 20 65 6e 64 0a 20 20 20 20 20 20 20 20 20 20 20   end.           
4a90: 20 70 72 69 6e 74 42 6f 6f 6b 6d 61 72 6b 28 30   printBookmark(0
4aa0: 2c 20 22 42 52 45 41 4b 20 42 59 20 23 45 4e 44  , "BREAK BY #END
4ab0: 22 2c 20 69 29 0a 20 20 20 20 20 20 20 20 20 20  ", i).          
4ac0: 20 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20    break.        
4ad0: 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74  elif sLine.start
4ae0: 73 77 69 74 68 28 22 23 22 29 3a 0a 20 20 20 20  swith("#"):.    
4af0: 20 20 20 20 20 20 20 20 23 20 63 6f 6d 6d 65 6e          # commen
4b00: 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 61  t.            pa
4b10: 73 73 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  ss.        elif 
4b20: 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68  sLine.startswith
4b30: 28 22 44 45 46 3a 22 29 3a 0a 20 20 20 20 20 20  ("DEF:"):.      
4b40: 20 20 20 20 20 20 23 20 64 65 66 69 6e 69 74 69        # definiti
4b50: 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d  on.            m
4b60: 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 44 45 46   = re.match("DEF
4b70: 3a 20 2b 28 5b 61 2d 7a 41 2d 5a 5f 5d 5b 61 2d  : +([a-zA-Z_][a-
4b80: 7a 41 2d 5a 5f 30 2d 39 5d 2a 29 20 2b 28 2e 2b  zA-Z_0-9]*) +(.+
4b90: 29 24 22 2c 20 73 4c 69 6e 65 2e 73 74 72 69 70  )$", sLine.strip
4ba0: 28 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  ()).            
4bb0: 69 66 20 6d 3a 0a 20 20 20 20 20 20 20 20 20 20  if m:.          
4bc0: 20 20 20 20 20 20 64 44 45 46 5b 22 7b 22 2b 6d        dDEF["{"+m
4bd0: 2e 67 72 6f 75 70 28 31 29 2b 22 7d 22 5d 20 3d  .group(1)+"}"] =
4be0: 20 6d 2e 67 72 6f 75 70 28 32 29 0a 20 20 20 20   m.group(2).    
4bf0: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
4c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
4c10: 69 6e 74 28 22 45 72 72 6f 72 20 69 6e 20 64 65  int("Error in de
4c20: 66 69 6e 69 74 69 6f 6e 3a 20 22 2c 20 65 6e 64  finition: ", end
4c30: 3d 22 22 29 0a 20 20 20 20 20 20 20 20 20 20 20  ="").           
4c40: 20 20 20 20 20 70 72 69 6e 74 28 73 4c 69 6e 65       print(sLine
4c50: 2e 73 74 72 69 70 28 29 29 0a 20 20 20 20 20 20  .strip()).      
4c60: 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61    elif sLine.sta
4c70: 72 74 73 77 69 74 68 28 22 54 45 53 54 3a 22 29  rtswith("TEST:")
4c80: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  :.            # 
4c90: 74 65 73 74 0a 20 20 20 20 20 20 20 20 20 20 20  test.           
4ca0: 20 6c 54 65 73 74 2e 61 70 70 65 6e 64 28 22 7b   lTest.append("{
4cb0: 3a 3c 38 7d 22 2e 66 6f 72 6d 61 74 28 69 29 20  :<8}".format(i) 
4cc0: 2b 20 22 20 20 22 20 2b 20 73 4c 69 6e 65 5b 35  + "  " + sLine[5
4cd0: 3a 5d 2e 73 74 72 69 70 28 29 29 0a 20 20 20 20  :].strip()).    
4ce0: 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73      elif sLine.s
4cf0: 74 61 72 74 73 77 69 74 68 28 22 54 4f 44 4f 3a  tartswith("TODO:
4d00: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
4d10: 23 20 74 6f 64 6f 0a 20 20 20 20 20 20 20 20 20  # todo.         
4d20: 20 20 20 70 61 73 73 0a 20 20 20 20 20 20 20 20     pass.        
4d30: 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74  elif sLine.start
4d40: 73 77 69 74 68 28 28 22 4f 50 54 47 52 4f 55 50  swith(("OPTGROUP
4d50: 2f 22 2c 20 22 4f 50 54 53 4f 46 54 57 41 52 45  /", "OPTSOFTWARE
4d60: 3a 22 2c 20 22 4f 50 54 2f 22 2c 20 22 4f 50 54  :", "OPT/", "OPT
4d70: 4c 41 4e 47 2f 22 2c 20 22 4f 50 54 44 45 46 41  LANG/", "OPTDEFA
4d80: 55 4c 54 55 49 4c 41 4e 47 3a 22 2c 20 22 4f 50  ULTUILANG:", "OP
4d90: 54 4c 41 42 45 4c 2f 22 2c 20 22 4f 50 54 50 52  TLABEL/", "OPTPR
4da0: 49 4f 52 49 54 59 2f 22 29 29 3a 0a 20 20 20 20  IORITY/")):.    
4db0: 20 20 20 20 20 20 20 20 23 20 6f 70 74 69 6f 6e          # option
4dc0: 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 4f  s.            lO
4dd0: 70 74 2e 61 70 70 65 6e 64 28 73 4c 69 6e 65 29  pt.append(sLine)
4de0: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c  .        elif sL
4df0: 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ine.startswith("
4e00: 21 21 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  !!"):.          
4e10: 20 20 23 20 62 6f 6f 6b 6d 61 72 6b 0a 20 20 20    # bookmark.   
4e20: 20 20 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e           m = re.
4e30: 6d 61 74 63 68 28 22 21 21 2b 22 2c 20 73 4c 69  match("!!+", sLi
4e40: 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  ne).            
4e50: 6e 45 78 4d 6b 20 3d 20 6c 65 6e 28 6d 2e 67 72  nExMk = len(m.gr
4e60: 6f 75 70 28 30 29 29 0a 20 20 20 20 20 20 20 20  oup(0)).        
4e70: 20 20 20 20 69 66 20 73 4c 69 6e 65 5b 6e 45 78      if sLine[nEx
4e80: 4d 6b 3a 5d 2e 73 74 72 69 70 28 29 3a 0a 20 20  Mk:].strip():.  
4e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
4ea0: 69 6e 74 42 6f 6f 6b 6d 61 72 6b 28 6e 45 78 4d  intBookmark(nExM
4eb0: 6b 2d 32 2c 20 73 4c 69 6e 65 5b 6e 45 78 4d 6b  k-2, sLine[nExMk
4ec0: 3a 5d 2e 73 74 72 69 70 28 29 2c 20 69 29 0a 20  :].strip(), i). 
4ed0: 20 20 20 20 20 20 20 23 20 47 72 61 70 68 20 72         # Graph r
4ee0: 75 6c 65 73 0a 20 20 20 20 20 20 20 20 65 6c 69  ules.        eli
4ef0: 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69  f sLine.startswi
4f00: 74 68 28 22 40 40 40 40 47 52 41 50 48 3a 22 29  th("@@@@GRAPH:")
4f10: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  :.            # 
4f20: 72 75 6c 65 73 20 67 72 61 70 68 20 63 61 6c 6c  rules graph call
4f30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d  .            m =
4f40: 20 72 65 2e 6d 61 74 63 68 28 72 22 40 40 40 40   re.match(r"@@@@
4f50: 47 52 41 50 48 3a 20 2a 28 5c 77 2b 29 22 2c 20  GRAPH: *(\w+)", 
4f60: 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 29 0a 20  sLine.strip()). 
4f70: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6d 3a             if m:
4f80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
4f90: 20 70 72 69 6e 74 42 6f 6f 6b 6d 61 72 6b 28 31   printBookmark(1
4fa0: 2c 20 22 40 47 52 41 50 48 3a 20 22 20 2b 20 6d  , "@GRAPH: " + m
4fb0: 2e 67 72 6f 75 70 28 31 29 2c 20 69 29 0a 20 20  .group(1), i).  
4fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 52                lR
4fd0: 75 6c 65 4c 69 6e 65 2e 61 70 70 65 6e 64 28 5b  uleLine.append([
4fe0: 69 2c 20 22 40 40 40 40 22 2b 6d 2e 67 72 6f 75  i, "@@@@"+m.grou
4ff0: 70 28 31 29 5d 29 0a 20 20 20 20 20 20 20 20 20  p(1)]).         
5000: 20 20 20 20 20 20 20 62 47 72 61 70 68 20 3d 20         bGraph = 
5010: 54 72 75 65 0a 20 20 20 20 20 20 20 20 20 20 20  True.           
5020: 20 6c 47 72 61 70 68 52 75 6c 65 2e 61 70 70 65   lGraphRule.appe
5030: 6e 64 28 5b 69 2c 20 73 4c 69 6e 65 5d 29 0a 20  nd([i, sLine]). 
5040: 20 20 20 20 20 20 20 20 20 20 20 62 47 72 61 70             bGrap
5050: 68 20 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20  h = True.       
5060: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
5070: 74 73 77 69 74 68 28 22 40 40 40 40 45 4e 44 5f  tswith("@@@@END_
5080: 47 52 41 50 48 22 29 3a 0a 20 20 20 20 20 20 20  GRAPH"):.       
5090: 20 20 20 20 20 6c 47 72 61 70 68 52 75 6c 65 2e       lGraphRule.
50a0: 61 70 70 65 6e 64 28 5b 69 2c 20 73 4c 69 6e 65  append([i, sLine
50b0: 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 62  ]).            b
50c0: 47 72 61 70 68 20 3d 20 46 61 6c 73 65 0a 20 20  Graph = False.  
50d0: 20 20 20 20 20 20 65 6c 69 66 20 72 65 2e 6d 61        elif re.ma
50e0: 74 63 68 28 22 40 40 40 40 20 2a 24 22 2c 20 73  tch("@@@@ *$", s
50f0: 4c 69 6e 65 29 3a 0a 20 20 20 20 20 20 20 20 20  Line):.         
5100: 20 20 20 70 61 73 73 0a 20 20 20 20 20 20 20 20     pass.        
5110: 65 6c 69 66 20 62 47 72 61 70 68 3a 0a 20 20 20  elif bGraph:.   
5120: 20 20 20 20 20 20 20 20 20 6c 47 72 61 70 68 52           lGraphR
5130: 75 6c 65 2e 61 70 70 65 6e 64 28 5b 69 2c 20 73  ule.append([i, s
5140: 4c 69 6e 65 5d 29 0a 20 20 20 20 20 20 20 20 23  Line]).        #
5150: 20 52 65 67 65 78 20 72 75 6c 65 73 0a 20 20 20   Regex rules.   
5160: 20 20 20 20 20 65 6c 69 66 20 72 65 2e 6d 61 74       elif re.mat
5170: 63 68 28 22 5b 20 c2 a0 5c 74 5d 2a 24 22 2c 20  ch("[ ..\t]*$", 
5180: 73 4c 69 6e 65 29 3a 0a 20 20 20 20 20 20 20 20  sLine):.        
5190: 20 20 20 20 23 20 65 6d 70 74 79 20 6c 69 6e 65      # empty line
51a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 61 73  .            pas
51b0: 73 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73  s.        elif s
51c0: 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28  Line.startswith(
51d0: 28 22 20 20 20 20 22 2c 20 22 5c 74 22 29 29 3a  ("    ", "\t")):
51e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 72  .            # r
51f0: 75 6c 65 20 28 63 6f 6e 74 69 6e 75 61 74 69 6f  ule (continuatio
5200: 6e 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c  n).            l
5210: 52 75 6c 65 4c 69 6e 65 5b 2d 31 5d 5b 31 5d 20  RuleLine[-1][1] 
5220: 2b 3d 20 22 20 22 20 2b 20 73 4c 69 6e 65 2e 73  += " " + sLine.s
5230: 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 65  trip().        e
5240: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
5250: 20 23 20 6e 65 77 20 72 75 6c 65 0a 20 20 20 20   # new rule.    
5260: 20 20 20 20 20 20 20 20 6c 52 75 6c 65 4c 69 6e          lRuleLin
5270: 65 2e 61 70 70 65 6e 64 28 5b 69 2c 20 73 4c 69  e.append([i, sLi
5280: 6e 65 2e 73 74 72 69 70 28 29 5d 29 0a 0a 20 20  ne.strip()])..  
5290: 20 20 23 20 67 65 6e 65 72 61 74 69 6e 67 20 6f    # generating o
52a0: 70 74 69 6f 6e 73 20 66 69 6c 65 73 0a 20 20 20  ptions files.   
52b0: 20 70 72 69 6e 74 28 22 20 20 70 61 72 73 69 6e   print("  parsin
52c0: 67 20 6f 70 74 69 6f 6e 73 2e 2e 2e 22 29 0a 20  g options..."). 
52d0: 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20     try:.        
52e0: 64 4f 70 74 69 6f 6e 73 2c 20 64 4f 70 74 50 72  dOptions, dOptPr
52f0: 69 6f 72 69 74 79 20 3d 20 70 72 65 70 61 72 65  iority = prepare
5300: 4f 70 74 69 6f 6e 73 28 6c 4f 70 74 29 0a 20 20  Options(lOpt).  
5310: 20 20 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20    except:.      
5320: 20 20 74 72 61 63 65 62 61 63 6b 2e 70 72 69 6e    traceback.prin
5330: 74 5f 65 78 63 28 29 0a 20 20 20 20 20 20 20 20  t_exc().        
5340: 65 78 69 74 28 29 0a 0a 20 20 20 20 23 20 74 65  exit()..    # te
5350: 73 74 73 0a 20 20 20 20 70 72 69 6e 74 28 22 20  sts.    print(" 
5360: 20 6c 69 73 74 20 74 65 73 74 73 2e 2e 2e 22 29   list tests...")
5370: 0a 20 20 20 20 73 47 43 54 65 73 74 73 20 3d 20  .    sGCTests = 
5380: 22 5c 6e 22 2e 6a 6f 69 6e 28 6c 54 65 73 74 29  "\n".join(lTest)
5390: 0a 20 20 20 20 73 47 43 54 65 73 74 73 4a 53 20  .    sGCTestsJS 
53a0: 3d 20 27 7b 20 22 61 44 61 74 61 22 3a 20 27 20  = '{ "aData": ' 
53b0: 2b 20 6a 73 6f 6e 2e 64 75 6d 70 73 28 6c 54 65  + json.dumps(lTe
53c0: 73 74 2c 20 65 6e 73 75 72 65 5f 61 73 63 69 69  st, ensure_ascii
53d0: 3d 46 61 6c 73 65 29 20 2b 20 22 20 7d 5c 6e 22  =False) + " }\n"
53e0: 0a 0a 20 20 20 20 23 20 70 72 6f 63 65 73 73 69  ..    # processi
53f0: 6e 67 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20  ng.    print("  
5400: 70 72 65 70 61 72 69 6e 67 20 72 75 6c 65 73 2e  preparing rules.
5410: 2e 2e 22 29 0a 20 20 20 20 62 50 61 72 61 67 72  ..").    bParagr
5420: 61 70 68 20 3d 20 54 72 75 65 0a 20 20 20 20 6c  aph = True.    l
5430: 50 61 72 61 67 72 61 70 68 52 75 6c 65 73 20 3d  ParagraphRules =
5440: 20 5b 5d 0a 20 20 20 20 6c 53 65 6e 74 65 6e 63   [].    lSentenc
5450: 65 52 75 6c 65 73 20 3d 20 5b 5d 0a 20 20 20 20  eRules = [].    
5460: 6c 50 61 72 61 67 72 61 70 68 52 75 6c 65 73 4a  lParagraphRulesJ
5470: 53 20 3d 20 5b 5d 0a 20 20 20 20 6c 53 65 6e 74  S = [].    lSent
5480: 65 6e 63 65 52 75 6c 65 73 4a 53 20 3d 20 5b 5d  enceRulesJS = []
5490: 0a 0a 20 20 20 20 66 6f 72 20 6e 4c 69 6e 65 2c  ..    for nLine,
54a0: 20 73 4c 69 6e 65 20 69 6e 20 6c 52 75 6c 65 4c   sLine in lRuleL
54b0: 69 6e 65 3a 0a 20 20 20 20 20 20 20 20 69 66 20  ine:.        if 
54c0: 73 4c 69 6e 65 3a 0a 20 20 20 20 20 20 20 20 20  sLine:.         
54d0: 20 20 20 69 66 20 73 4c 69 6e 65 20 3d 3d 20 22     if sLine == "
54e0: 5b 2b 2b 5d 22 3a 0a 20 20 20 20 20 20 20 20 20  [++]":.         
54f0: 20 20 20 20 20 20 20 62 50 61 72 61 67 72 61 70         bParagrap
5500: 68 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20  h = False.      
5510: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
5520: 20 20 20 20 20 20 20 20 20 20 20 20 61 52 75 6c              aRul
5530: 65 20 3d 20 63 72 65 61 74 65 52 75 6c 65 28 73  e = createRule(s
5540: 4c 69 6e 65 2c 20 6e 4c 69 6e 65 2c 20 73 4c 61  Line, nLine, sLa
5550: 6e 67 2c 20 62 50 61 72 61 67 72 61 70 68 2c 20  ng, bParagraph, 
5560: 64 4f 70 74 50 72 69 6f 72 69 74 79 29 0a 20 20  dOptPriority).  
5570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
5580: 20 61 52 75 6c 65 3a 0a 20 20 20 20 20 20 20 20   aRule:.        
5590: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62              if b
55a0: 50 61 72 61 67 72 61 70 68 3a 0a 20 20 20 20 20  Paragraph:.     
55b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
55c0: 20 20 20 6c 50 61 72 61 67 72 61 70 68 52 75 6c     lParagraphRul
55d0: 65 73 2e 61 70 70 65 6e 64 28 61 52 75 6c 65 29  es.append(aRule)
55e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
55f0: 20 20 20 20 20 20 20 20 20 6c 50 61 72 61 67 72           lParagr
5600: 61 70 68 52 75 6c 65 73 4a 53 2e 61 70 70 65 6e  aphRulesJS.appen
5610: 64 28 6a 73 63 6f 6e 76 2e 70 79 52 75 6c 65 54  d(jsconv.pyRuleT
5620: 6f 4a 53 28 61 52 75 6c 65 2c 20 64 4a 53 52 45  oJS(aRule, dJSRE
5630: 47 45 58 45 53 2c 20 73 57 4f 52 44 4c 49 4d 49  GEXES, sWORDLIMI
5640: 54 4c 45 46 54 29 29 0a 20 20 20 20 20 20 20 20  TLEFT)).        
5650: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65              else
5660: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
5670: 20 20 20 20 20 20 20 20 20 20 6c 53 65 6e 74 65            lSente
5680: 6e 63 65 52 75 6c 65 73 2e 61 70 70 65 6e 64 28  nceRules.append(
5690: 61 52 75 6c 65 29 0a 20 20 20 20 20 20 20 20 20  aRule).         
56a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
56b0: 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 4a 53 2e  SentenceRulesJS.
56c0: 61 70 70 65 6e 64 28 6a 73 63 6f 6e 76 2e 70 79  append(jsconv.py
56d0: 52 75 6c 65 54 6f 4a 53 28 61 52 75 6c 65 2c 20  RuleToJS(aRule, 
56e0: 64 4a 53 52 45 47 45 58 45 53 2c 20 73 57 4f 52  dJSREGEXES, sWOR
56f0: 44 4c 49 4d 49 54 4c 45 46 54 29 29 0a 0a 20 20  DLIMITLEFT))..  
5700: 20 20 23 20 63 72 65 61 74 69 6e 67 20 66 69 6c    # creating fil
5710: 65 20 77 69 74 68 20 61 6c 6c 20 66 75 6e 63 74  e with all funct
5720: 69 6f 6e 73 20 63 61 6c 6c 61 62 6c 65 20 62 79  ions callable by
5730: 20 72 75 6c 65 73 0a 20 20 20 20 70 72 69 6e 74   rules.    print
5740: 28 22 20 20 63 72 65 61 74 69 6e 67 20 63 61 6c  ("  creating cal
5750: 6c 61 62 6c 65 73 2e 2e 2e 22 29 0a 20 20 20 20  lables...").    
5760: 73 50 79 43 61 6c 6c 61 62 6c 65 73 20 3d 20 22  sPyCallables = "
5770: 23 20 67 65 6e 65 72 61 74 65 64 20 63 6f 64 65  # generated code
5780: 2c 20 64 6f 20 6e 6f 74 20 65 64 69 74 5c 6e 22  , do not edit\n"
5790: 0a 20 20 20 20 73 4a 53 43 61 6c 6c 61 62 6c 65  .    sJSCallable
57a0: 73 20 3d 20 22 2f 2f 20 67 65 6e 65 72 61 74 65  s = "// generate
57b0: 64 20 63 6f 64 65 2c 20 64 6f 20 6e 6f 74 20 65  d code, do not e
57c0: 64 69 74 5c 6e 63 6f 6e 73 74 20 6f 45 76 61 6c  dit\nconst oEval
57d0: 46 75 6e 63 20 3d 20 7b 5c 6e 22 0a 20 20 20 20  Func = {\n".    
57e0: 66 6f 72 20 73 46 75 6e 63 4e 61 6d 65 2c 20 73  for sFuncName, s
57f0: 52 65 74 75 72 6e 20 69 6e 20 6c 46 55 4e 43 54  Return in lFUNCT
5800: 49 4f 4e 53 3a 0a 20 20 20 20 20 20 20 20 63 54  IONS:.        cT
5810: 79 70 65 20 3d 20 73 46 75 6e 63 4e 61 6d 65 5b  ype = sFuncName[
5820: 30 3a 31 5d 0a 20 20 20 20 20 20 20 20 69 66 20  0:1].        if 
5830: 63 54 79 70 65 20 3d 3d 20 22 63 22 3a 20 23 20  cType == "c": # 
5840: 63 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 20 20  condition.      
5850: 20 20 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20        sParams = 
5860: 22 73 2c 20 73 78 2c 20 6d 2c 20 64 44 41 2c 20  "s, sx, m, dDA, 
5870: 73 43 6f 75 6e 74 72 79 2c 20 62 43 6f 6e 64 4d  sCountry, bCondM
5880: 65 6d 6f 22 0a 20 20 20 20 20 20 20 20 65 6c 69  emo".        eli
5890: 66 20 63 54 79 70 65 20 3d 3d 20 22 6d 22 3a 20  f cType == "m": 
58a0: 23 20 6d 65 73 73 61 67 65 0a 20 20 20 20 20 20  # message.      
58b0: 20 20 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20        sParams = 
58c0: 22 73 2c 20 6d 22 0a 20 20 20 20 20 20 20 20 65  "s, m".        e
58d0: 6c 69 66 20 63 54 79 70 65 20 3d 3d 20 22 73 22  lif cType == "s"
58e0: 3a 20 23 20 73 75 67 67 65 73 74 69 6f 6e 0a 20  : # suggestion. 
58f0: 20 20 20 20 20 20 20 20 20 20 20 73 50 61 72 61             sPara
5900: 6d 73 20 3d 20 22 73 2c 20 6d 22 0a 20 20 20 20  ms = "s, m".    
5910: 20 20 20 20 65 6c 69 66 20 63 54 79 70 65 20 3d      elif cType =
5920: 3d 20 22 70 22 3a 20 23 20 70 72 65 70 72 6f 63  = "p": # preproc
5930: 65 73 73 6f 72 0a 20 20 20 20 20 20 20 20 20 20  essor.          
5940: 20 20 73 50 61 72 61 6d 73 20 3d 20 22 73 2c 20    sParams = "s, 
5950: 6d 22 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  m".        elif 
5960: 63 54 79 70 65 20 3d 3d 20 22 64 22 3a 20 23 20  cType == "d": # 
5970: 64 69 73 61 6d 62 69 67 75 61 74 6f 72 0a 20 20  disambiguator.  
5980: 20 20 20 20 20 20 20 20 20 20 73 50 61 72 61 6d            sParam
5990: 73 20 3d 20 22 73 2c 20 6d 2c 20 64 44 41 22 0a  s = "s, m, dDA".
59a0: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
59b0: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
59c0: 22 23 20 55 6e 6b 6e 6f 77 6e 20 66 75 6e 63 74  "# Unknown funct
59d0: 69 6f 6e 20 74 79 70 65 20 69 6e 20 5b 22 20 2b  ion type in [" +
59e0: 20 73 46 75 6e 63 4e 61 6d 65 20 2b 20 22 5d 22   sFuncName + "]"
59f0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 6f  ).            co
5a00: 6e 74 69 6e 75 65 0a 20 20 20 20 20 20 20 20 73  ntinue.        s
5a10: 50 79 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22  PyCallables += "
5a20: 64 65 66 20 7b 7d 20 28 7b 7d 29 3a 5c 6e 22 2e  def {} ({}):\n".
5a30: 66 6f 72 6d 61 74 28 73 46 75 6e 63 4e 61 6d 65  format(sFuncName
5a40: 2c 20 73 50 61 72 61 6d 73 29 0a 20 20 20 20 20  , sParams).     
5a50: 20 20 20 73 50 79 43 61 6c 6c 61 62 6c 65 73 20     sPyCallables 
5a60: 2b 3d 20 22 20 20 20 20 72 65 74 75 72 6e 20 22  += "    return "
5a70: 20 2b 20 73 52 65 74 75 72 6e 20 2b 20 22 5c 6e   + sReturn + "\n
5a80: 22 0a 20 20 20 20 20 20 20 20 73 4a 53 43 61 6c  ".        sJSCal
5a90: 6c 61 62 6c 65 73 20 2b 3d 20 22 20 20 20 20 7b  lables += "    {
5aa0: 7d 3a 20 66 75 6e 63 74 69 6f 6e 20 28 7b 7d 29  }: function ({})
5ab0: 22 2e 66 6f 72 6d 61 74 28 73 46 75 6e 63 4e 61  ".format(sFuncNa
5ac0: 6d 65 2c 20 73 50 61 72 61 6d 73 29 20 2b 20 22  me, sParams) + "
5ad0: 20 7b 5c 6e 22 0a 20 20 20 20 20 20 20 20 73 4a   {\n".        sJ
5ae0: 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 20  SCallables += " 
5af0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 20         return " 
5b00: 2b 20 6a 73 63 6f 6e 76 2e 70 79 32 6a 73 28 73  + jsconv.py2js(s
5b10: 52 65 74 75 72 6e 29 20 2b 20 22 3b 5c 6e 22 0a  Return) + ";\n".
5b20: 20 20 20 20 20 20 20 20 73 4a 53 43 61 6c 6c 61          sJSCalla
5b30: 62 6c 65 73 20 2b 3d 20 22 20 20 20 20 7d 2c 5c  bles += "    },\
5b40: 6e 22 0a 20 20 20 20 73 4a 53 43 61 6c 6c 61 62  n".    sJSCallab
5b50: 6c 65 73 20 2b 3d 20 22 7d 5c 6e 22 0a 0a 20 20  les += "}\n"..  
5b60: 20 20 64 69 73 70 6c 61 79 53 74 61 74 73 28 6c    displayStats(l
5b70: 50 61 72 61 67 72 61 70 68 52 75 6c 65 73 2c 20  ParagraphRules, 
5b80: 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 29 0a  lSentenceRules).
5b90: 0a 20 20 20 20 70 72 69 6e 74 28 22 55 6e 6e 61  .    print("Unna
5ba0: 6d 65 64 20 72 75 6c 65 73 3a 20 22 20 2b 20 73  med rules: " + s
5bb0: 74 72 28 6e 52 55 4c 45 57 49 54 48 4f 55 54 4e  tr(nRULEWITHOUTN
5bc0: 41 4d 45 29 29 0a 0a 20 20 20 20 64 20 3d 20 7b  AME))..    d = {
5bd0: 20 22 63 61 6c 6c 61 62 6c 65 73 22 3a 20 73 50   "callables": sP
5be0: 79 43 61 6c 6c 61 62 6c 65 73 2c 0a 20 20 20 20  yCallables,.    
5bf0: 20 20 20 20 20 20 22 63 61 6c 6c 61 62 6c 65 73        "callables
5c00: 4a 53 22 3a 20 73 4a 53 43 61 6c 6c 61 62 6c 65  JS": sJSCallable
5c10: 73 2c 0a 20 20 20 20 20 20 20 20 20 20 22 67 63  s,.          "gc
5c20: 74 65 73 74 73 22 3a 20 73 47 43 54 65 73 74 73  tests": sGCTests
5c30: 2c 0a 20 20 20 20 20 20 20 20 20 20 22 67 63 74  ,.          "gct
5c40: 65 73 74 73 4a 53 22 3a 20 73 47 43 54 65 73 74  estsJS": sGCTest
5c50: 73 4a 53 2c 0a 20 20 20 20 20 20 20 20 20 20 22  sJS,.          "
5c60: 70 61 72 61 67 72 61 70 68 5f 72 75 6c 65 73 22  paragraph_rules"
5c70: 3a 20 6d 65 72 67 65 52 75 6c 65 73 42 79 4f 70  : mergeRulesByOp
5c80: 74 69 6f 6e 28 6c 50 61 72 61 67 72 61 70 68 52  tion(lParagraphR
5c90: 75 6c 65 73 29 2c 0a 20 20 20 20 20 20 20 20 20  ules),.         
5ca0: 20 22 73 65 6e 74 65 6e 63 65 5f 72 75 6c 65 73   "sentence_rules
5cb0: 22 3a 20 6d 65 72 67 65 52 75 6c 65 73 42 79 4f  ": mergeRulesByO
5cc0: 70 74 69 6f 6e 28 6c 53 65 6e 74 65 6e 63 65 52  ption(lSentenceR
5cd0: 75 6c 65 73 29 2c 0a 20 20 20 20 20 20 20 20 20  ules),.         
5ce0: 20 22 70 61 72 61 67 72 61 70 68 5f 72 75 6c 65   "paragraph_rule
5cf0: 73 5f 4a 53 22 3a 20 6a 73 63 6f 6e 76 2e 77 72  s_JS": jsconv.wr
5d00: 69 74 65 52 75 6c 65 73 54 6f 4a 53 41 72 72 61  iteRulesToJSArra
5d10: 79 28 6d 65 72 67 65 52 75 6c 65 73 42 79 4f 70  y(mergeRulesByOp
5d20: 74 69 6f 6e 28 6c 50 61 72 61 67 72 61 70 68 52  tion(lParagraphR
5d30: 75 6c 65 73 4a 53 29 29 2c 0a 20 20 20 20 20 20  ulesJS)),.      
5d40: 20 20 20 20 22 73 65 6e 74 65 6e 63 65 5f 72 75      "sentence_ru
5d50: 6c 65 73 5f 4a 53 22 3a 20 6a 73 63 6f 6e 76 2e  les_JS": jsconv.
5d60: 77 72 69 74 65 52 75 6c 65 73 54 6f 4a 53 41 72  writeRulesToJSAr
5d70: 72 61 79 28 6d 65 72 67 65 52 75 6c 65 73 42 79  ray(mergeRulesBy
5d80: 4f 70 74 69 6f 6e 28 6c 53 65 6e 74 65 6e 63 65  Option(lSentence
5d90: 52 75 6c 65 73 4a 53 29 29 20 7d 0a 20 20 20 20  RulesJS)) }.    
5da0: 64 2e 75 70 64 61 74 65 28 64 4f 70 74 69 6f 6e  d.update(dOption
5db0: 73 29 0a 0a 20 20 20 20 23 20 63 6f 6d 70 69 6c  s)..    # compil
5dc0: 65 20 67 72 61 70 68 20 72 75 6c 65 73 0a 20 20  e graph rules.  
5dd0: 20 20 64 32 20 3d 20 63 72 67 2e 6d 61 6b 65 28    d2 = crg.make(
5de0: 6c 47 72 61 70 68 52 75 6c 65 2c 20 73 4c 61 6e  lGraphRule, sLan
5df0: 67 2c 20 62 4a 61 76 61 53 63 72 69 70 74 29 0a  g, bJavaScript).
5e00: 20 20 20 20 64 2e 75 70 64 61 74 65 28 64 32 29      d.update(d2)
5e10: 0a 0a 20 20 20 20 72 65 74 75 72 6e 20 64 0a     ..    return d.