我猜想該調用的第一個參數是總是一個十六進制數字,不必檢查或轉換。我也推測參數2和3始終與0xFF進行AND運算。最後,我推測被調用的函數和被移位的參數都是簡單的字 - 即匹配\w+
。有了這些假設,以下似乎就是你想做的事情;
use v5.12;
while (<>) {
chomp ;
if (/^(\w+) \( .* \) \s* ; $ /x) {
my $call = $1 ; # function name being called
s/^\w+ \(//x ; # Strip off fn call and open paren
s/ \) \s* ; \s* $ //x ; # Strip off close paren and semicolon
my ($arg1 , $arg2 , $arg3) = split ',' ; # split into arguements of the call
my $new_args = join("," , $arg1 , transform($arg2) , transform($arg3)) ;
say "$call($new_args);" ;
}
else {
say $_ ;
}
}
sub transform {
$_ = shift ;
my $replacement ;
s/^\s* \(//x; # Strip off opening paren
s/ \) \s* $ //x; # Strip off closing paren
s/ & 0xFF $ //x ; # Strip off ANDing all ones
if (/^ \w+ $/x) { # Simple var name left?
$replacement = "BYTE0(" . $_ . ")" ;
}
elsif (/^\((\w+) >> (\d+) \) $ /x) { # var name shifted some number of bits
my $var_name = $1 ;
my $shift_size = $2 ;
my $byte_num = $shift_size/8 ;
$replacement = "BYTE" . $byte_num . "(" . $var_name . ")" ;
}
else {
warn "Dont understand '$_' on line $.\n";
$replacement = $_ ;
}
return $replacement
}
它的unix過濾器風格 - STDIN上的輸入,STDOUT上的轉換輸出。當我餵它時,這構成了數據;
hello
Send(0x39,((rLoss>>8)&0xFF),(rLoss&0xFF));
world
Receive(0x12,(rWin&0xFF),((rWin>>16)&0xFF));
bye
它吐出來
hello
Send(0x39,BYTE1(rLoss),BYTE0(rLoss));
world
Receive(0x12,BYTE0(rWin),BYTE2(rWin));
bye
希望內嵌註釋說明了代碼。關於是否嘗試轉變線條或單獨放置線條的決定完全基於第一個正則表達式 - 一個字(fn調用),然後是括號中的內容 - 這可能是也可能不是您想要的。也許你知道,它始終呼籲「發送」,在這種情況下,你可以把它放在正則表達式中。
您可能不熟悉的唯一的其他事情是整數除法運算符'/'。這用於翻譯被移位到BYTE num宏調用的位數。
尋求調試幫助的問題(「**爲什麼不是這個代碼工作?」)必須包含所需的行爲,特定的問題或錯誤*和最短的代碼*來重現它**自問**。沒有**明確問題陳述**的問題對其他讀者沒有用處。請參閱:如何創建[mcve]。 –
你在說什麼?這不是Perl代碼。我看起來像C.你想用Perl轉換這些數據嗎? – simbabque
Upvoter ...請解釋 – toolic