First import of my first designs for a front-end generator for Ligodity.
This commit is contained in:
parent
6d3679290d
commit
685c25de9a
296
src/parser/generator/doc/essai.ml
Normal file
296
src/parser/generator/doc/essai.ml
Normal file
@ -0,0 +1,296 @@
|
||||
type region
|
||||
type 'a reg
|
||||
type lexeme = string reg
|
||||
|
||||
(* Tokens *)
|
||||
|
||||
type integer = [`Integer of lexeme reg]
|
||||
type natural = [`Natural of lexeme reg]
|
||||
type ident = [`Ident of lexeme reg]
|
||||
type uident = [`Uident of lexeme reg]
|
||||
type chr = [`Chr of lexeme reg]
|
||||
type str = [`Str of lexeme reg]
|
||||
|
||||
type bool_or = [`bool_or of lexeme reg]
|
||||
type bool_and = [`bool_and of lexeme reg]
|
||||
type lt = [`lt of lexeme reg]
|
||||
type le = [`le of lexeme reg]
|
||||
type gt = [`gt of lexeme reg]
|
||||
type ge = [`ge of lexeme reg]
|
||||
type eq = [`eq of lexeme reg]
|
||||
type ne = [`ne of lexeme reg]
|
||||
type cat = [`cat of lexeme reg]
|
||||
type cons = [`cons of lexeme reg]
|
||||
type plus = [`plus of lexeme reg]
|
||||
type minus = [`minus of lexeme reg]
|
||||
type times = [`times of lexeme reg]
|
||||
type slash = [`slash of lexeme reg]
|
||||
type div = [`div of lexeme reg]
|
||||
type kwd_mod = [`kwd_mod of lexeme reg]
|
||||
type uminus = [`uminus of lexeme reg]
|
||||
type kwd_not = [`kwd_not of lexeme reg]
|
||||
|
||||
type lpar = [`lpar of lexeme reg]
|
||||
type rpar = [`rpar of lexeme reg]
|
||||
type lbracket = [`lbracket of lexeme reg]
|
||||
type rbracket = [`rbracket of lexeme reg]
|
||||
type lbrace = [`lbrace of lexeme reg]
|
||||
type rbrace = [`rbrace of lexeme reg]
|
||||
type semi = [`semi of lexeme reg]
|
||||
type comma = [`comma of lexeme reg]
|
||||
type colon = [`colon of lexeme reg]
|
||||
type vbar = [`vbar of lexeme reg]
|
||||
type arrow = [`arrow of lexeme reg]
|
||||
type wild = [`wild of lexeme reg]
|
||||
|
||||
type kwd_and = [`kwd_and of lexeme reg]
|
||||
type kwd_begin = [`kwd_begin of lexeme reg]
|
||||
type kwd_else = [`kwd_else of lexeme reg]
|
||||
type kwd_end = [`kwd_end of lexeme reg]
|
||||
type kwd_false = [`kwd_false of lexeme reg]
|
||||
type kwd_fun = [`kwd_fun of lexeme reg]
|
||||
type kwd_if = [`kwd_if of lexeme reg]
|
||||
type kwd_in = [`kwd_in of lexeme reg]
|
||||
type kwd_let = [`kwd_let of lexeme reg]
|
||||
type kwd_list = [`kwd_list of lexeme reg]
|
||||
type kwd_map = [`kwd_map of lexeme reg]
|
||||
type kwd_match = [`kwd_match of lexeme reg]
|
||||
type kwd_of = [`kwd_of of lexeme reg]
|
||||
type kwd_set = [`kwd_set of lexeme reg]
|
||||
type kwd_then = [`kwd_then of lexeme reg]
|
||||
type kwd_true = [`kwd_true of lexeme reg]
|
||||
type kwd_type = [`kwd_type of lexeme reg]
|
||||
type kwd_with = [`kwd_with of lexeme reg]
|
||||
|
||||
type token =
|
||||
Integer of integer
|
||||
| Natural of natural
|
||||
| Ident of ident
|
||||
| Uident of uident
|
||||
| Chr of chr
|
||||
| Str of str
|
||||
| Bool_or of bool_or
|
||||
| Bool_and of bool_and
|
||||
| Lt of lt
|
||||
| Le of le
|
||||
| Gt of gt
|
||||
| Ge of ge
|
||||
| Eq of eq
|
||||
| Ne of ne
|
||||
| Cat of cat
|
||||
| Cons of cons
|
||||
| Plus of plus
|
||||
| Minus of minus
|
||||
| Times of times
|
||||
| Slash of slash
|
||||
| Div of div
|
||||
| Kwd_mod of kwd_mod
|
||||
| Uminus of uminus
|
||||
| Kwd_not of kwd_not
|
||||
| Lpar of lpar
|
||||
| Rpar of rpar
|
||||
| Lbracket of lbracket
|
||||
| Rbracket of rbracket
|
||||
| Lbrace of lbrace
|
||||
| Rbrace of rbrace
|
||||
| Semi of semi
|
||||
| Comma of comma
|
||||
| Colon of colon
|
||||
| Vbar of vbar
|
||||
| Arrow of arrow
|
||||
| Wild of wild
|
||||
| Kwd_and of kwd_and
|
||||
| Kwd_begin of kwd_begin
|
||||
| Kwd_else of kwd_else
|
||||
| Kwd_end of kwd_end
|
||||
| Kwd_false of kwd_false
|
||||
| Kwd_fun of kwd_fun
|
||||
| Kwd_if of kwd_if
|
||||
| Kwd_in of kwd_in
|
||||
| Kwd_let of kwd_let
|
||||
| Kwd_list of kwd_list
|
||||
| Kwd_map of kwd_map
|
||||
| Kwd_match of kwd_match
|
||||
| Kwd_of of kwd_of
|
||||
| Kwd_set of kwd_set
|
||||
| Kwd_then of kwd_then
|
||||
| Kwd_true of kwd_true
|
||||
| Kwd_type of kwd_type
|
||||
| Kwd_with of kwd_with
|
||||
|
||||
(* The following are meant to be part of a library *)
|
||||
|
||||
type 'item seq = 'item list
|
||||
type 'item nseq = 'item * 'item seq
|
||||
type ('item,'sep) nsepseq = 'item * ('sep * 'item) list
|
||||
type ('item,'sep) sepseq = ('item,'sep) nsepseq option
|
||||
type ('item,'sep) sep_or_term_list =
|
||||
('item,'sep) nsepseq * 'sep option
|
||||
|
||||
(* The following are specific to the present grammar *)
|
||||
|
||||
type 'item list_of__rec_0 = {
|
||||
lbracket__1 : lbracket;
|
||||
list_of__rec_0__2 : ('item, semi) nsepseq;
|
||||
rbracket__3 : rbracket
|
||||
}
|
||||
|
||||
type 'item list_of = [`List of 'item list_of__rec_0]
|
||||
|
||||
type 'item tuple__rec_0 = {
|
||||
item__1 : 'item;
|
||||
comma__2 : comma;
|
||||
tuple__rec_0__3 : ('item, comma) nsepseq
|
||||
}
|
||||
|
||||
type 'item tuple = [`Tuple of 'item tuple__rec_0]
|
||||
|
||||
type 'item par__rec_0 = {
|
||||
lpar__1 : lpar;
|
||||
item__2 : 'item;
|
||||
rpar__3 : rpar
|
||||
}
|
||||
|
||||
type 'item par = [`Par of 'item par__rec_0]
|
||||
|
||||
(* Non-recursive value declarations *)
|
||||
|
||||
type sub_irrefutable = [
|
||||
`P_Var of string
|
||||
| `P_Wild
|
||||
| `P_Unit
|
||||
| closed_irrefutable par
|
||||
]
|
||||
|
||||
and closed_irrefutable = [
|
||||
sub_irrefutable tuple
|
||||
| `P_SubI of sub_irrefutable (* `P_SubI necessary *)
|
||||
]
|
||||
|
||||
type irrefutable = [
|
||||
sub_irrefutable tuple
|
||||
| sub_irrefutable
|
||||
]
|
||||
|
||||
type let_binding__rec_1 = {
|
||||
variable__1 : variable;
|
||||
sub_irrefutable__nseq__2 : sub_irrefutable nseq;
|
||||
eq__3 : eq;
|
||||
expr__4 : expr
|
||||
}
|
||||
|
||||
type let_binding__rec_2 = {
|
||||
irrefutable__1 : irrefutable;
|
||||
eq__2 : eq;
|
||||
expr__3 : expr
|
||||
}
|
||||
|
||||
type let_binding = [
|
||||
`LetFun of let_binding__rec_1
|
||||
| `LetNonFun of let_binding__rec_2 (* `LetNonFun necessary *)
|
||||
]
|
||||
|
||||
type let_bindings = (let_binding, kwd_and) nsepseq
|
||||
|
||||
type let_declarations = {
|
||||
kwd_let : kwd_let;
|
||||
let_bindings : let_bindings
|
||||
}
|
||||
|
||||
(*
|
||||
type pattern = [
|
||||
`P_Cons of {sub_pattern: sub_pattern; cons: cons; tail: tail}
|
||||
| `P_Tuple
|
||||
*)
|
||||
|
||||
(* Type declarations *)
|
||||
|
||||
type type_name = ident
|
||||
type field_name = ident
|
||||
type constr = uident
|
||||
|
||||
type type_constr = [
|
||||
`T_Constr of ident
|
||||
| kwd_set
|
||||
| kwd_map
|
||||
| kwd_list
|
||||
]
|
||||
|
||||
type record_type = {
|
||||
lbrace : lbrace;
|
||||
record_type__2 : (field_decl, semi) sep_or_term_list;
|
||||
rbrace : rbrace
|
||||
}
|
||||
|
||||
and field_decl = {
|
||||
field_name : field_name;
|
||||
colon : colon;
|
||||
type_expr : type_expr
|
||||
}
|
||||
|
||||
and variant = {
|
||||
constr : constr;
|
||||
kwd_of : kwd_of;
|
||||
cartesian : cartesian
|
||||
}
|
||||
|
||||
and sum_type = {
|
||||
vbar_opt : vbar option;
|
||||
sum_type__2 : (variant, vbar) nsepseq
|
||||
}
|
||||
|
||||
and type_param__rec_1 = {
|
||||
core_type : core_type;
|
||||
type_constr : type_constr
|
||||
}
|
||||
|
||||
and type_param = [
|
||||
(type_expr, comma) nsepseq par
|
||||
| `T_App of type_param__rec_1
|
||||
]
|
||||
|
||||
and core_type__rec_1 = {
|
||||
type_param : type_param;
|
||||
type_constr : type_constr
|
||||
}
|
||||
|
||||
and core_type = [
|
||||
`T_Alias of type_name
|
||||
| `T_App of core_type__rec_1
|
||||
| cartesian par
|
||||
]
|
||||
|
||||
and fun_type__rec_0 = {
|
||||
core_type : core_type;
|
||||
arrow : arrow;
|
||||
fun_type : fun_type
|
||||
}
|
||||
|
||||
and fun_type = [
|
||||
`T_Fun of fun_type__rec_0
|
||||
| `T_Core of core_type (* `T_Core necessary *)
|
||||
]
|
||||
|
||||
and cartesian = (fun_type, times) nsepseq
|
||||
|
||||
and type_expr = [
|
||||
`T_Prod of cartesian
|
||||
| `T_Sum of sum_type
|
||||
| `T_Record of record_type
|
||||
]
|
||||
|
||||
type type_declaration = {
|
||||
kwd_type__1 : kwd_type;
|
||||
type_name__2 : type_name;
|
||||
eq__3 : eq;
|
||||
type_expr__4 : type_expr
|
||||
}
|
||||
|
||||
(* Entry *)
|
||||
|
||||
type statement = [
|
||||
`Let of let_declarations
|
||||
| `TypeDecl of type_declaration
|
||||
]
|
||||
|
||||
type program = statement list
|
270
src/parser/generator/doc/mini_ml.bnf
Normal file
270
src/parser/generator/doc/mini_ml.bnf
Normal file
@ -0,0 +1,270 @@
|
||||
(* Extended Backus-Naur Form (EBNF) for Mini-ML *)
|
||||
|
||||
(* LEXIS *)
|
||||
|
||||
let nl = ['\n' '\r']
|
||||
let blank = [' ' '\t']
|
||||
|
||||
let digit = ['0'-'9']
|
||||
let natural = digit | digit (digit | '_')* digit
|
||||
let integer = '-'? natural
|
||||
|
||||
let small = ['a'-'z']
|
||||
let capital = ['A'-'Z']
|
||||
let letter = small | capital
|
||||
|
||||
let ichar = letter | digit | ['_' '\'']
|
||||
let ident = small ichar* | '_' ichar+
|
||||
let uident = capital ichar*
|
||||
|
||||
let hexa = digit | ['A'-'F']
|
||||
let byte = hexa hexa
|
||||
|
||||
let esc = "\\n" | "\\\\" | "\\b" | "\\r" | "\\t"
|
||||
let string
|
||||
let char_set = [^'\'' '\\'] # nl
|
||||
| "\\'" | esc | "\\x" byte | "\\0" digit digit
|
||||
let char = "'" char_set "'"
|
||||
|
||||
|
||||
(* SYNTAX *)
|
||||
|
||||
(* Helpers *)
|
||||
|
||||
(* The following are meant to be part of a library *)
|
||||
|
||||
sep_or_term_list<item,sep> ::=
|
||||
item sep ...
|
||||
| (item sep)+
|
||||
|
||||
seq<item> ::= nseq<item>?
|
||||
|
||||
nseq<item> ::= item seq<item>
|
||||
|
||||
nsepseq<item,sep> ::=
|
||||
item
|
||||
| item sep nsepseq<item,sep>
|
||||
|
||||
sepseq<item,sep> ::= nsepseq<item,sep>?
|
||||
|
||||
(* The following are specific to the present grammar *)
|
||||
|
||||
list_of<item> ::= "[" item ";" ... "]"
|
||||
|
||||
csv<item> ::= item "," item "," ...
|
||||
|
||||
(* Entry *)
|
||||
|
||||
program ::= statement* EOF
|
||||
|
||||
statement ::=
|
||||
let_declarations
|
||||
| type_declaration
|
||||
|
||||
(* Type declarations *)
|
||||
|
||||
type_declaration ::= "type" type_name "=" type_expr
|
||||
|
||||
type_name == ident
|
||||
|
||||
type_expr ::=
|
||||
cartesian
|
||||
| sum_type
|
||||
| record_type
|
||||
|
||||
cartesian ::= fun_type "*" ...
|
||||
|
||||
fun_type ::=
|
||||
core_type "->" fun_type
|
||||
| core_type
|
||||
|
||||
core_type ::=
|
||||
type_name
|
||||
| type_param type_constr
|
||||
| "(" cartesian ")"
|
||||
|
||||
type_param ==
|
||||
core_type type_constr
|
||||
| type_tuple type_constr
|
||||
|
||||
type_constr == type_name
|
||||
|
||||
type_tuple ::= "(" type_expr "," ... ")"
|
||||
|
||||
sum_type ::= variant "|" ...
|
||||
|
||||
variant ::= constr "of" cartesian
|
||||
|
||||
constr == uident
|
||||
|
||||
record_type ::=
|
||||
"{" sep_or_term_list<field_decl, ";"> "}"
|
||||
|
||||
field_decl ::= field_name ":" type_expr
|
||||
|
||||
field_name == ident
|
||||
|
||||
(* Non-recursive value declarations *)
|
||||
|
||||
let_declarations ::= "let" let_bindings
|
||||
|
||||
let_bindings := let_binding "and" ...
|
||||
|
||||
let_binding ::=
|
||||
value_name pattern+ "=" expr
|
||||
| let_lhs "=" expr
|
||||
|
||||
value_name == ident
|
||||
|
||||
(* Patterns *)
|
||||
|
||||
let_lhs ::=
|
||||
pattern "::" cons_pat
|
||||
| pattern "," pattern "," ...
|
||||
| core_pattern
|
||||
|
||||
core_pattern ::=
|
||||
variable
|
||||
| "_"
|
||||
| "(" ")"
|
||||
| number
|
||||
| "true"
|
||||
| "false"
|
||||
| string
|
||||
| list_of<cons_pat>
|
||||
| "(" ptuple ")"
|
||||
| constr core_pattern
|
||||
|
||||
variable == ident
|
||||
number == int
|
||||
|
||||
ptuple ::= csv<cons_pat>
|
||||
|
||||
unit ::= "(" ")"
|
||||
|
||||
cons_pat ::=
|
||||
pattern "::" cons_pat
|
||||
| pattern
|
||||
|
||||
pattern ::=
|
||||
"(" cons_pat ")"
|
||||
| core_pattern
|
||||
|
||||
(* Expressions *)
|
||||
|
||||
expr ::=
|
||||
base_cond__open<expr>
|
||||
| match_expr<base_cond>
|
||||
|
||||
base_cond__open<x> ::=
|
||||
base_expr<x>
|
||||
| conditional<x>
|
||||
|
||||
base_cond ::= base_cond__open<base_cond>
|
||||
|
||||
base_expr<right_expr> ::=
|
||||
let_expr<right_expr>
|
||||
| fun_expr<right_expr>
|
||||
| csv<op_expr>
|
||||
| op_expr
|
||||
|
||||
conditional<right_expr> ::=
|
||||
if_then_else<right_expr>
|
||||
| if_then<right_expr>
|
||||
|
||||
if_then<right_expr> ::= "if" expr "then" right_expr
|
||||
|
||||
if_then_else<right_expr> ::=
|
||||
"if" expr "then" closed_if "else" right_expr
|
||||
|
||||
base_if_then_else__open<x> ::=
|
||||
base_expr<x>
|
||||
| if_then_else<x>
|
||||
|
||||
base_if_then_else ::=
|
||||
base_if_then_else__open<base_if_then_else>
|
||||
|
||||
closed_if ::=
|
||||
base_if_then_else__open<closed_if>
|
||||
| match_expr<base_if_then_else>
|
||||
|
||||
match_expr<right_expr> ::=
|
||||
"match" expr "with" cases<right_expr>
|
||||
|
||||
cases<right_expr> ::=
|
||||
case<right_expr>
|
||||
| cases<base_cond> "|" case<right_expr>
|
||||
|
||||
case<right_expr> ::= let_lhs "->" right_expr
|
||||
|
||||
let_in<right_expr> ::= "let" par_let "in" right_expr
|
||||
|
||||
fun_expr<right_expr> ::= "fun" pattern+ "->" right_expr
|
||||
|
||||
op_expr ::=
|
||||
op_expr "||" conj_expr
|
||||
| conj_expr
|
||||
|
||||
conj_expr ::=
|
||||
conj_expr "&&" comp_expr
|
||||
| comp_expr
|
||||
|
||||
comp_expr ::=
|
||||
comp_expr "<" cat_expr
|
||||
| comp_expr "<=" cat_expr
|
||||
| comp_expr ">" cat_expr
|
||||
| comp_expr ">=" cat_expr
|
||||
| comp_expr "=" cat_expr
|
||||
| comp_expr "<>" cat_expr
|
||||
| cat_expr
|
||||
|
||||
cat_expr ::=
|
||||
cons_expr "^" cat_expr
|
||||
| cons_expr
|
||||
|
||||
cons_expr ::=
|
||||
add_expr "::" cons_expr
|
||||
| add_expr
|
||||
|
||||
add_expr ::=
|
||||
add_expr "+" mult_expr
|
||||
| add_expr "-" mult_expr
|
||||
| mult_expr
|
||||
|
||||
mult_expr ::=
|
||||
mult_expr "*" unary_expr
|
||||
| mult_expr "div" unary_expr
|
||||
| mult_expr "mod" unary_expr
|
||||
| unary_expr
|
||||
|
||||
unary_expr ::=
|
||||
"-" core_expr
|
||||
| "not" core_expr
|
||||
| call_expr
|
||||
|
||||
call_expr ::=
|
||||
call_expr core_expr
|
||||
| core_expr
|
||||
|
||||
core_expr ::=
|
||||
number
|
||||
| module_name "." variable
|
||||
| string
|
||||
| char
|
||||
| "()"
|
||||
| "false"
|
||||
| "true"
|
||||
| list_of<expr>
|
||||
| "(" expr ")"
|
||||
| constr
|
||||
| sequence
|
||||
| record_expr
|
||||
|
||||
module_name == uident
|
||||
|
||||
record_expr ::=
|
||||
"{" sep_or_term_list(field_assignment,";") "}"
|
||||
|
||||
field_assignment ::= field_name "=" expr
|
||||
|
||||
sequence ::= "begin" (expr ";" ...)? "end"
|
270
src/parser/generator/doc/mini_ml2.bnf
Normal file
270
src/parser/generator/doc/mini_ml2.bnf
Normal file
@ -0,0 +1,270 @@
|
||||
(* Extended Backus-Naur Form (EBNF) for Mini-ML *)
|
||||
|
||||
(* LEXIS *)
|
||||
|
||||
let nl = ['\n' '\r']
|
||||
let blank = [' ' '\t']
|
||||
|
||||
let digit = ['0'-'9']
|
||||
let natural = digit | digit (digit | '_')* digit
|
||||
token int = '-'? natural
|
||||
|
||||
let small = ['a'-'z']
|
||||
let capital = ['A'-'Z']
|
||||
let letter = small | capital
|
||||
|
||||
let ichar = letter | digit | ['_' '\'']
|
||||
token ident = small ichar* | '_' ichar+
|
||||
token uident = capital ichar*
|
||||
|
||||
let esc = "\\n" | "\\\\" | "\\b" | "\\r" | "\\t"
|
||||
token string
|
||||
|
||||
let hexa = digit | ['A'-'F']
|
||||
let byte = hexa hexa
|
||||
let char_set = [^'\'' '\\'] # nl
|
||||
| "\\'" | esc | "\\x" byte | "\\0" digit digit
|
||||
token char = "'" char_set "'"
|
||||
|
||||
|
||||
(* SYNTAX *)
|
||||
|
||||
(* Helpers *)
|
||||
|
||||
(* The following are meant to be part of a library *)
|
||||
|
||||
sep_or_term_list<item,sep> ::=
|
||||
item sep ...
|
||||
| (item sep)+
|
||||
|
||||
seq<item> ::= nseq<item>?
|
||||
|
||||
nseq<item> ::= item seq<item>
|
||||
|
||||
nsepseq<item,sep> ::=
|
||||
item
|
||||
| item sep nsepseq<item,sep>
|
||||
|
||||
sepseq<item,sep> ::= nsepseq<item,sep>?
|
||||
|
||||
(* The following are specific to the present grammar *)
|
||||
|
||||
list_of<item> ::= "[" item ";" ... "]"
|
||||
|
||||
csv<item> ::= item "," item "," ...
|
||||
|
||||
(* Entry *)
|
||||
|
||||
program ::= statement* EOF
|
||||
|
||||
statement ::=
|
||||
let_declarations
|
||||
| type_declaration
|
||||
|
||||
(* Type declarations *)
|
||||
|
||||
type_declaration ::= "type" type_name "=" type_expr
|
||||
|
||||
type_name == ident
|
||||
|
||||
type_expr ::=
|
||||
cartesian
|
||||
| sum_type
|
||||
| record_type
|
||||
|
||||
cartesian ::= fun_type "*" ...
|
||||
|
||||
fun_type ::=
|
||||
core_type "->" fun_type
|
||||
| core_type
|
||||
|
||||
core_type ::=
|
||||
type_name
|
||||
| type_param type_constr
|
||||
| "(" cartesian ")"
|
||||
|
||||
type_param ==
|
||||
core_type type_constr
|
||||
| type_tuple type_constr
|
||||
|
||||
type_constr == type_name
|
||||
|
||||
type_tuple ::= "(" type_expr "," ... ")"
|
||||
|
||||
sum_type ::= variant "|" ...
|
||||
|
||||
variant ::= constr "of" cartesian
|
||||
|
||||
constr == uident
|
||||
|
||||
record_type ::=
|
||||
"{" sep_or_term_list<field_decl,";"> "}"
|
||||
|
||||
field_decl ::= field_name ":" type_expr
|
||||
|
||||
field_name == ident
|
||||
|
||||
(* Non-recursive value declarations *)
|
||||
|
||||
let_declarations ::= "let" let_bindings
|
||||
|
||||
let_bindings := let_binding "and" ...
|
||||
|
||||
let_binding ::=
|
||||
value_name pattern+ "=" expr
|
||||
| let_lhs "=" expr
|
||||
|
||||
value_name == ident
|
||||
|
||||
(* Patterns *)
|
||||
|
||||
let_lhs ::=
|
||||
pattern "::" cons_pat
|
||||
| pattern "," pattern "," ...
|
||||
| core_pattern
|
||||
|
||||
core_pattern ::=
|
||||
variable
|
||||
| "_"
|
||||
| "(" ")"
|
||||
| number
|
||||
| "true"
|
||||
| "false"
|
||||
| string
|
||||
| list_of<cons_pat>
|
||||
| "(" ptuple ")"
|
||||
| constr core_pattern
|
||||
|
||||
variable == ident
|
||||
number == int
|
||||
|
||||
ptuple ::= csv<cons_pat>
|
||||
|
||||
unit ::= "(" ")"
|
||||
|
||||
cons_pat ::=
|
||||
pattern "::" cons_pat
|
||||
| pattern
|
||||
|
||||
pattern ::=
|
||||
"(" cons_pat ")"
|
||||
| core_pattern
|
||||
|
||||
(* Expressions *)
|
||||
|
||||
expr ::=
|
||||
base_cond__open<expr>
|
||||
| match_expr<base_cond>
|
||||
|
||||
base_cond__open<x> ::=
|
||||
base_expr<x>
|
||||
| conditional<x>
|
||||
|
||||
base_cond ::= base_cond__open<base_cond>
|
||||
|
||||
base_expr<right_expr> ::=
|
||||
let_expr<right_expr>
|
||||
| fun_expr<right_expr>
|
||||
| csv<op_expr>
|
||||
| op_expr
|
||||
|
||||
conditional<right_expr> ::=
|
||||
if_then_else<right_expr>
|
||||
| if_then<right_expr>
|
||||
|
||||
if_then<right_expr> ::= "if" expr "then" right_expr
|
||||
|
||||
if_then_else<right_expr> ::=
|
||||
"if" expr "then" closed_if "else" right_expr
|
||||
|
||||
base_if_then_else__open<x> ::=
|
||||
base_expr<x>
|
||||
| if_then_else<x>
|
||||
|
||||
base_if_then_else ::=
|
||||
base_if_then_else__open<base_if_then_else>
|
||||
|
||||
closed_if ::=
|
||||
base_if_then_else__open<closed_if>
|
||||
| match_expr<base_if_then_else>
|
||||
|
||||
match_expr<right_expr> ::=
|
||||
"match" expr "with" cases<right_expr>
|
||||
|
||||
cases<right_expr> ::=
|
||||
case<right_expr>
|
||||
| cases<base_cond> "|" case<right_expr>
|
||||
|
||||
case<right_expr> ::= let_lhs "->" right_expr
|
||||
|
||||
let_in<right_expr> ::= "let" par_let "in" right_expr
|
||||
|
||||
fun_expr<right_expr> ::= "fun" pattern+ "->" right_expr
|
||||
|
||||
op_expr ::=
|
||||
op_expr "||" conj_expr
|
||||
| conj_expr
|
||||
|
||||
conj_expr ::=
|
||||
conj_expr "&&" comp_expr
|
||||
| comp_expr
|
||||
|
||||
comp_expr ::=
|
||||
comp_expr "<" cat_expr
|
||||
| comp_expr "<=" cat_expr
|
||||
| comp_expr ">" cat_expr
|
||||
| comp_expr ">=" cat_expr
|
||||
| comp_expr "=" cat_expr
|
||||
| comp_expr "<>" cat_expr
|
||||
| cat_expr
|
||||
|
||||
cat_expr ::=
|
||||
cons_expr "^" cat_expr
|
||||
| cons_expr
|
||||
|
||||
cons_expr ::=
|
||||
add_expr "::" cons_expr
|
||||
| add_expr
|
||||
|
||||
add_expr ::=
|
||||
add_expr "+" mult_expr
|
||||
| add_expr "-" mult_expr
|
||||
| mult_expr
|
||||
|
||||
mult_expr ::=
|
||||
mult_expr "*" unary_expr
|
||||
| mult_expr "div" unary_expr
|
||||
| mult_expr "mod" unary_expr
|
||||
| unary_expr
|
||||
|
||||
unary_expr ::=
|
||||
"-" core_expr
|
||||
| "not" core_expr
|
||||
| call_expr
|
||||
|
||||
call_expr ::=
|
||||
call_expr core_expr
|
||||
| core_expr
|
||||
|
||||
core_expr ::=
|
||||
number
|
||||
| module_name "." variable
|
||||
| string
|
||||
| char
|
||||
| "()"
|
||||
| "false"
|
||||
| "true"
|
||||
| list_of<expr>
|
||||
| "(" expr ")"
|
||||
| constr
|
||||
| sequence
|
||||
| record_expr
|
||||
|
||||
module_name == uident
|
||||
|
||||
record_expr ::=
|
||||
"{" sep_or_term_list<field_assignment,";"> "}"
|
||||
|
||||
field_assignment ::= field_name "=" expr
|
||||
|
||||
sequence ::= "begin" (expr ";" ...)? "end"
|
249
src/parser/generator/doc/mini_ml3.bnf
Normal file
249
src/parser/generator/doc/mini_ml3.bnf
Normal file
@ -0,0 +1,249 @@
|
||||
(* Extended Backus-Naur Form (EBNF) for Mini-ML *)
|
||||
|
||||
(* LEXIS *)
|
||||
|
||||
let nl = ['\n' '\r']
|
||||
let blank = [' ' '\t']
|
||||
|
||||
let digit = ['0'-'9']
|
||||
let natural = digit | digit (digit | '_')* digit
|
||||
token int = '-'? natural
|
||||
|
||||
let small = ['a'-'z']
|
||||
let capital = ['A'-'Z']
|
||||
let letter = small | capital
|
||||
|
||||
let ichar = letter | digit | ['_' '\'']
|
||||
token ident = small ichar* | '_' ichar+
|
||||
token uident = capital ichar*
|
||||
|
||||
let esc = "\\n" | "\\\\" | "\\b" | "\\r" | "\\t"
|
||||
let hexa = digit | ['A'-'F']
|
||||
let byte = hexa hexa
|
||||
let char_set = [^'\'' '\\'] # nl
|
||||
| "\\'" | esc | "\\x" byte | "\\0" digit digit
|
||||
token char = "'" char_set "'"
|
||||
|
||||
token string
|
||||
|
||||
|
||||
(* SYNTAX *)
|
||||
|
||||
(* Helpers *)
|
||||
|
||||
(* The following are meant to be part of a library *)
|
||||
|
||||
sep_or_term_list<item,sep> ::=
|
||||
item sep etc.
|
||||
| (item sep)+
|
||||
|
||||
seq<item> ::= nseq<item>?
|
||||
|
||||
nseq<item> ::= item seq<item>
|
||||
|
||||
nsepseq<item,sep> ::=
|
||||
item
|
||||
| item sep nsepseq<item,sep>
|
||||
|
||||
sepseq<item,sep> ::= nsepseq<item,sep>?
|
||||
|
||||
(* The following are specific to the present grammar *)
|
||||
|
||||
list_of<item> ::= "[" item ";" etc. "]"
|
||||
|
||||
csv<item> ::= item "," item "," etc.
|
||||
|
||||
(* Entry *)
|
||||
|
||||
program ::= statement*
|
||||
|
||||
statement ::=
|
||||
let_declarations
|
||||
| type_declaration
|
||||
|
||||
(* Type declarations *)
|
||||
|
||||
type_declaration ::= "type" type_name "=" type_expr
|
||||
|
||||
type_name == ident
|
||||
|
||||
type_expr ::=
|
||||
cartesian
|
||||
| sum_type
|
||||
| record_type
|
||||
|
||||
cartesian ::= fun_type "*" etc.
|
||||
|
||||
fun_type ::=
|
||||
core_type "->" fun_type
|
||||
| core_type
|
||||
|
||||
core_type ::=
|
||||
type_name
|
||||
| type_param type_constr
|
||||
| "(" cartesian ")"
|
||||
|
||||
type_param ==
|
||||
core_type type_constr
|
||||
| type_tuple type_constr
|
||||
|
||||
type_constr == type_name
|
||||
|
||||
type_tuple ::= "(" type_expr "," etc. ")"
|
||||
|
||||
sum_type ::= "|"? variant "|" etc.
|
||||
|
||||
variant ::= constr "of" cartesian
|
||||
|
||||
constr == uident
|
||||
|
||||
record_type ::=
|
||||
"{" sep_or_term_list<field_decl,";"> "}"
|
||||
|
||||
field_decl ::= field_name ":" type_expr
|
||||
|
||||
field_name == ident
|
||||
|
||||
(* Non-recursive value declarations *)
|
||||
|
||||
let_declarations ::= "let" let_bindings
|
||||
|
||||
let_bindings := let_binding "and" etc.
|
||||
|
||||
let_binding ::=
|
||||
value_name pattern+ "=" expr
|
||||
| let_lhs "=" expr
|
||||
|
||||
value_name == ident
|
||||
|
||||
(* Patterns *)
|
||||
|
||||
let_lhs ::=
|
||||
pattern "::" cons_pat
|
||||
| pattern "," pattern "," etc.
|
||||
| core_pattern
|
||||
|
||||
core_pattern ::=
|
||||
variable
|
||||
| "_"
|
||||
| "(" ")"
|
||||
| number
|
||||
| "true"
|
||||
| "false"
|
||||
| string
|
||||
| list_of<cons_pat>
|
||||
| "(" ptuple ")"
|
||||
| constr core_pattern
|
||||
|
||||
variable == ident
|
||||
number == int
|
||||
|
||||
ptuple ::= csv<cons_pat>
|
||||
|
||||
unit ::= "(" ")"
|
||||
|
||||
cons_pat ::=
|
||||
pattern "::" cons_pat
|
||||
| pattern
|
||||
|
||||
pattern ::=
|
||||
"(" cons_pat ")"
|
||||
| core_pattern
|
||||
|
||||
(* Expressions *)
|
||||
|
||||
expr ::=
|
||||
base_cond__<expr>
|
||||
| match_expr<base_cond>
|
||||
|
||||
base_cond__<x> ::=
|
||||
base_expr<x>
|
||||
| conditional<x>
|
||||
|
||||
base_cond ::= base_cond__<base_cond>
|
||||
|
||||
base_expr<right_expr> ::=
|
||||
let_expr<right_expr>
|
||||
| fun_expr<right_expr>
|
||||
| csv<op_expr>
|
||||
| op_expr
|
||||
|
||||
conditional<right_expr> ::=
|
||||
if_then_else<right_expr>
|
||||
| if_then<right_expr>
|
||||
|
||||
if_then<right_expr> ::= "if" expr "then" right_expr
|
||||
|
||||
if_then_else<right_expr> ::=
|
||||
"if" expr "then" closed_if "else" right_expr
|
||||
|
||||
base_if_then_else__<x> ::=
|
||||
base_expr<x>
|
||||
| if_then_else<x>
|
||||
|
||||
base_if_then_else ::=
|
||||
base_if_then_else__<base_if_then_else>
|
||||
|
||||
closed_if ::=
|
||||
base_if_then_else__<closed_if>
|
||||
| match_expr<base_if_then_else>
|
||||
|
||||
match_expr<right_expr> ::=
|
||||
"match" expr "with" cases<right_expr>
|
||||
|
||||
cases<right_expr> ::=
|
||||
case<right_expr>
|
||||
| cases<base_cond> "|" case<right_expr>
|
||||
|
||||
case<right_expr> ::= let_lhs "->" right_expr
|
||||
|
||||
let_in<right_expr> ::= "let" par_let "in" right_expr
|
||||
|
||||
fun_expr<right_expr> ::= "fun" pattern+ "->" right_expr
|
||||
|
||||
op_expr ::=
|
||||
op_expr "||" %left %prec1 op_expr
|
||||
| op_expr "&&" %left %prec2 op_expr
|
||||
| op_expr "<" %left %prec3 op_expr
|
||||
| op_expr "<=" %left %prec3 op_expr
|
||||
| op_expr ">" %left %prec3 op_expr
|
||||
| op_expr ">=" %left %prec3 op_expr
|
||||
| op_expr "=" %left %prec3 op_expr
|
||||
| op_expr "<>" %left %prec3 op_expr
|
||||
| op_expr "^" %right %prec4 op_expr
|
||||
| op_expr "::" %right %prec5 op_expr
|
||||
| op_expr "+" %left %prec6 op_expr
|
||||
| op_expr "-" %left %prec6 op_expr
|
||||
| op_expr "*" %left %prec7 op_expr
|
||||
| op_expr "div" %left %prec7 op_expr
|
||||
| op_expr "mod" %left %prec7 op_expr
|
||||
| "-" %prec8 op_expr
|
||||
| "not" %prec8 op_expr
|
||||
| call_expr
|
||||
|
||||
call_expr ::=
|
||||
call_expr core_expr
|
||||
| core_expr
|
||||
|
||||
core_expr ::=
|
||||
number
|
||||
| module_name "." variable
|
||||
| string
|
||||
| char
|
||||
| "()"
|
||||
| "false"
|
||||
| "true"
|
||||
| list_of<expr>
|
||||
| "(" expr ")"
|
||||
| constr
|
||||
| sequence
|
||||
| record_expr
|
||||
|
||||
module_name == uident
|
||||
|
||||
record_expr ::=
|
||||
"{" sep_or_term_list<field_assignment,";"> "}"
|
||||
|
||||
field_assignment ::= field_name "=" expr
|
||||
|
||||
sequence ::= "begin" sep_or_term_list<expr,";">? "end"
|
336
src/parser/generator/doc/mini_ml4.bnf
Normal file
336
src/parser/generator/doc/mini_ml4.bnf
Normal file
@ -0,0 +1,336 @@
|
||||
(* Extended Backus-Naur Form (EBNF) for Mini-ML *)
|
||||
|
||||
(* LEXIS *)
|
||||
|
||||
let digit = ['0'-'9']
|
||||
let natural = digit | digit (digit | '_')* digit
|
||||
%token integer = '-'? natural
|
||||
%token natural = natural 'n'
|
||||
|
||||
let small = ['a'-'z']
|
||||
let capital = ['A'-'Z']
|
||||
let letter = small | capital
|
||||
|
||||
let ichar = letter | digit | ['_' '\'']
|
||||
%token ident = small ichar* | '_' ichar+
|
||||
%token uident = capital ichar*
|
||||
|
||||
let esc = "\\n" | "\\\\" | "\\b" | "\\r" | "\\t"
|
||||
let hexa = digit | ['A'-'F']
|
||||
let byte = hexa hexa
|
||||
let char_set = [^'\'' '\\'] # nl
|
||||
| "\\'" | esc | "\\x" byte | "\\0" digit digit
|
||||
%token chr = "'" char_set "'"
|
||||
|
||||
%token str
|
||||
|
||||
%token bool_or = "||" %left %prec1
|
||||
%token bool_and = "&&" %left %prec2
|
||||
%token lt = "<" %left %prec3
|
||||
%token le = "<=" %left %prec3
|
||||
%token gt = ">" %left %prec3
|
||||
%token ge = ">=" %left %prec3
|
||||
%token eq = "=" %left %prec3
|
||||
%token ne = "<>" %left %prec3
|
||||
%token cat = "^" %right %prec4
|
||||
%token cons = "::" %right %prec5
|
||||
%token plus = "+" %left %prec6
|
||||
%token minus = "-" %left %prec6
|
||||
%token times = "*" %left %prec7
|
||||
%token slash = "/" %left %prec7
|
||||
%token kwd_div = "div" %left %prec7
|
||||
%token kwd_mod = "mod" %left %prec7
|
||||
%token uminus = "-" %prec8
|
||||
%token kwd_not = "not" %prec8
|
||||
|
||||
%token lpar = "("
|
||||
%token rpar = ")"
|
||||
%token lbracket = "["
|
||||
%token rbracket = "]"
|
||||
%token lbrace = "{"
|
||||
%token rbrace = "}"
|
||||
%token semi = ";"
|
||||
%token comma = ","
|
||||
%token colon = ":"
|
||||
%token vbar = "|"
|
||||
%token arrow = "->"
|
||||
%token wild = "_"
|
||||
|
||||
(* SYNTAX *)
|
||||
|
||||
(* Helpers *)
|
||||
|
||||
(* The following are meant to be part of a library *)
|
||||
|
||||
%ocaml "Utils"
|
||||
type 'item seq = 'item list
|
||||
type 'item nseq = 'item * 'item seq
|
||||
type ('item,'sep) nsepseq = 'item * ('sep * 'item) list
|
||||
type ('item,'sep) sepseq = ('item,'sep) nsepseq option
|
||||
type ('item,'sep) sep_or_term_list =
|
||||
('item,'sep) nsepseq * 'sep option
|
||||
%end
|
||||
|
||||
%menhir_decl "Parser"
|
||||
%start program interactive_expr
|
||||
%type <AST.t> program
|
||||
%type <AST.expr> interactive_expr
|
||||
%type <('item,'sep) sep_or_term_list> sep_or_term_list
|
||||
%end
|
||||
|
||||
%menhir_rule "Parser"
|
||||
seq(item):
|
||||
(**) { [] }
|
||||
| X seq(item) { $1::$2 }
|
||||
|
||||
nseq(item):
|
||||
item seq(item) { $1,$2 }
|
||||
|
||||
nsepseq(item,sep):
|
||||
item { $1, [] }
|
||||
| item sep nsepseq(item,sep) { let h,t = $3 in $1, ($2,h)::t }
|
||||
|
||||
sepseq(item,sep):
|
||||
(**) { None }
|
||||
| nsepseq(item,sep) { Some $1 }
|
||||
|
||||
sep_or_term_list(item,sep):
|
||||
nsepseq(item,sep) {
|
||||
$1, None
|
||||
}
|
||||
| nseq(item sep {$1,$2}) {
|
||||
let (first,sep), tail = $1 in
|
||||
let rec trans (seq, prev_sep as acc) = function
|
||||
[] -> acc
|
||||
| (item,next_sep)::others ->
|
||||
trans ((prev_sep,item)::seq, next_sep) others in
|
||||
let list, term = trans ([],sep) tail
|
||||
in (first, List.rev list), Some term }
|
||||
%end
|
||||
|
||||
(* The following are specific to the present grammar *)
|
||||
|
||||
list<item> ::= "[" item ";" etc. "]"
|
||||
|
||||
tuple<item> ::= item "," item "," etc.
|
||||
|
||||
par<item> ::= "(" item ")"
|
||||
|
||||
(* Entry *)
|
||||
|
||||
program == statement*
|
||||
|
||||
statement ::=
|
||||
let_declarations { `Let }
|
||||
| type_declaration { `TypeDecl }
|
||||
|
||||
(* Type declarations *)
|
||||
|
||||
type_declaration == "type" type_name "=" type_expr
|
||||
|
||||
type_name == ident
|
||||
|
||||
type_expr ::=
|
||||
cartesian { `T_Prod }
|
||||
| sum_type { `T_Sum }
|
||||
| record_type { `T_Record }
|
||||
|
||||
cartesian == fun_type "*" etc.
|
||||
|
||||
fun_type ::=
|
||||
core_type "->" fun_type { `T_Fun }
|
||||
| core_type { `T_Core }
|
||||
|
||||
core_type ::=
|
||||
type_name { `T_Alias }
|
||||
| type_param type_constr { `T_App }
|
||||
| par<cartesian>
|
||||
|
||||
type_param ::=
|
||||
par<type_expr "," etc.>
|
||||
| core_type type_constr { `T_App }
|
||||
|
||||
type_constr ::=
|
||||
ident { `T_Constr }
|
||||
| "set"
|
||||
| "map"
|
||||
| "list"
|
||||
|
||||
sum_type == "|"? variant "|" etc.
|
||||
|
||||
variant == constr "of" cartesian
|
||||
|
||||
constr == uident
|
||||
|
||||
record_type ==
|
||||
"{" sep_or_term_list<field_decl,";"> "}"
|
||||
|
||||
field_decl == field_name ":" type_expr
|
||||
|
||||
field_name == ident
|
||||
|
||||
(* Non-recursive value declarations *)
|
||||
|
||||
let_declarations == "let" let_bindings
|
||||
|
||||
let_bindings == let_binding "and" etc.
|
||||
|
||||
let_binding ::=
|
||||
variable sub_irrefutable+ "=" expr { `LetFun }
|
||||
| irrefutable "=" expr { `LetNonFun }
|
||||
|
||||
(* Patterns *)
|
||||
|
||||
irrefutable ::=
|
||||
tuple<sub_irrefutable> { `P_Tuple }
|
||||
| sub_irrefutable
|
||||
|
||||
sub_irrefutable ::=
|
||||
variable { `P_Var }
|
||||
| "_" { `P_Wild }
|
||||
| unit { `P_Unit }
|
||||
| par<closed_irrefutable>
|
||||
|
||||
closed_irrefutable ::=
|
||||
tuple<sub_irrefutable>
|
||||
| sub_irrefutable { `P_SubI }
|
||||
|
||||
pattern ::=
|
||||
sub_pattern "::" tail { `P_Cons }
|
||||
| tuple<sub_pattern> { `P_Tuple }
|
||||
| core_pattern { `P_Core }
|
||||
|
||||
sub_pattern ::=
|
||||
par<tail>
|
||||
| core_pattern { `P_Core }
|
||||
|
||||
core_pattern ::=
|
||||
variable { `P_Var }
|
||||
| "_" { `P_Wild }
|
||||
| unit { `P_Unit }
|
||||
| integer { `P_Int }
|
||||
| natural { `P_Nat }
|
||||
| "true" { `P_True }
|
||||
| "false" { `P_False }
|
||||
| str { `P_Str }
|
||||
| chr { `P_Chr }
|
||||
| list<tail> { `P_List }
|
||||
| constr sub_pattern { `P_Constr }
|
||||
| record_pattern { `P_Record }
|
||||
| par<tuple<tail>>
|
||||
|
||||
variable == ident
|
||||
|
||||
record_pattern ::=
|
||||
"{" sep_or_term_list<field_pattern,";"> "}"
|
||||
|
||||
field_pattern ::= field_name "=" sub_pattern
|
||||
|
||||
unit ::= "(" ")"
|
||||
|
||||
tail ::=
|
||||
sub_pattern "::" tail
|
||||
| sub_pattern
|
||||
|
||||
(* Expressions *)
|
||||
|
||||
expr ::=
|
||||
base_cond__<expr>
|
||||
| match_expr<base_cond>
|
||||
|
||||
base_cond__<x> ::=
|
||||
base_expr<x>
|
||||
| conditional<x>
|
||||
|
||||
base_cond == base_cond__<base_cond>
|
||||
|
||||
base_expr<right_expr> ::=
|
||||
let_expr<right_expr>
|
||||
| fun_expr<right_expr>
|
||||
| csv<op_expr>
|
||||
|
||||
conditional<right_expr> ::=
|
||||
if_then_else<right_expr>
|
||||
| if_then<right_expr>
|
||||
|
||||
if_then<right_expr> ::=
|
||||
"if" expr "then" right_expr { `IfThen }
|
||||
|
||||
if_then_else<right_expr> ::=
|
||||
"if" expr "then" closed_if "else" right_expr { `IfThenElse }
|
||||
|
||||
base_if_then_else__<x> ::=
|
||||
base_expr<x>
|
||||
| if_then_else<x>
|
||||
|
||||
base_if_then_else ::=
|
||||
base_if_then_else__<base_if_then_else>
|
||||
|
||||
closed_if ::=
|
||||
base_if_then_else__<closed_if>
|
||||
| match_expr<base_if_then_else>
|
||||
|
||||
match_expr<right_expr> ::=
|
||||
"match" expr "with" cases<right_expr>
|
||||
|
||||
cases<right_expr> ::=
|
||||
case<right_expr>
|
||||
| cases<base_cond> "|" case<right_expr>
|
||||
|
||||
case<right_expr> ::= pattern "->" right_expr
|
||||
|
||||
let_in<right_expr> ::= "let" par_let "in" right_expr
|
||||
|
||||
fun_expr<right_expr> ::= "fun" sub_pattern+ "->" right_expr
|
||||
|
||||
op_expr ::=
|
||||
op_expr "||" op_expr
|
||||
| op_expr "&&" op_expr
|
||||
| op_expr "<" op_expr
|
||||
| op_expr "<=" op_expr
|
||||
| op_expr ">" op_expr
|
||||
| op_expr ">=" op_expr
|
||||
| op_expr "=" op_expr
|
||||
| op_expr "<>" op_expr
|
||||
| op_expr "^" op_expr
|
||||
| op_expr "::" op_expr
|
||||
| op_expr "+" op_expr
|
||||
| op_expr "-" op_expr
|
||||
| op_expr "*" op_expr
|
||||
| op_expr "/" op_expr
|
||||
| op_expr "div" op_expr
|
||||
| op_expr "mod" op_expr
|
||||
| "-" op_expr
|
||||
| "not" op_expr
|
||||
| call_expr
|
||||
|
||||
call_expr ::=
|
||||
call_expr core_expr
|
||||
| core_expr
|
||||
|
||||
core_expr ::=
|
||||
variable
|
||||
| module_name "." path
|
||||
| unit
|
||||
| integer
|
||||
| natural
|
||||
| "false"
|
||||
| "true"
|
||||
| str
|
||||
| chr
|
||||
| constr
|
||||
| sequence
|
||||
| record_expr
|
||||
| list<expr>
|
||||
| par<expr>
|
||||
|
||||
module_name == uident
|
||||
|
||||
path == ident "." etc.
|
||||
|
||||
record_expr ::=
|
||||
"{" sep_or_term_list<field_assignment,";"> "}"
|
||||
|
||||
field_assignment ::= field_name "=" expr
|
||||
|
||||
sequence ::= "begin" sep_or_term_list<expr,";">? "end"
|
Loading…
Reference in New Issue
Block a user