Grammalecte  Hex Artifact Content

Artifact 45224279a816d58279e472689e812200cbafdf55648175f7e4722fe30919427c:


0000: 22 22 22 0a 47 72 61 6d 6d 61 6c 65 63 74 65 3a  """.Grammalecte:
0010: 20 63 6f 6d 70 69 6c 65 20 72 75 6c 65 73 0a 22   compile rules."
0020: 22 22 0a 0a 69 6d 70 6f 72 74 20 72 65 0a 69 6d  ""..import re.im
0030: 70 6f 72 74 20 74 72 61 63 65 62 61 63 6b 0a 69  port traceback.i
0040: 6d 70 6f 72 74 20 6a 73 6f 6e 0a 0a 69 6d 70 6f  mport json..impo
0050: 72 74 20 63 6f 6d 70 69 6c 65 5f 72 75 6c 65 73  rt compile_rules
0060: 5f 6a 73 5f 63 6f 6e 76 65 72 74 20 61 73 20 6a  _js_convert as j
0070: 73 63 6f 6e 76 0a 69 6d 70 6f 72 74 20 63 6f 6d  sconv.import com
0080: 70 69 6c 65 5f 72 75 6c 65 73 5f 67 72 61 70 68  pile_rules_graph
0090: 20 61 73 20 63 72 67 0a 0a 0a 64 44 45 46 20 3d   as crg...dDEF =
00a0: 20 7b 7d 0a 6c 46 55 4e 43 54 49 4f 4e 53 20 3d   {}.lFUNCTIONS =
00b0: 20 5b 5d 0a 0a 61 52 55 4c 45 53 45 54 20 3d 20   []..aRULESET = 
00c0: 73 65 74 28 29 20 20 20 20 20 23 20 73 65 74 20  set()     # set 
00d0: 6f 66 20 72 75 6c 65 2d 69 64 73 20 74 6f 20 63  of rule-ids to c
00e0: 68 65 63 6b 20 69 66 20 74 68 65 72 65 20 69 73  heck if there is
00f0: 20 73 65 76 65 72 61 6c 20 72 75 6c 65 73 20 77   several rules w
0100: 69 74 68 20 74 68 65 20 73 61 6d 65 20 69 64 0a  ith the same id.
0110: 6e 52 55 4c 45 57 49 54 48 4f 55 54 4e 41 4d 45  nRULEWITHOUTNAME
0120: 20 3d 20 30 0a 0a 64 4a 53 52 45 47 45 58 45 53   = 0..dJSREGEXES
0130: 20 3d 20 7b 7d 0a 0a 73 57 4f 52 44 4c 49 4d 49   = {}..sWORDLIMI
0140: 54 4c 45 46 54 20 20 3d 20 72 22 28 3f 3c 21 5b  TLEFT  = r"(?<![
0150: 5c 77 2e 2c e2 80 93 2d 5d 29 22 20 20 20 23 20  \w.,...-])"   # 
0160: 72 22 28 3f 3c 21 5b 2d 2e 2c e2 80 94 5d 29 5c  r"(?<![-.,...])\
0170: 62 22 20 20 73 65 65 6d 73 20 73 6c 6f 77 65 72  b"  seems slower
0180: 0a 73 57 4f 52 44 4c 49 4d 49 54 52 49 47 48 54  .sWORDLIMITRIGHT
0190: 20 3d 20 72 22 28 3f 21 5b 5c 77 e2 80 93 2d 5d   = r"(?![\w...-]
01a0: 29 22 20 20 20 20 20 20 23 20 72 22 5c 62 28 3f  )"      # r"\b(?
01b0: 21 2d e2 80 94 29 22 20 20 20 20 20 20 20 73 65  !-...)"       se
01c0: 65 6d 73 20 73 6c 6f 77 65 72 0a 0a 0a 64 65 66  ems slower...def
01d0: 20 70 72 65 70 61 72 65 46 75 6e 63 74 69 6f 6e   prepareFunction
01e0: 20 28 73 29 3a 0a 20 20 20 20 22 63 6f 6e 76 65   (s):.    "conve
01f0: 72 74 20 73 69 6d 70 6c 65 20 72 75 6c 65 20 73  rt simple rule s
0200: 79 6e 74 61 78 20 74 6f 20 61 20 73 74 72 69 6e  yntax to a strin
0210: 67 20 6f 66 20 50 79 74 68 6f 6e 20 63 6f 64 65  g of Python code
0220: 22 0a 20 20 20 20 73 20 3d 20 73 2e 72 65 70 6c  ".    s = s.repl
0230: 61 63 65 28 22 5f 5f 61 6c 73 6f 5f 5f 22 2c 20  ace("__also__", 
0240: 22 62 43 6f 6e 64 4d 65 6d 6f 22 29 0a 20 20 20  "bCondMemo").   
0250: 20 73 20 3d 20 73 2e 72 65 70 6c 61 63 65 28 22   s = s.replace("
0260: 5f 5f 65 6c 73 65 5f 5f 22 2c 20 22 6e 6f 74 20  __else__", "not 
0270: 62 43 6f 6e 64 4d 65 6d 6f 22 29 0a 20 20 20 20  bCondMemo").    
0280: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73 53  s = re.sub(r"isS
0290: 74 61 72 74 20 2a 5c 28 5c 29 22 2c 20 27 62 65  tart *\(\)", 'be
02a0: 66 6f 72 65 28 22 5e 20 2a 24 7c 2c 20 2a 24 22  fore("^ *$|, *$"
02b0: 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72  )', s).    s = r
02c0: 65 2e 73 75 62 28 72 22 69 73 52 65 61 6c 53 74  e.sub(r"isRealSt
02d0: 61 72 74 20 2a 5c 28 5c 29 22 2c 20 27 62 65 66  art *\(\)", 'bef
02e0: 6f 72 65 28 22 5e 20 2a 24 22 29 27 2c 20 73 29  ore("^ *$")', s)
02f0: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
0300: 72 22 69 73 53 74 61 72 74 30 20 2a 5c 28 5c 29  r"isStart0 *\(\)
0310: 22 2c 20 27 62 65 66 6f 72 65 30 28 22 5e 20 2a  ", 'before0("^ *
0320: 24 7c 2c 20 2a 24 22 29 27 2c 20 73 29 0a 20 20  $|, *$")', s).  
0330: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69    s = re.sub(r"i
0340: 73 52 65 61 6c 53 74 61 72 74 30 20 2a 5c 28 5c  sRealStart0 *\(\
0350: 29 22 2c 20 27 62 65 66 6f 72 65 30 28 22 5e 20  )", 'before0("^ 
0360: 2a 24 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20  *$")', s).    s 
0370: 3d 20 72 65 2e 73 75 62 28 72 22 69 73 45 6e 64  = re.sub(r"isEnd
0380: 20 2a 5c 28 5c 29 22 2c 20 27 61 66 74 65 72 28   *\(\)", 'after(
0390: 22 5e 20 2a 24 7c 5e 2c 22 29 27 2c 20 73 29 0a  "^ *$|^,")', s).
03a0: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
03b0: 22 69 73 52 65 61 6c 45 6e 64 20 2a 5c 28 5c 29  "isRealEnd *\(\)
03c0: 22 2c 20 27 61 66 74 65 72 28 22 5e 20 2a 24 22  ", 'after("^ *$"
03d0: 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72  )', s).    s = r
03e0: 65 2e 73 75 62 28 72 22 69 73 45 6e 64 30 20 2a  e.sub(r"isEnd0 *
03f0: 5c 28 5c 29 22 2c 20 27 61 66 74 65 72 30 28 22  \(\)", 'after0("
0400: 5e 20 2a 24 7c 5e 2c 22 29 27 2c 20 73 29 0a 20  ^ *$|^,")', s). 
0410: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0420: 69 73 52 65 61 6c 45 6e 64 30 20 2a 5c 28 5c 29  isRealEnd0 *\(\)
0430: 22 2c 20 27 61 66 74 65 72 30 28 22 5e 20 2a 24  ", 'after0("^ *$
0440: 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  ")', s).    s = 
0450: 72 65 2e 73 75 62 28 72 22 28 73 65 6c 65 63 74  re.sub(r"(select
0460: 7c 65 78 63 6c 75 64 65 29 5b 28 5d 5b 5c 5c 5d  |exclude)[(][\\]
0470: 28 5c 64 2b 29 22 2c 20 27 5c 5c 31 28 64 54 6f  (\d+)", '\\1(dTo
0480: 6b 65 6e 50 6f 73 2c 20 6d 2e 73 74 61 72 74 28  kenPos, m.start(
0490: 5c 5c 32 29 2c 20 6d 2e 67 72 6f 75 70 28 5c 5c  \\2), m.group(\\
04a0: 32 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  2)', s).    s = 
04b0: 72 65 2e 73 75 62 28 72 22 64 65 66 69 6e 65 5b  re.sub(r"define[
04c0: 28 5d 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27 64  (][\\](\d+)", 'd
04d0: 65 66 69 6e 65 28 64 54 6f 6b 65 6e 50 6f 73 2c  efine(dTokenPos,
04e0: 20 6d 2e 73 74 61 72 74 28 5c 5c 31 29 27 2c 20   m.start(\\1)', 
04f0: 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75  s).    s = re.su
0500: 62 28 72 22 28 6d 6f 72 70 68 7c 6d 6f 72 70 68  b(r"(morph|morph
0510: 65 78 7c 64 69 73 70 6c 61 79 49 6e 66 6f 29 5b  ex|displayInfo)[
0520: 28 5d 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27 5c  (][\\](\d+)", '\
0530: 5c 31 28 28 6d 2e 73 74 61 72 74 28 5c 5c 32 29  \1((m.start(\\2)
0540: 2c 20 6d 2e 67 72 6f 75 70 28 5c 5c 32 29 29 27  , m.group(\\2))'
0550: 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  , s).    s = re.
0560: 73 75 62 28 72 22 28 6d 6f 72 70 68 7c 6d 6f 72  sub(r"(morph|mor
0570: 70 68 65 78 7c 64 69 73 70 6c 61 79 49 6e 66 6f  phex|displayInfo
0580: 29 5b 28 5d 22 2c 20 27 5c 5c 31 28 64 54 6f 6b  )[(]", '\\1(dTok
0590: 65 6e 50 6f 73 2c 20 27 2c 20 73 29 0a 20 20 20  enPos, ', s).   
05a0: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 28 73   s = re.sub(r"(s
05b0: 75 67 67 5c 77 2b 7c 73 77 69 74 63 68 5c 77 2b  ugg\w+|switch\w+
05c0: 29 5c 28 40 22 2c 20 27 5c 5c 31 28 6d 2e 67 72  )\(@", '\\1(m.gr
05d0: 6f 75 70 28 69 5b 34 5d 29 27 2c 20 73 29 0a 20  oup(i[4])', s). 
05e0: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
05f0: 77 6f 72 64 5c 28 5c 73 2a 31 5c 62 22 2c 20 27  word\(\s*1\b", '
0600: 6e 65 78 74 77 6f 72 64 31 28 73 2c 20 6d 2e 65  nextword1(s, m.e
0610: 6e 64 28 29 27 2c 20 73 29 20 20 20 20 20 20 20  nd()', s)       
0620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0630: 20 20 20 20 20 20 20 20 20 20 20 23 20 77 6f 72             # wor
0640: 64 28 31 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  d(1).    s = re.
0650: 73 75 62 28 72 22 77 6f 72 64 5c 28 5c 73 2a 2d  sub(r"word\(\s*-
0660: 31 5c 62 22 2c 20 27 70 72 65 76 77 6f 72 64 31  1\b", 'prevword1
0670: 28 73 2c 20 6d 2e 73 74 61 72 74 28 29 27 2c 20  (s, m.start()', 
0680: 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s)              
0690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06a0: 20 23 20 77 6f 72 64 28 2d 31 29 0a 20 20 20 20   # word(-1).    
06b0: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 77 6f 72  s = re.sub(r"wor
06c0: 64 5c 28 5c 73 2a 28 5c 64 29 22 2c 20 27 6e 65  d\(\s*(\d)", 'ne
06d0: 78 74 77 6f 72 64 28 73 2c 20 6d 2e 65 6e 64 28  xtword(s, m.end(
06e0: 29 2c 20 5c 5c 31 27 2c 20 73 29 20 20 20 20 20  ), \\1', s)     
06f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0700: 20 20 20 20 20 20 20 20 23 20 77 6f 72 64 28 6e          # word(n
0710: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0720: 28 72 22 77 6f 72 64 5c 28 5c 73 2a 2d 28 5c 64  (r"word\(\s*-(\d
0730: 29 22 2c 20 27 70 72 65 76 77 6f 72 64 28 73 2c  )", 'prevword(s,
0740: 20 6d 2e 73 74 61 72 74 28 29 2c 20 5c 5c 31 27   m.start(), \\1'
0750: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
0760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
0770: 77 6f 72 64 28 2d 6e 29 0a 20 20 20 20 73 20 3d  word(-n).    s =
0780: 20 72 65 2e 73 75 62 28 72 22 62 65 66 6f 72 65   re.sub(r"before
0790: 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 5b  \(\s*", 'look(s[
07a0: 3a 6d 2e 73 74 61 72 74 28 29 5d 2c 20 27 2c 20  :m.start()], ', 
07b0: 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s)              
07c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07d0: 20 20 20 20 20 23 20 62 65 66 6f 72 65 28 73 29       # before(s)
07e0: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
07f0: 72 22 61 66 74 65 72 5c 28 5c 73 2a 22 2c 20 27  r"after\(\s*", '
0800: 6c 6f 6f 6b 28 73 5b 6d 2e 65 6e 64 28 29 3a 5d  look(s[m.end():]
0810: 2c 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20  , ', s)         
0820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0830: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61               # a
0840: 66 74 65 72 28 73 29 0a 20 20 20 20 73 20 3d 20  fter(s).    s = 
0850: 72 65 2e 73 75 62 28 72 22 74 65 78 74 61 72 65  re.sub(r"textare
0860: 61 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73  a\(\s*", 'look(s
0870: 2c 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20  , ', s)         
0880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08a0: 20 20 20 20 23 20 74 65 78 74 61 72 65 61 28 73      # textarea(s
08b0: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
08c0: 28 72 22 62 65 66 6f 72 65 5f 63 68 6b 31 5c 28  (r"before_chk1\(
08d0: 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63 68 6b 31  \s*", 'look_chk1
08e0: 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 73 5b 3a 6d  (dTokenPos, s[:m
08f0: 2e 73 74 61 72 74 28 29 5d 2c 20 30 2c 20 27 2c  .start()], 0, ',
0900: 20 73 29 20 20 20 20 20 20 20 20 20 20 20 23 20   s)           # 
0910: 62 65 66 6f 72 65 5f 63 68 6b 31 28 73 29 0a 20  before_chk1(s). 
0920: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0930: 61 66 74 65 72 5f 63 68 6b 31 5c 28 5c 73 2a 22  after_chk1\(\s*"
0940: 2c 20 27 6c 6f 6f 6b 5f 63 68 6b 31 28 64 54 6f  , 'look_chk1(dTo
0950: 6b 65 6e 50 6f 73 2c 20 73 5b 6d 2e 65 6e 64 28  kenPos, s[m.end(
0960: 29 3a 5d 2c 20 6d 2e 65 6e 64 28 29 2c 20 27 2c  ):], m.end(), ',
0970: 20 73 29 20 20 20 20 20 20 20 20 23 20 61 66 74   s)        # aft
0980: 65 72 5f 63 68 6b 31 28 73 29 0a 20 20 20 20 73  er_chk1(s).    s
0990: 20 3d 20 72 65 2e 73 75 62 28 72 22 74 65 78 74   = re.sub(r"text
09a0: 61 72 65 61 5f 63 68 6b 31 5c 28 5c 73 2a 22 2c  area_chk1\(\s*",
09b0: 20 27 6c 6f 6f 6b 5f 63 68 6b 31 28 64 54 6f 6b   'look_chk1(dTok
09c0: 65 6e 50 6f 73 2c 20 73 2c 20 30 2c 20 27 2c 20  enPos, s, 0, ', 
09d0: 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s)              
09e0: 20 20 20 20 20 20 20 23 20 74 65 78 74 61 72 65         # textare
09f0: 61 5f 63 68 6b 31 28 73 29 0a 20 20 20 20 73 20  a_chk1(s).    s 
0a00: 3d 20 72 65 2e 73 75 62 28 72 22 2f 30 22 2c 20  = re.sub(r"/0", 
0a10: 27 73 78 5b 6d 2e 73 74 61 72 74 28 29 3a 6d 2e  'sx[m.start():m.
0a20: 65 6e 64 28 29 5d 27 2c 20 73 29 20 20 20 20 20  end()]', 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 20 20 20 20 20 20 20 20 20 20                  
0a50: 20 20 20 20 20 20 23 20 2f 30 0a 20 20 20 20 73        # /0.    s
0a60: 20 3d 20 72 65 2e 73 75 62 28 72 22 62 65 66 6f   = re.sub(r"befo
0a70: 72 65 30 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b  re0\(\s*", 'look
0a80: 28 73 78 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2c  (sx[:m.start()],
0a90: 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20   ', s)          
0aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ab0: 20 20 20 20 20 20 20 23 20 62 65 66 6f 72 65 30         # before0
0ac0: 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73  (s).    s = re.s
0ad0: 75 62 28 72 22 61 66 74 65 72 30 5c 28 5c 73 2a  ub(r"after0\(\s*
0ae0: 22 2c 20 27 6c 6f 6f 6b 28 73 78 5b 6d 2e 65 6e  ", 'look(sx[m.en
0af0: 64 28 29 3a 5d 2c 20 27 2c 20 73 29 20 20 20 20  d():], ', s)    
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 20 20 20 20 20 20 20 20 20                  
0b20: 23 20 61 66 74 65 72 30 28 73 29 0a 20 20 20 20  # after0(s).    
0b30: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 74 65 78  s = re.sub(r"tex
0b40: 74 61 72 65 61 30 5c 28 5c 73 2a 22 2c 20 27 6c  tarea0\(\s*", 'l
0b50: 6f 6f 6b 28 73 78 2c 20 27 2c 20 73 29 20 20 20  ook(sx, ', s)   
0b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b80: 20 20 20 20 20 20 20 20 23 20 74 65 78 74 61 72          # textar
0b90: 65 61 30 28 73 29 0a 20 20 20 20 73 20 3d 20 72  ea0(s).    s = r
0ba0: 65 2e 73 75 62 28 72 22 62 65 66 6f 72 65 30 5f  e.sub(r"before0_
0bb0: 63 68 6b 31 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f  chk1\(\s*", 'loo
0bc0: 6b 5f 63 68 6b 31 28 64 54 6f 6b 65 6e 50 6f 73  k_chk1(dTokenPos
0bd0: 2c 20 73 78 5b 3a 6d 2e 73 74 61 72 74 28 29 5d  , sx[:m.start()]
0be0: 2c 20 30 2c 20 27 2c 20 73 29 20 20 20 20 20 20  , 0, ', s)      
0bf0: 20 20 20 23 20 62 65 66 6f 72 65 30 5f 63 68 6b     # before0_chk
0c00: 31 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  1(s).    s = re.
0c10: 73 75 62 28 72 22 61 66 74 65 72 30 5f 63 68 6b  sub(r"after0_chk
0c20: 31 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63  1\(\s*", 'look_c
0c30: 68 6b 31 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 73  hk1(dTokenPos, s
0c40: 78 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20 6d 2e 65  x[m.end():], m.e
0c50: 6e 64 28 29 2c 20 27 2c 20 73 29 20 20 20 20 20  nd(), ', s)     
0c60: 20 23 20 61 66 74 65 72 30 5f 63 68 6b 31 28 73   # after0_chk1(s
0c70: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0c80: 28 72 22 74 65 78 74 61 72 65 61 30 5f 63 68 6b  (r"textarea0_chk
0c90: 31 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63  1\(\s*", 'look_c
0ca0: 68 6b 31 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 73  hk1(dTokenPos, s
0cb0: 78 2c 20 30 2c 20 27 2c 20 73 29 20 20 20 20 20  x, 0, ', s)     
0cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
0cd0: 74 65 78 74 61 72 65 61 30 5f 63 68 6b 31 28 73  textarea0_chk1(s
0ce0: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0cf0: 28 72 22 69 73 45 6e 64 4f 66 4e 47 5c 28 5c 73  (r"isEndOfNG\(\s
0d00: 2a 5c 29 22 2c 20 27 69 73 45 6e 64 4f 66 4e 47  *\)", 'isEndOfNG
0d10: 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 73 5b 6d 2e  (dTokenPos, s[m.
0d20: 65 6e 64 28 29 3a 5d 2c 20 6d 2e 65 6e 64 28 29  end():], m.end()
0d30: 29 27 2c 20 73 29 20 20 20 20 20 20 20 20 23 20  )', s)        # 
0d40: 69 73 45 6e 64 4f 66 4e 47 28 73 29 0a 20 20 20  isEndOfNG(s).   
0d50: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73   s = re.sub(r"is
0d60: 4e 65 78 74 4e 6f 74 43 4f 44 5c 28 5c 73 2a 5c  NextNotCOD\(\s*\
0d70: 29 22 2c 20 27 69 73 4e 65 78 74 4e 6f 74 43 4f  )", 'isNextNotCO
0d80: 44 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 73 5b 6d  D(dTokenPos, s[m
0d90: 2e 65 6e 64 28 29 3a 5d 2c 20 6d 2e 65 6e 64 28  .end():], m.end(
0da0: 29 29 27 2c 20 73 29 20 20 23 20 69 73 4e 65 78  ))', s)  # isNex
0db0: 74 4e 6f 74 43 4f 44 28 73 29 0a 20 20 20 20 73  tNotCOD(s).    s
0dc0: 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73 4e 65   = re.sub(r"isNe
0dd0: 78 74 56 65 72 62 5c 28 5c 73 2a 5c 29 22 2c 20  xtVerb\(\s*\)", 
0de0: 27 69 73 4e 65 78 74 56 65 72 62 28 64 54 6f 6b  'isNextVerb(dTok
0df0: 65 6e 50 6f 73 2c 20 73 5b 6d 2e 65 6e 64 28 29  enPos, s[m.end()
0e00: 3a 5d 2c 20 6d 2e 65 6e 64 28 29 29 27 2c 20 73  :], m.end())', s
0e10: 29 20 20 20 20 20 20 23 20 69 73 4e 65 78 74 56  )      # isNextV
0e20: 65 72 62 28 73 29 0a 20 20 20 20 73 20 3d 20 72  erb(s).    s = r
0e30: 65 2e 73 75 62 28 72 22 5c 62 73 70 65 6c 6c 20  e.sub(r"\bspell 
0e40: 2a 5b 28 5d 22 2c 20 27 5f 6f 53 70 65 6c 6c 43  *[(]", '_oSpellC
0e50: 68 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 27  hecker.isValid('
0e60: 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  , s).    s = re.
0e70: 73 75 62 28 72 22 5b 5c 5c 5d 28 5c 64 2b 29 22  sub(r"[\\](\d+)"
0e80: 2c 20 27 6d 2e 67 72 6f 75 70 28 5c 5c 31 29 27  , 'm.group(\\1)'
0e90: 2c 20 73 29 0a 20 20 20 20 72 65 74 75 72 6e 20  , s).    return 
0ea0: 73 0a 0a 0a 64 65 66 20 75 70 70 65 72 63 61 73  s...def uppercas
0eb0: 65 20 28 73 2c 20 73 4c 61 6e 67 29 3a 0a 20 20  e (s, sLang):.  
0ec0: 20 20 22 28 66 6c 61 67 20 69 20 69 73 20 6e 6f    "(flag i is no
0ed0: 74 20 65 6e 6f 75 67 68 29 3a 20 63 6f 6e 76 65  t enough): conve
0ee0: 72 74 73 20 72 65 67 65 78 20 74 6f 20 75 70 70  rts regex to upp
0ef0: 65 72 63 61 73 65 20 72 65 67 65 78 3a 20 27 66  ercase regex: 'f
0f00: 6f 6f 27 20 62 65 63 6f 6d 65 73 20 27 5b 46 66  oo' becomes '[Ff
0f10: 5d 5b 4f 6f 5d 5b 4f 6f 5d 27 2c 20 62 75 74 20  ][Oo][Oo]', but 
0f20: 27 42 61 72 27 20 62 65 63 6f 6d 65 73 20 27 42  'Bar' becomes 'B
0f30: 5b 41 61 5d 5b 52 72 5d 27 2e 22 0a 20 20 20 20  [Aa][Rr]'.".    
0f40: 73 55 70 20 3d 20 22 22 0a 20 20 20 20 6e 53 74  sUp = "".    nSt
0f50: 61 74 65 20 3d 20 30 0a 20 20 20 20 66 6f 72 20  ate = 0.    for 
0f60: 69 20 69 6e 20 72 61 6e 67 65 28 30 2c 20 6c 65  i in range(0, le
0f70: 6e 28 73 29 29 3a 0a 20 20 20 20 20 20 20 20 63  n(s)):.        c
0f80: 20 3d 20 73 5b 69 5d 0a 20 20 20 20 20 20 20 20   = s[i].        
0f90: 69 66 20 63 20 3d 3d 20 22 5b 22 3a 0a 20 20 20  if c == "[":.   
0fa0: 20 20 20 20 20 20 20 20 20 6e 53 74 61 74 65 20           nState 
0fb0: 3d 20 31 0a 20 20 20 20 20 20 20 20 69 66 20 6e  = 1.        if n
0fc0: 53 74 61 74 65 20 3d 3d 20 31 20 61 6e 64 20 63  State == 1 and c
0fd0: 20 3d 3d 20 22 5d 22 3a 0a 20 20 20 20 20 20 20   == "]":.       
0fe0: 20 20 20 20 20 6e 53 74 61 74 65 20 3d 20 30 0a       nState = 0.
0ff0: 20 20 20 20 20 20 20 20 69 66 20 63 20 3d 3d 20          if c == 
1000: 22 3c 22 20 61 6e 64 20 69 20 3e 20 33 20 61 6e  "<" and i > 3 an
1010: 64 20 73 5b 69 2d 33 3a 69 5d 20 3d 3d 20 22 28  d s[i-3:i] == "(
1020: 3f 50 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ?P":.           
1030: 20 6e 53 74 61 74 65 20 3d 20 32 0a 20 20 20 20   nState = 2.    
1040: 20 20 20 20 69 66 20 6e 53 74 61 74 65 20 3d 3d      if nState ==
1050: 20 32 20 61 6e 64 20 63 20 3d 3d 20 22 3e 22 3a   2 and c == ">":
1060: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74  .            nSt
1070: 61 74 65 20 3d 20 30 0a 20 20 20 20 20 20 20 20  ate = 0.        
1080: 69 66 20 63 20 3d 3d 20 22 3f 22 20 61 6e 64 20  if c == "?" and 
1090: 69 20 3e 20 30 20 61 6e 64 20 73 5b 69 2d 31 3a  i > 0 and s[i-1:
10a0: 69 5d 20 3d 3d 20 22 28 22 20 61 6e 64 20 73 5b  i] == "(" and s[
10b0: 69 2b 31 3a 69 2b 32 5d 20 21 3d 20 22 3a 22 3a  i+1:i+2] != ":":
10c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74  .            nSt
10d0: 61 74 65 20 3d 20 35 0a 20 20 20 20 20 20 20 20  ate = 5.        
10e0: 69 66 20 6e 53 74 61 74 65 20 3d 3d 20 35 20 61  if nState == 5 a
10f0: 6e 64 20 63 20 3d 3d 20 22 29 22 3a 0a 20 20 20  nd c == ")":.   
1100: 20 20 20 20 20 20 20 20 20 6e 53 74 61 74 65 20           nState 
1110: 3d 20 30 0a 20 20 20 20 20 20 20 20 69 66 20 63  = 0.        if c
1120: 2e 69 73 61 6c 70 68 61 28 29 20 61 6e 64 20 63  .isalpha() and c
1130: 2e 69 73 6c 6f 77 65 72 28 29 20 61 6e 64 20 6e  .islower() and n
1140: 53 74 61 74 65 20 3d 3d 20 30 3a 0a 20 20 20 20  State == 0:.    
1150: 20 20 20 20 20 20 20 20 69 66 20 63 20 3d 3d 20          if c == 
1160: 22 69 22 20 61 6e 64 20 28 73 4c 61 6e 67 20 3d  "i" and (sLang =
1170: 3d 20 22 74 72 22 20 6f 72 20 73 4c 61 6e 67 20  = "tr" or sLang 
1180: 3d 3d 20 22 61 7a 22 29 3a 0a 20 20 20 20 20 20  == "az"):.      
1190: 20 20 20 20 20 20 20 20 20 20 73 55 70 20 2b 3d            sUp +=
11a0: 20 22 5b c4 b0 22 20 2b 20 63 20 2b 20 22 5d 22   "[.." + c + "]"
11b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
11c0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
11d0: 20 20 20 73 55 70 20 2b 3d 20 22 5b 22 20 2b 20     sUp += "[" + 
11e0: 63 2e 75 70 70 65 72 28 29 20 2b 20 63 20 2b 20  c.upper() + c + 
11f0: 22 5d 22 0a 20 20 20 20 20 20 20 20 65 6c 69 66  "]".        elif
1200: 20 63 2e 69 73 61 6c 70 68 61 28 29 20 61 6e 64   c.isalpha() and
1210: 20 63 2e 69 73 6c 6f 77 65 72 28 29 20 61 6e 64   c.islower() and
1220: 20 6e 53 74 61 74 65 20 3d 3d 20 31 20 61 6e 64   nState == 1 and
1230: 20 73 5b 69 2b 31 3a 69 2b 32 5d 20 21 3d 20 22   s[i+1:i+2] != "
1240: 2d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  -":.            
1250: 69 66 20 73 5b 69 2d 31 3a 69 5d 20 3d 3d 20 22  if s[i-1:i] == "
1260: 2d 22 20 61 6e 64 20 73 5b 69 2d 32 3a 69 2d 31  -" and s[i-2:i-1
1270: 5d 2e 69 73 6c 6f 77 65 72 28 29 3a 20 20 23 20  ].islower():  # 
1280: 5b 61 2d 7a 5d 20 2d 3e 20 5b 61 2d 7a 41 2d 5a  [a-z] -> [a-zA-Z
1290: 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ].              
12a0: 20 20 73 55 70 20 2b 3d 20 63 20 2b 20 73 5b 69    sUp += c + s[i
12b0: 2d 32 3a 69 2d 31 5d 2e 75 70 70 65 72 28 29 20  -2:i-1].upper() 
12c0: 2b 20 22 2d 22 20 2b 20 63 2e 75 70 70 65 72 28  + "-" + c.upper(
12d0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c  ).            el
12e0: 69 66 20 63 20 3d 3d 20 22 69 22 20 61 6e 64 20  if c == "i" and 
12f0: 28 73 4c 61 6e 67 20 3d 3d 20 22 74 72 22 20 6f  (sLang == "tr" o
1300: 72 20 73 4c 61 6e 67 20 3d 3d 20 22 61 7a 22 29  r sLang == "az")
1310: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
1320: 20 20 73 55 70 20 2b 3d 20 22 c4 b0 22 20 2b 20    sUp += ".." + 
1330: 63 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c  c.            el
1340: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
1350: 20 20 20 20 73 55 70 20 2b 3d 20 63 2e 75 70 70      sUp += c.upp
1360: 65 72 28 29 20 2b 20 63 0a 20 20 20 20 20 20 20  er() + c.       
1370: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
1380: 20 20 20 73 55 70 20 2b 3d 20 63 0a 20 20 20 20     sUp += c.    
1390: 20 20 20 20 69 66 20 63 20 3d 3d 20 22 5c 5c 22      if c == "\\"
13a0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 53  :.            nS
13b0: 74 61 74 65 20 3d 20 34 0a 20 20 20 20 20 20 20  tate = 4.       
13c0: 20 65 6c 69 66 20 6e 53 74 61 74 65 20 3d 3d 20   elif nState == 
13d0: 34 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e  4:.            n
13e0: 53 74 61 74 65 20 3d 20 30 0a 20 20 20 20 72 65  State = 0.    re
13f0: 74 75 72 6e 20 73 55 70 0a 0a 0a 64 65 66 20 63  turn sUp...def c
1400: 6f 75 6e 74 47 72 6f 75 70 49 6e 52 65 67 65 78  ountGroupInRegex
1410: 20 28 73 52 65 67 65 78 29 3a 0a 20 20 20 20 22   (sRegex):.    "
1420: 72 65 74 75 72 6e 73 20 74 68 65 20 6e 75 6d 62  returns the numb
1430: 65 72 20 6f 66 20 67 72 6f 75 70 73 20 69 6e 20  er of groups in 
1440: 3c 73 52 65 67 65 78 3e 22 0a 20 20 20 20 74 72  <sRegex>".    tr
1450: 79 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  y:.        retur
1460: 6e 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 52 65  n re.compile(sRe
1470: 67 65 78 29 2e 67 72 6f 75 70 73 0a 20 20 20 20  gex).groups.    
1480: 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20  except:.        
1490: 74 72 61 63 65 62 61 63 6b 2e 70 72 69 6e 74 5f  traceback.print_
14a0: 65 78 63 28 29 0a 20 20 20 20 20 20 20 20 70 72  exc().        pr
14b0: 69 6e 74 28 73 52 65 67 65 78 29 0a 20 20 20 20  int(sRegex).    
14c0: 72 65 74 75 72 6e 20 30 0a 0a 0a 64 65 66 20 63  return 0...def c
14d0: 72 65 61 74 65 52 75 6c 65 20 28 73 2c 20 6e 49  reateRule (s, nI
14e0: 64 4c 69 6e 65 2c 20 73 4c 61 6e 67 2c 20 62 50  dLine, sLang, bP
14f0: 61 72 61 67 72 61 70 68 2c 20 64 4f 70 74 50 72  aragraph, dOptPr
1500: 69 6f 72 69 74 79 29 3a 0a 20 20 20 20 22 72 65  iority):.    "re
1510: 74 75 72 6e 73 20 72 75 6c 65 20 61 73 20 6c 69  turns rule as li
1520: 73 74 20 5b 6f 70 74 69 6f 6e 20 6e 61 6d 65 2c  st [option name,
1530: 20 72 65 67 65 78 2c 20 62 43 61 73 65 49 6e 73   regex, bCaseIns
1540: 65 6e 73 69 74 69 76 65 2c 20 69 64 65 6e 74 69  ensitive, identi
1550: 66 69 65 72 2c 20 6c 69 73 74 20 6f 66 20 61 63  fier, list of ac
1560: 74 69 6f 6e 73 5d 22 0a 20 20 20 20 67 6c 6f 62  tions]".    glob
1570: 61 6c 20 64 4a 53 52 45 47 45 58 45 53 0a 20 20  al dJSREGEXES.  
1580: 20 20 67 6c 6f 62 61 6c 20 6e 52 55 4c 45 57 49    global nRULEWI
1590: 54 48 4f 55 54 4e 41 4d 45 0a 0a 20 20 20 20 73  THOUTNAME..    s
15a0: 4c 69 6e 65 49 64 20 3d 20 73 74 72 28 6e 49 64  LineId = str(nId
15b0: 4c 69 6e 65 29 20 2b 20 28 22 70 22 20 69 66 20  Line) + ("p" if 
15c0: 62 50 61 72 61 67 72 61 70 68 20 65 6c 73 65 20  bParagraph else 
15d0: 22 73 22 29 0a 20 20 20 20 73 52 75 6c 65 49 64  "s").    sRuleId
15e0: 20 3d 20 73 4c 69 6e 65 49 64 0a 0a 20 20 20 20   = sLineId..    
15f0: 23 23 23 23 20 47 52 41 50 48 20 43 41 4c 4c 0a  #### GRAPH CALL.
1600: 20 20 20 20 69 66 20 73 2e 73 74 61 72 74 73 77      if s.startsw
1610: 69 74 68 28 22 40 40 40 40 22 29 3a 0a 20 20 20  ith("@@@@"):.   
1620: 20 20 20 20 20 69 66 20 62 50 61 72 61 67 72 61       if bParagra
1630: 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ph:.            
1640: 70 72 69 6e 74 28 22 45 72 72 6f 72 2e 20 47 72  print("Error. Gr
1650: 61 70 68 20 63 61 6c 6c 20 63 61 6e 20 62 65 20  aph call can be 
1660: 6d 61 64 65 20 6f 6e 6c 79 20 61 66 74 65 72 20  made only after 
1670: 74 68 65 20 66 69 72 73 74 20 70 61 73 73 20 28  the first pass (
1680: 73 65 6e 74 65 6e 63 65 20 62 79 20 73 65 6e 74  sentence by sent
1690: 65 6e 63 65 29 22 29 0a 20 20 20 20 20 20 20 20  ence)").        
16a0: 20 20 20 20 65 78 69 74 28 29 0a 20 20 20 20 20      exit().     
16b0: 20 20 20 72 65 74 75 72 6e 20 5b 22 40 40 40 40     return ["@@@@
16c0: 22 2c 20 73 5b 34 3a 5d 2c 20 73 4c 69 6e 65 49  ", s[4:], sLineI
16d0: 64 5d 0a 0a 20 20 20 20 23 23 23 23 20 4f 50 54  d]..    #### OPT
16e0: 49 4f 4e 53 0a 20 20 20 20 73 4f 70 74 69 6f 6e  IONS.    sOption
16f0: 20 3d 20 46 61 6c 73 65 20 20 20 20 20 20 20 20   = False        
1700: 20 23 20 46 61 6c 73 65 20 6f 72 20 5b 61 2d 7a   # False or [a-z
1710: 30 2d 39 5d 2b 20 6e 61 6d 65 0a 20 20 20 20 6e  0-9]+ name.    n
1720: 50 72 69 6f 72 69 74 79 20 3d 20 34 20 20 20 20  Priority = 4    
1730: 20 20 20 20 20 20 20 23 20 44 65 66 61 75 6c 74         # Default
1740: 20 69 73 20 34 2c 20 76 61 6c 75 65 20 6d 75 73   is 4, value mus
1750: 74 20 62 65 20 62 65 74 77 65 65 6e 20 30 20 61  t be between 0 a
1760: 6e 64 20 39 0a 20 20 20 20 74 47 72 6f 75 70 73  nd 9.    tGroups
1770: 20 3d 20 4e 6f 6e 65 20 20 20 20 20 20 20 20 20   = None         
1780: 20 23 20 63 6f 64 65 20 66 6f 72 20 67 72 6f 75   # code for grou
1790: 70 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67 20 28  ps positioning (
17a0: 6f 6e 6c 79 20 75 73 65 66 75 6c 20 66 6f 72 20  only useful for 
17b0: 4a 61 76 61 53 63 72 69 70 74 29 0a 20 20 20 20  JavaScript).    
17c0: 63 43 61 73 65 4d 6f 64 65 20 3d 20 27 69 27 20  cCaseMode = 'i' 
17d0: 20 20 20 20 20 20 20 20 23 20 69 3a 20 63 61 73          # i: cas
17e0: 65 20 69 6e 73 65 6e 73 69 74 69 76 65 2c 20 20  e insensitive,  
17f0: 73 3a 20 63 61 73 65 20 73 65 6e 73 69 74 69 76  s: case sensitiv
1800: 65 2c 20 20 75 3a 20 75 70 70 65 72 63 61 73 69  e,  u: uppercasi
1810: 6e 67 20 61 6c 6c 6f 77 65 64 0a 20 20 20 20 63  ng allowed.    c
1820: 57 6f 72 64 4c 69 6d 69 74 4c 65 66 74 20 3d 20  WordLimitLeft = 
1830: 27 5b 27 20 20 20 20 23 20 5b 3a 20 77 6f 72 64  '['    # [: word
1840: 20 6c 69 6d 69 74 2c 20 3c 3a 20 6e 6f 20 73 70   limit, <: no sp
1850: 65 63 69 66 69 63 20 6c 69 6d 69 74 0a 20 20 20  ecific limit.   
1860: 20 63 57 6f 72 64 4c 69 6d 69 74 52 69 67 68 74   cWordLimitRight
1870: 20 3d 20 27 5d 27 20 20 20 23 20 5d 3a 20 77 6f   = ']'   # ]: wo
1880: 72 64 20 6c 69 6d 69 74 2c 20 3e 3a 20 6e 6f 20  rd limit, >: no 
1890: 73 70 65 63 69 66 69 63 20 6c 69 6d 69 74 0a 20  specific limit. 
18a0: 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28     m = re.match(
18b0: 22 5e 5f 5f 28 3f 50 3c 62 6f 72 64 65 72 73 5f  "^__(?P<borders_
18c0: 61 6e 64 5f 63 61 73 65 3e 5b 5b 3c 5d 5c 5c 77  and_case>[[<]\\w
18d0: 5b 5d 3e 5d 29 28 3f 50 3c 6f 70 74 69 6f 6e 3e  []>])(?P<option>
18e0: 2f 5b 61 2d 7a 41 2d 5a 30 2d 39 5d 2b 7c 29 28  /[a-zA-Z0-9]+|)(
18f0: 3f 50 3c 72 75 6c 65 69 64 3e 5c 5c 28 5c 5c 77  ?P<ruleid>\\(\\w
1900: 2b 5c 5c 29 7c 29 28 3f 50 3c 70 72 69 6f 72 69  +\\)|)(?P<priori
1910: 74 79 3e 21 5b 30 2d 39 5d 7c 29 5f 5f 20 2a 22  ty>![0-9]|)__ *"
1920: 2c 20 73 29 0a 20 20 20 20 69 66 20 6d 3a 0a 20  , s).    if m:. 
1930: 20 20 20 20 20 20 20 63 57 6f 72 64 4c 69 6d 69         cWordLimi
1940: 74 4c 65 66 74 20 3d 20 6d 2e 67 72 6f 75 70 28  tLeft = m.group(
1950: 27 62 6f 72 64 65 72 73 5f 61 6e 64 5f 63 61 73  'borders_and_cas
1960: 65 27 29 5b 30 5d 0a 20 20 20 20 20 20 20 20 63  e')[0].        c
1970: 43 61 73 65 4d 6f 64 65 20 3d 20 6d 2e 67 72 6f  CaseMode = m.gro
1980: 75 70 28 27 62 6f 72 64 65 72 73 5f 61 6e 64 5f  up('borders_and_
1990: 63 61 73 65 27 29 5b 31 5d 0a 20 20 20 20 20 20  case')[1].      
19a0: 20 20 63 57 6f 72 64 4c 69 6d 69 74 52 69 67 68    cWordLimitRigh
19b0: 74 20 3d 20 6d 2e 67 72 6f 75 70 28 27 62 6f 72  t = m.group('bor
19c0: 64 65 72 73 5f 61 6e 64 5f 63 61 73 65 27 29 5b  ders_and_case')[
19d0: 32 5d 0a 20 20 20 20 20 20 20 20 73 4f 70 74 69  2].        sOpti
19e0: 6f 6e 20 3d 20 6d 2e 67 72 6f 75 70 28 27 6f 70  on = m.group('op
19f0: 74 69 6f 6e 27 29 5b 31 3a 5d 20 20 69 66 20 6d  tion')[1:]  if m
1a00: 2e 67 72 6f 75 70 28 27 6f 70 74 69 6f 6e 27 29  .group('option')
1a10: 20 20 65 6c 73 65 20 46 61 6c 73 65 0a 20 20 20    else False.   
1a20: 20 20 20 20 20 69 66 20 6d 2e 67 72 6f 75 70 28       if m.group(
1a30: 27 72 75 6c 65 69 64 27 29 3a 0a 20 20 20 20 20  'ruleid'):.     
1a40: 20 20 20 20 20 20 20 73 52 75 6c 65 49 64 20 3d         sRuleId =
1a50: 20 20 6d 2e 67 72 6f 75 70 28 27 72 75 6c 65 69    m.group('rulei
1a60: 64 27 29 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20  d')[1:-1].      
1a70: 20 20 20 20 20 20 69 66 20 73 52 75 6c 65 49 64        if sRuleId
1a80: 20 69 6e 20 61 52 55 4c 45 53 45 54 3a 0a 20 20   in aRULESET:.  
1a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
1aa0: 69 6e 74 28 22 23 20 45 72 72 6f 72 2e 20 53 65  int("# Error. Se
1ab0: 76 65 72 61 6c 20 72 75 6c 65 73 20 68 61 76 65  veral rules have
1ac0: 20 74 68 65 20 73 61 6d 65 20 69 64 3a 20 22 20   the same id: " 
1ad0: 2b 20 73 52 75 6c 65 49 64 29 0a 20 20 20 20 20  + sRuleId).     
1ae0: 20 20 20 20 20 20 20 20 20 20 20 65 78 69 74 28             exit(
1af0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 52  ).            aR
1b00: 55 4c 45 53 45 54 2e 61 64 64 28 73 52 75 6c 65  ULESET.add(sRule
1b10: 49 64 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65  Id).        else
1b20: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 52  :.            nR
1b30: 55 4c 45 57 49 54 48 4f 55 54 4e 41 4d 45 20 2b  ULEWITHOUTNAME +
1b40: 3d 20 31 0a 20 20 20 20 20 20 20 20 6e 50 72 69  = 1.        nPri
1b50: 6f 72 69 74 79 20 3d 20 64 4f 70 74 50 72 69 6f  ority = dOptPrio
1b60: 72 69 74 79 2e 67 65 74 28 73 4f 70 74 69 6f 6e  rity.get(sOption
1b70: 2c 20 34 29 0a 20 20 20 20 20 20 20 20 69 66 20  , 4).        if 
1b80: 6d 2e 67 72 6f 75 70 28 27 70 72 69 6f 72 69 74  m.group('priorit
1b90: 79 27 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  y'):.           
1ba0: 20 6e 50 72 69 6f 72 69 74 79 20 3d 20 69 6e 74   nPriority = int
1bb0: 28 6d 2e 67 72 6f 75 70 28 27 70 72 69 6f 72 69  (m.group('priori
1bc0: 74 79 27 29 5b 31 3a 5d 29 0a 20 20 20 20 20 20  ty')[1:]).      
1bd0: 20 20 73 20 3d 20 73 5b 6d 2e 65 6e 64 28 30 29    s = s[m.end(0)
1be0: 3a 5d 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20  :].    else:.   
1bf0: 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 57 61       print("# Wa
1c00: 72 6e 69 6e 67 2e 20 4e 6f 20 6f 70 74 69 6f 6e  rning. No option
1c10: 20 64 65 66 69 6e 65 64 20 61 74 20 6c 69 6e 65   defined at line
1c20: 3a 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a 0a  : " + sLineId)..
1c30: 20 20 20 20 23 23 23 23 20 52 45 47 45 58 20 54      #### REGEX T
1c40: 52 49 47 47 45 52 0a 20 20 20 20 69 20 3d 20 73  RIGGER.    i = s
1c50: 2e 66 69 6e 64 28 22 20 3c 3c 2d 22 29 0a 20 20  .find(" <<-").  
1c60: 20 20 69 66 20 69 20 3d 3d 20 2d 31 3a 0a 20 20    if i == -1:.  
1c70: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45        print("# E
1c80: 72 72 6f 72 3a 20 6e 6f 20 63 6f 6e 64 69 74 69  rror: no conditi
1c90: 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  on at line " + s
1ca0: 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20 20  LineId).        
1cb0: 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20 20  return None.    
1cc0: 73 52 65 67 65 78 20 3d 20 73 5b 3a 69 5d 2e 73  sRegex = s[:i].s
1cd0: 74 72 69 70 28 29 0a 20 20 20 20 73 20 3d 20 73  trip().    s = s
1ce0: 5b 69 2b 34 3a 5d 0a 0a 20 20 20 20 23 20 4a 53  [i+4:]..    # JS
1cf0: 20 67 72 6f 75 70 73 20 70 6f 73 69 74 69 6f 6e   groups position
1d00: 69 6e 67 20 63 6f 64 65 73 0a 20 20 20 20 6d 20  ing codes.    m 
1d10: 3d 20 72 65 2e 73 65 61 72 63 68 28 22 40 40 5c  = re.search("@@\
1d20: 5c 53 2b 22 2c 20 73 52 65 67 65 78 29 0a 20 20  \S+", sRegex).  
1d30: 20 20 69 66 20 6d 3a 0a 20 20 20 20 20 20 20 20    if m:.        
1d40: 74 47 72 6f 75 70 73 20 3d 20 6a 73 63 6f 6e 76  tGroups = jsconv
1d50: 2e 67 72 6f 75 70 73 50 6f 73 69 74 69 6f 6e 69  .groupsPositioni
1d60: 6e 67 43 6f 64 65 54 6f 4c 69 73 74 28 73 52 65  ngCodeToList(sRe
1d70: 67 65 78 5b 6d 2e 73 74 61 72 74 28 29 2b 32 3a  gex[m.start()+2:
1d80: 5d 29 0a 20 20 20 20 20 20 20 20 73 52 65 67 65  ]).        sRege
1d90: 78 20 3d 20 73 52 65 67 65 78 5b 3a 6d 2e 73 74  x = sRegex[:m.st
1da0: 61 72 74 28 29 5d 2e 73 74 72 69 70 28 29 0a 20  art()].strip(). 
1db0: 20 20 20 23 20 4a 53 20 72 65 67 65 78 0a 20 20     # JS regex.  
1dc0: 20 20 6d 20 3d 20 72 65 2e 73 65 61 72 63 68 28    m = re.search(
1dd0: 22 3c 6a 73 3e 2e 2b 3c 2f 6a 73 3e 69 3f 22 2c  "<js>.+</js>i?",
1de0: 20 73 52 65 67 65 78 29 0a 20 20 20 20 69 66 20   sRegex).    if 
1df0: 6d 3a 0a 20 20 20 20 20 20 20 20 64 4a 53 52 45  m:.        dJSRE
1e00: 47 45 58 45 53 5b 73 4c 69 6e 65 49 64 5d 20 3d  GEXES[sLineId] =
1e10: 20 6d 2e 67 72 6f 75 70 28 30 29 0a 20 20 20 20   m.group(0).    
1e20: 20 20 20 20 73 52 65 67 65 78 20 3d 20 73 52 65      sRegex = sRe
1e30: 67 65 78 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2e  gex[:m.start()].
1e40: 73 74 72 69 70 28 29 0a 20 20 20 20 69 66 20 22  strip().    if "
1e50: 3c 6a 73 3e 22 20 69 6e 20 73 52 65 67 65 78 20  <js>" in sRegex 
1e60: 6f 72 20 22 3c 2f 6a 73 3e 22 20 69 6e 20 73 52  or "</js>" in sR
1e70: 65 67 65 78 3a 0a 20 20 20 20 20 20 20 20 70 72  egex:.        pr
1e80: 69 6e 74 28 22 23 20 45 72 72 6f 72 3a 20 4a 61  int("# Error: Ja
1e90: 76 61 53 63 72 69 70 74 20 72 65 67 65 78 20 6e  vaScript regex n
1ea0: 6f 74 20 64 65 6c 69 6d 69 74 65 64 20 61 74 20  ot delimited at 
1eb0: 6c 69 6e 65 20 22 20 2b 20 73 4c 69 6e 65 49 64  line " + sLineId
1ec0: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ).        return
1ed0: 20 4e 6f 6e 65 0a 0a 20 20 20 20 23 20 71 75 6f   None..    # quo
1ee0: 74 65 73 20 3f 0a 20 20 20 20 69 66 20 73 52 65  tes ?.    if sRe
1ef0: 67 65 78 2e 73 74 61 72 74 73 77 69 74 68 28 27  gex.startswith('
1f00: 22 27 29 20 61 6e 64 20 73 52 65 67 65 78 2e 65  "') and sRegex.e
1f10: 6e 64 73 77 69 74 68 28 27 22 27 29 3a 0a 20 20  ndswith('"'):.  
1f20: 20 20 20 20 20 20 73 52 65 67 65 78 20 3d 20 73        sRegex = s
1f30: 52 65 67 65 78 5b 31 3a 2d 31 5d 0a 0a 20 20 20  Regex[1:-1]..   
1f40: 20 23 23 20 64 65 66 69 6e 69 74 69 6f 6e 73 0a   ## definitions.
1f50: 20 20 20 20 66 6f 72 20 73 44 65 66 2c 20 73 52      for sDef, sR
1f60: 65 70 6c 20 69 6e 20 64 44 45 46 2e 69 74 65 6d  epl in dDEF.item
1f70: 73 28 29 3a 0a 20 20 20 20 20 20 20 20 73 52 65  s():.        sRe
1f80: 67 65 78 20 3d 20 73 52 65 67 65 78 2e 72 65 70  gex = sRegex.rep
1f90: 6c 61 63 65 28 73 44 65 66 2c 20 73 52 65 70 6c  lace(sDef, sRepl
1fa0: 29 0a 0a 20 20 20 20 23 23 20 63 6f 75 6e 74 20  )..    ## count 
1fb0: 6e 75 6d 62 65 72 20 6f 66 20 67 72 6f 75 70 73  number of groups
1fc0: 20 28 6d 75 73 74 20 62 65 20 64 6f 6e 65 20 62   (must be done b
1fd0: 65 66 6f 72 65 20 6d 6f 64 69 66 79 69 6e 67 20  efore modifying 
1fe0: 74 68 65 20 72 65 67 65 78 29 0a 20 20 20 20 6e  the regex).    n
1ff0: 47 72 6f 75 70 20 3d 20 63 6f 75 6e 74 47 72 6f  Group = countGro
2000: 75 70 49 6e 52 65 67 65 78 28 73 52 65 67 65 78  upInRegex(sRegex
2010: 29 0a 20 20 20 20 69 66 20 6e 47 72 6f 75 70 20  ).    if nGroup 
2020: 3e 20 30 3a 0a 20 20 20 20 20 20 20 20 69 66 20  > 0:.        if 
2030: 6e 6f 74 20 74 47 72 6f 75 70 73 3a 0a 20 20 20  not tGroups:.   
2040: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
2050: 23 20 57 61 72 6e 69 6e 67 3a 20 67 72 6f 75 70  # Warning: group
2060: 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67 20 63 6f  s positioning co
2070: 64 65 20 66 6f 72 20 4a 61 76 61 53 63 72 69 70  de for JavaScrip
2080: 74 20 73 68 6f 75 6c 64 20 62 65 20 64 65 66 69  t should be defi
2090: 6e 65 64 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ned at line " + 
20a0: 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20  sLineId).       
20b0: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
20c0: 20 20 20 69 66 20 6e 47 72 6f 75 70 20 21 3d 20     if nGroup != 
20d0: 6c 65 6e 28 74 47 72 6f 75 70 73 29 3a 0a 20 20  len(tGroups):.  
20e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
20f0: 69 6e 74 28 22 23 20 45 72 72 6f 72 3a 20 67 72  int("# Error: gr
2100: 6f 75 70 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67  oups positioning
2110: 20 63 6f 64 65 20 69 72 72 65 6c 65 76 61 6e 74   code irrelevant
2120: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 4c 69   at line " + sLi
2130: 6e 65 49 64 29 0a 0a 20 20 20 20 23 23 20 77 6f  neId)..    ## wo
2140: 72 64 20 6c 69 6d 69 74 0a 20 20 20 20 69 66 20  rd limit.    if 
2150: 63 57 6f 72 64 4c 69 6d 69 74 4c 65 66 74 20 3d  cWordLimitLeft =
2160: 3d 20 27 5b 27 20 61 6e 64 20 6e 6f 74 20 73 52  = '[' and not sR
2170: 65 67 65 78 2e 73 74 61 72 74 73 77 69 74 68 28  egex.startswith(
2180: 28 22 5e 22 2c 20 27 e2 80 99 27 2c 20 22 27 22  ("^", '...', "'"
2190: 2c 20 22 2c 22 29 29 3a 0a 20 20 20 20 20 20 20  , ",")):.       
21a0: 20 73 52 65 67 65 78 20 3d 20 73 57 4f 52 44 4c   sRegex = sWORDL
21b0: 49 4d 49 54 4c 45 46 54 20 2b 20 73 52 65 67 65  IMITLEFT + sRege
21c0: 78 0a 20 20 20 20 69 66 20 63 57 6f 72 64 4c 69  x.    if cWordLi
21d0: 6d 69 74 52 69 67 68 74 20 3d 3d 20 27 5d 27 20  mitRight == ']' 
21e0: 61 6e 64 20 6e 6f 74 20 73 52 65 67 65 78 2e 65  and not sRegex.e
21f0: 6e 64 73 77 69 74 68 28 28 22 24 22 2c 20 27 e2  ndswith(("$", '.
2200: 80 99 27 2c 20 22 27 22 2c 20 22 2c 22 29 29 3a  ..', "'", ",")):
2210: 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78 20  .        sRegex 
2220: 3d 20 73 52 65 67 65 78 20 2b 20 73 57 4f 52 44  = sRegex + sWORD
2230: 4c 49 4d 49 54 52 49 47 48 54 0a 0a 20 20 20 20  LIMITRIGHT..    
2240: 23 23 20 63 61 73 69 6e 67 20 6d 6f 64 65 0a 20  ## casing mode. 
2250: 20 20 20 69 66 20 63 43 61 73 65 4d 6f 64 65 20     if cCaseMode 
2260: 3d 3d 20 22 69 22 3a 0a 20 20 20 20 20 20 20 20  == "i":.        
2270: 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69 76 65  bCaseInsensitive
2280: 20 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20 20   = True.        
2290: 69 66 20 6e 6f 74 20 73 52 65 67 65 78 2e 73 74  if not sRegex.st
22a0: 61 72 74 73 77 69 74 68 28 22 28 3f 69 29 22 29  artswith("(?i)")
22b0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 52  :.            sR
22c0: 65 67 65 78 20 3d 20 22 28 3f 69 29 22 20 2b 20  egex = "(?i)" + 
22d0: 73 52 65 67 65 78 0a 20 20 20 20 65 6c 69 66 20  sRegex.    elif 
22e0: 63 43 61 73 65 4d 6f 64 65 20 3d 3d 20 22 73 22  cCaseMode == "s"
22f0: 3a 0a 20 20 20 20 20 20 20 20 62 43 61 73 65 49  :.        bCaseI
2300: 6e 73 65 6e 73 69 74 69 76 65 20 3d 20 46 61 6c  nsensitive = Fal
2310: 73 65 0a 20 20 20 20 20 20 20 20 73 52 65 67 65  se.        sRege
2320: 78 20 3d 20 73 52 65 67 65 78 2e 72 65 70 6c 61  x = sRegex.repla
2330: 63 65 28 22 28 3f 69 29 22 2c 20 22 22 29 0a 20  ce("(?i)", ""). 
2340: 20 20 20 65 6c 69 66 20 63 43 61 73 65 4d 6f 64     elif cCaseMod
2350: 65 20 3d 3d 20 22 75 22 3a 0a 20 20 20 20 20 20  e == "u":.      
2360: 20 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69    bCaseInsensiti
2370: 76 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20  ve = False.     
2380: 20 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67     sRegex = sReg
2390: 65 78 2e 72 65 70 6c 61 63 65 28 22 28 3f 69 29  ex.replace("(?i)
23a0: 22 2c 20 22 22 29 0a 20 20 20 20 20 20 20 20 73  ", "").        s
23b0: 52 65 67 65 78 20 3d 20 75 70 70 65 72 63 61 73  Regex = uppercas
23c0: 65 28 73 52 65 67 65 78 2c 20 73 4c 61 6e 67 29  e(sRegex, sLang)
23d0: 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20  .    else:.     
23e0: 20 20 20 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e     print("# Unkn
23f0: 6f 77 6e 20 63 61 73 65 20 6d 6f 64 65 20 5b 22  own case mode ["
2400: 20 2b 20 63 43 61 73 65 4d 6f 64 65 20 2b 20 22   + cCaseMode + "
2410: 5d 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 4c  ] at line " + sL
2420: 69 6e 65 49 64 29 0a 0a 20 20 20 20 23 23 20 63  ineId)..    ## c
2430: 68 65 63 6b 20 72 65 67 65 78 0a 20 20 20 20 74  heck regex.    t
2440: 72 79 3a 0a 20 20 20 20 20 20 20 20 72 65 2e 63  ry:.        re.c
2450: 6f 6d 70 69 6c 65 28 73 52 65 67 65 78 29 0a 20  ompile(sRegex). 
2460: 20 20 20 65 78 63 65 70 74 3a 0a 20 20 20 20 20     except:.     
2470: 20 20 20 70 72 69 6e 74 28 22 23 20 52 65 67 65     print("# Rege
2480: 78 20 65 72 72 6f 72 20 61 74 20 6c 69 6e 65 20  x error at line 
2490: 22 2c 20 6e 49 64 4c 69 6e 65 29 0a 20 20 20 20  ", nIdLine).    
24a0: 20 20 20 20 70 72 69 6e 74 28 73 52 65 67 65 78      print(sRegex
24b0: 29 0a 20 20 20 20 20 20 20 20 74 72 61 63 65 62  ).        traceb
24c0: 61 63 6b 2e 70 72 69 6e 74 5f 65 78 63 28 29 0a  ack.print_exc().
24d0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e          return N
24e0: 6f 6e 65 0a 20 20 20 20 23 23 20 67 72 6f 75 70  one.    ## group
24f0: 73 20 69 6e 20 6e 6f 6e 20 67 72 6f 75 70 69 6e  s in non groupin
2500: 67 20 70 61 72 65 6e 74 68 65 73 69 73 0a 20 20  g parenthesis.  
2510: 20 20 66 6f 72 20 78 20 69 6e 20 72 65 2e 66 69    for x in re.fi
2520: 6e 64 69 74 65 72 28 72 22 5c 28 5c 3f 3a 5b 5e  nditer(r"\(\?:[^
2530: 29 5d 2a 5c 28 5b 5b 5c 77 20 2d 5d 22 2c 20 73  )]*\([[\w -]", s
2540: 52 65 67 65 78 29 3a 0a 20 20 20 20 20 20 20 20  Regex):.        
2550: 70 72 69 6e 74 28 22 23 20 57 61 72 6e 69 6e 67  print("# Warning
2560: 3a 20 67 72 6f 75 70 73 20 69 6e 73 69 64 65 20  : groups inside 
2570: 6e 6f 6e 20 67 72 6f 75 70 69 6e 67 20 70 61 72  non grouping par
2580: 65 6e 74 68 65 73 69 73 20 69 6e 20 72 65 67 65  enthesis in rege
2590: 78 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 4c  x at line " + sL
25a0: 69 6e 65 49 64 29 0a 0a 20 20 20 20 23 23 23 23  ineId)..    ####
25b0: 20 50 41 52 53 45 20 41 43 54 49 4f 4e 53 0a 20   PARSE ACTIONS. 
25c0: 20 20 20 6c 41 63 74 69 6f 6e 73 20 3d 20 5b 5d     lActions = []
25d0: 0a 20 20 20 20 6e 41 63 74 69 6f 6e 20 3d 20 31  .    nAction = 1
25e0: 0a 20 20 20 20 66 6f 72 20 73 41 63 74 69 6f 6e  .    for sAction
25f0: 20 69 6e 20 73 2e 73 70 6c 69 74 28 22 20 3c 3c   in s.split(" <<
2600: 2d 20 22 29 3a 0a 20 20 20 20 20 20 20 20 74 20  - "):.        t 
2610: 3d 20 63 72 65 61 74 65 41 63 74 69 6f 6e 28 73  = createAction(s
2620: 52 75 6c 65 49 64 20 2b 20 22 5f 22 20 2b 20 73  RuleId + "_" + s
2630: 74 72 28 6e 41 63 74 69 6f 6e 29 2c 20 73 41 63  tr(nAction), sAc
2640: 74 69 6f 6e 2c 20 6e 47 72 6f 75 70 29 0a 20 20  tion, nGroup).  
2650: 20 20 20 20 20 20 6e 41 63 74 69 6f 6e 20 2b 3d        nAction +=
2660: 20 31 0a 20 20 20 20 20 20 20 20 69 66 20 74 3a   1.        if t:
2670: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 41 63  .            lAc
2680: 74 69 6f 6e 73 2e 61 70 70 65 6e 64 28 74 29 0a  tions.append(t).
2690: 20 20 20 20 69 66 20 6e 6f 74 20 6c 41 63 74 69      if not lActi
26a0: 6f 6e 73 3a 0a 20 20 20 20 20 20 20 20 72 65 74  ons:.        ret
26b0: 75 72 6e 20 4e 6f 6e 65 0a 0a 20 20 20 20 72 65  urn None..    re
26c0: 74 75 72 6e 20 5b 73 4f 70 74 69 6f 6e 2c 20 73  turn [sOption, s
26d0: 52 65 67 65 78 2c 20 62 43 61 73 65 49 6e 73 65  Regex, bCaseInse
26e0: 6e 73 69 74 69 76 65 2c 20 73 4c 69 6e 65 49 64  nsitive, sLineId
26f0: 2c 20 73 52 75 6c 65 49 64 2c 20 6e 50 72 69 6f  , sRuleId, nPrio
2700: 72 69 74 79 2c 20 6c 41 63 74 69 6f 6e 73 2c 20  rity, lActions, 
2710: 74 47 72 6f 75 70 73 5d 0a 0a 0a 64 65 66 20 63  tGroups]...def c
2720: 68 65 63 6b 52 65 66 65 72 65 6e 63 65 4e 75 6d  heckReferenceNum
2730: 62 65 72 73 20 28 73 54 65 78 74 2c 20 73 41 63  bers (sText, sAc
2740: 74 69 6f 6e 49 64 2c 20 6e 54 6f 6b 65 6e 29 3a  tionId, nToken):
2750: 0a 20 20 20 20 22 63 68 65 63 6b 20 69 66 20 74  .    "check if t
2760: 6f 6b 65 6e 20 72 65 66 65 72 65 6e 63 65 73 20  oken references 
2770: 69 6e 20 3c 73 54 65 78 74 3e 20 67 72 65 61 74  in <sText> great
2780: 65 72 20 74 68 61 6e 20 3c 6e 54 6f 6b 65 6e 3e  er than <nToken>
2790: 20 28 64 65 62 75 67 67 69 6e 67 29 22 0a 20 20   (debugging)".  
27a0: 20 20 66 6f 72 20 78 20 69 6e 20 72 65 2e 66 69    for x in re.fi
27b0: 6e 64 69 74 65 72 28 72 22 5c 5c 28 5c 64 2b 29  nditer(r"\\(\d+)
27c0: 22 2c 20 73 54 65 78 74 29 3a 0a 20 20 20 20 20  ", sText):.     
27d0: 20 20 20 69 66 20 69 6e 74 28 78 2e 67 72 6f 75     if int(x.grou
27e0: 70 28 31 29 29 20 3e 20 6e 54 6f 6b 65 6e 3a 0a  p(1)) > nToken:.
27f0: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
2800: 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20 74 6f  t("# Error in to
2810: 6b 65 6e 20 69 6e 64 65 78 20 61 74 20 6c 69 6e  ken index at lin
2820: 65 20 22 20 2b 20 73 41 63 74 69 6f 6e 49 64 20  e " + sActionId 
2830: 2b 20 22 20 28 22 2b 73 74 72 28 6e 54 6f 6b 65  + " ("+str(nToke
2840: 6e 29 2b 22 20 74 6f 6b 65 6e 73 20 6f 6e 6c 79  n)+" tokens only
2850: 29 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  )").            
2860: 70 72 69 6e 74 28 73 54 65 78 74 29 0a 0a 0a 64  print(sText)...d
2870: 65 66 20 63 68 65 63 6b 49 66 54 68 65 72 65 49  ef checkIfThereI
2880: 73 43 6f 64 65 20 28 73 54 65 78 74 2c 20 73 41  sCode (sText, sA
2890: 63 74 69 6f 6e 49 64 29 3a 0a 20 20 20 20 22 63  ctionId):.    "c
28a0: 68 65 63 6b 20 69 66 20 74 68 65 72 65 20 69 73  heck if there is
28b0: 20 63 6f 64 65 20 69 6e 20 3c 73 54 65 78 74 3e   code in <sText>
28c0: 20 28 64 65 62 75 67 67 69 6e 67 29 22 0a 20 20   (debugging)".  
28d0: 20 20 69 66 20 72 65 2e 73 65 61 72 63 68 28 22    if re.search("
28e0: 5b 2e 5d 5c 5c 77 2b 5b 28 5d 7c 73 75 67 67 5c  [.]\\w+[(]|sugg\
28f0: 5c 77 2b 5b 28 5d 7c 5c 5c 28 5b 30 2d 39 5d 7c  \w+[(]|\\([0-9]|
2900: 5c 5c 5b 5b 30 2d 39 5d 22 2c 20 73 54 65 78 74  \\[[0-9]", sText
2910: 29 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  ):.        print
2920: 28 22 23 20 57 61 72 6e 69 6e 67 20 61 74 20 6c  ("# Warning at l
2930: 69 6e 65 20 22 20 2b 20 73 41 63 74 69 6f 6e 49  ine " + sActionI
2940: 64 20 2b 20 22 3a 20 20 54 68 69 73 20 6d 65 73  d + ":  This mes
2950: 73 61 67 65 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20  sage looks like 
2960: 63 6f 64 65 2e 20 4c 69 6e 65 20 73 68 6f 75 6c  code. Line shoul
2970: 64 20 70 72 6f 62 61 62 6c 79 20 62 65 67 69 6e  d probably begin
2980: 20 77 69 74 68 20 3d 22 29 0a 20 20 20 20 20 20   with =").      
2990: 20 20 70 72 69 6e 74 28 73 54 65 78 74 29 0a 0a    print(sText)..
29a0: 0a 64 65 66 20 63 72 65 61 74 65 41 63 74 69 6f  .def createActio
29b0: 6e 20 28 73 49 64 41 63 74 69 6f 6e 2c 20 73 41  n (sIdAction, sA
29c0: 63 74 69 6f 6e 2c 20 6e 47 72 6f 75 70 29 3a 0a  ction, nGroup):.
29d0: 20 20 20 20 22 72 65 74 75 72 6e 73 20 61 6e 20      "returns an 
29e0: 61 63 74 69 6f 6e 20 74 6f 20 70 65 72 66 6f 72  action to perfor
29f0: 6d 20 61 73 20 61 20 74 75 70 6c 65 20 28 63 6f  m as a tuple (co
2a00: 6e 64 69 74 69 6f 6e 2c 20 61 63 74 69 6f 6e 20  ndition, action 
2a10: 74 79 70 65 2c 20 61 63 74 69 6f 6e 5b 2c 20 69  type, action[, i
2a20: 47 72 6f 75 70 20 5b 2c 20 6d 65 73 73 61 67 65  Group [, message
2a30: 2c 20 55 52 4c 20 5d 5d 29 22 0a 20 20 20 20 6d  , URL ]])".    m
2a40: 20 3d 20 72 65 2e 73 65 61 72 63 68 28 72 22 28   = re.search(r"(
2a50: 5b 2d 7e 3d 3e 5d 29 28 5c 64 2a 7c 29 3e 3e 22  [-~=>])(\d*|)>>"
2a60: 2c 20 73 41 63 74 69 6f 6e 29 0a 20 20 20 20 69  , sAction).    i
2a70: 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20  f not m:.       
2a80: 20 70 72 69 6e 74 28 22 23 20 4e 6f 20 61 63 74   print("# No act
2a90: 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ion at line " + 
2aa0: 73 49 64 41 63 74 69 6f 6e 29 0a 20 20 20 20 20  sIdAction).     
2ab0: 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a     return None..
2ac0: 20 20 20 20 23 23 23 23 20 43 4f 4e 44 49 54 49      #### CONDITI
2ad0: 4f 4e 0a 20 20 20 20 73 43 6f 6e 64 69 74 69 6f  ON.    sConditio
2ae0: 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 3a 6d 2e 73  n = sAction[:m.s
2af0: 74 61 72 74 28 29 5d 2e 73 74 72 69 70 28 29 0a  tart()].strip().
2b00: 20 20 20 20 69 66 20 73 43 6f 6e 64 69 74 69 6f      if sConditio
2b10: 6e 3a 0a 20 20 20 20 20 20 20 20 73 43 6f 6e 64  n:.        sCond
2b20: 69 74 69 6f 6e 20 3d 20 70 72 65 70 61 72 65 46  ition = prepareF
2b30: 75 6e 63 74 69 6f 6e 28 73 43 6f 6e 64 69 74 69  unction(sConditi
2b40: 6f 6e 29 0a 20 20 20 20 20 20 20 20 6c 46 55 4e  on).        lFUN
2b50: 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28 28 22  CTIONS.append(("
2b60: 5f 63 5f 22 2b 73 49 64 41 63 74 69 6f 6e 2c 20  _c_"+sIdAction, 
2b70: 73 43 6f 6e 64 69 74 69 6f 6e 29 29 0a 20 20 20  sCondition)).   
2b80: 20 20 20 20 20 63 68 65 63 6b 52 65 66 65 72 65       checkRefere
2b90: 6e 63 65 4e 75 6d 62 65 72 73 28 73 43 6f 6e 64  nceNumbers(sCond
2ba0: 69 74 69 6f 6e 2c 20 73 49 64 41 63 74 69 6f 6e  ition, sIdAction
2bb0: 2c 20 6e 47 72 6f 75 70 29 0a 20 20 20 20 20 20  , nGroup).      
2bc0: 20 20 69 66 20 22 2e 6d 61 74 63 68 22 20 69 6e    if ".match" in
2bd0: 20 73 43 6f 6e 64 69 74 69 6f 6e 3a 0a 20 20 20   sCondition:.   
2be0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
2bf0: 23 20 45 72 72 6f 72 2e 20 4a 53 20 63 6f 6d 70  # Error. JS comp
2c00: 61 74 69 62 69 6c 69 74 79 2e 20 44 6f 6e 27 74  atibility. Don't
2c10: 20 75 73 65 20 2e 6d 61 74 63 68 28 29 20 69 6e   use .match() in
2c20: 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 75 73 65 20   condition, use 
2c30: 2e 73 65 61 72 63 68 28 29 22 29 0a 20 20 20 20  .search()").    
2c40: 20 20 20 20 73 43 6f 6e 64 69 74 69 6f 6e 20 3d      sCondition =
2c50: 20 22 5f 63 5f 22 2b 73 49 64 41 63 74 69 6f 6e   "_c_"+sIdAction
2c60: 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20  .    else:.     
2c70: 20 20 20 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20     sCondition = 
2c80: 4e 6f 6e 65 0a 0a 20 20 20 20 23 23 23 23 20 69  None..    #### i
2c90: 47 72 6f 75 70 20 2f 20 70 6f 73 69 74 69 6f 6e  Group / position
2ca0: 69 6e 67 0a 20 20 20 20 69 47 72 6f 75 70 20 3d  ing.    iGroup =
2cb0: 20 69 6e 74 28 6d 2e 67 72 6f 75 70 28 32 29 29   int(m.group(2))
2cc0: 20 69 66 20 6d 2e 67 72 6f 75 70 28 32 29 20 65   if m.group(2) e
2cd0: 6c 73 65 20 30 0a 20 20 20 20 69 66 20 69 47 72  lse 0.    if iGr
2ce0: 6f 75 70 20 3e 20 6e 47 72 6f 75 70 3a 0a 20 20  oup > nGroup:.  
2cf0: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 53        print("# S
2d00: 65 6c 65 63 74 65 64 20 67 72 6f 75 70 20 3e 20  elected group > 
2d10: 67 72 6f 75 70 20 6e 75 6d 62 65 72 20 69 6e 20  group number in 
2d20: 72 65 67 65 78 20 61 74 20 6c 69 6e 65 20 22 20  regex at line " 
2d30: 2b 20 73 49 64 41 63 74 69 6f 6e 29 0a 0a 20 20  + sIdAction)..  
2d40: 20 20 23 23 23 23 20 41 43 54 49 4f 4e 0a 20 20    #### ACTION.  
2d50: 20 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74    sAction = sAct
2d60: 69 6f 6e 5b 6d 2e 65 6e 64 28 29 3a 5d 2e 73 74  ion[m.end():].st
2d70: 72 69 70 28 29 0a 20 20 20 20 63 41 63 74 69 6f  rip().    cActio
2d80: 6e 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29 0a 20  n = m.group(1). 
2d90: 20 20 20 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d     if cAction ==
2da0: 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 23 23   "-":.        ##
2db0: 20 65 72 72 6f 72 0a 20 20 20 20 20 20 20 20 69   error.        i
2dc0: 4d 73 67 20 3d 20 73 41 63 74 69 6f 6e 2e 66 69  Msg = sAction.fi
2dd0: 6e 64 28 22 20 23 20 22 29 0a 20 20 20 20 20 20  nd(" # ").      
2de0: 20 20 69 66 20 69 4d 73 67 20 3d 3d 20 2d 31 3a    if iMsg == -1:
2df0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 4d 73  .            sMs
2e00: 67 20 3d 20 22 23 20 45 72 72 6f 72 2e 20 45 72  g = "# Error. Er
2e10: 72 6f 72 20 6d 65 73 73 61 67 65 20 6e 6f 74 20  ror message not 
2e20: 66 6f 75 6e 64 2e 22 0a 20 20 20 20 20 20 20 20  found.".        
2e30: 20 20 20 20 73 55 52 4c 20 3d 20 22 22 0a 20 20      sURL = "".  
2e40: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
2e50: 73 4d 73 67 20 2b 20 22 20 41 63 74 69 6f 6e 20  sMsg + " Action 
2e60: 69 64 3a 20 22 20 2b 20 73 49 64 41 63 74 69 6f  id: " + sIdActio
2e70: 6e 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a  n).        else:
2e80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 4d 73  .            sMs
2e90: 67 20 3d 20 73 41 63 74 69 6f 6e 5b 69 4d 73 67  g = sAction[iMsg
2ea0: 2b 33 3a 5d 2e 73 74 72 69 70 28 29 0a 20 20 20  +3:].strip().   
2eb0: 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e           sAction
2ec0: 20 3d 20 73 41 63 74 69 6f 6e 5b 3a 69 4d 73 67   = sAction[:iMsg
2ed0: 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20 20  ].strip().      
2ee0: 20 20 20 20 20 20 73 55 52 4c 20 3d 20 22 22 0a        sURL = "".
2ef0: 20 20 20 20 20 20 20 20 20 20 20 20 6d 55 52 4c              mURL
2f00: 20 3d 20 72 65 2e 73 65 61 72 63 68 28 22 5b 7c   = re.search("[|
2f10: 5d 20 2a 28 68 74 74 70 73 3f 3a 2f 2f 2e 2a 29  ] *(https?://.*)
2f20: 22 2c 20 73 4d 73 67 29 0a 20 20 20 20 20 20 20  ", sMsg).       
2f30: 20 20 20 20 20 69 66 20 6d 55 52 4c 3a 0a 20 20       if mURL:.  
2f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 55                sU
2f50: 52 4c 20 3d 20 6d 55 52 4c 2e 67 72 6f 75 70 28  RL = mURL.group(
2f60: 31 29 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20  1).strip().     
2f70: 20 20 20 20 20 20 20 20 20 20 20 73 4d 73 67 20             sMsg 
2f80: 3d 20 73 4d 73 67 5b 3a 6d 55 52 4c 2e 73 74 61  = sMsg[:mURL.sta
2f90: 72 74 28 30 29 5d 2e 73 74 72 69 70 28 29 0a 20  rt(0)].strip(). 
2fa0: 20 20 20 20 20 20 20 20 20 20 20 63 68 65 63 6b             check
2fb0: 52 65 66 65 72 65 6e 63 65 4e 75 6d 62 65 72 73  ReferenceNumbers
2fc0: 28 73 4d 73 67 2c 20 73 49 64 41 63 74 69 6f 6e  (sMsg, sIdAction
2fd0: 2c 20 6e 47 72 6f 75 70 29 0a 20 20 20 20 20 20  , nGroup).      
2fe0: 20 20 20 20 20 20 69 66 20 73 4d 73 67 5b 30 3a        if sMsg[0:
2ff0: 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20  1] == "=":.     
3000: 20 20 20 20 20 20 20 20 20 20 20 73 4d 73 67 20             sMsg 
3010: 3d 20 70 72 65 70 61 72 65 46 75 6e 63 74 69 6f  = prepareFunctio
3020: 6e 28 73 4d 73 67 5b 31 3a 5d 29 0a 20 20 20 20  n(sMsg[1:]).    
3030: 20 20 20 20 20 20 20 20 20 20 20 20 6c 46 55 4e              lFUN
3040: 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28 28 22  CTIONS.append(("
3050: 5f 6d 5f 22 2b 73 49 64 41 63 74 69 6f 6e 2c 20  _m_"+sIdAction, 
3060: 73 4d 73 67 29 29 0a 20 20 20 20 20 20 20 20 20  sMsg)).         
3070: 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 22 3d         sMsg = "=
3080: 5f 6d 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a 20  _m_"+sIdAction. 
3090: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
30a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
30b0: 20 63 68 65 63 6b 49 66 54 68 65 72 65 49 73 43   checkIfThereIsC
30c0: 6f 64 65 28 73 4d 73 67 2c 20 73 49 64 41 63 74  ode(sMsg, sIdAct
30d0: 69 6f 6e 29 0a 0a 20 20 20 20 63 68 65 63 6b 52  ion)..    checkR
30e0: 65 66 65 72 65 6e 63 65 4e 75 6d 62 65 72 73 28  eferenceNumbers(
30f0: 73 41 63 74 69 6f 6e 2c 20 73 49 64 41 63 74 69  sAction, sIdActi
3100: 6f 6e 2c 20 6e 47 72 6f 75 70 29 0a 20 20 20 20  on, nGroup).    
3110: 69 66 20 73 41 63 74 69 6f 6e 5b 30 3a 31 5d 20  if sAction[0:1] 
3120: 3d 3d 20 22 3d 22 20 6f 72 20 63 41 63 74 69 6f  == "=" or cActio
3130: 6e 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20  n == "=":.      
3140: 20 20 73 41 63 74 69 6f 6e 20 3d 20 70 72 65 70    sAction = prep
3150: 61 72 65 46 75 6e 63 74 69 6f 6e 28 73 41 63 74  areFunction(sAct
3160: 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 73 41 63  ion).        sAc
3170: 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 2e 72  tion = sAction.r
3180: 65 70 6c 61 63 65 28 22 6d 2e 67 72 6f 75 70 28  eplace("m.group(
3190: 69 5b 34 5d 29 22 2c 20 22 6d 2e 67 72 6f 75 70  i[4])", "m.group
31a0: 28 22 2b 73 74 72 28 69 47 72 6f 75 70 29 2b 22  ("+str(iGroup)+"
31b0: 29 22 29 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20  )").    else:.  
31c0: 20 20 20 20 20 20 63 68 65 63 6b 49 66 54 68 65        checkIfThe
31d0: 72 65 49 73 43 6f 64 65 28 73 41 63 74 69 6f 6e  reIsCode(sAction
31e0: 2c 20 73 49 64 41 63 74 69 6f 6e 29 0a 0a 20 20  , sIdAction)..  
31f0: 20 20 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d 20    if cAction == 
3200: 22 3e 22 3a 0a 20 20 20 20 20 20 20 20 23 23 20  ">":.        ## 
3210: 6e 6f 20 61 63 74 69 6f 6e 2c 20 62 72 65 61 6b  no action, break
3220: 20 6c 6f 6f 70 20 69 66 20 63 6f 6e 64 69 74 69   loop if conditi
3230: 6f 6e 20 69 73 20 46 61 6c 73 65 0a 20 20 20 20  on is False.    
3240: 20 20 20 20 72 65 74 75 72 6e 20 5b 73 43 6f 6e      return [sCon
3250: 64 69 74 69 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c  dition, cAction,
3260: 20 22 22 5d 0a 0a 20 20 20 20 69 66 20 6e 6f 74   ""]..    if not
3270: 20 73 41 63 74 69 6f 6e 3a 0a 20 20 20 20 20 20   sAction:.      
3280: 20 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72    print("# Error
3290: 20 69 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c 69   in action at li
32a0: 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e  ne " + sIdAction
32b0: 20 2b 20 22 3a 20 20 54 68 69 73 20 61 63 74 69   + ":  This acti
32c0: 6f 6e 20 69 73 20 65 6d 70 74 79 2e 22 29 0a 20  on is empty."). 
32d0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e 6f         return No
32e0: 6e 65 0a 0a 20 20 20 20 69 66 20 63 41 63 74 69  ne..    if cActi
32f0: 6f 6e 20 3d 3d 20 22 2d 22 3a 0a 20 20 20 20 20  on == "-":.     
3300: 20 20 20 23 23 20 65 72 72 6f 72 20 64 65 74 65     ## error dete
3310: 63 74 65 64 20 2d 2d 3e 20 73 75 67 67 65 73 74  cted --> suggest
3320: 69 6f 6e 0a 20 20 20 20 20 20 20 20 69 66 20 73  ion.        if s
3330: 41 63 74 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22  Action[0:1] == "
3340: 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  =":.            
3350: 6c 46 55 4e 43 54 49 4f 4e 53 2e 61 70 70 65 6e  lFUNCTIONS.appen
3360: 64 28 28 22 5f 73 5f 22 2b 73 49 64 41 63 74 69  d(("_s_"+sIdActi
3370: 6f 6e 2c 20 73 41 63 74 69 6f 6e 5b 31 3a 5d 29  on, sAction[1:])
3380: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 41  ).            sA
3390: 63 74 69 6f 6e 20 3d 20 22 3d 5f 73 5f 22 2b 73  ction = "=_s_"+s
33a0: 49 64 41 63 74 69 6f 6e 0a 20 20 20 20 20 20 20  IdAction.       
33b0: 20 65 6c 69 66 20 73 41 63 74 69 6f 6e 2e 73 74   elif sAction.st
33c0: 61 72 74 73 77 69 74 68 28 27 22 27 29 20 61 6e  artswith('"') an
33d0: 64 20 73 41 63 74 69 6f 6e 2e 65 6e 64 73 77 69  d sAction.endswi
33e0: 74 68 28 27 22 27 29 3a 0a 20 20 20 20 20 20 20  th('"'):.       
33f0: 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 73       sAction = s
3400: 41 63 74 69 6f 6e 5b 31 3a 2d 31 5d 0a 20 20 20  Action[1:-1].   
3410: 20 20 20 20 20 69 66 20 6e 6f 74 20 73 4d 73 67       if not sMsg
3420: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72  :.            pr
3430: 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20  int("# Error in 
3440: 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22  action at line "
3450: 20 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b 20 22   + sIdAction + "
3460: 3a 20 20 74 68 65 20 6d 65 73 73 61 67 65 20 69  :  the message i
3470: 73 20 65 6d 70 74 79 2e 22 29 0a 20 20 20 20 20  s empty.").     
3480: 20 20 20 72 65 74 75 72 6e 20 5b 73 43 6f 6e 64     return [sCond
3490: 69 74 69 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20  ition, cAction, 
34a0: 73 41 63 74 69 6f 6e 2c 20 69 47 72 6f 75 70 2c  sAction, iGroup,
34b0: 20 73 4d 73 67 2c 20 73 55 52 4c 5d 0a 20 20 20   sMsg, sURL].   
34c0: 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d   elif cAction ==
34d0: 20 22 7e 22 3a 0a 20 20 20 20 20 20 20 20 23 23   "~":.        ##
34e0: 20 74 65 78 74 20 70 72 6f 63 65 73 73 6f 72 0a   text processor.
34f0: 20 20 20 20 20 20 20 20 69 66 20 73 41 63 74 69          if sActi
3500: 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a  on[0:1] == "=":.
3510: 20 20 20 20 20 20 20 20 20 20 20 20 6c 46 55 4e              lFUN
3520: 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28 28 22  CTIONS.append(("
3530: 5f 70 5f 22 2b 73 49 64 41 63 74 69 6f 6e 2c 20  _p_"+sIdAction, 
3540: 73 41 63 74 69 6f 6e 5b 31 3a 5d 29 29 0a 20 20  sAction[1:])).  
3550: 20 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f            sActio
3560: 6e 20 3d 20 22 3d 5f 70 5f 22 2b 73 49 64 41 63  n = "=_p_"+sIdAc
3570: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 65 6c 69  tion.        eli
3580: 66 20 73 41 63 74 69 6f 6e 2e 73 74 61 72 74 73  f sAction.starts
3590: 77 69 74 68 28 27 22 27 29 20 61 6e 64 20 73 41  with('"') and sA
35a0: 63 74 69 6f 6e 2e 65 6e 64 73 77 69 74 68 28 27  ction.endswith('
35b0: 22 27 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "'):.           
35c0: 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69   sAction = sActi
35d0: 6f 6e 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20 20  on[1:-1].       
35e0: 20 72 65 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74   return [sCondit
35f0: 69 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41  ion, cAction, sA
3600: 63 74 69 6f 6e 2c 20 69 47 72 6f 75 70 5d 0a 20  ction, iGroup]. 
3610: 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 20     elif cAction 
3620: 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20  == "=":.        
3630: 23 23 20 64 69 73 61 6d 62 69 67 75 61 74 6f 72  ## disambiguator
3640: 0a 20 20 20 20 20 20 20 20 69 66 20 73 41 63 74  .        if sAct
3650: 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a  ion[0:1] == "=":
3660: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 41 63  .            sAc
3670: 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 31  tion = sAction[1
3680: 3a 5d 0a 20 20 20 20 20 20 20 20 69 66 20 22 64  :].        if "d
3690: 65 66 69 6e 65 22 20 69 6e 20 73 41 63 74 69 6f  efine" in sActio
36a0: 6e 20 61 6e 64 20 6e 6f 74 20 72 65 2e 73 65 61  n and not re.sea
36b0: 72 63 68 28 72 22 64 65 66 69 6e 65 5c 28 64 54  rch(r"define\(dT
36c0: 6f 6b 65 6e 50 6f 73 2c 20 2a 6d 5c 2e 73 74 61  okenPos, *m\.sta
36d0: 72 74 2e 2a 2c 20 5c 5b 2e 2a 5c 5d 20 2a 5c 29  rt.*, \[.*\] *\)
36e0: 22 2c 20 73 41 63 74 69 6f 6e 29 3a 0a 20 20 20  ", sAction):.   
36f0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
3700: 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69 6f  # Error in actio
3710: 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49  n at line " + sI
3720: 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 73 65 63  dAction + ": sec
3730: 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 66 6f 72  ond argument for
3740: 20 64 65 66 69 6e 65 20 6d 75 73 74 20 62 65 20   define must be 
3750: 61 20 6c 69 73 74 20 6f 66 20 73 74 72 69 6e 67  a list of string
3760: 73 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  s").            
3770: 70 72 69 6e 74 28 73 41 63 74 69 6f 6e 29 0a 20  print(sAction). 
3780: 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f 4e         lFUNCTION
3790: 53 2e 61 70 70 65 6e 64 28 28 22 5f 64 5f 22 2b  S.append(("_d_"+
37a0: 73 49 64 41 63 74 69 6f 6e 2c 20 73 41 63 74 69  sIdAction, sActi
37b0: 6f 6e 29 29 0a 20 20 20 20 20 20 20 20 73 41 63  on)).        sAc
37c0: 74 69 6f 6e 20 3d 20 22 5f 64 5f 22 2b 73 49 64  tion = "_d_"+sId
37d0: 41 63 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 72  Action.        r
37e0: 65 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69 6f  eturn [sConditio
37f0: 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41 63 74  n, cAction, sAct
3800: 69 6f 6e 5d 0a 20 20 20 20 65 6c 73 65 3a 0a 20  ion].    else:. 
3810: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20         print("# 
3820: 55 6e 6b 6e 6f 77 6e 20 61 63 74 69 6f 6e 20 61  Unknown action a
3830: 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64 41 63  t line " + sIdAc
3840: 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 72 65  tion).        re
3850: 74 75 72 6e 20 4e 6f 6e 65 0a 0a 0a 64 65 66 20  turn None...def 
3860: 5f 63 61 6c 63 52 75 6c 65 73 53 74 61 74 73 20  _calcRulesStats 
3870: 28 6c 52 75 6c 65 73 29 3a 0a 20 20 20 20 22 63  (lRules):.    "c
3880: 6f 75 6e 74 20 72 75 6c 65 73 20 61 6e 64 20 61  ount rules and a
3890: 63 74 69 6f 6e 73 22 0a 20 20 20 20 64 20 3d 20  ctions".    d = 
38a0: 7b 27 3d 27 3a 30 2c 20 27 7e 27 3a 20 30 2c 20  {'=':0, '~': 0, 
38b0: 27 2d 27 3a 20 30 2c 20 27 3e 27 3a 20 30 7d 0a  '-': 0, '>': 0}.
38c0: 20 20 20 20 66 6f 72 20 61 52 75 6c 65 20 69 6e      for aRule in
38d0: 20 6c 52 75 6c 65 73 3a 0a 20 20 20 20 20 20 20   lRules:.       
38e0: 20 69 66 20 61 52 75 6c 65 5b 30 5d 20 21 3d 20   if aRule[0] != 
38f0: 22 40 40 40 40 22 3a 0a 20 20 20 20 20 20 20 20  "@@@@":.        
3900: 20 20 20 20 66 6f 72 20 61 41 63 74 69 6f 6e 20      for aAction 
3910: 69 6e 20 61 52 75 6c 65 5b 36 5d 3a 0a 20 20 20  in aRule[6]:.   
3920: 20 20 20 20 20 20 20 20 20 20 20 20 20 64 5b 61               d[a
3930: 41 63 74 69 6f 6e 5b 31 5d 5d 20 3d 20 64 5b 61  Action[1]] = d[a
3940: 41 63 74 69 6f 6e 5b 31 5d 5d 20 2b 20 31 0a 20  Action[1]] + 1. 
3950: 20 20 20 72 65 74 75 72 6e 20 28 64 2c 20 6c 65     return (d, le
3960: 6e 28 6c 52 75 6c 65 73 29 29 0a 0a 0a 64 65 66  n(lRules))...def
3970: 20 64 69 73 70 6c 61 79 53 74 61 74 73 20 28 6c   displayStats (l
3980: 50 61 72 61 67 72 61 70 68 52 75 6c 65 73 2c 20  ParagraphRules, 
3990: 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 29 3a  lSentenceRules):
39a0: 0a 20 20 20 20 22 64 69 73 70 6c 61 79 20 72 75  .    "display ru
39b0: 6c 65 73 20 6e 75 6d 62 65 72 73 22 0a 20 20 20  les numbers".   
39c0: 20 70 72 69 6e 74 28 22 20 20 7b 3a 3e 31 38 7d   print("  {:>18}
39d0: 20 7b 3a 3e 31 38 7d 20 7b 3a 3e 31 38 7d 20 7b   {:>18} {:>18} {
39e0: 3a 3e 31 38 7d 22 2e 66 6f 72 6d 61 74 28 22 44  :>18}".format("D
39f0: 49 53 41 4d 42 49 47 55 41 54 4f 52 22 2c 20 22  ISAMBIGUATOR", "
3a00: 54 45 58 54 20 50 52 4f 43 45 53 53 4f 52 22 2c  TEXT PROCESSOR",
3a10: 20 22 47 52 41 4d 4d 41 52 20 43 48 45 43 4b 49   "GRAMMAR CHECKI
3a20: 4e 47 22 2c 20 22 52 45 47 45 58 22 29 29 0a 20  NG", "REGEX")). 
3a30: 20 20 20 64 2c 20 6e 52 75 6c 65 20 3d 20 5f 63     d, nRule = _c
3a40: 61 6c 63 52 75 6c 65 73 53 74 61 74 73 28 6c 50  alcRulesStats(lP
3a50: 61 72 61 67 72 61 70 68 52 75 6c 65 73 29 0a 20  aragraphRules). 
3a60: 20 20 20 70 72 69 6e 74 28 22 c2 a7 20 7b 3a 3e     print(".. {:>
3a70: 31 30 7d 20 61 63 74 69 6f 6e 73 20 7b 3a 3e 31  10} actions {:>1
3a80: 30 7d 20 61 63 74 69 6f 6e 73 20 7b 3a 3e 31 30  0} actions {:>10
3a90: 7d 20 61 63 74 69 6f 6e 73 20 20 69 6e 20 7b 3a  } actions  in {:
3aa0: 3e 38 7d 20 72 75 6c 65 73 22 2e 66 6f 72 6d 61  >8} rules".forma
3ab0: 74 28 64 5b 27 3d 27 5d 2c 20 64 5b 27 7e 27 5d  t(d['='], d['~']
3ac0: 2c 20 64 5b 27 2d 27 5d 2c 20 6e 52 75 6c 65 29  , d['-'], nRule)
3ad0: 29 0a 20 20 20 20 64 2c 20 6e 52 75 6c 65 20 3d  ).    d, nRule =
3ae0: 20 5f 63 61 6c 63 52 75 6c 65 73 53 74 61 74 73   _calcRulesStats
3af0: 28 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 29  (lSentenceRules)
3b00: 0a 20 20 20 20 70 72 69 6e 74 28 22 73 20 7b 3a  .    print("s {:
3b10: 3e 31 30 7d 20 61 63 74 69 6f 6e 73 20 7b 3a 3e  >10} actions {:>
3b20: 31 30 7d 20 61 63 74 69 6f 6e 73 20 7b 3a 3e 31  10} actions {:>1
3b30: 30 7d 20 61 63 74 69 6f 6e 73 20 20 69 6e 20 7b  0} actions  in {
3b40: 3a 3e 38 7d 20 72 75 6c 65 73 22 2e 66 6f 72 6d  :>8} rules".form
3b50: 61 74 28 64 5b 27 3d 27 5d 2c 20 64 5b 27 7e 27  at(d['='], d['~'
3b60: 5d 2c 20 64 5b 27 2d 27 5d 2c 20 6e 52 75 6c 65  ], d['-'], nRule
3b70: 29 29 0a 0a 0a 64 65 66 20 6d 65 72 67 65 52 75  ))...def mergeRu
3b80: 6c 65 73 42 79 4f 70 74 69 6f 6e 20 28 6c 52 75  lesByOption (lRu
3b90: 6c 65 73 29 3a 0a 20 20 20 20 22 72 65 74 75 72  les):.    "retur
3ba0: 6e 73 20 61 20 6c 69 73 74 20 6f 66 20 74 75 70  ns a list of tup
3bb0: 6c 65 73 20 5b 6f 70 74 69 6f 6e 2c 20 6c 69 73  les [option, lis
3bc0: 74 20 6f 66 20 72 75 6c 65 73 5d 20 6b 65 65 70  t of rules] keep
3bd0: 69 6e 67 20 74 68 65 20 72 75 6c 65 73 20 6f 72  ing the rules or
3be0: 64 65 72 22 0a 20 20 20 20 6c 46 69 6e 61 6c 20  der".    lFinal 
3bf0: 3d 20 5b 5d 0a 20 20 20 20 6c 54 65 6d 70 20 3d  = [].    lTemp =
3c00: 20 5b 5d 0a 20 20 20 20 73 4f 70 74 69 6f 6e 20   [].    sOption 
3c10: 3d 20 4e 6f 6e 65 0a 20 20 20 20 66 6f 72 20 61  = None.    for a
3c20: 52 75 6c 65 20 69 6e 20 6c 52 75 6c 65 73 3a 0a  Rule in lRules:.
3c30: 20 20 20 20 20 20 20 20 69 66 20 61 52 75 6c 65          if aRule
3c40: 5b 30 5d 20 21 3d 20 73 4f 70 74 69 6f 6e 3a 0a  [0] != sOption:.
3c50: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73              if s
3c60: 4f 70 74 69 6f 6e 20 21 3d 20 4e 6f 6e 65 3a 0a  Option != None:.
3c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3c80: 6c 46 69 6e 61 6c 2e 61 70 70 65 6e 64 28 5b 73  lFinal.append([s
3c90: 4f 70 74 69 6f 6e 2c 20 6c 54 65 6d 70 5d 29 0a  Option, lTemp]).
3ca0: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 6e 65              # ne
3cb0: 77 20 74 75 70 6c 65 0a 20 20 20 20 20 20 20 20  w tuple.        
3cc0: 20 20 20 20 73 4f 70 74 69 6f 6e 20 3d 20 61 52      sOption = aR
3cd0: 75 6c 65 5b 30 5d 0a 20 20 20 20 20 20 20 20 20  ule[0].         
3ce0: 20 20 20 6c 54 65 6d 70 20 3d 20 5b 5d 0a 20 20     lTemp = [].  
3cf0: 20 20 20 20 20 20 6c 54 65 6d 70 2e 61 70 70 65        lTemp.appe
3d00: 6e 64 28 61 52 75 6c 65 5b 31 3a 5d 29 0a 20 20  nd(aRule[1:]).  
3d10: 20 20 6c 46 69 6e 61 6c 2e 61 70 70 65 6e 64 28    lFinal.append(
3d20: 5b 73 4f 70 74 69 6f 6e 2c 20 6c 54 65 6d 70 5d  [sOption, lTemp]
3d30: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 6c 46 69  ).    return lFi
3d40: 6e 61 6c 0a 0a 0a 64 65 66 20 70 72 65 70 61 72  nal...def prepar
3d50: 65 4f 70 74 69 6f 6e 73 20 28 6c 4f 70 74 69 6f  eOptions (lOptio
3d60: 6e 4c 69 6e 65 73 29 3a 0a 20 20 20 20 22 72 65  nLines):.    "re
3d70: 74 75 72 6e 73 20 61 20 64 69 63 74 69 6f 6e 61  turns a dictiona
3d80: 72 79 20 77 69 74 68 20 64 61 74 61 20 61 62 6f  ry with data abo
3d90: 75 74 20 6f 70 74 69 6f 6e 73 22 0a 20 20 20 20  ut options".    
3da0: 73 4c 61 6e 67 20 3d 20 22 22 0a 20 20 20 20 73  sLang = "".    s
3db0: 44 65 66 61 75 6c 74 55 49 4c 61 6e 67 20 3d 20  DefaultUILang = 
3dc0: 22 22 0a 20 20 20 20 6c 53 74 72 75 63 74 4f 70  "".    lStructOp
3dd0: 74 20 3d 20 5b 5d 0a 20 20 20 20 6c 4f 70 74 20  t = [].    lOpt 
3de0: 3d 20 5b 5d 0a 20 20 20 20 64 4f 70 74 4c 61 62  = [].    dOptLab
3df0: 65 6c 20 3d 20 7b 7d 0a 20 20 20 20 64 4f 70 74  el = {}.    dOpt
3e00: 50 72 69 6f 72 69 74 79 20 3d 20 7b 7d 0a 20 20  Priority = {}.  
3e10: 20 20 66 6f 72 20 73 4c 69 6e 65 20 69 6e 20 6c    for sLine in l
3e20: 4f 70 74 69 6f 6e 4c 69 6e 65 73 3a 0a 20 20 20  OptionLines:.   
3e30: 20 20 20 20 20 73 4c 69 6e 65 20 3d 20 73 4c 69       sLine = sLi
3e40: 6e 65 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20  ne.strip().     
3e50: 20 20 20 69 66 20 73 4c 69 6e 65 2e 73 74 61 72     if sLine.star
3e60: 74 73 77 69 74 68 28 22 4f 50 54 47 52 4f 55 50  tswith("OPTGROUP
3e70: 2f 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  /"):.           
3e80: 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f   m = re.match("O
3e90: 50 54 47 52 4f 55 50 2f 28 5b 61 2d 7a 30 2d 39  PTGROUP/([a-z0-9
3ea0: 5d 2b 29 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e  ]+):(.+)$", sLin
3eb0: 65 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c  e).            l
3ec0: 53 74 72 75 63 74 4f 70 74 2e 61 70 70 65 6e 64  StructOpt.append
3ed0: 28 20 28 6d 2e 67 72 6f 75 70 28 31 29 2c 20 6c  ( (m.group(1), l
3ee0: 69 73 74 28 6d 61 70 28 73 74 72 2e 73 70 6c 69  ist(map(str.spli
3ef0: 74 2c 20 6d 2e 67 72 6f 75 70 28 32 29 2e 73 70  t, m.group(2).sp
3f00: 6c 69 74 28 22 2c 22 29 29 29 29 20 29 0a 20 20  lit(",")))) ).  
3f10: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
3f20: 2e 73 74 61 72 74 73 77 69 74 68 28 22 4f 50 54  .startswith("OPT
3f30: 53 4f 46 54 57 41 52 45 3a 22 29 3a 0a 20 20 20  SOFTWARE:"):.   
3f40: 20 20 20 20 20 20 20 20 20 6c 4f 70 74 20 3d 20           lOpt = 
3f50: 5b 20 5b 73 2c 20 7b 7d 5d 20 20 66 6f 72 20 73  [ [s, {}]  for s
3f60: 20 69 6e 20 73 4c 69 6e 65 5b 31 32 3a 5d 2e 73   in sLine[12:].s
3f70: 74 72 69 70 28 29 2e 73 70 6c 69 74 28 29 20 5d  trip().split() ]
3f80: 20 20 23 20 64 6f 6e e2 80 99 74 20 75 73 65 20    # don...t use 
3f90: 74 75 70 6c 65 73 20 28 73 2c 20 7b 7d 29 2c 20  tuples (s, {}), 
3fa0: 62 65 63 61 75 73 65 20 75 6e 6b 6e 6f 77 6e 20  because unknown 
3fb0: 74 6f 20 4a 53 0a 20 20 20 20 20 20 20 20 65 6c  to JS.        el
3fc0: 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77  if sLine.startsw
3fd0: 69 74 68 28 22 4f 50 54 2f 22 29 3a 0a 20 20 20  ith("OPT/"):.   
3fe0: 20 20 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e           m = re.
3ff0: 6d 61 74 63 68 28 22 4f 50 54 2f 28 5b 61 2d 7a  match("OPT/([a-z
4000: 30 2d 39 5d 2b 29 3a 28 2e 2b 29 24 22 2c 20 73  0-9]+):(.+)$", s
4010: 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20  Line).          
4020: 20 20 66 6f 72 20 69 2c 20 73 4f 70 74 20 69 6e    for i, sOpt in
4030: 20 65 6e 75 6d 65 72 61 74 65 28 6d 2e 67 72 6f   enumerate(m.gro
4040: 75 70 28 32 29 2e 73 70 6c 69 74 28 29 29 3a 0a  up(2).split()):.
4050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4060: 6c 4f 70 74 5b 69 5d 5b 31 5d 5b 6d 2e 67 72 6f  lOpt[i][1][m.gro
4070: 75 70 28 31 29 5d 20 3d 20 65 76 61 6c 28 73 4f  up(1)] = eval(sO
4080: 70 74 29 0a 20 20 20 20 20 20 20 20 65 6c 69 66  pt).        elif
4090: 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74   sLine.startswit
40a0: 68 28 22 4f 50 54 50 52 49 4f 52 49 54 59 2f 22  h("OPTPRIORITY/"
40b0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d  ):.            m
40c0: 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54   = re.match("OPT
40d0: 50 52 49 4f 52 49 54 59 2f 28 5b 61 2d 7a 30 2d  PRIORITY/([a-z0-
40e0: 39 5d 2b 29 3a 20 2a 28 5b 30 2d 39 5d 29 24 22  9]+): *([0-9])$"
40f0: 2c 20 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20  , sLine).       
4100: 20 20 20 20 20 64 4f 70 74 50 72 69 6f 72 69 74       dOptPriorit
4110: 79 5b 6d 2e 67 72 6f 75 70 28 31 29 5d 20 3d 20  y[m.group(1)] = 
4120: 69 6e 74 28 6d 2e 67 72 6f 75 70 28 32 29 29 0a  int(m.group(2)).
4130: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69          elif sLi
4140: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 4f  ne.startswith("O
4150: 50 54 4c 41 4e 47 2f 22 29 3a 0a 20 20 20 20 20  PTLANG/"):.     
4160: 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61         m = re.ma
4170: 74 63 68 28 22 4f 50 54 4c 41 4e 47 2f 28 5b 61  tch("OPTLANG/([a
4180: 2d 7a 5d 5b 61 2d 7a 5d 28 3f 3a 5f 5b 41 2d 5a  -z][a-z](?:_[A-Z
4190: 5d 5b 41 2d 5a 5d 7c 29 29 3a 28 2e 2b 29 24 22  ][A-Z]|)):(.+)$"
41a0: 2c 20 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20  , sLine).       
41b0: 20 20 20 20 20 73 4c 61 6e 67 20 3d 20 6d 2e 67       sLang = m.g
41c0: 72 6f 75 70 28 31 29 5b 3a 32 5d 0a 20 20 20 20  roup(1)[:2].    
41d0: 20 20 20 20 20 20 20 20 64 4f 70 74 4c 61 62 65          dOptLabe
41e0: 6c 5b 73 4c 61 6e 67 5d 20 3d 20 7b 20 22 5f 5f  l[sLang] = { "__
41f0: 6f 70 74 69 6f 6e 74 69 74 6c 65 5f 5f 22 3a 20  optiontitle__": 
4200: 6d 2e 67 72 6f 75 70 28 32 29 2e 73 74 72 69 70  m.group(2).strip
4210: 28 29 20 7d 0a 20 20 20 20 20 20 20 20 65 6c 69  () }.        eli
4220: 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69  f sLine.startswi
4230: 74 68 28 22 4f 50 54 44 45 46 41 55 4c 54 55 49  th("OPTDEFAULTUI
4240: 4c 41 4e 47 3a 22 29 3a 0a 20 20 20 20 20 20 20  LANG:"):.       
4250: 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63       m = re.matc
4260: 68 28 22 4f 50 54 44 45 46 41 55 4c 54 55 49 4c  h("OPTDEFAULTUIL
4270: 41 4e 47 3a 20 2a 28 5b 61 2d 7a 5d 5b 61 2d 7a  ANG: *([a-z][a-z
4280: 5d 28 3f 3a 5f 5b 41 2d 5a 5d 5b 41 2d 5a 5d 7c  ](?:_[A-Z][A-Z]|
4290: 29 29 24 22 2c 20 73 4c 69 6e 65 29 0a 20 20 20  ))$", sLine).   
42a0: 20 20 20 20 20 20 20 20 20 73 44 65 66 61 75 6c           sDefaul
42b0: 74 55 49 4c 61 6e 67 20 3d 20 6d 2e 67 72 6f 75  tUILang = m.grou
42c0: 70 28 31 29 5b 3a 32 5d 0a 20 20 20 20 20 20 20  p(1)[:2].       
42d0: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
42e0: 74 73 77 69 74 68 28 22 4f 50 54 4c 41 42 45 4c  tswith("OPTLABEL
42f0: 2f 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  /"):.           
4300: 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f   m = re.match("O
4310: 50 54 4c 41 42 45 4c 2f 28 5b 61 2d 7a 30 2d 39  PTLABEL/([a-z0-9
4320: 5d 2b 29 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e  ]+):(.+)$", sLin
4330: 65 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 64  e).            d
4340: 4f 70 74 4c 61 62 65 6c 5b 73 4c 61 6e 67 5d 5b  OptLabel[sLang][
4350: 6d 2e 67 72 6f 75 70 28 31 29 5d 20 3d 20 6c 69  m.group(1)] = li
4360: 73 74 28 6d 61 70 28 73 74 72 2e 73 74 72 69 70  st(map(str.strip
4370: 2c 20 6d 2e 67 72 6f 75 70 28 32 29 2e 73 70 6c  , m.group(2).spl
4380: 69 74 28 22 7c 22 29 29 29 20 20 69 66 20 22 7c  it("|")))  if "|
4390: 22 20 69 6e 20 6d 2e 67 72 6f 75 70 28 32 29 20  " in m.group(2) 
43a0: 20 65 6c 73 65 20 20 5b 6d 2e 67 72 6f 75 70 28   else  [m.group(
43b0: 32 29 2e 73 74 72 69 70 28 29 2c 20 22 22 5d 0a  2).strip(), ""].
43c0: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
43d0: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
43e0: 22 23 20 45 72 72 6f 72 2e 20 57 72 6f 6e 67 20  "# Error. Wrong 
43f0: 6f 70 74 69 6f 6e 20 6c 69 6e 65 20 69 6e 3a 5c  option line in:\
4400: 6e 20 20 22 29 0a 20 20 20 20 20 20 20 20 20 20  n  ").          
4410: 20 20 70 72 69 6e 74 28 73 4c 69 6e 65 29 0a 20    print(sLine). 
4420: 20 20 20 70 72 69 6e 74 28 22 20 20 6f 70 74 69     print("  opti
4430: 6f 6e 73 20 64 65 66 69 6e 65 64 20 66 6f 72 3a  ons defined for:
4440: 20 22 20 2b 20 22 2c 20 22 2e 6a 6f 69 6e 28 5b   " + ", ".join([
4450: 20 74 5b 30 5d 20 66 6f 72 20 74 20 69 6e 20 6c   t[0] for t in l
4460: 4f 70 74 20 5d 29 29 0a 20 20 20 20 64 4f 70 74  Opt ])).    dOpt
4470: 69 6f 6e 73 20 3d 20 7b 20 22 6c 53 74 72 75 63  ions = { "lStruc
4480: 74 4f 70 74 22 3a 20 6c 53 74 72 75 63 74 4f 70  tOpt": lStructOp
4490: 74 2c 20 22 64 4f 70 74 4c 61 62 65 6c 22 3a 20  t, "dOptLabel": 
44a0: 64 4f 70 74 4c 61 62 65 6c 2c 20 22 73 44 65 66  dOptLabel, "sDef
44b0: 61 75 6c 74 55 49 4c 61 6e 67 22 3a 20 73 44 65  aultUILang": sDe
44c0: 66 61 75 6c 74 55 49 4c 61 6e 67 20 7d 0a 20 20  faultUILang }.  
44d0: 20 20 64 4f 70 74 69 6f 6e 73 2e 75 70 64 61 74    dOptions.updat
44e0: 65 28 7b 20 22 64 4f 70 74 22 2b 6b 3a 20 76 20  e({ "dOpt"+k: v 
44f0: 20 66 6f 72 20 6b 2c 20 76 20 69 6e 20 6c 4f 70   for k, v in lOp
4500: 74 20 7d 29 0a 20 20 20 20 72 65 74 75 72 6e 20  t }).    return 
4510: 64 4f 70 74 69 6f 6e 73 2c 20 64 4f 70 74 50 72  dOptions, dOptPr
4520: 69 6f 72 69 74 79 0a 0a 0a 64 65 66 20 70 72 69  iority...def pri
4530: 6e 74 42 6f 6f 6b 6d 61 72 6b 20 28 6e 4c 65 76  ntBookmark (nLev
4540: 65 6c 2c 20 73 43 6f 6d 6d 65 6e 74 2c 20 6e 4c  el, sComment, nL
4550: 69 6e 65 29 3a 0a 20 20 20 20 22 70 72 69 6e 74  ine):.    "print
4560: 20 62 6f 6f 6b 6d 61 72 6b 20 77 69 74 68 69 6e   bookmark within
4570: 20 74 68 65 20 72 75 6c 65 73 20 66 69 6c 65 22   the rules file"
4580: 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 7b 3a  .    print("  {:
4590: 3e 36 7d 3a 20 20 7b 7d 22 2e 66 6f 72 6d 61 74  >6}:  {}".format
45a0: 28 6e 4c 69 6e 65 2c 20 22 20 20 22 20 2a 20 6e  (nLine, "  " * n
45b0: 4c 65 76 65 6c 20 2b 20 73 43 6f 6d 6d 65 6e 74  Level + sComment
45c0: 29 29 0a 0a 0a 64 65 66 20 6d 61 6b 65 20 28 73  ))...def make (s
45d0: 70 4c 61 6e 67 2c 20 73 4c 61 6e 67 2c 20 62 4a  pLang, sLang, bJ
45e0: 61 76 61 53 63 72 69 70 74 29 3a 0a 20 20 20 20  avaScript):.    
45f0: 22 63 6f 6d 70 69 6c 65 20 72 75 6c 65 73 2c 20  "compile rules, 
4600: 72 65 74 75 72 6e 73 20 61 20 64 69 63 74 69 6f  returns a dictio
4610: 6e 61 72 79 20 6f 66 20 76 61 6c 75 65 73 22 0a  nary of values".
4620: 20 20 20 20 23 20 66 6f 72 20 63 6c 61 72 69 74      # for clarit
4630: 79 20 70 75 72 70 6f 73 65 2c 20 64 6f 6e e2 80  y purpose, don..
4640: 99 74 20 63 72 65 61 74 65 20 61 6e 79 20 66 69  .t create any fi
4650: 6c 65 20 68 65 72 65 0a 0a 20 20 20 20 70 72 69  le here..    pri
4660: 6e 74 28 22 3e 20 72 65 61 64 20 72 75 6c 65 73  nt("> read rules
4670: 20 66 69 6c 65 2e 2e 2e 22 29 0a 20 20 20 20 74   file...").    t
4680: 72 79 3a 0a 20 20 20 20 20 20 20 20 6c 52 75 6c  ry:.        lRul
4690: 65 73 20 3d 20 6f 70 65 6e 28 73 70 4c 61 6e 67  es = open(spLang
46a0: 20 2b 20 22 2f 72 75 6c 65 73 2e 67 72 78 22 2c   + "/rules.grx",
46b0: 20 27 72 27 2c 20 65 6e 63 6f 64 69 6e 67 3d 22   'r', encoding="
46c0: 75 74 66 2d 38 22 29 2e 72 65 61 64 6c 69 6e 65  utf-8").readline
46d0: 73 28 29 0a 20 20 20 20 65 78 63 65 70 74 3a 0a  s().    except:.
46e0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 45          print("E
46f0: 72 72 6f 72 2e 20 52 75 6c 65 73 20 66 69 6c 65  rror. Rules file
4700: 20 69 6e 20 70 72 6f 6a 65 63 74 20 5b 22 20 2b   in project [" +
4710: 20 73 4c 61 6e 67 20 2b 20 22 5d 20 6e 6f 74 20   sLang + "] not 
4720: 66 6f 75 6e 64 2e 22 29 0a 20 20 20 20 20 20 20  found.").       
4730: 20 65 78 69 74 28 29 0a 0a 20 20 20 20 23 20 72   exit()..    # r
4740: 65 6d 6f 76 69 6e 67 20 63 6f 6d 6d 65 6e 74 73  emoving comments
4750: 2c 20 7a 65 72 6f 69 6e 67 20 65 6d 70 74 79 20  , zeroing empty 
4760: 6c 69 6e 65 73 2c 20 63 72 65 61 74 69 6e 67 20  lines, creating 
4770: 64 65 66 69 6e 69 74 69 6f 6e 73 2c 20 73 74 6f  definitions, sto
4780: 72 69 6e 67 20 74 65 73 74 73 2c 20 6d 65 72 67  ring tests, merg
4790: 69 6e 67 20 72 75 6c 65 20 6c 69 6e 65 73 0a 20  ing rule lines. 
47a0: 20 20 20 70 72 69 6e 74 28 22 20 20 70 61 72 73     print("  pars
47b0: 69 6e 67 20 72 75 6c 65 73 2e 2e 2e 22 29 0a 20  ing rules..."). 
47c0: 20 20 20 6c 52 75 6c 65 4c 69 6e 65 20 3d 20 5b     lRuleLine = [
47d0: 5d 0a 20 20 20 20 6c 54 65 73 74 20 3d 20 5b 5d  ].    lTest = []
47e0: 0a 20 20 20 20 6c 4f 70 74 20 3d 20 5b 5d 0a 20  .    lOpt = []. 
47f0: 20 20 20 62 47 72 61 70 68 20 3d 20 46 61 6c 73     bGraph = Fals
4800: 65 0a 20 20 20 20 6c 47 72 61 70 68 52 75 6c 65  e.    lGraphRule
4810: 20 3d 20 5b 5d 0a 0a 20 20 20 20 66 6f 72 20 69   = []..    for i
4820: 2c 20 73 4c 69 6e 65 20 69 6e 20 65 6e 75 6d 65  , sLine in enume
4830: 72 61 74 65 28 6c 52 75 6c 65 73 2c 20 31 29 3a  rate(lRules, 1):
4840: 0a 20 20 20 20 20 20 20 20 69 66 20 73 4c 69 6e  .        if sLin
4850: 65 2e 73 74 61 72 74 73 77 69 74 68 28 27 23 45  e.startswith('#E
4860: 4e 44 27 29 3a 0a 20 20 20 20 20 20 20 20 20 20  ND'):.          
4870: 20 20 23 20 61 72 62 69 74 72 61 72 79 20 65 6e    # arbitrary en
4880: 64 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72  d.            pr
4890: 69 6e 74 42 6f 6f 6b 6d 61 72 6b 28 30 2c 20 22  intBookmark(0, "
48a0: 42 52 45 41 4b 20 42 59 20 23 45 4e 44 22 2c 20  BREAK BY #END", 
48b0: 69 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 62  i).            b
48c0: 72 65 61 6b 0a 20 20 20 20 20 20 20 20 65 6c 69  reak.        eli
48d0: 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69  f sLine.startswi
48e0: 74 68 28 22 23 22 29 3a 0a 20 20 20 20 20 20 20  th("#"):.       
48f0: 20 20 20 20 20 23 20 63 6f 6d 6d 65 6e 74 0a 20       # comment. 
4900: 20 20 20 20 20 20 20 20 20 20 20 70 61 73 73 0a             pass.
4910: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69          elif sLi
4920: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 44  ne.startswith("D
4930: 45 46 3a 22 29 3a 0a 20 20 20 20 20 20 20 20 20  EF:"):.         
4940: 20 20 20 23 20 64 65 66 69 6e 69 74 69 6f 6e 0a     # definition.
4950: 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20              m = 
4960: 72 65 2e 6d 61 74 63 68 28 22 44 45 46 3a 20 2b  re.match("DEF: +
4970: 28 5b 61 2d 7a 41 2d 5a 5f 5d 5b 61 2d 7a 41 2d  ([a-zA-Z_][a-zA-
4980: 5a 5f 30 2d 39 5d 2a 29 20 2b 28 2e 2b 29 24 22  Z_0-9]*) +(.+)$"
4990: 2c 20 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 29  , sLine.strip())
49a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
49b0: 6d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  m:.             
49c0: 20 20 20 64 44 45 46 5b 22 7b 22 2b 6d 2e 67 72     dDEF["{"+m.gr
49d0: 6f 75 70 28 31 29 2b 22 7d 22 5d 20 3d 20 6d 2e  oup(1)+"}"] = m.
49e0: 67 72 6f 75 70 28 32 29 0a 20 20 20 20 20 20 20  group(2).       
49f0: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
4a00: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
4a10: 28 22 45 72 72 6f 72 20 69 6e 20 64 65 66 69 6e  ("Error in defin
4a20: 69 74 69 6f 6e 3a 20 22 2c 20 65 6e 64 3d 22 22  ition: ", end=""
4a30: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
4a40: 20 20 70 72 69 6e 74 28 73 4c 69 6e 65 2e 73 74    print(sLine.st
4a50: 72 69 70 28 29 29 0a 20 20 20 20 20 20 20 20 65  rip()).        e
4a60: 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73  lif sLine.starts
4a70: 77 69 74 68 28 22 54 45 53 54 3a 22 29 3a 0a 20  with("TEST:"):. 
4a80: 20 20 20 20 20 20 20 20 20 20 20 23 20 74 65 73             # tes
4a90: 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 54  t.            lT
4aa0: 65 73 74 2e 61 70 70 65 6e 64 28 22 7b 3a 3c 38  est.append("{:<8
4ab0: 7d 22 2e 66 6f 72 6d 61 74 28 69 29 20 2b 20 22  }".format(i) + "
4ac0: 20 20 22 20 2b 20 73 4c 69 6e 65 5b 35 3a 5d 2e    " + sLine[5:].
4ad0: 73 74 72 69 70 28 29 29 0a 20 20 20 20 20 20 20  strip()).       
4ae0: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
4af0: 74 73 77 69 74 68 28 22 54 4f 44 4f 3a 22 29 3a  tswith("TODO:"):
4b00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 74  .            # t
4b10: 6f 64 6f 0a 20 20 20 20 20 20 20 20 20 20 20 20  odo.            
4b20: 70 61 73 73 0a 20 20 20 20 20 20 20 20 65 6c 69  pass.        eli
4b30: 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69  f sLine.startswi
4b40: 74 68 28 28 22 4f 50 54 47 52 4f 55 50 2f 22 2c  th(("OPTGROUP/",
4b50: 20 22 4f 50 54 53 4f 46 54 57 41 52 45 3a 22 2c   "OPTSOFTWARE:",
4b60: 20 22 4f 50 54 2f 22 2c 20 22 4f 50 54 4c 41 4e   "OPT/", "OPTLAN
4b70: 47 2f 22 2c 20 22 4f 50 54 44 45 46 41 55 4c 54  G/", "OPTDEFAULT
4b80: 55 49 4c 41 4e 47 3a 22 2c 20 22 4f 50 54 4c 41  UILANG:", "OPTLA
4b90: 42 45 4c 2f 22 2c 20 22 4f 50 54 50 52 49 4f 52  BEL/", "OPTPRIOR
4ba0: 49 54 59 2f 22 29 29 3a 0a 20 20 20 20 20 20 20  ITY/")):.       
4bb0: 20 20 20 20 20 23 20 6f 70 74 69 6f 6e 73 0a 20       # options. 
4bc0: 20 20 20 20 20 20 20 20 20 20 20 6c 4f 70 74 2e             lOpt.
4bd0: 61 70 70 65 6e 64 28 73 4c 69 6e 65 29 0a 20 20  append(sLine).  
4be0: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
4bf0: 2e 73 74 61 72 74 73 77 69 74 68 28 22 21 21 22  .startswith("!!"
4c00: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  ):.            #
4c10: 20 62 6f 6f 6b 6d 61 72 6b 0a 20 20 20 20 20 20   bookmark.      
4c20: 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74        m = re.mat
4c30: 63 68 28 22 21 21 2b 22 2c 20 73 4c 69 6e 65 29  ch("!!+", sLine)
4c40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 45 78  .            nEx
4c50: 4d 6b 20 3d 20 6c 65 6e 28 6d 2e 67 72 6f 75 70  Mk = len(m.group
4c60: 28 30 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  (0)).           
4c70: 20 69 66 20 73 4c 69 6e 65 5b 6e 45 78 4d 6b 3a   if sLine[nExMk:
4c80: 5d 2e 73 74 72 69 70 28 29 3a 0a 20 20 20 20 20  ].strip():.     
4c90: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
4ca0: 42 6f 6f 6b 6d 61 72 6b 28 6e 45 78 4d 6b 2d 32  Bookmark(nExMk-2
4cb0: 2c 20 73 4c 69 6e 65 5b 6e 45 78 4d 6b 3a 2d 33  , sLine[nExMk:-3
4cc0: 5d 2e 73 74 72 69 70 28 29 2c 20 69 29 0a 20 20  ].strip(), i).  
4cd0: 20 20 20 20 20 20 23 20 47 72 61 70 68 20 72 75        # Graph ru
4ce0: 6c 65 73 0a 20 20 20 20 20 20 20 20 65 6c 69 66  les.        elif
4cf0: 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74   sLine.startswit
4d00: 68 28 22 40 40 40 40 47 52 41 50 48 3a 22 29 3a  h("@@@@GRAPH:"):
4d10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 72  .            # r
4d20: 75 6c 65 73 20 67 72 61 70 68 20 63 61 6c 6c 0a  ules graph call.
4d30: 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20              m = 
4d40: 72 65 2e 6d 61 74 63 68 28 72 22 40 40 40 40 47  re.match(r"@@@@G
4d50: 52 41 50 48 3a 20 2a 28 5c 77 2b 29 22 2c 20 73  RAPH: *(\w+)", s
4d60: 4c 69 6e 65 2e 73 74 72 69 70 28 29 29 0a 20 20  Line.strip()).  
4d70: 20 20 20 20 20 20 20 20 20 20 69 66 20 6d 3a 0a            if m:.
4d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d90: 70 72 69 6e 74 42 6f 6f 6b 6d 61 72 6b 28 31 2c  printBookmark(1,
4da0: 20 22 5f 5f 5f 5f 20 47 52 41 50 48 3a 20 22 20   "____ GRAPH: " 
4db0: 2b 20 6d 2e 67 72 6f 75 70 28 31 29 20 2b 20 22  + m.group(1) + "
4dc0: 20 5f 5f 5f 5f 22 2c 20 69 29 0a 20 20 20 20 20   ____", i).     
4dd0: 20 20 20 20 20 20 20 20 20 20 20 6c 52 75 6c 65             lRule
4de0: 4c 69 6e 65 2e 61 70 70 65 6e 64 28 5b 69 2c 20  Line.append([i, 
4df0: 22 40 40 40 40 22 2b 6d 2e 67 72 6f 75 70 28 31  "@@@@"+m.group(1
4e00: 29 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  )]).            
4e10: 20 20 20 20 62 47 72 61 70 68 20 3d 20 54 72 75      bGraph = Tru
4e20: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 47  e.            lG
4e30: 72 61 70 68 52 75 6c 65 2e 61 70 70 65 6e 64 28  raphRule.append(
4e40: 5b 69 2c 20 73 4c 69 6e 65 5d 29 0a 20 20 20 20  [i, sLine]).    
4e50: 20 20 20 20 20 20 20 20 62 47 72 61 70 68 20 3d          bGraph =
4e60: 20 54 72 75 65 0a 20 20 20 20 20 20 20 20 65 6c   True.        el
4e70: 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77  if sLine.startsw
4e80: 69 74 68 28 22 40 40 40 40 45 4e 44 5f 47 52 41  ith("@@@@END_GRA
4e90: 50 48 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  PH"):.          
4ea0: 20 20 23 6c 47 72 61 70 68 52 75 6c 65 2e 61 70    #lGraphRule.ap
4eb0: 70 65 6e 64 28 5b 69 2c 20 73 4c 69 6e 65 5d 29  pend([i, sLine])
4ec0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 47 72  .            bGr
4ed0: 61 70 68 20 3d 20 46 61 6c 73 65 0a 20 20 20 20  aph = False.    
4ee0: 20 20 20 20 65 6c 69 66 20 72 65 2e 6d 61 74 63      elif re.matc
4ef0: 68 28 22 40 40 40 40 20 2a 24 22 2c 20 73 4c 69  h("@@@@ *$", sLi
4f00: 6e 65 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ne):.           
4f10: 20 70 61 73 73 0a 20 20 20 20 20 20 20 20 65 6c   pass.        el
4f20: 69 66 20 62 47 72 61 70 68 3a 0a 20 20 20 20 20  if bGraph:.     
4f30: 20 20 20 20 20 20 20 6c 47 72 61 70 68 52 75 6c         lGraphRul
4f40: 65 2e 61 70 70 65 6e 64 28 5b 69 2c 20 73 4c 69  e.append([i, sLi
4f50: 6e 65 5d 29 0a 20 20 20 20 20 20 20 20 23 20 52  ne]).        # R
4f60: 65 67 65 78 20 72 75 6c 65 73 0a 20 20 20 20 20  egex rules.     
4f70: 20 20 20 65 6c 69 66 20 72 65 2e 6d 61 74 63 68     elif re.match
4f80: 28 22 5b 20 c2 a0 5c 74 5d 2a 24 22 2c 20 73 4c  ("[ ..\t]*$", sL
4f90: 69 6e 65 29 3a 0a 20 20 20 20 20 20 20 20 20 20  ine):.          
4fa0: 20 20 23 20 65 6d 70 74 79 20 6c 69 6e 65 0a 20    # empty line. 
4fb0: 20 20 20 20 20 20 20 20 20 20 20 70 61 73 73 0a             pass.
4fc0: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69          elif sLi
4fd0: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 28 22  ne.startswith(("
4fe0: 20 20 20 20 22 2c 20 22 5c 74 22 29 29 3a 0a 20      ", "\t")):. 
4ff0: 20 20 20 20 20 20 20 20 20 20 20 23 20 72 75 6c             # rul
5000: 65 20 28 63 6f 6e 74 69 6e 75 61 74 69 6f 6e 29  e (continuation)
5010: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 52 75  .            lRu
5020: 6c 65 4c 69 6e 65 5b 2d 31 5d 5b 31 5d 20 2b 3d  leLine[-1][1] +=
5030: 20 22 20 22 20 2b 20 73 4c 69 6e 65 2e 73 74 72   " " + sLine.str
5040: 69 70 28 29 0a 20 20 20 20 20 20 20 20 65 6c 73  ip().        els
5050: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  e:.            #
5060: 20 6e 65 77 20 72 75 6c 65 0a 20 20 20 20 20 20   new rule.      
5070: 20 20 20 20 20 20 6c 52 75 6c 65 4c 69 6e 65 2e        lRuleLine.
5080: 61 70 70 65 6e 64 28 5b 69 2c 20 73 4c 69 6e 65  append([i, sLine
5090: 2e 73 74 72 69 70 28 29 5d 29 0a 0a 20 20 20 20  .strip()])..    
50a0: 23 20 67 65 6e 65 72 61 74 69 6e 67 20 6f 70 74  # generating opt
50b0: 69 6f 6e 73 20 66 69 6c 65 73 0a 20 20 20 20 70  ions files.    p
50c0: 72 69 6e 74 28 22 20 20 70 61 72 73 69 6e 67 20  rint("  parsing 
50d0: 6f 70 74 69 6f 6e 73 2e 2e 2e 22 29 0a 20 20 20  options...").   
50e0: 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 64 4f   try:.        dO
50f0: 70 74 69 6f 6e 73 2c 20 64 4f 70 74 50 72 69 6f  ptions, dOptPrio
5100: 72 69 74 79 20 3d 20 70 72 65 70 61 72 65 4f 70  rity = prepareOp
5110: 74 69 6f 6e 73 28 6c 4f 70 74 29 0a 20 20 20 20  tions(lOpt).    
5120: 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20  except:.        
5130: 74 72 61 63 65 62 61 63 6b 2e 70 72 69 6e 74 5f  traceback.print_
5140: 65 78 63 28 29 0a 20 20 20 20 20 20 20 20 65 78  exc().        ex
5150: 69 74 28 29 0a 0a 20 20 20 20 23 20 74 65 73 74  it()..    # test
5160: 73 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 6c  s.    print("  l
5170: 69 73 74 20 74 65 73 74 73 2e 2e 2e 22 29 0a 20  ist tests..."). 
5180: 20 20 20 73 47 43 54 65 73 74 73 20 3d 20 22 5c     sGCTests = "\
5190: 6e 22 2e 6a 6f 69 6e 28 6c 54 65 73 74 29 0a 20  n".join(lTest). 
51a0: 20 20 20 73 47 43 54 65 73 74 73 4a 53 20 3d 20     sGCTestsJS = 
51b0: 27 7b 20 22 61 44 61 74 61 22 3a 20 27 20 2b 20  '{ "aData": ' + 
51c0: 6a 73 6f 6e 2e 64 75 6d 70 73 28 6c 54 65 73 74  json.dumps(lTest
51d0: 2c 20 65 6e 73 75 72 65 5f 61 73 63 69 69 3d 46  , ensure_ascii=F
51e0: 61 6c 73 65 29 20 2b 20 22 20 7d 5c 6e 22 0a 0a  alse) + " }\n"..
51f0: 20 20 20 20 23 20 70 72 6f 63 65 73 73 69 6e 67      # processing
5200: 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 70 72  .    print("  pr
5210: 65 70 61 72 69 6e 67 20 72 75 6c 65 73 2e 2e 2e  eparing rules...
5220: 22 29 0a 20 20 20 20 62 50 61 72 61 67 72 61 70  ").    bParagrap
5230: 68 20 3d 20 54 72 75 65 0a 20 20 20 20 6c 50 61  h = True.    lPa
5240: 72 61 67 72 61 70 68 52 75 6c 65 73 20 3d 20 5b  ragraphRules = [
5250: 5d 0a 20 20 20 20 6c 53 65 6e 74 65 6e 63 65 52  ].    lSentenceR
5260: 75 6c 65 73 20 3d 20 5b 5d 0a 20 20 20 20 6c 50  ules = [].    lP
5270: 61 72 61 67 72 61 70 68 52 75 6c 65 73 4a 53 20  aragraphRulesJS 
5280: 3d 20 5b 5d 0a 20 20 20 20 6c 53 65 6e 74 65 6e  = [].    lSenten
5290: 63 65 52 75 6c 65 73 4a 53 20 3d 20 5b 5d 0a 0a  ceRulesJS = []..
52a0: 20 20 20 20 66 6f 72 20 6e 4c 69 6e 65 2c 20 73      for nLine, s
52b0: 4c 69 6e 65 20 69 6e 20 6c 52 75 6c 65 4c 69 6e  Line in lRuleLin
52c0: 65 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73 4c  e:.        if sL
52d0: 69 6e 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ine:.           
52e0: 20 69 66 20 73 4c 69 6e 65 20 3d 3d 20 22 5b 2b   if sLine == "[+
52f0: 2b 5d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  +]":.           
5300: 20 20 20 20 20 62 50 61 72 61 67 72 61 70 68 20       bParagraph 
5310: 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20  = False.        
5320: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
5330: 20 20 20 20 20 20 20 20 20 20 61 52 75 6c 65 20            aRule 
5340: 3d 20 63 72 65 61 74 65 52 75 6c 65 28 73 4c 69  = createRule(sLi
5350: 6e 65 2c 20 6e 4c 69 6e 65 2c 20 73 4c 61 6e 67  ne, nLine, sLang
5360: 2c 20 62 50 61 72 61 67 72 61 70 68 2c 20 64 4f  , bParagraph, dO
5370: 70 74 50 72 69 6f 72 69 74 79 29 0a 20 20 20 20  ptPriority).    
5380: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 61              if a
5390: 52 75 6c 65 3a 0a 20 20 20 20 20 20 20 20 20 20  Rule:.          
53a0: 20 20 20 20 20 20 20 20 20 20 69 66 20 62 50 61            if bPa
53b0: 72 61 67 72 61 70 68 3a 0a 20 20 20 20 20 20 20  ragraph:.       
53c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
53d0: 20 6c 50 61 72 61 67 72 61 70 68 52 75 6c 65 73   lParagraphRules
53e0: 2e 61 70 70 65 6e 64 28 61 52 75 6c 65 29 0a 20  .append(aRule). 
53f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5400: 20 20 20 20 20 20 20 6c 50 61 72 61 67 72 61 70         lParagrap
5410: 68 52 75 6c 65 73 4a 53 2e 61 70 70 65 6e 64 28  hRulesJS.append(
5420: 6a 73 63 6f 6e 76 2e 70 79 52 75 6c 65 54 6f 4a  jsconv.pyRuleToJ
5430: 53 28 61 52 75 6c 65 2c 20 64 4a 53 52 45 47 45  S(aRule, dJSREGE
5440: 58 45 53 2c 20 73 57 4f 52 44 4c 49 4d 49 54 4c  XES, sWORDLIMITL
5450: 45 46 54 29 29 0a 20 20 20 20 20 20 20 20 20 20  EFT)).          
5460: 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a            else:.
5470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5480: 20 20 20 20 20 20 20 20 6c 53 65 6e 74 65 6e 63          lSentenc
5490: 65 52 75 6c 65 73 2e 61 70 70 65 6e 64 28 61 52  eRules.append(aR
54a0: 75 6c 65 29 0a 20 20 20 20 20 20 20 20 20 20 20  ule).           
54b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 53 65               lSe
54c0: 6e 74 65 6e 63 65 52 75 6c 65 73 4a 53 2e 61 70  ntenceRulesJS.ap
54d0: 70 65 6e 64 28 6a 73 63 6f 6e 76 2e 70 79 52 75  pend(jsconv.pyRu
54e0: 6c 65 54 6f 4a 53 28 61 52 75 6c 65 2c 20 64 4a  leToJS(aRule, dJ
54f0: 53 52 45 47 45 58 45 53 2c 20 73 57 4f 52 44 4c  SREGEXES, sWORDL
5500: 49 4d 49 54 4c 45 46 54 29 29 0a 0a 20 20 20 20  IMITLEFT))..    
5510: 23 20 63 72 65 61 74 69 6e 67 20 66 69 6c 65 20  # creating file 
5520: 77 69 74 68 20 61 6c 6c 20 66 75 6e 63 74 69 6f  with all functio
5530: 6e 73 20 63 61 6c 6c 61 62 6c 65 20 62 79 20 72  ns callable by r
5540: 75 6c 65 73 0a 20 20 20 20 70 72 69 6e 74 28 22  ules.    print("
5550: 20 20 63 72 65 61 74 69 6e 67 20 63 61 6c 6c 61    creating calla
5560: 62 6c 65 73 2e 2e 2e 22 29 0a 20 20 20 20 73 50  bles...").    sP
5570: 79 43 61 6c 6c 61 62 6c 65 73 20 3d 20 22 23 20  yCallables = "# 
5580: 67 65 6e 65 72 61 74 65 64 20 63 6f 64 65 2c 20  generated code, 
5590: 64 6f 20 6e 6f 74 20 65 64 69 74 5c 6e 22 0a 20  do not edit\n". 
55a0: 20 20 20 73 4a 53 43 61 6c 6c 61 62 6c 65 73 20     sJSCallables 
55b0: 3d 20 22 2f 2f 20 67 65 6e 65 72 61 74 65 64 20  = "// generated 
55c0: 63 6f 64 65 2c 20 64 6f 20 6e 6f 74 20 65 64 69  code, do not edi
55d0: 74 5c 6e 63 6f 6e 73 74 20 6f 45 76 61 6c 46 75  t\nconst oEvalFu
55e0: 6e 63 20 3d 20 7b 5c 6e 22 0a 20 20 20 20 66 6f  nc = {\n".    fo
55f0: 72 20 73 46 75 6e 63 4e 61 6d 65 2c 20 73 52 65  r sFuncName, sRe
5600: 74 75 72 6e 20 69 6e 20 6c 46 55 4e 43 54 49 4f  turn in lFUNCTIO
5610: 4e 53 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73  NS:.        if s
5620: 46 75 6e 63 4e 61 6d 65 2e 73 74 61 72 74 73 77  FuncName.startsw
5630: 69 74 68 28 22 5f 63 5f 22 29 3a 20 23 20 63 6f  ith("_c_"): # co
5640: 6e 64 69 74 69 6f 6e 0a 20 20 20 20 20 20 20 20  ndition.        
5650: 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20 22 73      sParams = "s
5660: 2c 20 73 78 2c 20 6d 2c 20 64 54 6f 6b 65 6e 50  , sx, m, dTokenP
5670: 6f 73 2c 20 73 43 6f 75 6e 74 72 79 2c 20 62 43  os, sCountry, bC
5680: 6f 6e 64 4d 65 6d 6f 22 0a 20 20 20 20 20 20 20  ondMemo".       
5690: 20 65 6c 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e   elif sFuncName.
56a0: 73 74 61 72 74 73 77 69 74 68 28 22 5f 6d 5f 22  startswith("_m_"
56b0: 29 3a 20 23 20 6d 65 73 73 61 67 65 0a 20 20 20  ): # message.   
56c0: 20 20 20 20 20 20 20 20 20 73 50 61 72 61 6d 73           sParams
56d0: 20 3d 20 22 73 2c 20 6d 22 0a 20 20 20 20 20 20   = "s, m".      
56e0: 20 20 65 6c 69 66 20 73 46 75 6e 63 4e 61 6d 65    elif sFuncName
56f0: 2e 73 74 61 72 74 73 77 69 74 68 28 22 5f 73 5f  .startswith("_s_
5700: 22 29 3a 20 23 20 73 75 67 67 65 73 74 69 6f 6e  "): # suggestion
5710: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61  .            sPa
5720: 72 61 6d 73 20 3d 20 22 73 2c 20 6d 22 0a 20 20  rams = "s, m".  
5730: 20 20 20 20 20 20 65 6c 69 66 20 73 46 75 6e 63        elif sFunc
5740: 4e 61 6d 65 2e 73 74 61 72 74 73 77 69 74 68 28  Name.startswith(
5750: 22 5f 70 5f 22 29 3a 20 23 20 70 72 65 70 72 6f  "_p_"): # prepro
5760: 63 65 73 73 6f 72 0a 20 20 20 20 20 20 20 20 20  cessor.         
5770: 20 20 20 73 50 61 72 61 6d 73 20 3d 20 22 73 2c     sParams = "s,
5780: 20 6d 22 0a 20 20 20 20 20 20 20 20 65 6c 69 66   m".        elif
5790: 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61 72 74   sFuncName.start
57a0: 73 77 69 74 68 28 22 5f 64 5f 22 29 3a 20 23 20  swith("_d_"): # 
57b0: 64 69 73 61 6d 62 69 67 75 61 74 6f 72 0a 20 20  disambiguator.  
57c0: 20 20 20 20 20 20 20 20 20 20 73 50 61 72 61 6d            sParam
57d0: 73 20 3d 20 22 73 2c 20 6d 2c 20 64 54 6f 6b 65  s = "s, m, dToke
57e0: 6e 50 6f 73 22 0a 20 20 20 20 20 20 20 20 65 6c  nPos".        el
57f0: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
5800: 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e 6f 77 6e  print("# Unknown
5810: 20 66 75 6e 63 74 69 6f 6e 20 74 79 70 65 20 69   function type i
5820: 6e 20 5b 22 20 2b 20 73 46 75 6e 63 4e 61 6d 65  n [" + sFuncName
5830: 20 2b 20 22 5d 22 29 0a 20 20 20 20 20 20 20 20   + "]").        
5840: 20 20 20 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20      continue.   
5850: 20 20 20 20 20 73 50 79 43 61 6c 6c 61 62 6c 65       sPyCallable
5860: 73 20 2b 3d 20 22 64 65 66 20 7b 7d 20 28 7b 7d  s += "def {} ({}
5870: 29 3a 5c 6e 22 2e 66 6f 72 6d 61 74 28 73 46 75  ):\n".format(sFu
5880: 6e 63 4e 61 6d 65 2c 20 73 50 61 72 61 6d 73 29  ncName, sParams)
5890: 0a 20 20 20 20 20 20 20 20 73 50 79 43 61 6c 6c  .        sPyCall
58a0: 61 62 6c 65 73 20 2b 3d 20 22 20 20 20 20 72 65  ables += "    re
58b0: 74 75 72 6e 20 22 20 2b 20 73 52 65 74 75 72 6e  turn " + sReturn
58c0: 20 2b 20 22 5c 6e 22 0a 20 20 20 20 20 20 20 20   + "\n".        
58d0: 73 4a 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20  sJSCallables += 
58e0: 22 20 20 20 20 7b 7d 3a 20 66 75 6e 63 74 69 6f  "    {}: functio
58f0: 6e 20 28 7b 7d 29 22 2e 66 6f 72 6d 61 74 28 73  n ({})".format(s
5900: 46 75 6e 63 4e 61 6d 65 2c 20 73 50 61 72 61 6d  FuncName, sParam
5910: 73 29 20 2b 20 22 20 7b 5c 6e 22 0a 20 20 20 20  s) + " {\n".    
5920: 20 20 20 20 73 4a 53 43 61 6c 6c 61 62 6c 65 73      sJSCallables
5930: 20 2b 3d 20 22 20 20 20 20 20 20 20 20 72 65 74   += "        ret
5940: 75 72 6e 20 22 20 2b 20 6a 73 63 6f 6e 76 2e 70  urn " + jsconv.p
5950: 79 32 6a 73 28 73 52 65 74 75 72 6e 29 20 2b 20  y2js(sReturn) + 
5960: 22 3b 5c 6e 22 0a 20 20 20 20 20 20 20 20 73 4a  ";\n".        sJ
5970: 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 20  SCallables += " 
5980: 20 20 20 7d 2c 5c 6e 22 0a 20 20 20 20 73 4a 53     },\n".    sJS
5990: 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 7d 5c  Callables += "}\
59a0: 6e 22 0a 0a 20 20 20 20 64 69 73 70 6c 61 79 53  n"..    displayS
59b0: 74 61 74 73 28 6c 50 61 72 61 67 72 61 70 68 52  tats(lParagraphR
59c0: 75 6c 65 73 2c 20 6c 53 65 6e 74 65 6e 63 65 52  ules, lSentenceR
59d0: 75 6c 65 73 29 0a 0a 20 20 20 20 70 72 69 6e 74  ules)..    print
59e0: 28 22 55 6e 6e 61 6d 65 64 20 72 75 6c 65 73 3a  ("Unnamed rules:
59f0: 20 22 20 2b 20 73 74 72 28 6e 52 55 4c 45 57 49   " + str(nRULEWI
5a00: 54 48 4f 55 54 4e 41 4d 45 29 29 0a 0a 20 20 20  THOUTNAME))..   
5a10: 20 64 56 61 72 73 20 3d 20 7b 20 20 20 22 63 61   dVars = {   "ca
5a20: 6c 6c 61 62 6c 65 73 22 3a 20 73 50 79 43 61 6c  llables": sPyCal
5a30: 6c 61 62 6c 65 73 2c 0a 20 20 20 20 20 20 20 20  lables,.        
5a40: 20 20 20 20 20 20 20 20 22 63 61 6c 6c 61 62 6c          "callabl
5a50: 65 73 4a 53 22 3a 20 73 4a 53 43 61 6c 6c 61 62  esJS": sJSCallab
5a60: 6c 65 73 2c 0a 20 20 20 20 20 20 20 20 20 20 20  les,.           
5a70: 20 20 20 20 20 22 67 63 74 65 73 74 73 22 3a 20       "gctests": 
5a80: 73 47 43 54 65 73 74 73 2c 0a 20 20 20 20 20 20  sGCTests,.      
5a90: 20 20 20 20 20 20 20 20 20 20 22 67 63 74 65 73            "gctes
5aa0: 74 73 4a 53 22 3a 20 73 47 43 54 65 73 74 73 4a  tsJS": sGCTestsJ
5ab0: 53 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  S,.             
5ac0: 20 20 20 22 70 61 72 61 67 72 61 70 68 5f 72 75     "paragraph_ru
5ad0: 6c 65 73 22 3a 20 6d 65 72 67 65 52 75 6c 65 73  les": mergeRules
5ae0: 42 79 4f 70 74 69 6f 6e 28 6c 50 61 72 61 67 72  ByOption(lParagr
5af0: 61 70 68 52 75 6c 65 73 29 2c 0a 20 20 20 20 20  aphRules),.     
5b00: 20 20 20 20 20 20 20 20 20 20 20 22 73 65 6e 74             "sent
5b10: 65 6e 63 65 5f 72 75 6c 65 73 22 3a 20 6d 65 72  ence_rules": mer
5b20: 67 65 52 75 6c 65 73 42 79 4f 70 74 69 6f 6e 28  geRulesByOption(
5b30: 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 29 2c  lSentenceRules),
5b40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5b50: 20 22 70 61 72 61 67 72 61 70 68 5f 72 75 6c 65   "paragraph_rule
5b60: 73 5f 4a 53 22 3a 20 6a 73 63 6f 6e 76 2e 77 72  s_JS": jsconv.wr
5b70: 69 74 65 52 75 6c 65 73 54 6f 4a 53 41 72 72 61  iteRulesToJSArra
5b80: 79 28 6d 65 72 67 65 52 75 6c 65 73 42 79 4f 70  y(mergeRulesByOp
5b90: 74 69 6f 6e 28 6c 50 61 72 61 67 72 61 70 68 52  tion(lParagraphR
5ba0: 75 6c 65 73 4a 53 29 29 2c 0a 20 20 20 20 20 20  ulesJS)),.      
5bb0: 20 20 20 20 20 20 20 20 20 20 22 73 65 6e 74 65            "sente
5bc0: 6e 63 65 5f 72 75 6c 65 73 5f 4a 53 22 3a 20 6a  nce_rules_JS": j
5bd0: 73 63 6f 6e 76 2e 77 72 69 74 65 52 75 6c 65 73  sconv.writeRules
5be0: 54 6f 4a 53 41 72 72 61 79 28 6d 65 72 67 65 52  ToJSArray(mergeR
5bf0: 75 6c 65 73 42 79 4f 70 74 69 6f 6e 28 6c 53 65  ulesByOption(lSe
5c00: 6e 74 65 6e 63 65 52 75 6c 65 73 4a 53 29 29 20  ntenceRulesJS)) 
5c10: 7d 0a 20 20 20 20 64 56 61 72 73 2e 75 70 64 61  }.    dVars.upda
5c20: 74 65 28 64 4f 70 74 69 6f 6e 73 29 0a 0a 20 20  te(dOptions)..  
5c30: 20 20 23 20 63 6f 6d 70 69 6c 65 20 67 72 61 70    # compile grap
5c40: 68 20 72 75 6c 65 73 0a 20 20 20 20 64 56 61 72  h rules.    dVar
5c50: 73 32 20 3d 20 63 72 67 2e 6d 61 6b 65 28 6c 47  s2 = crg.make(lG
5c60: 72 61 70 68 52 75 6c 65 2c 20 64 44 45 46 2c 20  raphRule, dDEF, 
5c70: 73 4c 61 6e 67 2c 20 62 4a 61 76 61 53 63 72 69  sLang, bJavaScri
5c80: 70 74 29 0a 20 20 20 20 64 56 61 72 73 2e 75 70  pt).    dVars.up
5c90: 64 61 74 65 28 64 56 61 72 73 32 29 0a 0a 20 20  date(dVars2)..  
5ca0: 20 20 72 65 74 75 72 6e 20 64 56 61 72 73 0a       return dVars.