符号约定
语法
以下符号由 词法分析器(Lexer)和 语法(Syntax)语法片段使用:
| 符号 | 示例 | 含义 |
|---|---|---|
| CAPITAL | KW_IF, INTEGER_LITERAL | 由词法分析器产生的词法单元 |
| ItalicCamelCase | LetStatement, Item | 语法产物 |
string | x, while, * | 精确的字符 |
| x? | pub? | 可选项 |
| x* | OuterAttribute* | 0 个或多个 x |
| x+ | MacroMatch+ | 1 个或多个 x |
| xa..b | HEX_DIGIT1..6 | a 到 b 次重复 x,不包含 b |
| xa..=b | HEX_DIGIT1..=5 | a 到 b 次重复 x,包含 b |
| xn:a..=b | #n:1..=255 | a 到 b 次重复 x(包含 b),计数绑定到名称 n |
| xn | #n | x 重复绑定到 n 的次数,由先前标记的重复定义 |
| Rule1 Rule2 | fn Name Parameters | 按顺序排列的规则序列 |
| | | u8 | u16, Block | Item | 其中之一 |
| ! | !COMMENT | 如果表达式不匹配则匹配,不消耗任何输入 |
| [ ] | [b B] | 列出的任意字符 |
| [ - ] | [a-z] | 范围内的任意字符 |
| ~[ ] | ~[b B] | 除列出字符外的任意字符 |
~string | ~\n, ~*/ | 除此序列外的任意字符 |
| ( ) | (, Parameter)? | 分组项 |
| ^ | b' ^ ASCII_FOR_CHAR | 序列的其余部分必须匹配,否则解析无条件失败([硬切操作符]) |
| U+xxxx..xxxxxx | U+0060 | 单个 Unicode 字符 |
| <text> | <any ASCII char except CR> | 应匹配内容的英文描述 |
| Rule suffix | IDENTIFIER_OR_KEYWORD except crate | 对前一规则的修改 |
| // Comment. | // Single line comment. | 延伸到行尾的注释。 |
序列的优先级高于 | 交替。
硬切操作符
语法使用有序交替:解析器从左到右尝试替代方案,并采用第一个匹配的方案。如果某个替代方案在序列中途失败,解析器通常会回溯并尝试下一个替代方案。切操作符(^)会阻止这种情况。一旦序列中 ^ 左侧的所有表达式都已匹配,序列的其余部分必须匹配,否则解析无条件失败。
Mizushima 等人将切操作符引入了解析表达式文法。在 PEG 文献中,软切仅阻止在直接包含的有序选择中回溯 — 外部选择仍然可以恢复。硬切阻止所有经过切点的回溯;失败是确定性的。本文法中使用的 ^ 是硬切。
硬切操作符是必要的,因为 Rust 中的某些词法单元以本身是有效词法单元的前缀开头。例如,c" 开始一个 C 字符串字面量,但单独的 c 是一个有效的标识符。如果没有切,如果 c"\0" 作为 C 字符串字面量词法分析失败(因为 C 字符串中不允许空字节),解析器可能会回溯并将其词法分析为两个词法单元:标识符 c 和字符串字面量 "\0"。c" 之后的切 阻止了这种情况 — 一旦识别出开头的分隔符,解析器就无法回溯。同样的推理适用于字节字面量、字节字符串字面量、原始字符串字面量以及其他以前缀开头的字面量,这些前缀本身是有效的词法单元。
字符串表产物
语法中的某些规则 — 特别是一元运算符、二元运算符和关键字 — 以简化形式给出:作为可打印字符串的列表。这些情况构成了关于词法单元规则的子集,并假定是由 DFA 驱动的词法分析阶段的结果,该阶段操作所有此类字符串表条目的析取。
当此类字符串以 monospace 字体出现在语法中时,它是对此类字符串表产物的单个成员的隐式引用。有关更多信息,请参阅词法单元。
语法可视化
每个语法块下方都有一个按钮,用于切换语法图的显示。方形元素是非终结符规则,圆角矩形是终结符。