Разобрать cpp файлы с помощью python, чтобы найти функции, имеющие начало "{" и конец "}" - PullRequest
0 голосов
/ 21 мая 2018

Привет, я новичок в программировании, но немного разбираюсь.Я пытаюсь сделать скрипт Python, который дал файл cpp следующим образом:

///////////////////////////////////
// experimentOrientVertices.cpp
// (modifying square.cpp)
// 
// Sumanta Guha.
///////////////////////////////////

#ifdef __APPLE__
#  include <GL/glew.h>
#  include <GL/freeglut.h>
#  include <OpenGL/glext.h>
#else
#  include <GL/glew.h>
#  include <GL/freeglut.h>
#  include <GL/glext.h>
#pragma comment(lib, "glew32.lib") 
#endif

// Drawing routine.
void drawScene(void)
{
   glClear(GL_COLOR_BUFFER_BIT);

   glColor3f(0.0, 0.0, 0.0);

   // Draw a polygon with specified vertices.
   glPolygonMode(GL_FRONT, GL_LINE);
   glPolygonMode(GL_BACK, GL_FILL);
   glBegin(GL_POLYGON);
      glVertex3f(20.0, 20.0, 0.0);
      glVertex3f(80.0, 20.0, 0.0);
      glVertex3f(80.0, 80.0, 0.0);
      glVertex3f(20.0, 80.0, 0.0);
   glEnd();

   /*
   glPolygonMode(GL_FRONT, GL_LINE);
   glPolygonMode(GL_BACK, GL_FILL);
   glBegin(GL_POLYGON);
      glVertex3f(20.0, 80.0, 0.0);
      glVertex3f(20.0, 20.0, 0.0);
      glVertex3f(80.0, 20.0, 0.0);
      glVertex3f(80.0, 80.0, 0.0);
   glEnd();
   */

   /*
   glPolygonMode(GL_FRONT, GL_LINE);
   glPolygonMode(GL_BACK, GL_FILL);
   glBegin(GL_POLYGON);
      glVertex3f(80.0, 80.0, 0.0);
      glVertex3f(80.0, 20.0, 0.0);
      glVertex3f(20.0, 20.0, 0.0);
      glVertex3f(20.0, 80.0, 0.0);
   glEnd();
   */

   glFlush(); 
}

// Initialization routine.
void setup(void) 
{
   glClearColor(1.0, 1.0, 1.0, 0.0); 
}

// OpenGL window reshape routine.
void resize(int w, int h)
{
   glViewport(0, 0, w, h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.0, 100.0, 0.0, 100.0, -1.0, 1.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
   switch(key) 
   {
      case 27:
         exit(0);
         break;
      default:
         break;
   }
}

// Main routine.
int main(int argc, char **argv) 
{
   glutInit(&argc, argv);

   glutInitContextVersion(4, 3);
   glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);

   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); 
   glutInitWindowSize(500, 500);
   glutInitWindowPosition(100, 100); 
   glutCreateWindow("experimentOrientVertices.cpp");
   glutDisplayFunc(drawScene); 
   glutReshapeFunc(resize);  
   glutKeyboardFunc(keyInput);

   glewExperimental = GL_TRUE;
   glewInit();

   setup(); 

   glutMainLoop(); 
}

Должен вывести это:

[['21=>59']]
[['63=>65']]
[['69=>76']]
[['80=>89'], ['82=>88']]
[['93=>113']]

И вот проблема, скрипт ниже выдает это:

[['21=>59']]
[['63=>65'], ['65=>63']]
[['69=>76'], ['76=>69']]
[['80=>89'], ['82=>88'], ['88=>82'], ['89=>80']]
[['93=>113'], ['113=>93']]

И .. на самом деле, я не могу понять, как спасибо. Спасибо за потраченное время, надеюсь, что вы хорошо ответили на вопрос!

Вот мой сценарий:

from sys import argv

token = {
        '{': 0
        }
level = ["" for i in range(10)]

funcStartStop = [] #list to store each function start and stop brackets value

def functionCount(filename):
    inFile = open(filename, 'r')
    currLine = 0
    mbracketopenline = [] #list to store the currLine value if a { is found
    mbracketcloseline = [] #list to store the currLine value if a } is found
    first = True
    for line in inFile:
        currLine += 1
        if "{" in line:
            token["{"] += 1
            if first:
                first = False
            mbracketopenline.append(currLine)
        if "}" in line:
            token["{"] -= 1
            mbracketcloseline.append(currLine)
        if not first and token["{"] == 0:
            first = True
            tmpfuncStartStop = []
            for i in range(mgraffeopenline.__len__()):
                tmpfuncStartStop.append([str(str(mbracketopenline[i])+"=>"+str(mbracketcloseline[-i-1]))]) #store opening and
                                                                        #closing brackets in a list of list, so at the end of the cycle
                                                                        #should be something like: [['1=>10'],['3=>8']]
            funcStartStop.append(tmpfuncStartStop)
            mbracketcloseline = mbracketopenline = []

if __name__ == '__main__':
    functionCount(argv[1])
    for i in funcStartStop:
        print(i)

1 Ответ

0 голосов
/ 22 мая 2018

Игнорирование ошибок кода, допущенных при адаптации вашего примера для 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, предназначенный именно для этого.Это может занять немного больше времени для установки, но это даст вам гораздо больше информации о коде, чем такой анализ.Конечно, все зависит от вашего фактического варианта использования ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...