以下字元被視為空白:空格、水平製表符、歸位符、換行符和換頁符。空白會被忽略,但它們會分隔相鄰的識別符、字面值和關鍵字,否則這些識別符、字面值或關鍵字會被混淆為一個單一的識別符、字面值或關鍵字。
註解以兩個字元 (* 開頭,中間沒有空白,並以字元 *) 結尾,中間沒有空白。註解被視為空白字元。註解不會出現在字串或字元字面值內。巢狀註解會被正確處理。
|
識別符是由字母、數字、_ (底線字元) 和 ' (單引號) 組成的序列,且開頭為字母或底線。字母至少包含 ASCII 集中的 52 個大小寫字母。目前的實作也將 ISO 8859-1 集中的某些字元識別為字母(字元 192–214 和 216–222 為大寫字母;字元 223–246 和 248–255 為小寫字母)。此功能已被棄用,為了未來相容性,應避免使用。
識別符中的所有字元都有意義。目前的實作接受長度最多為 16000000 個字元的識別符。
在許多地方,OCaml 會區分大寫的識別符和以小寫字母開頭的識別符。在此目的下,底線字元被視為小寫字母。
|
整數字面值是一個或多個數字的序列,可選擇性地在前面加上負號。預設情況下,整數字面值是十進位 (基數 10)。以下前綴選擇不同的基數
前綴 | 基數 |
0x, 0X | 十六進位 (基數 16) |
0o, 0O | 八進位 (基數 8) |
0b, 0B | 二進位 (基數 2) |
(開頭的 0 是數字零;八進位的 O 是字母 O。)整數字面值後面可以跟著字母 l、L 或 n 之一,表示此整數的類型分別為 int32、int64 或 nativeint,而不是整數字面值的預設類型 int。超出可表示的整數值範圍的整數字面值的解釋是未定義的。
為了方便和可讀性,底線字元 (_) 在整數字面值中被接受(並忽略)。
|
浮點十進位字面值由整數部分、小數部分和指數部分組成。整數部分是一個或多個數字的序列,可選擇性地在前面加上負號。小數部分是一個小數點,後面跟著零個、一個或多個數字。指數部分是字元 e 或 E,後面跟著可選的 + 或 - 符號,然後是一個或多個數字。它被解釋為 10 的冪。小數部分或指數部分可以省略,但不能同時省略,以避免與整數字面值混淆。超出可表示的浮點數值範圍的浮點字面值的解釋是未定義的。
浮點十六進位字面值以 0x 或 0X 前綴表示。語法類似於浮點十進位字面值,但有以下差異。整數部分和小數部分使用十六進位數字。指數部分以字元 p 或 P 開頭。它是以十進位寫成的,並解釋為 2 的冪。
為了方便和可讀性,底線字元 (_) 在浮點字面值中被接受(並忽略)。
|
字元常值以 ' (單引號) 字元分隔。兩個單引號之間可以包含一個不同於 ' 和 \ 的字元,或下列跳脫序列之一
序列 | 表示的字元 |
\\ | 反斜線 (\) |
\" | 雙引號 (") |
\' | 單引號 (') |
\n | 換行 (LF) |
\r | 歸位 (CR) |
\t | 水平製表符 (TAB) |
\b | 退格 (BS) |
\space | 空格 (SPC) |
\ddd | ASCII 碼為十進制 ddd 的字元 |
\xhh | ASCII 碼為十六進制 hh 的字元 |
\oooo | ASCII 碼為八進制 ooo 的字元 |
|
字串常值以 " (雙引號) 字元分隔。兩個雙引號之間包含一系列不同於 " 和 \ 的字元、字元常值表中給出的跳脫序列,或 Unicode 字元跳脫序列。
Unicode 字元跳脫序列會被替換為指定 Unicode 純量值的 UTF-8 編碼。Unicode 純量值是 0x0000...0xD7FF 或 0xE000...0x10FFFF 範圍內的整數,使用 1 到 6 個十六進位數字定義;允許前導零。
換行序列是選擇性地以歸位字元開頭的換行字元。自 OCaml 5.2 起,字串常值中發生的換行序列會被正規化為單一換行字元。
為了允許跨行分割長字串常值,序列 \newline spaces-or-tabs (行尾的反斜線,後接下一行開頭的任意數量的空格和水平製表符) 會在字串常值中被忽略。
跳脫換行比非跳脫換行提供更方便的行為,因為縮排不被視為字串常值的一部分。
帶引號的字串常值為字串常值提供了替代的詞彙語法。它們可用於表示不需跳脫的任意內容的字串。帶引號的字串以一對匹配的 { quoted-string-id | 和 | quoted-string-id } 分隔,兩側具有相同的 quoted-string-id。帶引號的字串不會以特殊方式解譯任何字元1,但要求序列 | quoted-string-id } 本身不會出現在字串中。識別符 quoted-string-id 是小寫字母和底線 (可能為空) 的序列,可以自由選擇以避免此類問題。
目前的實作對字串常值的長度幾乎沒有限制。
為了避免歧義,在表達式中命名標籤不能僅在語法上定義為三個符號 ~、ident 和 : 的序列,而必須在詞彙層級定義。
|
命名標籤有兩種形式:用於正常參數的 label 和用於選擇性參數的 optlabel。它們只是由第一個字元區分,即 ~ 或 ?。
儘管 label 和 optlabel 是表達式中的詞彙實體,但為了提高可讀性,它們的擴展 ~ label-name : 和 ? label-name : 將用於語法中。另請注意,在類型表達式內部,此擴展可以按字面意思理解,即 真的有 3 個符號,它們之間有可選的空格。
|
另請參閱以下語言擴展:擴展運算符、擴展索引運算符和綁定運算符。
諸如 <=> 或 !! 之類的「運算符字元」序列,會從 infix-symbol 或 prefix-symbol 類別讀取為單個符號。這些符號在表達式內部會被解析為前綴和中綴運算符,但在其他情況下行為類似於正常的識別符。
以下識別符保留為關鍵字,不得用於其他用途
and as assert asr begin class constraint do done downto else end exception external false for fun function functor if in include inherit initializer land lazy let lor lsl lsr lxor match method mod module mutable new nonrec object of open or private rec sig struct then to true try type val virtual when while with
以下字元序列也是關鍵字
!= # & && ' ( ) * + , - -. -> . .. .~ : :: := :> ; ;; < <- = > >] >} ? [ [< [> [| ] _ ` { {< | |] || } ~
請注意,以下識別符是現在已停止維護的 Camlp4 系統的關鍵字,為了向後相容性的原因,應避免使用。
parser value $ $$ $: <: << >> ??
詞彙歧義根據「最長匹配」規則解決:當一個字元序列可以以幾種不同的方式分解為兩個符號時,保留的分解是第一個符號最長的分解。
|
產生 OCaml 原始程式碼的預處理器可以在其輸出中插入行號指示符,以便編譯器產生的錯誤訊息包含參考預處理前原始檔案的行號和檔案名稱,而不是預處理後的檔案。行號指示符從一行的開頭開始,由 # (井號) 組成,後接一個正整數 (原始行號),再後接一個字元串 (原始檔案名稱)。在詞彙分析期間,行號指示符會被視為空白。