免费注册 查看新帖 |

Chinaunix

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

请教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 22:10 |只看该作者
回复 2# GhostFromHeaven


    太牛了,这正是我想要的结果。
再稍稍改进下就可以变成grep -n的那种结果了,也就是文件名:行号:行内容

论坛徽章:
0
3 [报告]
发表于 2013-05-23 22:14 |只看该作者
回复 2# GhostFromHeaven


    这样写能判定函数嵌套吗?
比如函数体这样定义的
def fuction1 = {
    something1
    something2
    def function = {
        something1
        something2
        something.save(test)
    }
    something.save(test)
}

论坛徽章:
0
4 [报告]
发表于 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
5 [报告]
发表于 2013-05-24 09:48 |只看该作者
回复 5# GhostFromHeaven


    非常感谢,很有参考价值,最近才粗略的把python的基础看完,还没有一些实践课题,所以应用上有些困难,感谢提供这么有价值的参考代码

论坛徽章:
0
6 [报告]
发表于 2013-05-24 13:26 |只看该作者
回复 5# GhostFromHeaven


    发现有些代码中有switch-case语句,这样怎么判定呢?
switch(para) {
    case para1:
        something
        save(sth.)
        break
    case para2:
        something
        save(sth.)
        break
    default:
        something
        save(sth.)
}

论坛徽章:
0
7 [报告]
发表于 2013-05-24 14:18 |只看该作者
本帖最后由 GhostFromHeaven 于 2013-05-24 14:22 编辑

回复 7# abcfy2

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

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

论坛徽章:
0
8 [报告]
发表于 2013-05-24 15:12 |只看该作者
回复 8# GhostFromHeaven


    调用的时候肯定是xxx.save的,这个样例只是一个例子。实际代码如下:
switch (params.codeType){
                        case 'SJLX':
                                systemCodeInstance = new DataType(params)
                                result=systemCodeInstance.save(flush: true)                               
                                break
                        case 'SSY':
                                systemCodeInstance = new BelongDomain(params)
                                result=systemCodeInstance.save(flush: true)
                                break
                        case 'WLSX':
                                systemCodeInstance = new PhysicalProperty(params)
                                result=systemCodeInstance.save(flush: true)
                                break
                        case 'ItemDW':
                                systemCodeInstance = new ItemUnit(params)
                                systemCodeInstance.codeNum=PhysicalProperty.get(params.physicalProperty).codeName+'-'+params.codeName
                                result=systemCodeInstance.save(flush: true)
                                break
                        default:
                                systemCodeInstance = new BaudRate(params)
                                result=systemCodeInstance.save(flush: true)
                                break
                       
                }
需求上这几个save是不应该算进去的,每一条case语句中只有一个save方法,满足条件,不应该被筛选出来。
我是说这样的话正则应该怎么写呢?应该家进去一条语句判定

论坛徽章:
0
9 [报告]
发表于 2013-05-24 20:42 |只看该作者
回复 9# abcfy2

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

   

论坛徽章:
0
10 [报告]
发表于 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)
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP