Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

python_C_Parser.py

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