Advertisement
veblush

RadixMaker

Oct 12th, 2012
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.75 KB | None | 0 0
  1. #!/usr/bin/python2
  2.  
  3. import sys
  4. import csv
  5.  
  6. def make_length_group(data):
  7.     ldict = {}
  8.     for s, v in data:
  9.         ldict.setdefault(len(s), []).append((s, v))
  10.     return ldict
  11.  
  12. def make_prefix_tree(data, eos=True, compact=False):
  13.     def build_tree(data, eos):
  14.         cdict = {}
  15.         for st, val in data:
  16.             if eos:
  17.                 if len(st) > 0:
  18.                     cdict.setdefault(st[0], []).append((st[1:], val))
  19.                 else:
  20.                     cdict[0] = val
  21.             else:
  22.                 if len(st) > 1:
  23.                     cdict.setdefault(st[0], []).append((st[1:], val))
  24.                 else:
  25.                     cdict[st[0]] = val
  26.         rdict = {}
  27.         for key, value in cdict.iteritems():
  28.             if isinstance(value, list):
  29.                 rdict[key] = build_tree(value, eos)
  30.             else:
  31.                 rdict[key] = value
  32.         return rdict
  33.    
  34.     def make_compact(node):
  35.         if len(node) == 1 and isinstance(node.values()[0], dict) and len(node.values()[0]) == 1:
  36.             cnode = node.values()[0]
  37.             if cnode.keys()[0] == 0:
  38.                 newval = cnode[cnode.keys()[0]]
  39.                 node[node.keys()[0]] = newval
  40.             else:
  41.                 newkey = node.keys()[0] + cnode.keys()[0]
  42.                 newval = cnode[cnode.keys()[0]]
  43.                 del node[node.keys()[0]]
  44.                 node[newkey] = newval
  45.                 make_compact(node)
  46.         else:
  47.             for key, value in node.iteritems():
  48.                 if isinstance(value, dict):
  49.                     make_compact(value)
  50.  
  51.     node = build_tree(data, eos)
  52.     if compact:
  53.         make_compact(node)
  54.     return node
  55.  
  56. def make_strcmp(key, index = 0, usemem = False):
  57.     if isinstance(key, str):
  58.         if usemem:
  59.             return "!memcmp(s+%d, \"%s\", %d)" % (index, key, len(key))
  60.         else:
  61.             return "!strcmp(s+%d, \"%s\")" % (index, key)
  62.     else:
  63.         return "s[%d] == %d" % (index, key)
  64.  
  65. def make_strncmp(key, index = 0, usemem = False):
  66.     if isinstance(key, str):
  67.         if len(key) == 1:
  68.             return "s[%d] == '%s'" % (index, key)
  69.         else:
  70.             if usemem:
  71.                 return "!memcmp(s+%d, \"%s\", %d)" % (index, key, len(key))
  72.             else:
  73.                 return "!strncmp(s+%d, \"%s\", %d)" % (index, key, len(key))
  74.     else:
  75.         return "s[%d] == %d" % (index, key)
  76.  
  77. def make_prefix_tree_to_switch(data, depth = 0):
  78.     ldict = make_length_group(data)
  79.     t = make_prefix_tree(data, eos = True, compact = True)
  80.     make_prefix_tree_to_switch_sub(t, depth, usemem = False)
  81.  
  82. def make_prefix_tree_to_switch_len(data, depth = 0):
  83.     ldict = make_length_group(data)
  84.     istr = '\t'*depth
  85.     print "%sswitch (len) {" % (istr)
  86.     for l, ldata in sorted(ldict.iteritems(), key = lambda x: x[0]):
  87.         print "%scase %d:" % (istr, l),
  88.         t = make_prefix_tree(ldata, eos = False, compact = True)
  89.         make_prefix_tree_to_switch_sub(t, depth + 1, usemem = True)
  90.     print "%sdefault: return -1;" % (istr)
  91.     print "%s}" % (istr)
  92.                    
  93. def make_prefix_tree_to_switch_sub(node, depth = 0, usemem = False, index = 0):
  94.     istr = '\t'*depth
  95.     if len(node) > 1:
  96.         print
  97.         print "%sswitch (s[%d]) {" % (istr, index)
  98.         for key, value in sorted(node.iteritems(), key = lambda x: x[0]):
  99.             if isinstance(key, str):
  100.                 print "%scase '%s':" % (istr, key),
  101.             else:
  102.                 print "%scase %d:" % (istr, key),
  103.             if isinstance(value, dict):
  104.                 make_prefix_tree_to_switch_sub(value, depth+1, usemem, index+1)
  105.             else:
  106.                 print "return %d;" % (value);
  107.         print "%sdefault: return -1;" % (istr)
  108.         print "%s}" % (istr)
  109.     else:
  110.         key = node.keys()[0]
  111.         val = node.values()[0]
  112.         if isinstance(val, dict):
  113.             print "if (%s)" % (make_strncmp(key, index, usemem)),
  114.             make_prefix_tree_to_switch_sub(val, depth, usemem, index+len(key))
  115.             print "%selse return -1;" % (istr);
  116.         else:
  117.             print "if (%s)" % (make_strcmp(key, index, usemem)),
  118.             print "return %d; else return -1;" % (val)
  119.  
  120. # >copy con Test.txt
  121. # apple 1
  122. # apps  2
  123. # bana  3
  124. # banana    4
  125.  
  126. def main():
  127.     # read input
  128.     argv = sys.argv[1:]
  129.     input = argv[0] if len(argv) > 0 else "Test.txt"
  130.     data = []
  131.     for s, v in csv.reader(open(input), csv.excel_tab):
  132.         data.append((s, int(v)))
  133.     # work
  134.     print "int parse(const char* s) {",
  135.     make_prefix_tree_to_switch(data, 1)
  136.     print "}"
  137.     print
  138.     print "int parse(const char* s, size_t len) {"
  139.     make_prefix_tree_to_switch_len(data, 1)
  140.     print "}"
  141.  
  142. if __name__ == "__main__":
  143.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement