2012-12-04 66 views
1

我使用Flex在代碼源更換號碼的表達:更換號碼的表達與柔性

例如:

Input string: ... echo "test"; if ($isReady) $variable = 2 * 5; ... 
Desired result string: ... echo "test"; if ($isReady) $variable = 10; ... 

我的代碼:

%{ 
#include <stdio.h> 
#include <stdlib.h> 
%} 

MYEXP [0-9]+[ \t\n\r]*\+[ \t\n\r]*[0-9]+ 

%% 

{MYEXP} { 
    printf("multiplication "); 
    // code for processing 
} 

%% 


void main() 
{ 
    yylex(); 
} 

我如何處理乘法使用Flex ?或者我必須用C語言來處理?

+0

(1)MYEXP匹配加法表達式(+),而不是乘法(*)。 (2)你可以把你匹配的表達式中的兩個數字與一些C代碼(你有printf的地方)分開並執行算術。 –

+0

是的,我的錯誤:)我發現與GNU Flex匹配的子字符串,他與我乘以C.謝謝你 – grogsy

回答

1

一些答案在評論中,但問題還沒有在兩年內得到答案。爲了完成這個目的,我想一些筆記會對那些將來會想到這樣的事情的人有用。

簡單的算術表達式,在問題中例舉的形式可以通過類似flex的工具來識別,該工具使用FSA(Finite State Automaton或FSM Finite State Machine)匹配正則表達式。這適用於語法簡單id + id,但在表達式變得更復雜時失敗。 id + id * id中的運算符優先級的處理和類似於((id + id) * (id + id))的嵌套括號意味着常規語法不能再工作。這需要一個上下文無關語法。 (計算機科學的學生應該從喬姆斯基語言理論中瞭解這一點)。所以只能在flex中對最簡單的表達形式進行操作。

的更換簡單的表達式,其中只含有常數,是稱爲常量摺疊的優化,並且通過大多數編譯器作爲標準進行。將此作爲大多數代碼的預處理形式執行不會產生任何改進。因此,當提議編寫工具來完成這樣的工作時,你必須反思它是否必要!

現在回到問題的實際細節,這些細節已經在評論中找到;是的,每個運營商都需要一個規則,加法和乘法;當匹配一個子字符串將需要拿起操作數。它會是這個樣子:

MYplusEXP [0-9]+[ \t\n\r]*\+[ \t\n\r]*[0-9]+ 
MYmultEXP [0-9]+[ \t\n\r]*\*[ \t\n\r]*[0-9]+ 

%% 
      char [20] left; char * right; 
{MYplusEXP} {right = strstr(yytext,"+"); /* yytext is already terminated with \0 */ 
      strncopy(left,yytext,right-yytext+1);   
      printf("%d",atoi(left)+atoi(right)); 
      } 
{MYmultEXP} {right = strstr(yytext,"*"); 
      strncopy(left,yytext,right-yytext+1);   
      printf("%d",atoi(left)*atoi(right)); 
      } 

但是我覺得有點髒這樣做指針運算

總之後,它可能會更好地與其他工具進行或者根本沒有!