我的主要目标是解析python循环,这样我就可以为我的分析插入一些语句。
Normal code:
#A.py
[code Starts]
.
.
.
while [condition]:
[statements]
[statements]
[statements]
.
.
.
[code ends]
检测代码:
Normal code:
#A.py
[code Starts]
.
.
.
count =0 <---------- inserted code
print "Entry of loop" <---------- inserted code
while [condition]:
print "Iteration Number " + count++ <---------- inserted code
[statements]
[statements]
[statements]
print "Exit of loop" <---------- inserted code
.
.
.
[code ends]
我的目标是通过适当的缩进将上述代码插入适当的位置。循环也可以是for循环。要实现上述检测代码,我需要解析A.py文件中的循环并插入这些代码。
有没有一种很好的方法来解析这些循环并得到循环的行号,以便我可以进行检测?
谢谢
答案 0 :(得分:1)
解析通常是一项艰巨的任务。 您可以使用Pygments python库,它是一个语法高亮库。 这似乎与您打算做的不同,但事实并非如此。毕竟,着色代码基本上是将颜色信息添加到代码块中。
使用PythonLexer,您可以为每一行提取标记并添加您想要的任何注释。如果您不想只处理while循环,而且还需要for循环,if语句......
,这将会派上用场答案 1 :(得分:1)
pyparsing
有一个包含完整(?)Python语法分析器的示例文件。从长远来看,这可能是一个有趣的选择 - 尤其是当您的分析项目获得更多功能时
答案 2 :(得分:0)
执行此操作的最简单方法是逐行扫描文件,并在找到匹配的行时添加语句。
以下代码可以满足您的需求,但 非常强大:
def add_info_on_loops(iterable):
in_loop = False
for line in iterable:
if not in_loop:
if line.startswith('for ') or line.startswith('while '):
in_loop = True
yield 'count = 0\n'
yield 'print "Entry of loop"\n'
yield line
yield ' print "Iteration Number:", count'
yield ' count += 1\n'
else:
yield line
else:
if not line.startswith(' '):
in_loop = False
yield 'print "Exit of loop"\n'
yield line
用法:
>>> code = StringIO("""[code Starts]
... .
... .
... .
... while [condition]:
... [statements]
... [statements]
... [statements]
...
... .
... .
... .
... [code ends]""")
>>> print ''.join(add_info_on_loops(code))
[code Starts]
.
.
.
count = 0
print "Entry of loop"
while [condition]:
print "Iteration Number:", count count += 1
[statements]
[statements]
[statements]
print "Exit of loop"
.
.
.
[code ends]
代码的缺陷:
if condition: for x in a: ...
这样的东西无法识别。这可以解决在检查我们是否有循环之前剥离空白行(但是你必须考虑不同级别的缩进等)。for x in a: print x
)。在这种情况下,您将获得错误的输出。轻松修复:
。count
变量很麻烦。你应该在某个地方有一个整数id,并使用count_0
,count_1
之类的变量名,每次找到一个新循环时都会增加id。for(a,b) in x:
未被检测为循环,而for (a,b) in x:
被检测到。这很容易解决。首先,检查行是否以for
和while
开头,下一个字符不能是字母,数字,下划线(实际上在python3中,您也可以使用unicode字符,这会变得更难测试,但可能)。for x in a: indented_last_line_of_code()
退出print
不会被添加。(很容易修复在函数的in_loop
之外添加for
的检查,看看我们是否有这种情况。)正如你所看到的那样,编写一段代码可以完成你所要求的并不是那么简单。
我相信你能做的最好的事情就是使用ast
解析代码,然后访问树并在正确的位置添加节点,然后重新访问代码并生成python源代码(通常节点上有指示源代码中的行,允许您复制粘贴完全相同的代码。)