2015-01-17 2 views
1

다음 코드는 define.c 파일을 한 줄씩 읽고 모든 "#define" 지시문을 해시에 저장합니다 (이름과 대체 텍스트를 정의 함). 그런 다음 사용법이 연속 된 행에서 발견되면이를 대체합니다.Perl 대체 : 변수를 사용할 수 없습니다. perl regex

"#define" 지시어를 사용하는 경우 대체에 문제가 있습니다. #defines을 해시에 올바르게 저장하고 있습니다.

나는 perl과 regex의 초보자이며 어째서 작동하지 않는지 바보 같은 것을 지적 할 수 없다.
도움이 필요하십니까?

#include <stdio.h> 

#define VALUE 10 
#define PLACE (20 + 0) 
#define NUM (VALUE + 10) 
int main() 
{ 
    int num; 
    num = NUM + 25 + NUM + PLACE; 
    return 0; 
} 

Expected Output: **defines.i**

#include <stdio.h> 

#define VALUE 10 
#define PLACE (20 + 0) 
#define NUM (VALUE + 10) 
int main() 
{ 
    int num; 
    num = (10 + 10) + 25 + (10 + 10) + (20 + 0); 
    // or 
    num = (VALUE + 10) + 25 + (VALUE + 10) + (20 + 0); 
    return 0; 
} 

#!/usr/bin/perl -w 

use strict; 
my %definesHash; 

open(FILE, "defines.c") || die "Cannot open $!\n"; 
open(OUT, ">defines.i") || die "Cannot open $!\n"; 


while (<FILE>) 
{ 
my $line = $_; 
if ($line =~ /#define\s+/) 
{ 
    $line =~ s/#define\s+//g; 
    if ($line =~ /\b([\w]+)\b\s+/) 
    { 
    my $define = $1; 
    $line =~ s/\b[\w]+\b\s+//; 
    $definesHash{$define} = ""; 
    if($line =~ /\s*(.*)\s*/) 
    { 
     $definesHash{$define} = $1; 
    } 
    } 
    print OUT $_; 
} 
else 
{ 
    my($def, $replace); 
    while (($def, $replace) = each(%definesHash)) 
    { 
    print " $def => $replace \n"; 
    if ($line =~ /$def/) 
    { 
     $line =~ s/$def/$replace/g; #****** Some Problem Here, But What? ******** 
    } 
    } 
    print OUT $line; 
} 
} 

close(FILE); 
close(OUT); 

defines.c은 내가 코멘트에 지적으로 문제가 대체에 알고있다. 해시의 내용이 올바른 것 같지만 대체 후에는 원래 줄이 횡설수설하는 것을 볼 수 있습니다.
변수를 대체하여 사용합니까?

+0

예제 및 예상 결과를 제공 할 수 있습니까? – Sobrique

+0

스크립트가 제대로 작동합니다. 나는 예상 한 결과를 얻는다. – Toto

+0

프로그램이 예상 출력을 제공하고 정상적으로 작동합니다. 문제가있는 곳? 예상 결과를 얻을 수 없습니까? – Praveen

답변

1

스크립트가 해시의 순서 (오히려 장애)에 따라 달라집니다. 그 교체는 else에서 발생하기 때문에

#define VALUE 10 
#define NUM (VALUE + 10) 

정의

는 업데이트되지 않습니다 - 그래서 교체는 #define없이 라인에 발생합니다.

그러나, 당신은 each 당신을 제공합니다 어떤 순서에 따라 교체를 수행 - 그래서 NUM를 교체하려고 VALUE다음을 대체하려고 할 수있다. 그들은이 같은 와서

은 아마 각 정의에서 초기 교체를 수행 할 것 :

#!/usr/bin/perl 

use warnings; 
use strict; 
my %definesHash; 

open(my $fh_in, '<', "defines.c") || die "Cannot open $!\n"; 
open(my $fh_out, '>', "defines.i") || die "Cannot open $!\n"; 

while (<$fh_in>) { 
    if (/^#define\s+(\w+)\s+(.*)\s*$/) { 
     my ($define, $replacement) = ($1, $2); 
     # perform existing replacements on 
     # the current $replacement 
     while (my ($def, $replace) = each %definesHash) { 
      $replacement =~ s/$def/\Q$replace/g; 
     } 
     $definesHash{$define} = $replacement; 
    } 
    else { 
     while (my ($def, $replace) = each(%definesHash)) { 
      print " $def => $replace \n"; 
      s/$def/$replace/g; 
     } 
    } 

    print $fh_out $_; 
} 

close($fh_in); 
close($fh_out); 

을 아니면 여기 \Q로 이스케이프 이스케이프 정규식 메타 문자, 수 있습니다.

+0

나는 해쉬의 순서를 알 수 없다는 것을 알았다. 이것은 예상 출력을 완전히 생성하지 않습니다. 나는 이것을 고칠 수 있었다. BTW 컴팩트 코드 주셔서 감사합니다. – user3144089

+0

무엇이 문제가 되었습니까? –

+0

나는 질문 아래의 주석에 넣었다. 참조하십시오. 제 생각에는이 질문이 마음에 안 들면 이것을 삭제하고 싶습니다. – user3144089