Как извлечь начальные номера строк, связанные с определениями функций программы на C, написав анализатор на python? - PullRequest
0 голосов
/ 11 октября 2019

Я пытаюсь написать скрипт на Python для извлечения номеров начальных строк определений функций C-программы. Я использовал библиотеку синтаксического анализа C в Python, называемую «Pyclibrary», и использовал ее для извлечения имен функций из моего C-файла. Затем я помещаю эти имена в список, перебираю его, ищу номера строк, где они были найдены, и удаляю дубликаты, сохраняя только первый экземпляр поиска. Но это не работает в тех случаях, когда первый экземпляр не является определением функции. Мне нужно уточнить мою логику для того же. Любые выводы будут оценены.

Вот мой код:

from pyclibrary import CParser
from pyclibrary import CLibrary
import pandas as pd

parser = CParser(['path/to/c/file/sample.c'])


my_list = []
list_of_func = []
d1 = []
d2 = []
d3 = []
func1 = parser.defs['functions']
inside_function = 0
left_brack_num = 0

for i in func1:
    my_list.append(str(i))

with open('path/to/c/file/sample.c') as myFile:
    for num, line in enumerate(myFile, 1):
        for i in range(len(my_list)):
            if my_list[i] in line:
                list_of_func.append([my_list[i], num]) 
                d1.append(my_list[i])
                d2.append(num)
                inside_function = 1

            if inside_function == 1:
                left_brack_num += line.count("{")
                if "}" in line:
                    left_brack_num -= line.count("}")
                    if left_brack_num == 0:
                        d3.append(num)
                        inside_function = 0

Data ={'Function Name': d1, 'Starting Line number': d2}
df2d = pd.DataFrame(Data)
df2d.drop_duplicates(subset = 'Function Name', 
                     keep = 'first', inplace = True) 
snd = pd.Series(list_of_func)

print(df2d) 

1 Ответ

1 голос
/ 11 октября 2019

Парсинг AC-файла вручную, как правило, плохая идея, есть много угловых случаев, и вы в конечном итоге заново изобретаете колесо.

Если вы можете скомпилировать файл с отладочными символами, вы можете легко найти ваши символыwith:

nm -l ./foo --defined-only| grep :

Где:

  • nm Перечисляет символы, определенные в двоичном файле
  • -l Записывает номер файла и строки, гдесимвол определен
  • grep сохраняет только пользовательские символы.

Например, если я попробую с этим файлом:

int a;
int f1(){}
int f2(){}
int main(){}

Скомпилировано с gcc -o foo foo.c -g, Я получаю следующие символы:

000000000000402c B a    /home/user/foo.c:1
0000000000001125 T f1   /home/user/foo.c:2
000000000000112c T f2   /home/user/foo.c:3
0000000000001133 T main /home/user/foo.c:4

Обратите внимание, что я получаю как функцию, так и глобальные переменные. Если вам нужны только функции, вы можете отфильтровать их, используя 2-е поле, и оставить их только с T значением


Если вы действительно хотите запустить из своего файла C, выВозможно, вы захотите использовать cscope ( см. этот пост ).

...