免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5083 | 回复: 9
打印 上一主题 下一主题

请教python分析groovy代码文件的写法 [复制链接]

论坛徽章:
0
1 [报告]
发表于 2013-05-23 21:56 |显示全部楼层
本帖最后由 GhostFromHeaven 于 2013-05-23 22:01 编辑

回复 1# abcfy2
那个文件讲的太复杂,没看懂,我写了一个简单的,处理一个文件,加个循环就可以处理多个文件了。

我做了一些假设,如果对你的情况不适合,可以增加些复杂的条件。
  1. #-*- coding:utf-8 -*-=
  2. import re
  3. import string
  4. pattern_func_def = re.compile('''\s*def\s+.*?\s+\{\s*''')
  5. pattern_save = re.compile('''\.save\s*\(.*?\)''')
  6. pattern_left_brace = re.compile('''.*?\{.*?''')
  7. pattern_right_brace = re.compile('''.*?\}.*?''')

  8. STATE_UNDEFINED = -1
  9. STATE_OPEN = 0
  10. STATE_CLOSED = 1

  11. brace_count = 0
  12. got_function_definition = False
  13. state = STATE_UNDEFINED #-1:Undefined, 0:Open, 1:Closed
  14. got_full_function = False
  15. save_count_in_1_function = 0

  16. if __name__ == "__main__":
  17.     filename = "to_parse.groovy"
  18.     line_index = 0
  19.     with open(filename, "r") as fin:
  20.         for line in fin:
  21.             line = line.strip('\n')
  22.             line_index += 1
  23.             # 假设  def xxx = {在同一行
  24.             if state != STATE_OPEN  and pattern_func_def.search(line):
  25.                 state = STATE_OPEN
  26.                
  27.             # 假设每行最多一个{
  28.             if state == STATE_OPEN and pattern_left_brace.search(line):
  29.                 brace_count -= 1
  30.             
  31.             # 假设每行最多一个}
  32.             if state == STATE_OPEN and pattern_right_brace.search(line):
  33.                 brace_count += 1
  34.             
  35.             # 假设每行最多一个.save()
  36.             if state == STATE_OPEN and pattern_save.search(line):
  37.                 save_count_in_1_function += 1
  38.                 # 如果有多个save,则打印出来
  39.                 if save_count_in_1_function > 1:
  40.                     print "%04d:%s" %(line_index, line)
  41.             
  42.             # 函数定义结束
  43.             if brace_count == 0:
  44.                 state = STATE_CLOSED
  45.                 save_count_in_1_function = 0
复制代码
样例文件
  1. 1
  2. 2
  3. def fuction = {
  4.     dosomething
  5.     something.save(xyz)
  6.     something.save(123)
  7. }abc
  8. 3
  9. 4

  10. def fuction = {
  11.     dosomething
  12.     something.save(abc)
  13.     something.save(def)
  14. }abc
复制代码


   

论坛徽章:
0
2 [报告]
发表于 2013-05-23 23:01 |显示全部楼层
本帖最后由 GhostFromHeaven 于 2013-05-23 23:12 编辑

