詞法
在D中,詞法分析獨立於語法分析和語義分析。詞法分析器將源文件分割成記號。詞法描述瞭如何識別記號。D的詞法被設計爲適於高速掃描,它擁有最小的特殊規則集合,只有一遍翻譯,這使得構造一個正確的掃描程序很容易。對於熟悉 C 和 C++ 的人來說,記號也很容易識別。
編譯的階段
編譯被分爲多個階段。每個階段都不依賴於後繼的階段。例如,掃描程序不依賴於語義分析程序。這種分離使語法制導編輯器等語言工具相對容易構造。這也使通過將其存儲爲‘符號’形式來壓縮 D 源碼成爲可能。
- 源碼字符集
先檢查源文件使用的是什麼字符集,然後使用合適的掃描程序。可以使用 ASCII 或 UTF 格式。 - 詞法分析
源文件被分割爲記號序列。特殊記號會被處理,然後刪除。 - 語法分析
符號序列被解析爲語法樹。 - 語義分析
遍歷語法樹,聲明變量、載入符號表、分配型別並從大體上決定程序的意義。 - 優化
優化是可選的一步,它試圖語義等價的重寫程序,但是生成一個更爲快速的版本。 - 代碼生成
採用目標架構的指令來實現程序的語義。典型的結果是生成一個目標文件,它會作爲連接器的輸入。
源碼文本
D 源碼文本可以是下面各種形式之一:
- ASCII
- UTF-8
- UTF-16BE
- UTF-16LE
- UTF-32BE
- UTF-32LE
UTF-8 是傳統的7位 ASCII 的超集。 源代碼文檔的開始可以是下面的任一個 UTF BOMs(字節序標誌)之一:
格式 | BOM |
---|---|
UTF-8 | EF BB BF |
UTF-16BE | FE FF |
UTF-16LE | FF FE |
UTF-32BE | 00 00 FE FF |
UTF-32LE | FF FE 00 00 |
ASCII | no BOM |
D 中沒有“雙連符”或者“三連符” 。 (譯註:三連符是一些由 ?? 開頭的連續的三字符組合,它包括 ??=,??/,??',??(,??),??!,??<,??>和??-,這些字符將被直接替換爲對應的字符,分別爲#,,^,[,],|,{,}和~。引入三連符是爲了方便的輸入這些字符,早期有些鍵盤不支持它們。雙連符同理。顯然 Walter 認爲這些東西早就過時了。)
源代碼文檔由 空白、行尾、註釋、特殊記號序列、記號等組成,結尾處必須是 文件尾 。
應使用貪心算法將源代碼文檔分割爲記號,也就是詞法分析器每次都試圖生成一個最長的符號。例如:>>
是一個右移運算符,而不是兩個大於運算符。
文件尾
文件尾: 文件的物理結尾 /u0000 /u001A
EndOfFile: physical end of the file /u0000 /u001A
在遇到上述之一時認爲文件終止。
行尾
行尾: /u000D /u000A /u000D /u000A 文件尾
EndOfLine: /u000D /u000A /u000D /u000A EndOfFile
不允許用反斜線來將一行分爲多行,行長度也沒有限制。
空白
空白: 空格 空格 空白 空格: /u0020 /u0009 /u000B /u000C 行尾 註釋
WhiteSpace: Space Space WhiteSpace Space: /u0020 /u0009 /u000B /u000C EndOfLine Comment
空白被定義爲一系列的一個或多個空格、製表符、垂直製表符、表格填充、行尾或者註釋。
註釋
註釋: /* 字符 */ // 字符 行尾 /+ 字符 +/
Comment: /* Characters */ // Characters EndOfLine /+ Characters +/
D 有三種註釋:
- 塊註釋可以跨越多行,但是不能嵌套。
- 單行註釋在行尾結束。
- 嵌套註釋可以跨越多行並且可以嵌套。
從概念上來說,在記號化之前處理註釋。這意味着嵌入的字符串和註釋不會影響對註釋開始和註釋結束的識別:
a = 1; a = ; a = */ 3;
註釋不能被用作記號連接符,例如 abc/**/def
是兩個符號,abc 和 def ,而不是記號 abcdef 。
記號
記號: 標誌符 字符串文字量 字符文字量 整數文字量 浮點數文字量 關鍵字 / /= . .. ... & &= && | |= || - -= -- + += ++ < <= << <<= <> <>= > >= >>= >>>= >> >>> ! != !== !<> !<>= !< !<= !> !>= ( ) [ ] { } ? , ; : $ = == === * *= % %= ^ ^= ~ ~=
Token: Identifier StringLiteral CharacterLiteral IntegerLiteral FloatLiteral Keyword / /= . .. ... & &= && | |= || - -= -- + += ++ < <= << <<= <> <>= > >= >>= >>>= >> >>> ! != !== !<> !<>= !< !<= !> !>= ( ) [ ] { } ? , ; : $ = == === * *= % %= ^ ^= ~ ~=
標誌符
標誌符: 標誌符起始 標誌符起始 多個標誌符字符 多個標誌符字符: 標誌符字符 標誌符字符 多個標誌符字符 標誌符起始: _ 字母 通用字母 標誌符字符: 標誌符起始 數字
Identifier: IdentiferStart IdentiferStart IdentifierChars IdentifierChars: IdentiferChar IdentiferChar IdentifierChars IdentifierStart: _ Letter UniversalAlpha IdentifierChar: IdentiferStart Digit
標誌符由一個字母、下劃線或者一個 unicode 字母開頭,後面跟着任意個字母、下劃線、數字或者通用字母。通用字母的定義請參考 ISO/IEC 9899:1999(E) 附錄 D 。(這是 C99 標準) 標誌符長度任意,並且區分大小寫。以兩個下劃線開頭的標誌符是保留的。