Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Парсер кода программы на Perl


Автор: Octane 27.12.2007, 00:35
Здравствуйте.

При написание несложного парсера програмного кода C++ застрял на проверке правильности вызова функции по ее прототипу (зачем мне это нужно? не знаю smile задание такое), может кто подскажет идею как это сделать или пример какой приведет. Что то слышал что можно формировать динамически регулярные выражения и это как то можно использовать в моей ситуации, но никакой вразумительной информации по этой теме не получается найти...

Допустим есть код программы например на языке C++,
есть прототип функции int f1(int a, int b);
В коде программы вызываем функцию, например так: printf("%d",f1(5,7)); или c=f1(x,y); необходимо проверить правильность вызова этой функции по ее прототипу, т.е. найти функцию, найти соответствующий прототип и посчитать количество отправляемых в функцию параметров и по возможности соответствие типу (ограниченному количество, там например int, float, char)

Помогите пожалуйста разобраться с такой задачей)

Автор: KSURi 27.12.2007, 03:11
Организовать сбор и парсинг прототипов можно так: (писал прямо в форум, но должно работать)
Код

my %funcs;
foreach(split("\n", <DATA>)) # в __DATA__ - исходный Си код
{
    /(?:int|float|bool(?#void,etc.))\s*(\w+)\s*\((.+?)\);$/ || next; # цепляем прототипы ф-ий
    my($name, $params) = ($1, $2);
    foreach(split(/\s*,\s*/, $params)) # парсим параметры ф-ии
    {
        my($type, $var) = split /\s+/;
        push(@{$funcs{$name}{$type}}, $var);
    }
}

Над проверкой уже лень думать, но имхо сложно быть не должно... Завтречка, в смысле уже сегодня, может накидаю)

Автор: Octane 28.12.2007, 01:50
Спасибо) 
Вот что получилось  smile :
Код

open(FILE, "code.cpp") or die("Can't open file: $!");
print "~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
@s = <FILE>;
foreach (@s){
    /(?:void|int|float|char)\s+?(\w+)\(\s*(.*?)\s*\)\s*;/ || next;
    ($fname, $fparams) = ($1, $2);
    print " prototype: <$fname>";
    @s1 = split(/,/,$fparams);
    $i = 0;
    foreach (@s1) {
        /(\w+)\s+?(\w+)/ || next;
        ($type, $var) = ($1, $2);
        print "\n - var: $var, type: $type;";
        $i++;
    }
    $p{$fname} = $i;
    print "\n\n";
}
print "~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
foreach (@s){
    /\s*(\w+|\d*)\s{1}\(\s*(.*?)\s*\)\s*/ || next;
    ($fname, $fparams) = ($1, $2);
    print " function: <$fname>";
    @s1 = split(/,/, $fparams);
    $i = 0;
    foreach (@s1) {
        /\s*(\w+|\d*)/ || next;
        $var = $1;
        print "\n - var: $var;";
        $i++;
    }
    $f{$fname} = $i;
    print "\n\n";
}
print "~~~~~~~~~~~~~~~~~~~~~~~~~~";
foreach $k (keys %p) {
    if ($p{$k} == $f{$k}) {
        print "\n $k: Ok";
    }
    else {
        print "\n $k: error";
    }
}
close (FILE);


Код

#include<stdio.h>
#include<iostream.h>

int f1(int a, int b, int c);

float f2(float x, float y);

void f3(char cc);

int main(void) {

 int d;

 float z;

 char s = 'x';

 d = f1 (8, 12, 457);

 z = f2 (5.25, 3.75)

 f3 (s, v);

 return 1;

}

int f1(int a, int b, int c) {
return a+b+c;
}

float f2(float x, float y) {
return x*y;
}

void f3(char cc) {
cout>>cc;
}


Помогите довести до ума плиз))) 

и еще есть одна проблема, когда мы ищем функцию в коде программы то   повторно находим и прототипы, избавился от этого только добавлением пробела между именем функции и открывающей скобочкой, надо как то исправить, чтобы везде работало  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)