回复 4# abcfy2


    要想解决嵌套的问题也很简单
  1. #-*- coding:utf-8 -*-=
  2. import re
  3. import string
  4. pattern_func_def = re.compile('''\s*def\s+.*?\s+\{\s*''')
  5. pattern_save = re.compile('''\.save\s*\(.*?\)''')
  6. pattern_left_brace = re.compile('''.*?\{.*?''')
  7. pattern_right_brace = re.compile('''.*?\}.*?''')

  8. STATE_UNDEFINED = -1
  9. STATE_OPEN = 0
  10. STATE_CLOSED = 1
  11. state = STATE_UNDEFINED #-1:Undefined, 0:Open, 1:Closed

  12. def parse_groovy(fin, state, brace_count, line_index):
  13.     is_inner_function = False
  14.     if brace_count == -1 and state == STATE_OPEN:
  15.         is_inner_function = True
  16.     save_count_in_1_function = 0
  17.     while True:
  18.         line = fin.readline()
  19.         if not line:
  20.             return line_index
  21.         line = line.strip('\n')
  22.         line_index += 1
  23.         #print "%d:%s" %(line_index, line)
  24.         # 假设  def xxx = {在同一行
  25.         if pattern_func_def.search(line):
  26.             if state == STATE_OPEN:
  27.                line_index = parse_groovy(fin, state, -1, line_index)
  28.             state = STATE_OPEN
  29.             
  30.         # 假设每行最多一个{
  31.         if state == STATE_OPEN and pattern_left_brace.search(line):
  32.             brace_count -= 1
  33.         
  34.         # 假设每行最多一个}
  35.         if state == STATE_OPEN and pattern_right_brace.search(line):
  36.             brace_count += 1
  37.         
  38.         # 假设每行最多一个.save()
  39.         if state == STATE_OPEN and pattern_save.search(line):
  40.             save_count_in_1_function += 1
  41.             # 如果有多个save,则打印出来
  42.             if save_count_in_1_function > 1:
  43.                 print "%04d:%s" %(line_index, line)
  44.         
  45.         # 函数定义结束
  46.         if state == STATE_OPEN and brace_count == 0:
  47.             state = STATE_CLOSED
  48.             save_count_in_1_function = 0
  49.             if is_inner_function:
  50.                 return line_index
  51.             
  52. if __name__ == "__main__":
  53.     filename = "to_parse.groovy"
  54.     line_index = 0
  55.     with open(filename, "r") as fin:
  56.         parse_groovy(fin, state, 0, 0)
复制代码
  1. 1
  2. 2
  3. def fuction = {
  4.     dosomething
  5.     something.save(xyz)
  6.     something.save(123)
  7.     def fuction1 = {
  8.         dosomething
  9.         something.save(abc1)
  10.         something.save(def2)
  11.         def fuction2 = {
  12.             dosomething
  13.             something.save(abc1)
  14.             something.save(def2)
  15.         }
  16.         something.save(def2)
  17.     }
  18.     def fuction4 = {
  19.         dosomething
  20.         something.save(abc1)
  21.         something.save(def2)
  22.     }
  23.     something.save(defx)
  24. }abc
  25. 3
  26. 4

  27. def fuction = {
  28.     dosomething
  29.     something.save(abc)
  30.     something.save(def)
  31. }abc



复制代码
样例文件内容

论坛徽章:
0
3 [报告]
发表于 2013-05-24 14:18 |显示全部楼层
本帖最后由 GhostFromHeaven 于 2013-05-24 14:22 编辑

回复 7# abcfy2

这里匹配不到是因为直接用的save,不是xx.save

修改一个正则表达式即可:pattern_save = re.compile('''[\.\s]+save\s*\(.*?\)''')
   

论坛徽章:
0
4 [报告]
发表于 2013-05-24 20:42 |显示全部楼层
回复 9# abcfy2

如果方便的话,可以把你的需求文档或说明发给我(GhostFromHeaven@163.com),好一次做对,在论坛里交流比较慢。

   

论坛徽章:
0
5 [报告]
发表于 2013-05-24 22:45 |显示全部楼层
本帖最后由 GhostFromHeaven 于 2013-05-24 22:46 编辑

回复 9# abcfy2

switch不同case里的save不会被重复计数,但会把switch各分支中最多的save数加到函数里面。

打印格式为:文件名:行号:内容

