構文カテゴリ stx
は Lean.Parser.Command.syntax : command
syntax
コマンドのボディに出現する可能性のある指定子についての文法です。
文字列リテラルは アトム (if
・#eval
・where
などのキーワードを含む)としてパースされます:
stx ::=
str
文字列の先頭と末尾の空白はパースに影響しませんが、空白を入れた場合 証明状態 やエラーメッセージで構文を表示する時に Lean が対応する位置に空白が挿入されます。通常、構文規則のアトムとして出現する有効な識別子は予約キーワードになります。文字列リテラルの前にアンパサンド(&
)を置くとこの動作が抑制されます:
stx ::= ...
| &str
識別子は、指定された位置で期待される構文カテゴリを指定し、オプションで優先順位を指定できます:
stx ::= ...
| ident(:prec)?
修飾子 *
はクリーネスターで、直前の構文の0回以上の繰り返しにマッチします。これは many
と書くこともできます。
stx ::= ...
| `p*` is shorthand for `many(p)`. It uses parser `p` 0 or more times, and produces a
`nullNode` containing the array of parsed results. This parser has arity 1.
If `p` has arity more than 1, it is auto-grouped in the items generated by the parser.
stx *
修飾子 +
は直前の構文の1回以上の繰り返しにマッチします。これは many1
と書くこともできます。
stx ::= ...
| `p+` is shorthand for `many1(p)`. It uses parser `p` 1 or more times, and produces a
`nullNode` containing the array of parsed results. This parser has arity 1.
If `p` has arity more than 1, it is auto-grouped in the items generated by the parser.
stx +
修飾性 ?
は部分項をオプショナルにし、直前の構文の繰り返しに0回または1回(それ以上は繰り返さない)にマッチします。これは optional
と書くこともできます。
stx ::= ...
| `(p)?` is shorthand for `optional(p)`. It uses parser `p` 0 or 1 times, and produces a
`nullNode` containing the array of parsed results. This parser has arity 1.
`p` is allowed to have arity n > 1 (in which case the node will have either 0 or n children),
but if it has arity 0 then the result will be ambiguous.
Because `?` is an identifier character, `ident?` will not work as intended.
You have to write either `ident ?` or `(ident)?` for it to parse as the `?` combinator
applied to the `ident` parser.
stx ?
stx ::= ...
| Returns `some x` if `f` succeeds with value `x`, else returns `none`.
optional(stx)
修飾子 ,*
はカンマで区切られた直前の構文の0回以上の繰り返しにマッチします。これは sepBy
と書くこともできます。
stx ::= ...
| `p,*` is shorthand for `sepBy(p, ",")`. It parses 0 or more occurrences of
`p` separated by `,`, that is: `empty | p | p,p | p,p,p | ...`.
It produces a `nullNode` containing a `SepArray` with the interleaved parser
results. It has arity 1, and auto-groups its component parser if needed.
stx ,*
修飾子 ,+
はカンマで区切られた直前の構文の1回以上の繰り返しにマッチします。これは sepBy1
と書くこともできます。
stx ::= ...
| `p,+` is shorthand for `sepBy(p, ",")`. It parses 1 or more occurrences of
`p` separated by `,`, that is: `p | p,p | p,p,p | ...`.
It produces a `nullNode` containing a `SepArray` with the interleaved parser
results. It has arity 1, and auto-groups its component parser if needed.
stx ,+
修飾子 ,*,?
はカンマで区切られた直前の構文の0回以上の繰り返しにマッチし、繰り返しの最後のカンマを任意にすることができます。これは allowTrailingSep
を伴った sepBy
と書くこともできます。
stx ::= ...
| `p,*,?` is shorthand for `sepBy(p, ",", allowTrailingSep)`.
It parses 0 or more occurrences of `p` separated by `,`, possibly including
a trailing `,`, that is: `empty | p | p, | p,p | p,p, | p,p,p | ...`.
It produces a `nullNode` containing a `SepArray` with the interleaved parser
results. It has arity 1, and auto-groups its component parser if needed.
stx ,*,?
修飾子 ,+,?
はカンマで区切られた直前の構文の1回以上の繰り返しにマッチし、繰り返しの最後のカンマを任意にすることができます。これは allowTrailingSep
を伴った sepBy1
と書くこともできます。
stx ::= ...
| `p,+,?` is shorthand for `sepBy1(p, ",", allowTrailingSep)`.
It parses 1 or more occurrences of `p` separated by `,`, possibly including
a trailing `,`, that is: `p | p, | p,p | p,p, | p,p,p | ...`.
It produces a `nullNode` containing a `SepArray` with the interleaved parser
results. It has arity 1, and auto-groups its component parser if needed.
stx ,+,?
演算子 <|>
は orelse
と書くこともでき、どちらかの構文にマッチします。しかし、最初の分岐で何らかのトークンが消費された場合、その分岐がコミットされ、失敗はバックトラックされません:
stx ::= ...
| `p1 <|> p2` is shorthand for `orelse(p1, p2)`, and parses either `p1` or `p2`.
It does not backtrack, meaning that if `p1` consumes at least one token then
`p2` will not be tried. Therefore, the parsers should all differ in their first
token. The `atomic(p)` parser combinator can be used to locally backtrack a parser.
(For full backtracking, consider using extensible syntax classes instead.)
On success, if the inner parser does not generate exactly one node, it will be
automatically wrapped in a `group` node, so the result will always be arity 1.
The `<|>` combinator does not generate a node of its own, and in particular
does not tag the inner parsers to distinguish them, which can present a problem
when reconstructing the parse. A well formed `<|>` parser should use disjoint
node kinds for `p1` and `p2`.
stx <|> stx
stx ::= ...
| orelse(stx, stx)
演算子 !
は引数の補集合にマッチします。引数が失敗した場合に成功し、パース状態がリセットされます。
stx ::= ...
| `!p` parses the negation of `p`. That is, it fails if `p` succeeds, and
otherwise parses nothing. It has arity 0.
! stx
構文指定子は括弧を使ってグループ化することができます。
stx ::= ...
| (stx)
繰り返しは many
と many1
を使って定義することができます。後者は繰り返される構文のインスタンスが少なくとも1つ必要です。
stx ::= ...
| many(stx)
stx ::= ...
| many1(stx)
区切り文字を使った繰り返しは sepBy
と sepBy1
を使って定義することができ、それぞれ0個以上・1個以上の出現にマッチし、他の構文で区切られます。使い方は3種類あります:
-
パラメータが2つの場合は、文字列リテラルで指定されたアトムを使用して区切り文字をパースし、末尾の区切り文字を許容しません。
-
パラメータが3つの場合は、3番目のパラメータを使用して区切り文字をパースし、プリティプリンタのためにアトムを使用します。
-
パラメータが4つの場合、オプションとしてシーケンスの最後にセパレータを追加することができます。第4引数は常にキーワード allowTrailingSep
を指定しなければなりません。
stx ::= ...
| sepBy(stx, str)
stx ::= ...
| sepBy(stx, str, stx)
stx ::= ...
| sepBy(stx, str, stx, allowTrailingSep)
stx ::= ...
| sepBy1(stx, str)
stx ::= ...
| sepBy1(stx, str, stx)
stx ::= ...
| sepBy1(stx, str, stx, allowTrailingSep)