1

次のような関数呼び出しに一致する正規表現をまとめるのに苦労しています:

funcname (...(..
    ...)..(..(...
    )...)..)

そのため、関数は、複数の括弧で囲まれた複数のパラメーターを複数の行にまたがることができます。

ドットは、「(」または「)」以外の任意のものにすることができます。

sed または grep で正規表現を使用します。

ありがとう、リスト

4

2 に答える 2

0

そこで、この単純なパーサーを bash で書き続けました。完璧ではありませんが、出発点として役立ちます。たとえば、関数呼び出しがコメントアウトされているかどうかなどを区別できません。

while read file; do
    linenum=0
    while IFS= read -r line; do
        (( linenum++ ))
        if [ $fmatch -eq 0 ]; then
            if [[ ! $line =~ $funcname ]]; then
                continue
            fi
            linenummatch=$linenum
            fmatch=1
            fstripped=0
            openbracket=0
            closebracket=0
            spacenum=0
        fi

        linelen=${#line}
        position=0
        while [ $position -lt $linelen ]; do
            if [ $fstripped -eq 0 ]; then
                subline=${line:$position}
                mlen=`expr "$subline" : "$funcname"`
                if [ $mlen -gt 0 ]; then
                    (( position+=mlen ))
                    resultstr=$funcname
                    fstripped=1
                    continue
                fi
                (( position++ ))
                continue
            fi
            ch=${line:$position:1}

            case $ch in
                '(' )
                    (( openbracket++ ))
                    spacenum=0
                    newresultstr="$resultstr$ch"
                    ;;

                ')' )
                    if [ $openbracket -eq 0 ]; then
                        fmatch=0
                        break
                    fi
                    (( closebracket++ ))
                    spacenum=0
                    newresultstr="$resultstr$ch"
                    if [ $closebracket -eq $openbracket ]; then
                        echo "$file $linenummatch $newresultstr"
                        fmatch=0
                        break
                    fi
                    ;;

                ' ' | '\t' )
                    if [ $spacenum -eq 0 ]; then
                        newresultstr=$resultstr' '
                    fi
                    (( spacenum++ ))
                    ;;

                '\n' )
                    # line feeds are skipped
                    ;;
                * )
                    if [ $openbracket -eq 0 ]; then
                        fmatch=0
                        break
                    fi
                    spacenum=0
                    newresultstr="$resultstr$ch"
                    ;;
            esac
            resultstr=$newresultstr
            (( position++ ))
        done
    done < $file
done < $filelist
于 2012-08-06T15:46:16.060 に答える
0

C は不規則な言語であるため、そのためのパーサーが必要になる場合があります。あなたが抱えている問題は、すべての開き括弧が再び閉じられたときにうまくいくことです. C ではかなり奇妙なことができます。たとえば、それ自体が関数定義であるパラメーターを持つことができます。たとえば、次のプログラムで、a()、b()、c()、d()、e()、f()、および g() をどのように区別するかを考えてみましょう。

#include <stdio.h>

#define f(c) c;

char a()
{
    return f('z');
}

/*
A function in a comment.
char b()
{
    return 'y';
}
*/

char c(char d()) 
{
    return d(); 
}

#if 0
This code is not included
char g()
{
    return 'v';
}
#endif

void main()
{
    printf ("A function in a string: char e() { return 'x'; }\n");
    printf ("The result from passing a to c: %c\n", c(a));
    printf ("Press enter to exit");
    getchar();
}

正規表現でこの種のことをしようとする多くの試みを見てきましたが、それらのほとんどは壊滅的なバックトラッキングの問題に終わります。

于 2012-08-03T12:24:11.343 に答える