2012-11-18 46 views
1

只是爲了給您提供背景知識。我們有一個學校項目,我們需要用C編寫我們自己的編譯器。我的任務是編寫一個詞法分析。到目前爲止這麼好,但我在轉義序列方面遇到了一些困難。如何將轉義字符串轉換爲C中的一個字符

當我找到一個轉義序列和轉義序列是正確的,我把它保存在一個看起來像這樣的字符串,否則它是詞法錯誤。

我的問題是如何將只包含轉義序列的字符串轉換爲一個字符?所以我可以將它添加到包含字符串其餘部分的「緩衝區」中。

我對一個只包含轉義序列的大型表有了一個想法,然後逐一比較它,但它看起來並不優雅。

+0

你的意思是像''\ n''轉義序列,' '\ t''等?或者像''\ x9''這樣的數字一位數序列? –

+0

我有'\ n''\''\ t'和'\''的解決方案。我遇到了像剛剛寫的那樣的轉義序列問題。 – rojcyk

回答

2

你可以使用下面的代碼,用你的字符串調用xString2char。

char x2char(const char c) 
{ 
    if (c >= '0' && c <= '9') 
     return c - '0'; 
    if (c >= 'a' && c <= 'f') 
     return c - 'a'; 
    if (c >= 'A' && c <= 'F') 
     return c - 'A'; 
    //if we got here it's an error - handle it as you like... 
} 

char xString2char(const char* buf) 
{ 
    char ans; 
    ans = x2char(buf[2]); 
    ans <<= 4; 
    ans += x2char(buf[3]); 
    return ans; 
} 

這應該工作,只需添加錯誤檢查&處理(如果您尚未驗證它們在你的代碼)

+1

先生,謝謝。你幫了我很多! – rojcyk

+0

我的榮幸( - : –

-1

flex有start的條件。這使上下文分析成爲可能。 例如,有撓曲手冊中對C評論分析的示例(/**/之間):

<INITIAL>"/*" BEGIN(IN_COMMENT); 
<IN_COMMENT>{ 
"*/"   BEGIN(INITIAL); 
[^*\n]+   /* eat comment in chunks */ 
"*"    /* eat the lone star */ 
\n    yylineno++; 
} 

起始條件還使得字符串文字分析。有一個示例說明如何使用開始條件中的開始條件來匹配C風格的帶引號的字符串,並且在flex手冊中還有一個名爲"How do I expand backslash-escape sequences in C-style quoted strings?"的FAQ項目。 可能這會回答你的問題。

3

此解決方案可用於八進制,十六進制等所有長度和類型的數字轉義序列。

當你看到'\'時你會做什麼檢查下一個字符。如果它是一個'x'(或'X'),那麼你讀一個字符,如果它是一個十六進制數字(isxdigit),那麼你讀另一個字符。如果最後一個是而不是一個十六進制數字,然後將其放回到流中(「unget」操作),並且只使用您讀取的第一個數字。

您讀到的每個數字都放入一個字符串中,然後您可以使用例如strtol將該字符串轉換爲數字。將該號碼直接放入令牌值中。

對於八進制序列,最多隻需三個字符。


對於類似的方法的例子見this old lexer我很多年前。搜索 lex_getescape函數。雖然此方法使用直接算術代替strtoul將轉義碼轉換爲數字,而不是標準的isxdigit等函數。

相關問題