可以处理多个文件。
  1. #-*- coding:utf-8 -*-
  2. import os
  3. import re
  4. import string

  5. pattern_func_def = re.compile('''(?<!\S)def\s+.*?\s+\{\s*''')
  6. pattern_save = re.compile('''\.save\s*\(.*?\)''')

  7. pattern_switch = re.compile('''(?<!\S)switch\s*\(.*?\)\s*{''')
  8. pattern_case = re.compile('''(?<!\S)(case\s+\S+)|(default)\s*:''')
  9. pattern_break = re.compile('''(?<!\S)break(?!\S)''')

  10. pattern_left_brace = re.compile('''.*?\{.*?''')
  11. pattern_right_brace = re.compile('''.*?\}.*?''')

  12. class GroovyParser(object):
  13.     def __init__(self):
  14.         self.current_file_name = ""
  15.         self.current_file_handler = None
  16.         self.current_line = ""
  17.         self.current_line_index = 0
  18.         
  19.     def _get_line(self):
  20.         for self.current_line in open(self.current_file_name, "r"):
  21.             self.current_line_index += 1
  22.             self.current_line = self.current_line.strip('\n')
  23.             yield "%s" % self.current_line
  24.    
  25.     def print_line(self):
  26.         print "%10s:%04d:%s" % (os.path.basename(self.current_file_name),
  27.                                 self.current_line_index,
  28.                                 self.current_line)
  29.    
  30.     # 处理{}
  31.     def _handle_brace(self, line):
  32.         # 假设每行最多一个{
  33.         _brace_count = 0
  34.         if pattern_left_brace.search(line):
  35.             _brace_count -= 1

  36.         # 假设每行最多一个}
  37.         if pattern_right_brace.search(line):
  38.             _brace_count += 1
  39.         return _brace_count
  40.    
  41.     # 处理xx.save(yy)
  42.     def _handle_save(self, line, save_count):
  43.         _save_count_in_1_function = save_count
  44.         # 假设每行最多一个.save()
  45.         if pattern_save.search(line):
  46.             _save_count_in_1_function += 1
  47.             # 如果有多个save,则打印出来
  48.             if _save_count_in_1_function > 1:
  49.                 self.print_line()
  50.             return 1
  51.         return 0
  52.         
  53.     def parse_func_def(self):
  54.         _brace_count = -1
  55.         _save_count_in_1_function = 0
  56.         for line in self.line_reader:
  57.             #line = self.get_line()
  58.             if not line:
  59.                 break

  60.             # function
  61.             if pattern_func_def.search(line):
  62.                 self.parse_func_def()
  63.             
  64.             # switch
  65.             if pattern_switch.search(line):
  66.                _save_count_in_1_function = self.parse_switch_def(_save_count_in_1_function)
  67.             
  68.             # {}
  69.             _brace_count += self._handle_brace(line)
  70.             
  71.             # xx.save(yy)
  72.             _save_count_in_1_function += self._handle_save(line, _save_count_in_1_function)
  73.             
  74.             # 函数定义结束
  75.             if _brace_count == 0:
  76.                 return

  77.     def parse_switch_def(self, save_count):
  78.         _brace_count = -1
  79.         _save_count_in_1_function = save_count
  80.         _max_save_count = save_count
  81.         _all_save_count = save_count
  82.         for line in self.line_reader:
  83.             if not line:
  84.                 break
  85.             # switch
  86.             if pattern_switch.search(line):
  87.                 _all_save_count = self.parse_switch_def(_save_count_in_1_function)
  88.             
  89.             if pattern_case.search(line):
  90.                 _get_brace_count, _all_save_count = self.parse_case_def(_save_count_in_1_function)
  91.                 _brace_count += _get_brace_count
  92.             
  93.             if _max_save_count < _all_save_count:
  94.                _max_save_count = _all_save_count
  95.             
  96.             # {}
  97.             _brace_count += self._handle_brace(line)
  98.             
  99.             # xx.save(yy)
  100.             #_save_count_in_1_function += self._handle_save(line, _save_count_in_1_function)
  101.             # 定义结束
  102.             if _brace_count == 0:
  103.                 break
  104.         return _max_save_count
  105.    
  106.     def parse_case_def(self, save_count):
  107.         _brace_count = 0
  108.         _save_count_in_1_function = save_count
  109.         for line in self.line_reader:
  110.             if not line:
  111.                 break
  112.             
  113.             # xx.save(yy)
  114.             _save_count_in_1_function += self._handle_save(line, _save_count_in_1_function)
  115.             
  116.             # break
  117.             if pattern_break.search(line):
  118.                 break

  119.             # {}
  120.             _brace_count = self._handle_brace(line)
  121.             if _brace_count == -1:
  122.                 break
  123.         return (_brace_count, _save_count_in_1_function)

  124.     def parse(self, file_list):
  125.         for self.current_file_name in file_list:
  126.             self.line_reader = self._get_line()
  127.             self.current_line_index = 0
  128.             for line in self.line_reader:
  129.                 if not line:
  130.                     break
  131.                 if pattern_func_def.search(line):
  132.                     self.parse_func_def()
  133.         
  134. if __name__ == "__main__":
  135.     file_list = [r'C:\Users\fgl\Desktop\test\to_parse_2.groovy']#, 'to_parse_1.groovy']
  136.     gp = GroovyParser()
  137.     gp.parse(file_list)

  138.         
  139.         
