Skip to content

v0.1.z での構文の定式化

Takashi Suwa edited this page Aug 30, 2022 · 9 revisions

例 (Examples)

ラベルつきオプション引数 (Labeled optional parameters/arguments)

module Sample = struct
  val succ ?(diff = d-opt) x =
    match d-opt with
    | None   -> x + 1
    | Some d -> x + d
    end

  val main () =
    (succ 57, succ ?(diff = 42) 57)  % => (58, 99)
end
module Sample :> sig
  val succ : ?(diff : int) int -> int
end = struct
  val succ ?(diff = d : int = 1) (x : int) = x + d
end
require StdJaReport

StdJaReport.document ?(
  cjk-font-family   = `ipaexm`,
  latin-font-family = `Junicode`,
  main-font-size    = 11pt,
) (|
  title  = {Sample},
  author = {J. Smith},
|) '<
  +p{Hello World}
>

記法の凡例 (Notation)

[ARG]? ::= (empty) | ARG
[ARG]* ::= (empty) | [ARG]+
[ARG]+ ::= ARG [ARG]*
[ARG >? SEP]* ::= (empty) | [ARG >? SEP]+
[ARG >? SEP]+ ::= ARG | ARG SEP [ARG >? SEP]*
[SEP <? ARG]+ ::= [SEP]? ARG [SEP ARG]*

構文定義 (Syntax Definition)

# 式・型・種用の識別子,およびラベル (expression/type/kind identifiers and labels):
x, l ::= (a lowercased identifier)

# モジュール・シグネチャ用の識別子,およびコンストラクタ (module/signature identifiers and constructors):
X, C ::= (a capitalized identifier)

# 0階の型変数 (order-0 type variables):
type-var ::= (a lowercased identifier preceded by a single quotation mark)

# 列変数 (row variables):
row-var ::= (a lowercased identifier preceded by a single quotation mark and a question mark)

# ソースファイル (source files):
file ::=
  | header 'module' X [':>' S] '=' M

# ヘッダ (headers):
header ::=
  (要加筆)

# モジュール式 (module expressions):
M ::=
  | '(' M ')'
  | [X '.']* X                    # paths
  | 'fun' '(' X ':' S ')' '->' M  # functor abstractions
  | [X '.']* X [X '.']* X         # functor applications
  | 'struct' [B]* 'end'           # structures
  | [X '.']* X ':>' S             # coercion

# 束縛 (bindings):
B ::=
  | 'val' bind-val
  | 'type' bind-type
  | 'module' X [':>' S]? '=' M
  | 'signature' X '=' S
  | 'include' M

# 値束縛 (value bindings):
bind-val ::=
  | bind-val-single
  | 'rec' bind-val-single ['and' bind-val-single]

bind-val-single ::=
  | x quant [bind-val-parameter]* '=' E
  | 'math' [x]? \x quant [bind-val-parameter]* '=' E
  | 'inline' [x]? \x quant [bind-val-parameter]* '=' E
  | 'block' [x]? +x quant [bind-val-parameter]* '=' E

bind-val-parameter ::=
  | parameter
  | '?(' [opt-parameter >? ',']* ')' parameter

# 型束縛 (type bindings):
bind-type ::=
  | bind-type-single ['and' bind-type-single]*

bind-type-single ::=
  | x [type-var]* '=' T
  | x [type-var]* '=' ['|' <? constructor-branch]+

constructor-branch ::=
  | C ['of' T]?

# ラベルつきオプション引数 (labeled optional parameters):
opt-parameter ::=
  | label '=' P [':' T]? ['=' E]?

# 必須引数 (mandatory parameters):
parameter ::=
  | P                # patterns
  | '(' P ':' T ')'  # patterns with type annotations

# シグネチャ (signatures):
S ::=
  | '(' S ')'
  | [X '.']* X                 # paths
  | '(' X ':' S ')' '->' S     # functor signatures
  | 'sig' [D]* 'end'           # structure signatures
  | S 'with' 'type' bind-type

# 宣言 (declarations):
D ::=
  | 'val' x quant ':' T
  | 'type' x '::' K
  | 'type' bind-type
  | 'module' X ':' S
  | 'signature' X '=' S
  | 'include' S

# 1階の種 (order-1 kinds):
K ::=
  | base-kind
  | base-kind '->' K

# 基本種 (base kinds):
base-kind ::=
  | x  # kind names (only 'o' is valid)

# 列種 (row kinds):
row-kind ::=
  | '(|' [l >? ',']+ '|)'

# 型 (types):
T ::=
  | '(' T ')'
  | type-var                                     # type variables
  | [X '.']* x [T]*                              # type applications
  | [type-opts]? T '->' T                        # function types
  | T '*' T ['*' T]*                             # product types
  | '(|' [ l ':' T >? ',']+ ['|' row-var]? '|)'  # record types
  | 'math' cmd-parameter-types                   # math command types
  | 'inline' cmd-parameter-types                 # inline command types
  | 'block' cmd-parameter-types                  # block command types

cmd-parameter-types ::=
  | [' [cmd-parameter-type >? ',']* ']'

cmd-parameter-type ::=
  | [type-opts-closed]? T

type-opts ::=
  | '?(' [label ':' T >? ',']+ ['|' row-var]? ')'

# 全称量化子 (universal quantifiers):
quant ::=
  | [type-var]* ['(' row-var '::' row-kind ')']*

# 式 (expressions):
E ::=
  | '(' E ')'
  | [X '.']* x                                 # variables
  | 'fun' [bind-val-parameter]* '->' E         # abstractions
  | E [expr-opts]? E                           # applications
  | 'let' bind-val 'in' E                      # local value bindings
  | 'let' non-var-pattern '=' E 'in' E         # pattern matching by let
  | 'let' 'open' [X '.']* X 'in' E             # local module open
  | 'match' E 'with' ['|' <? P '->' E]+ 'end'  # pattern matching
  | 'if' E 'then' E 'else' E                   # conditional branching
  | [X '.']* C [E]?                            # constructor applications
  | E bin-op E                                 # binary operations
  | un-op E                                    # unary operations
  | matchable-const
  | non-matchable-const
  | '{' TI '}'                                 # inline texts
  | '\'<' TB '>'                               # block texts
  | '${' TM '}'                                # math formulae
  (要加筆)

# インラインテキスト (inline texts):
TI ::=
  (要加筆)

# ブロックテキスト (block texts):
TB ::=  
  (要加筆)

# 数式 (math formulae):
TM ::=
  (要加筆)

expr-opts ::=
  | '?(' [label '=' E >? ',']+ ')'

matchable-const ::=
  | '(' ')'  # the unit value
  | 'true'
  | 'false'
  | (a decimal integer literal)
  | (a hexadecimal integer literal)
  | (a string literal enclosed by back ticks)

non-matchable-const ::=
  | (a floating-point number literal)
  | (a length literal)

# パターン (patterns):
P ::=
  | x                # variable patterns
  | non-var-pattern  # non-variable patterns

# 変数を除くパターン (patterns except for variables):
non-var-pattern ::=
  | '(' non-var-pattern ')'
  | '_'                        # wildcards
  | [X '.']* C [P]?            # constructor patterns
  | '(' P ',' [P >? ',']+ ')'  # tuple patterns
  | matchable-const
Clone this wiki locally