2012-03-26 20 views
2

如果我在c或C++中使用字符串(c樣式或其他方式)的x + y-12/z算術表達式,如何在a中提取一個項目時間(包括運營商)?表達式中可能有也可能沒有空格,常數允許有多個數字。在c/C++中提取算術表達式中的項目

+1

C或C++ - 這是它嗎? – 2012-03-26 21:02:50

回答

3

如果你的輸入很簡單,你可以像這樣開始:

typedef struct token { 
    int type; 
    int ival; 
    char sval[256]; 
    int ssize; 
} Token; 

char *get_next_tok(char *buffer, Token *token) { 
    char *p = buffer; while (isspace(*p)) p++; // trim 
    if (my_isopchar(*p))  // checks -+*... 
    p=my_get_op(p, token); // a function to handle multi-char ops 
    else if (isdigit(*p)) { 
    token->ival=strtol(p, &p, 10); 
    token->type=TK_CONST; 
    } 
    else if (isalpha(*p)) { 
    while (isalpha(*p)) { 
    token->sval[token->ssize++] = *p; p++; 
    } 
    token->type = TK_VAR; 
    } 
    return p; 
} 
+0

什麼'while(isspace(* p))p ++;'做到了嗎? – Jack 2012-03-26 17:29:20

+0

它跳過空格(製表符,空格,換行符) – perreal 2012-03-26 17:30:19

+0

嗡嗡聲對我不起作用。也許是因爲如果myinput是'foo baa',它不會刪除任何:標籤,空格或換行符。當在while循環中測試這個條件'isspace(* p)'時,它會返回false,因爲第一個字符不是空格,所以字符串循環沒有完成。然後,而不是它,你可以寫:'char * buffer =「ba a kkk k k $ \ 0」; \t char * newbuf = malloc(strlen(buffer)+ 1); \t assert(NULL!= newbuf); \t char * p = buffer; \t char * ns = newbuf; \t \t 而(* P){ \t \t如果{ \t \t \t * NS ++ = *的p ++(isspace爲(* P)!); \t \t} \t \t p ++; \t} \t * ns ++ ='\ 0'; \t printf(「%s」,newbuf);' – Jack 2012-03-26 17:57:46

0

調查parsing。實際上,您所描述的內容可以使用正則表達式或手寫解析來輕鬆實現。想想你的表達的個體標記是什麼,以及代碼如何提取下一個標記。

1

簡單的方法:strtok

硬的方式:Flex+Bison

+2

非常困難的方式:[Boost.Spirit](http://www.boost.org/libs/spirit/) – ipc 2012-03-26 14:54:35

0

有一個非常好的tutorial on Flipcode on implementing scripting engines。你可以閱讀一些第一章。

基本上,您需要實現一個詞法分析器,將字符串分解爲令牌(標識符/常量/運算符)和令牌,您可以創建例如parse treereverse Polish notation通過recursive descent或使用LL parser這是相當優雅,如果你只是在解析算術表達式感興趣。

然後使用基於堆棧的解釋器評估反向波蘭語表示法,或者使用遞歸算法評估分析樹。

我用C++寫了一個小的expression evaluation class,它支持帶變量的簡單表達式。