Игнорирование ошибок кода, допущенных при адаптации вашего примера для SO (например, mgraffeopenline
вместо mbracketopenline
, functionCount()
не возвращая результат и т. Д.), В какой-то момент у вас есть:
mbracketcloseline = mbracketopenline = []
Эффективно устанавливая mbracketcloseline
и mbracketopenline
в один и тот же новый список, и каждый раз, когда вы изменяете каждый из них, вы изменяете один и тот же список.Это, прежде всего, и является причиной вашей проблемы, но есть и другие, которые следует учитывать.
Кроме того, как я уже говорил в своем комментарии, наличие нескольких фигурных скобок в одной строке вполне допустимо, и вы должны учитывать их (включаяих позиции) так что вам на самом деле нужно пройти код вашего символа за символом и подобрать каждое вхождение, что-то вроде:
def function_count(source):
result = []
progress = [] # a temporary list to keep our progress
level = -1 # we'll use an index to reference the level we're at
with open(source, "r") as f: # open the `source` file for reading
for i, line in enumerate(f): # enumerate and read the file line by line
# you can check `if "{" in line or "}" in line: ...` for a marginal speed-up
for char in line: # iterate over the characters in each line
if char == "{":
if level == -1: # we're at the root, start a root level
progress = []
result.append(progress)
progress.append([i + 1, None]) # store the line # at the level's start
level += 1 # increase the level
elif char == "}":
if level > -1: # if we're already deep in the source tree...
progress[level][1] = i + 1 # store the line # at the level's end
level -= 1 # decrease the level
return result
Что для вашего файла выдает:
[[[21, 59]],
[[63, 65]],
[[69, 76]],
[[80, 89], [82, 88]],
[[93, 113]]]
Но еслиВы должны были изменить функцию keyInput
на:
void keyInput(unsigned char key, int x, int y)
{ switch(key) {
case 27:
exit(0);
break;
default:
break;
}}
Она все равно даст действительный результат:
[[[21, 59]],
[[63, 65]],
[[69, 76]],
[[80, 86], [80, 86]],
[[90, 110]]]
И если вы хотите, чтобы она была напечатана, как в вашем примере (я нахожуразделить фактические индексы строк гораздо полезнее) просто замените строку:
progress[level][1] = i + 1 # store the line # at the level's end
на:
progress[level] = "{}=>{}".format(progress[level][0], i + 1)
Однако это не решает проблему zvone
упомянуто, где вы можете иметь фигурные скобки в комментариях, макросах, строках ... и все они будут считаться допустимыми началом / концом функций.Синтаксический анализатор кода гораздо больше, чем простое сопоставление символов.
Если вы действительно хотите углубиться в анализ кода C, есть очень полезный модуль pycparser
, предназначенный именно для этого.Это может занять немного больше времени для установки, но это даст вам гораздо больше информации о коде, чем такой анализ.Конечно, все зависит от вашего фактического варианта использования ...