只是爲了給您提供背景知識。我們有一個學校項目,我們需要用C編寫我們自己的編譯器。我的任務是編寫一個詞法分析。到目前爲止這麼好,但我在轉義序列方面遇到了一些困難。如何將轉義字符串轉換爲C中的一個字符
當我找到一個轉義序列和轉義序列是正確的,我把它保存在一個看起來像這樣的字符串,否則它是詞法錯誤。
我的問題是如何將只包含轉義序列的字符串轉換爲一個字符?所以我可以將它添加到包含字符串其餘部分的「緩衝區」中。
我對一個只包含轉義序列的大型表有了一個想法,然後逐一比較它,但它看起來並不優雅。
只是爲了給您提供背景知識。我們有一個學校項目,我們需要用C編寫我們自己的編譯器。我的任務是編寫一個詞法分析。到目前爲止這麼好,但我在轉義序列方面遇到了一些困難。如何將轉義字符串轉換爲C中的一個字符
當我找到一個轉義序列和轉義序列是正確的,我把它保存在一個看起來像這樣的字符串,否則它是詞法錯誤。
我的問題是如何將只包含轉義序列的字符串轉換爲一個字符?所以我可以將它添加到包含字符串其餘部分的「緩衝區」中。
我對一個只包含轉義序列的大型表有了一個想法,然後逐一比較它,但它看起來並不優雅。
你可以使用下面的代碼,用你的字符串調用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;
}
這應該工作,只需添加錯誤檢查&處理(如果您尚未驗證它們在你的代碼)
先生,謝謝。你幫了我很多! – rojcyk
我的榮幸( - : –
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項目。 可能這會回答你的問題。
此解決方案可用於八進制,十六進制等所有長度和類型的數字轉義序列。
當你看到'\'
時你會做什麼檢查下一個字符。如果它是一個'x'
(或'X'
),那麼你讀一個字符,如果它是一個十六進制數字(isxdigit
),那麼你讀另一個字符。如果最後一個是而不是一個十六進制數字,然後將其放回到流中(「unget」操作),並且只使用您讀取的第一個數字。
您讀到的每個數字都放入一個字符串中,然後您可以使用例如strtol
將該字符串轉換爲數字。將該號碼直接放入令牌值中。
對於八進制序列,最多隻需三個字符。
對於類似的方法的例子見this old lexer我很多年前。搜索 lex_getescape
函數。雖然此方法使用直接算術代替strtoul
將轉義碼轉換爲數字,而不是標準的isxdigit
等函數。
你的意思是像''\ n''轉義序列,' '\ t''等?或者像''\ x9''這樣的數字一位數序列? –
我有'\ n''\''\ t'和'\''的解決方案。我遇到了像剛剛寫的那樣的轉義序列問題。 – rojcyk