290 lines
5.9 KiB
Text
290 lines
5.9 KiB
Text
# Grammar for ECMArkup grammar descriptions
|
|
|
|
var token CHR; # <NL>
|
|
var token EQ; # ::
|
|
var token MATCH_REF; # $0
|
|
var token NL; # (actual newline character)
|
|
var token NT; # IdentifierName
|
|
var token NTALT; # |LineTerminator|
|
|
var token NTCALL; # Expression (when followed by `[` or `<`)
|
|
var token PRODID; # #comment
|
|
var token PROSE; # > any text following a greater than sign
|
|
var token T; # `var`
|
|
var token WPROSE; # [> any text after greater than sign, wrapped in brackets]
|
|
var token RUSTCOMMENT;# //comment
|
|
|
|
token But = "but";
|
|
token Empty = "empty";
|
|
token Here = "here";
|
|
token Lookahead = "lookahead";
|
|
token No = "no";
|
|
token Not = "not";
|
|
token Of = "of";
|
|
token One = "one";
|
|
token Or = "or";
|
|
token Through = "through";
|
|
token Returns = "returns";
|
|
token Some = "Some";
|
|
token None = "None";
|
|
token Arrow = "=>";
|
|
token Comma = ",";
|
|
token OpenBracket = "[";
|
|
token CloseBracket = "]";
|
|
token QuestionMark = "?";
|
|
token Tilde = "~";
|
|
token PlusSign = "+";
|
|
token Equal = "=";
|
|
token Equals = "==";
|
|
token IsNotEqualTo = "!=";
|
|
token IsNotIn = "<!";
|
|
token OpenBrace = "{";
|
|
token CloseBrace = "}";
|
|
token OpenParen = "(";
|
|
token CloseParen = ")";
|
|
token AtSign = "@";
|
|
token OpenAngle = "<";
|
|
token CloseAngle = ">";
|
|
token Impl = "impl";
|
|
token For = "for";
|
|
token Let = "let";
|
|
token SemiColon = ";";
|
|
token Lifetime = "'";
|
|
|
|
// Entry point for grammar_extension! macro's content.
|
|
goal nt rust_edsl {
|
|
rust_impl rust_nt_def_list => rust_edsl($0, $1);
|
|
}
|
|
|
|
nt rust_impl {
|
|
"impl" nt_type "for" nt_type "{" "}" ";" => rust_impl($1, $3);
|
|
"impl" "<" nt_type_params ">" nt_type "for" nt_type "{" "}" ";" => rust_param_impl($4, $6, $2);
|
|
}
|
|
|
|
nt rust_nt_def_list {
|
|
rust_nt_def_or_blank_line;
|
|
rust_nt_def_list rust_nt_def_or_blank_line => concat($0, $1);
|
|
}
|
|
|
|
nt rust_nt_def_or_blank_line {
|
|
NL => blank_line();
|
|
RUSTCOMMENT => blank_line();
|
|
rust_nt_def => nt_def_to_list($0);
|
|
}
|
|
|
|
// grammar extension syntax for adding/removing/extending the productions.
|
|
nt rust_nt_def {
|
|
"let" nt_lhs "=" "{" rust_rhs_line "}" ";" => rust_nt_def($1, $4);
|
|
}
|
|
|
|
nt rust_rhs_line {
|
|
rust_symbols => rust_rhs_line($0);
|
|
}
|
|
|
|
nt rust_symbols {
|
|
rust_symbol;
|
|
rust_symbols rust_symbol => concat($0, $1);
|
|
}
|
|
|
|
nt rust_symbol {
|
|
"{" rust_expr "}" => single($1);
|
|
symbol => single($0);
|
|
NL => empty();
|
|
}
|
|
|
|
nt rust_expr {
|
|
expr => rust_expr($0);
|
|
}
|
|
|
|
// Entry point for esgrammar files.
|
|
goal nt grammar {
|
|
nt_def_list;
|
|
}
|
|
|
|
nt nt_def_list {
|
|
nt_def_or_blank_line;
|
|
nt_def_list nt_def_or_blank_line => concat($0, $1);
|
|
}
|
|
|
|
nt nt_def_or_blank_line {
|
|
NL => blank_line();
|
|
nt_def => nt_def_to_list($0);
|
|
}
|
|
|
|
nt nt_def {
|
|
nt_type_line? nt_lhs EQ NL rhs_lines NL => nt_def($0, $1, $2, $4);
|
|
nt_type_line? nt_lhs EQ "one" "of" NL t_list_lines NL => nt_def_one_of($0, $1, $2, $6);
|
|
}
|
|
|
|
nt nt_lhs {
|
|
NT => nt_lhs_no_params($0);
|
|
NTCALL "[" params "]" => nt_lhs_with_params($0, $2);
|
|
}
|
|
|
|
nt params {
|
|
param => single($0);
|
|
params "," param => append($0, $2);
|
|
}
|
|
|
|
nt param {
|
|
NT;
|
|
}
|
|
|
|
nt nt_type_line {
|
|
"@" "returns" nt_type NL => $2;
|
|
}
|
|
|
|
// Define a type as understood by Rust type-system.
|
|
nt nt_type {
|
|
NT => simple_type($0);
|
|
NTCALL "<" nt_type_params ">" => parameterized_type($0, $2);
|
|
}
|
|
|
|
nt nt_type_params {
|
|
nt_type_param => single($0);
|
|
nt_type_params "," nt_type_param => append($0, $2);
|
|
}
|
|
|
|
nt nt_type_param {
|
|
nt_type;
|
|
"'" NT => lifetime_type($0);
|
|
}
|
|
|
|
nt t_list_lines {
|
|
t_list_line;
|
|
t_list_lines t_list_line => concat($0, $1);
|
|
}
|
|
|
|
nt t_list_line {
|
|
terminal_seq NL => t_list_line($0);
|
|
}
|
|
|
|
nt terminal_seq {
|
|
terminal => single($0);
|
|
terminal_seq terminal => append($0, $1);
|
|
}
|
|
|
|
nt terminal {
|
|
T => terminal($0);
|
|
CHR => chr($0);
|
|
}
|
|
|
|
nt rhs_lines {
|
|
rhs_line => single($0);
|
|
rhs_lines rhs_line => append($0, $1);
|
|
}
|
|
|
|
nt rhs_line {
|
|
ifdef? rhs reducer? PRODID? NL => rhs_line($0, $1, $2, $3);
|
|
PROSE NL => rhs_line_prose($0);
|
|
}
|
|
|
|
nt rhs {
|
|
symbols;
|
|
"[" "empty" "]" => empty_rhs();
|
|
}
|
|
|
|
nt reducer {
|
|
NL? "=>" expr => $2;
|
|
}
|
|
|
|
nt expr {
|
|
MATCH_REF => expr_match_ref($0);
|
|
NT "(" expr_args? ")" expr_try? => expr_call($0, $2, $4);
|
|
"Some" "(" expr ")" => expr_some($2);
|
|
"None" => expr_none();
|
|
}
|
|
|
|
nt expr_try {
|
|
"?";
|
|
}
|
|
|
|
nt expr_args {
|
|
expr => single($0);
|
|
expr_args "," expr => append($0, $2);
|
|
}
|
|
|
|
nt ifdef {
|
|
"[" definite_sigil NT "]" => ifdef($1, $2);
|
|
}
|
|
|
|
nt symbols {
|
|
symbol => single($0);
|
|
symbols symbol => append($0, $1);
|
|
}
|
|
|
|
nt symbol {
|
|
terminal;
|
|
nonterminal;
|
|
nonterminal "?" => optional($0);
|
|
nonterminal "but" "not" exclusion => but_not($0, $3);
|
|
nonterminal "but" "not" "one" "of" exclusion_list => but_not_one_of($0, $5);
|
|
"[" "lookahead" lookahead_assertion "]" => $2;
|
|
no_line_terminator_here;
|
|
WPROSE => $0;
|
|
}
|
|
|
|
nt no_line_terminator_here {
|
|
"[" "no" line_terminator "here" "]" => no_line_terminator_here($2);
|
|
}
|
|
|
|
nt nonterminal {
|
|
NT => nonterminal($0);
|
|
NTCALL "[" args "]" => nonterminal_apply($0, $2);
|
|
}
|
|
|
|
nt args {
|
|
arg => single($0);
|
|
args "," arg => append($0, $2);
|
|
}
|
|
|
|
nt arg {
|
|
sigil NT => arg_expr($0, $1);
|
|
}
|
|
|
|
nt sigil {
|
|
definite_sigil;
|
|
"?";
|
|
}
|
|
|
|
nt definite_sigil {
|
|
"~" => sigil_false();
|
|
"+" => sigil_true();
|
|
}
|
|
|
|
nt exclusion_list {
|
|
exclusion => single($0);
|
|
exclusion_list "or" exclusion => append($0, $2);
|
|
}
|
|
|
|
nt exclusion {
|
|
terminal => exclusion_terminal($0);
|
|
nonterminal => exclusion_nonterminal($0);
|
|
CHR "through" CHR => exclusion_chr_range($0, $2);
|
|
}
|
|
|
|
nt lookahead_assertion {
|
|
"==" terminal => la_eq($1);
|
|
"!=" terminal => la_ne($1);
|
|
"<!" NT => la_not_in_nonterminal($1);
|
|
"<!" "{" lookahead_exclusions "}" => la_not_in_set($2);
|
|
}
|
|
|
|
nt lookahead_exclusions {
|
|
lookahead_exclusion => single($0);
|
|
lookahead_exclusions "," lookahead_exclusion => append($0, $2);
|
|
}
|
|
|
|
nt lookahead_exclusion {
|
|
lookahead_exclusion_element => single($0);
|
|
lookahead_exclusion lookahead_exclusion_element => append($0, $1);
|
|
}
|
|
|
|
nt lookahead_exclusion_element {
|
|
terminal;
|
|
no_line_terminator_here;
|
|
}
|
|
|
|
nt line_terminator {
|
|
NT;
|
|
NTALT;
|
|
}
|