阅读表达式的 Scala 规范

reading the scala spec for expressions

我一定是错过了定义使用的符号 here in the spec 的地方。作为一个恰当的例子,完全破译它的前两行将非常有帮助:

Expr         ::=  (Bindings | id | `_') `=>' Expr
               |  Expr1

我对 id 在哪里定义,以及这个符号的语法(以及解释)一无所知。

谢谢!

id 来自 the lexical grammar。简而言之,就是:

upper            ::=  ‘A’ | … | ‘Z’ | ‘$’ | ‘_’  // and Unicode category Lu
lower            ::=  ‘a’ | … | ‘z’ // and Unicode category Ll
letter           ::=  upper | lower // and Unicode categories Lo, Lt, Nl
digit            ::=  ‘0’ | … | ‘9’
opchar           ::= // printableChar not matched by (whiteSpace | upper | lower |
                     // letter | digit | paren | delim | opchar | Unicode_Sm | Unicode_So)

op               ::=  opchar {opchar}
varid            ::=  lower idrest
plainid          ::=  upper idrest
                 |  varid
                 |  op
id               ::=  plainid
                 |  ‘`’ stringLiteral ‘`’
idrest           ::=  {letter | digit} [‘_’ op]

Bindings 进一步向下定义 in the context-free syntax, but is defined in Chapter 2

Names in Scala identify types, values, methods, and classes which are collectively called entities. Names are introduced by local definitions and declarations, inheritance, import clauses, or package clauses which are collectively called bindings.

但是它是什么意思意思

非正式语言:

Expr ::= (Bindings | id | `_') `=>' Expr
         |  Expr1

可以写成:

An Expr shall be taken to mean (::=) either ((...)) a Bindings, an id, or a literal underscore character ('_'), followed by the equals and right-angle-bracket characters ('=>'), followed by either an Expr or an Expr1.

即使是更多非正式语言,你也可以说:

An Expression (Expr) is any valid binding syntax (either a magic _ or a normal variable reference, one or more times, possibly with type ascriptions) or a variable reference, or just a magic _, followed by an arrow (=>), followed by any expression we allow in the language

我不确定非终结符 id 是如何定义的,但希望我能帮助您理解该符号。

符号看起来像 Backus-Naur Form。这意味着 Expr 是以下之一:

  1. Bindings '=>' Expr
  2. id '=>' Expr
  3. '_' '=>' Expr
  4. Expr1

' 引号中的标记是字符串文字,而未被引号括起来的标记是非终结符,这意味着它们可以进一步扩展。

所以如果我有以下代码片段:

x => x * x

然后可能会被解析为如下内容:

    Expr
   / |  \
 id '=>' Expr
 |        |
'x'     Expr1
          |
       BinaryOp
       /  |  \
   Expr1 '*' Expr1
     |        |
    id       id
     |        |
    'x'      'x'