复制代码
to_parse_2.zip (534 Bytes, 下载次数: 1)
   

论坛徽章:
0
6 [报告]
发表于 2013-05-25 23:36 |显示全部楼层
回复 12# abcfy2
1、switch的问题已经解决了,昨天就猜到if应该也要处理。你可以用最新的脚本试试。

2、你的意思是如果是if(xx.save && yy.save())这样的save都不算进去吗?

3、if (xx) {
          xx.save(yyy)
   } else {
         zzz.save(aaa)
   }

这样的怎么计算?
   

论坛徽章:
0
7 [报告]
发表于 2013-05-26 17:29 |显示全部楼层
本帖最后由 GhostFromHeaven 于 2013-05-26 17:34 编辑

回复 14# abcfy2
1、已经可以判断一行有多个save,多个{}

2、if的问题的解决了。
    思路是如果找到save(m个)就判断是否是if语句,如果是if语句就搜索.save()(n个),如果m>n就找到新的需要计数的save,否则不算。
  1. def fuction4 = {
  2.     dosomething
  3.     something.save(abc1).save(dxy)
  4.     something.save(def2)
  5.     if (xx.save() && yy.save())
  6.     {
  7.         xxa.save()
  8.     }
  9.    
  10.     if(xx.save() && yy.save())
  11.     {
  12.         xxa.save()
  13.     }
  14.    
  15.     if(xx.save(xx) && yy.save())
  16.     {
  17.         xxa.save()
  18.     }
  19.    
  20.     if(xx.save(xx) && yy.save(yy))
  21.     {
  22.         xxa.save()
  23.     }
  24. }
复制代码


parse_groovy.zip (22.12 KB, 下载次数: 4)
   

论坛徽章:
0
8 [报告]
发表于 2013-05-27 16:10 |显示全部楼层
本帖最后由 GhostFromHeaven 于 2013-05-27 16:18 编辑

回复 17# abcfy2

1、函数定义的模式匹配要修改一下,\s+要求函数名和{直接必须有空白字符,改成:
pattern_func_def = re.compile('''(?<!\S)def\s+.*?\s*\{\s*''')

pattern_func_def = re.compile('''(?<!\S)def\s+.*?\{\s*''')


2、还有下面这样的语句都删掉:

                if not line:
                    break

论坛徽章:
0
9 [报告]
发表于 2013-05-27 17:00 |显示全部楼层
回复 19# abcfy2

我试了下,没有扫出来。你再确认下。
   

论坛徽章:
0
10 [报告]
发表于 2013-05-27 18:48 |显示全部楼层
本帖最后由 GhostFromHeaven 于 2013-05-27 18:51 编辑

回复 21# abcfy2

1、
pattern_save = re.compile('''\.save\s*\(.*?\)|\.delete\s*\(.*?\)''')  #同时筛选save方法和delete方法

这句有问题,这样的话save和delete的数量就加在一起了。

前面有:rod.delete(),这个计算变为1了,后面的save自然就变为2,就会筛选出来。所以不能加delete。

2、
要想处理用同样的办法处理delete可以再增加处理函数。
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP