Want more features on Pastebin? Sign Up, it's FREE!
Guest

python_c_parser.py

By: a guest on Apr 11th, 2012  |  syntax: None  |  size: 5.55 KB  |  views: 32  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. import sys
  2. from operator import itemgetter, attrgetter
  3. from xml.etree.ElementTree import ElementTree
  4. import time
  5.  
  6. # parsing config
  7. CONFIG_FILE = "D:/python/cparser.xml"
  8.  
  9. tr = ElementTree()
  10. m=tr.parse(CONFIG_FILE)
  11. path = m.find("includeDir").text
  12. startXML = ""
  13. sXML = m.find("startXML")
  14. oXML = m.find("outputXML").text
  15. if sXML.attrib["active"] == "true":
  16.         startXML = sXML.text
  17. # parsing config
  18.  
  19. inc = []
  20. arr = []
  21. defineID = 2
  22. funcID = 1
  23.  
  24. def trim(l):
  25.         nl = []
  26.         for i in l:
  27.                 if len(i) > 0:
  28.                         nl.append(i)
  29.         return nl
  30.  
  31. def stripList(l):
  32.         for i in range(0,len(l)):
  33.                 l[i] = l[i].strip()
  34.         return l
  35.  
  36. def contains(lst, srch):
  37.         for x in lst:
  38.                 if x == srch:return True
  39.         return False
  40.        
  41. def cont(wrd, pattern):
  42.         for x in wrd:
  43.                 if x in pattern:
  44.                         return True
  45.         return False
  46.  
  47. apTmp = []
  48. zSlovo = ['a', 0]
  49. def makeHash(word):
  50.         global apTmp, hashTable
  51.        
  52.         if word[0] == zSlovo[0]:
  53.                 if word in [x[1] for x in apTmp[zSlovo[1]:] ]:
  54.                         return True
  55.                 else:
  56.                         return False
  57.         else:
  58.                 zSlovo[0] = word[0]
  59.                 zSlovo[1] = len(apTmp)
  60.                 return False
  61.                        
  62. def filter_existant(ar):
  63.         global tmp, apTmp
  64.         for x in range(0,len(ar)):
  65.                 if str.isdigit(ar[x][1][0]) or cont(ar[x][1], " \t.()#"):
  66.                         continue
  67.                
  68.                 if not makeHash(ar[x][1]):
  69.                         apTmp.append(ar[x])
  70.  
  71.  
  72.  
  73. tree = ElementTree()
  74. try:
  75.         if len(startXML) != 0:
  76.                 m=tree.parse(startXML)
  77.                 m=m.find("AutoComplete")
  78.                 l=list(m.iter("KeyWord"))
  79.                 for x in l:
  80.                         name = x.attrib["name"]
  81.                         func = funcID if x.attrib.__contains__("func") else defineID
  82.                         retval = ""
  83.                         parm = []
  84.                         if func:
  85.                                 ov = x.find("Overload")
  86.                                 if ov is not None:
  87.                                         retval = ov.attrib["retVal"]
  88.                                         p = list(ov.iter("Param"))
  89.                                         for i in p:
  90.                                                 parm.append(i.attrib["name"])
  91.                         arr.append((func, name, retval, parm))
  92. except:
  93.         if startXML != "":
  94.                 print("loading startXML failed")
  95.        
  96. def parseDefine(s):
  97.         global arr, defineID, funcID
  98.         s=s.replace("\t", " ")
  99.         ls = trim(s.split(" "))
  100.         arr.append((defineID, ls[1], '' if len(ls)<3 else ls[2], []))
  101. def parseFunc(s):
  102.         global arr, defineID, funcID
  103.         l = s.split("(")
  104.         ps = l[1].split(")")
  105.         ps = ')'.join(ps[:len(ps)-1]).split(",")
  106.         stripList(ps)
  107.         l[0] = l[0].replace(chr(0x9), ' ')
  108.         tl = trim(l[0].split(" "))
  109.         try:
  110.                 arr.append( (funcID, tl[len(tl)-1], ' '.join(tl[0:len(tl)-1]), ps) )
  111.         except:
  112.                 if len(s) == 2:
  113.                         arr.append( (funcID, tl[len(tl)-1], ' ', []) )
  114.  
  115. def parseC(file):
  116.         global inc
  117.         global arr
  118.         file=file.replace("\\", "/")
  119.         if file not in inc:
  120.                 inc.append(file)
  121.         else:
  122.                 return
  123.         nav = False
  124.         ncom = 0
  125.         stInd = 0
  126.         ndef = False
  127.         nusl = False
  128.         s = ""
  129.         zag = 0
  130.         bTyp = False
  131.         nZag2 = 0
  132.         bInc = False
  133.         try:
  134.                 fl = open(file, "r")
  135.                 print("parsing file: "+file)
  136.         except:
  137.                 return
  138.         f = fl.read()
  139.         fl.close()
  140.        
  141.         for i in range(0,len(f)):
  142.                        
  143.                 if f[i:i+2] == "/*":
  144.                         ncom = 1
  145.                         i+=1
  146.                         continue
  147.                        
  148.                 if f[i:i+2] == "*/":
  149.                         ncom = 0
  150.                         i+=1
  151.                         stInd = i+1
  152.                         continue
  153.  
  154.                 if ncom == 1:
  155.                         continue
  156.                        
  157.                 if f[i:i+2] == "//":
  158.                         nusl = True
  159.                         continue
  160.                        
  161.                 if (f[i]=="\r" or f[i]=="\n"):
  162.                         if nusl:
  163.                                 nusl = False
  164.                                 continue
  165.                                
  166.                         if bInc:
  167.                                 bInc = False
  168.                                 s = f[stInd:i]
  169.                                 s1 = s.split("<")
  170.                                 spl = s.split("\"")
  171.                                 if len(s1) > 1:
  172.                                         parseC(path+s1[1].split(">")[0].strip())
  173.                                 elif len(spl) > 1:
  174.                                         spl[1] = spl[1].replace("\\", "/")
  175.                                         if len(spl[1]) > 0:
  176.                                                 spl2 = file.split("/")
  177.                                                 if len(spl) == 3:
  178.                                                         parseC('/'.join(spl2[:len(spl2)-1])+"/"+spl[1])
  179.                         if ndef:
  180.                                 ndef = False
  181.                                 s = f[stInd:i]
  182.                                 try:
  183.                                         parseDefine(s)
  184.                                 except:
  185.                                         pass
  186.                                 s = ""
  187.                                 continue
  188.                         stInd = i+1
  189.                         continue
  190.                        
  191.                 if nusl:
  192.                         continue
  193.                        
  194.                 if f[i]=="{" and f[stInd:i].find("extern")==-1:
  195.                         nZag2 += 1
  196.                 if f[i]=="}":
  197.                         nZag2 -= 1
  198.                        
  199.                 if nZag2 > 0:
  200.                         continue
  201.                        
  202.                 if f[i]!="\"" and nav:
  203.                         continue
  204.                        
  205.                 if f[i:i+7] == "#define":
  206.                         stInd = i
  207.                         ndef = True
  208.                         continue
  209.                        
  210.                 if f[i:i+8] == "#include":
  211.                         bInc = True
  212.                         stInd = i
  213.                         continue
  214.                        
  215.                 if f[i]=="#":
  216.                         nusl = True
  217.                        
  218.                 if f[i]==";":
  219.                         if zag and not bTyp:
  220.                                 s = f[stInd:i]
  221.                                 try:
  222.                                         parseFunc(s)
  223.                                 except:
  224.                                         pass
  225.                                 zag = False
  226.                         else:
  227.                                 bTyp = False
  228.                         stInd = i+2
  229.                        
  230.                 if f[i]==")" and zag>0 and not ndef and not nusl and not bTyp:
  231.                         zag -= 1
  232.                         if zag == 0:
  233.                                 s = f[stInd:i+1]
  234.                                 try:
  235.                                         parseFunc(s)
  236.                                 except:
  237.                                         pass
  238.                                 zag = False
  239.                                 stInd = i+1
  240.                        
  241.                 if f[i]=="\"":
  242.                         nav^=True
  243.                        
  244.                
  245.                 if f[i] == "(" and not ndef and not nusl:
  246.                         zag += 1
  247.                        
  248.                 if f[i:i+7] == "typedef" and not nusl and not ndef:
  249.                         stInd = i
  250.                         bTyp = True
  251.  
  252. tmStart = time.clock()
  253. parseC(sys.argv[1])
  254. print("sorting ...")
  255. arr = sorted(arr, key=lambda x: x[1].upper())
  256. print("filtering ...")
  257. filter_existant(arr)
  258. arr = apTmp
  259. print("Took: %.3f seconds" % (time.clock()-tmStart))
  260.  
  261. # export
  262. fl = open(oXML, "w")
  263. fl.write("<?xml version=\"1.0\" encoding=\"Windows-1252\" ?>\n")
  264. fl.write("<NotepadPlus>\n")
  265. fl.write("\t<AutoComplete language=\"C\">\n")
  266. fl.write("\t\t<Environment ignoreCase=\"yes\" startFunc=\"(\" stopFunc=\")\" paramSeparator=\",\" terminal=\";\" />\n")
  267. for i in arr:
  268.         if(i[0] == defineID):
  269.                 fl.write("\t\t\t<KeyWord name=\""+i[1]+"\"/>\n")
  270.         if(i[0] == funcID):
  271.                 fl.write("\t\t\t<KeyWord name=\""+i[1]+"\" func=\"yes\">\n")
  272.                 fl.write("\t\t\t\t<Overload retVal=\""+i[2].replace('\n', ' ')+"\">\n")
  273.                 for j in i[3]:
  274.                         fl.write("\t\t\t\t\t<Param name=\""+j.strip()+"\"/>\n")
  275.                        
  276.                 fl.write("\t\t\t\t</Overload>\n")
  277.                 fl.write("\t\t\t</KeyWord>\n")
  278.                
  279. fl.write("\t</AutoComplete>\n")
  280. fl.write("</NotepadPlus>\n")
  281. fl.close()
clone this paste RAW Paste Data