我正在编写一个小的python脚本,它从dir中的几个.c文件中读取参数及其值。参数通常采用以下格式:
uint8 param1 = 1;
sint8 param2 = 2;
但是,有时它们看起来像这样:
param3 = {
1, 2, 3,
4, 5, 6
};
甚至:
param4 = {
1, 2, 3,
{
4, 5, 6
},
};
正如您怀疑在涉及param3 and param4
的情况下,该行将为param3 = {
并且param4
相同,因此不包含任何实际值。我想我会在通过搜索" {"来调用价值获取方法之前解决它。在一行中,如果找到了,那么通过找到&#34 ;;"的下一次迭代,找到它以某种方式结束。在包含" {"并且应该删除任何换行符,制表符和空格。
这是我希望方法在正确运行时显示的输出。
param3 = {1,2,3,4,5,6};
param4 = {1,2,3,{4,5,6},};
这是我正在使用的布局,formatFile(line)
是我需要帮助的方法。
for root, dirs, files in os.walk(PATH_DST_SOURCE):
for file in files:
if file.endswith('.c'):
with open(os.path.join(root, file), 'r') as this:
for line in this:
formatFile(line)
不幸的是,我不知道如何做到这一点,并希望得到一些帮助,甚至可以在正确的方向上轻推。当然,如果有更好的方法来解决我的问题,那么也欢迎这些!
答案 0 :(得分:3)
你可以尝试一种简单的方法(诚然不是逐行阅读):
with open(os.path.join(root, file), 'r') as this:
content = this.read().replace('\n', '') # whole file in one line
content = content.replace(';', ';\n') # add linebreak after each ';'
lines = content.split('\n') # now each line contains one parameter assignment
答案 1 :(得分:1)
提出一个完全不同的解决方案......只需稍加考虑一下......
将C文件解析为字符串通常是一项非常繁琐的工作,非常容易出错。您可以尝试使用一些正则表达式,但通常您会发现自己说:
如果你想构建一些健壮的东西,不要自己解析代码......尝试找到适合你的东西。 我会尝试做的例如是你的C文件的Swig接口,然后直接访问变量。
一般文档:http://www.swig.org/Doc1.3/Python.html
访问全球变量:http://www.swig.org/Doc1.3/Python.html#Python_nn16
如果您可以使用此解决方案,您唯一需要做的就是编写几行小接口文件,将其作为Swig软件的输入,这将为您生成一个包装C文件的python模块。
修改强>
这就是你在案件中可以做的事情:
1.安装Swig 2.创建一个文件myInterface.i,如下所示:
/* File: myInterface.i */
%include "stdint.i"
%{
#include "file.h"
%}
extern uint8 param1;
extern uint8 param2;
运行命令swig -python myInterface.i
这将为您生成头文件的python包装器。
在Python脚本中导入此文件,并直接从头文件中访问变量。
我不记得该怎么做数组,但他们肯定也可以访问!
答案 2 :(得分:1)
您可以这样尝试:拥有一个语句列表和一个包含当前语句的字符串;添加到当前语句,直到它以;
结尾,然后将其添加到语句列表中。
with open("file.c") as f:
statements = []
cur = ""
for line in f:
cur += line.strip()
if cur.endswith(";"):
statements.append(cur)
cur = ""
当然,这假设每个语句结尾;
实际上都在行的末尾,而不是,例如然后是行注释,或(部分)另一个语句。如果你还想解决这些问题,事情变得更加复杂(在行或块注释中或类似字符串中的类似语句的代码),你应该寻找一些现有的解析器库。
答案 3 :(得分:0)
使用正则表达式:
import re
pattern = r'((?P<type>\w+)\s+)?(?P<name>\w+)\s*=\s*(?P<value>.+?);'
with open("example.c") as cfile:
assignments = []
for m in re.finditer(pattern, cfile, re.DOTALL):
dic = m.groupdict()
dic["value"] = dic["value"].replace("\n", " ")
assignments.append(dic)
print assignments
从此代码中,您将获得一个字典列表,其中包含键"type"
(已分配变量的数据类型),"name"
(已分配变量名称)和"value"
(无论是否已分配)。每个字典代表一个任务。
输出为此(为清晰起见,手动添加换行符):
[{'type': 'uint8', 'name': 'param1', 'value': '1'},
{'type': 'sint8', 'name': 'param2', 'value': '2'},
{'type': None, 'name': 'param3', 'value': '{ 1, 2, 3, 4, 5, 6 }'},
{'type': None, 'name': 'param4', 'value': '{ 1, 2, 3, { 4, 5, 6 }, }'}]
...对于此输入文件:
uint8 param1 = 1;
sint8 param2 = 2;
param3 = {
1, 2, 3,
4, 5, 6
};
param4 = {
1, 2, 3,
{
4, 5, 6
},
};