use crate::syntax::Kind;
use sipha::expr;
pub fn add_expr_minimal(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("expr", |g: &mut sipha::builder::GrammarBuilder| {
g.node(Kind::NodeExpr, |g| {
g.choices(vec![
Box::new(|g| {
g.call("number_lit");
}),
Box::new(|g| {
g.call("string_lit");
}),
Box::new(|g| {
g.call("ident");
}),
Box::new(|g| {
g.call("lparen");
g.call("expr");
g.call("rparen");
}),
]);
});
});
}
pub fn add_primary(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("primary", |g: &mut sipha::builder::GrammarBuilder| {
g.node(Kind::NodePrimaryExpr, |g| {
g.choices(vec![
Box::new(|g| {
g.call("number_lit");
}),
Box::new(|g| {
g.call("string_lit");
}),
Box::new(|g| {
g.keyword(Kind::KwTrue, b"true");
}),
Box::new(|g| {
g.keyword(Kind::KwFalse, b"false");
}),
Box::new(|g| {
g.keyword(Kind::KwNull, b"null");
}),
Box::new(|g| {
g.call("special_lit");
}),
Box::new(|g| {
g.keyword(Kind::KwNew, b"new");
g.call("ident");
g.optional(|g| {
g.call("lparen");
g.optional(|g| {
g.call("expr");
g.zero_or_more(|g| {
g.call("comma");
g.call("expr");
});
});
g.call("rparen");
});
}),
Box::new(|g| {
g.node(Kind::NodeAnonFn, |g| {
g.keyword(Kind::KwFunction, b"function");
g.call("lparen");
g.optional(|g| {
g.call("param");
g.zero_or_more(|g| {
g.call("comma");
g.call("param");
});
});
g.call("rparen");
g.call("block");
});
}),
Box::new(|g| {
g.call("keyword_or_ident");
}),
Box::new(|g| {
g.node(Kind::NodeAnonFn, |g| {
g.call("lparen");
g.optional(|g| {
g.call("param");
g.zero_or_more(|g| {
g.call("comma");
g.call("param");
});
});
g.call("rparen");
g.call("arrow");
g.choices(vec![
Box::new(|g| {
g.call("expr");
}),
Box::new(|g| {
g.call("block");
}),
]);
});
}),
Box::new(|g| {
g.call("lparen");
g.call("expr");
g.call("rparen");
}),
Box::new(|g| {
g.call("bracket_literal");
}),
Box::new(|g| {
g.node(Kind::NodeSet, |g| {
g.call("op_lt");
g.choices(vec![
Box::new(|g| {
g.call("op_gt");
}),
Box::new(|g| {
g.call("expr");
g.zero_or_more(|g| {
g.call("comma");
g.call("expr");
});
g.call("op_gt");
}),
]);
});
}),
Box::new(|g| {
g.call("lbrace");
g.optional(|g| {
g.call("object_pair");
g.zero_or_more(|g| {
g.call("comma");
g.call("object_pair");
});
});
g.call("rbrace");
}),
]);
});
});
}
pub fn add_interval_literal(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule(
"interval_literal",
|g: &mut sipha::builder::GrammarBuilder| {
g.node(Kind::NodeInterval, |g| {
g.choices(vec![
Box::new(|g| {
g.call("rbracket");
g.call("expr");
g.call("dot_dot");
g.call("expr");
g.call("rbracket");
}),
Box::new(|g| {
g.call("rbracket");
g.call("expr");
g.call("dot_dot");
g.call("expr");
g.call("lbracket");
}),
Box::new(|g| {
g.call("lbracket");
g.call("expr");
g.call("dot_dot");
g.call("expr");
g.call("rbracket");
}),
Box::new(|g| {
g.call("lbracket");
g.call("expr");
g.call("dot_dot");
g.call("expr");
g.call("lbracket");
}),
]);
});
},
);
}
pub fn add_bracket_literal(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule(
"bracket_literal",
|g: &mut sipha::builder::GrammarBuilder| {
g.choices(vec![
Box::new(|g| {
g.node(Kind::NodeArray, |g| {
g.call("lbracket");
g.optional(|g| {
g.call("expr_as");
g.zero_or_more(|g| {
g.call("comma");
g.call("expr_as");
});
g.optional(|g| {
g.call("comma");
});
});
g.call("rbracket");
});
}),
Box::new(|g| {
g.call("interval_literal");
}),
Box::new(|g| {
g.node(Kind::NodeMap, |g| {
g.call("lbracket");
g.call("op_colon");
g.call("rbracket");
});
}),
Box::new(|g| {
g.node(Kind::NodeMap, |g| {
g.call("lbracket");
g.call("map_pair");
g.zero_or_more(|g| {
g.call("comma");
g.call("map_pair");
});
g.call("rbracket");
});
}),
]);
},
);
}
pub fn add_map_pair(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("map_pair", |g: &mut sipha::builder::GrammarBuilder| {
g.node(Kind::NodeMapPair, |g| {
g.call("expr");
g.call("op_colon");
g.call("expr");
});
});
}
pub fn add_object_pair(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("object_pair", |g: &mut sipha::builder::GrammarBuilder| {
g.node(Kind::NodeObjectPair, |g| {
g.choices(vec![
Box::new(|g| {
g.call("string_lit");
g.call("op_colon");
g.call("expr");
}),
Box::new(|g| {
g.call("keyword_or_ident");
g.call("op_colon");
g.call("expr");
}),
]);
});
});
}
pub fn add_postfix(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("postfix", |g: &mut sipha::builder::GrammarBuilder| {
g.call("primary");
g.zero_or_more(|g| {
g.choices(vec![
Box::new(|g| {
g.node(Kind::NodeCallExpr, |g| {
g.call("lparen");
g.optional(|g| {
g.call("expr");
g.zero_or_more(|g| {
g.call("comma");
g.call("expr");
});
});
g.call("rparen");
});
}),
Box::new(|g| {
g.node(Kind::NodeIndexExpr, |g| {
g.call("lbracket");
g.call("expr");
g.optional(|g| {
g.call("op_colon");
g.call("expr");
g.optional(|g| {
g.call("op_colon");
g.call("expr");
});
});
g.call("rbracket");
});
}),
Box::new(|g| {
g.node(Kind::NodeMemberExpr, |g| {
g.call("dot");
g.call("keyword_or_ident");
});
}),
Box::new(|g| {
g.call("op_plus_plus");
}),
Box::new(|g| {
g.call("op_minus_minus");
}),
Box::new(|g| {
g.call("op_bang_postfix");
}),
]);
});
});
}
pub fn add_unary(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("unary", |g: &mut sipha::builder::GrammarBuilder| {
g.choices(vec![
Box::new(|g| {
g.node(Kind::NodeUnaryExpr, |g| {
g.call("op_minus");
g.call("unary");
});
}),
Box::new(|g| {
g.node(Kind::NodeUnaryExpr, |g| {
g.call("op_plus");
g.call("unary");
});
}),
Box::new(|g| {
g.node(Kind::NodeUnaryExpr, |g| {
g.call("op_bang");
g.call("unary");
});
}),
Box::new(|g| {
g.node(Kind::NodeUnaryExpr, |g| {
g.call("not_kw");
g.call("unary");
});
}),
Box::new(|g| {
g.call("postfix");
}),
]);
});
}
fn left_assoc_interval_level(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("expr_interval", |g: &mut sipha::builder::GrammarBuilder| {
g.node(Kind::NodeBinaryLevel, |g| {
g.call("expr_add");
g.zero_or_more(|g| {
g.node(Kind::NodeInterval, |g| {
g.call("dot_dot");
g.call("expr_interval");
});
});
});
});
}
pub fn add_expr_power(g: &mut sipha::builder::GrammarBuilder) {
expr::right_assoc_infix_level(
g,
"expr_power",
"unary",
"op_power",
&Kind::NodeBinaryExpr,
Some("rhs"),
Some(&Kind::NodeExpr),
);
}
pub fn add_expr_mul(g: &mut sipha::builder::GrammarBuilder) {
expr::left_assoc_infix_level(
g,
"expr_mul",
"expr_power",
&["op_star", "op_slash", "op_backslash", "op_percent"],
&Kind::NodeBinaryExpr,
Some(&Kind::NodeBinaryLevel),
Some("rhs"),
Some(&Kind::NodeExpr),
);
}
pub fn add_expr_add(g: &mut sipha::builder::GrammarBuilder) {
expr::left_assoc_infix_level(
g,
"expr_add",
"expr_mul",
&["op_plus", "op_minus"],
&Kind::NodeBinaryExpr,
Some(&Kind::NodeBinaryLevel),
Some("rhs"),
Some(&Kind::NodeExpr),
);
}
pub fn add_expr_interval(g: &mut sipha::builder::GrammarBuilder) {
left_assoc_interval_level(g);
}
pub fn add_expr_compare(g: &mut sipha::builder::GrammarBuilder) {
expr::left_assoc_infix_level(
g,
"expr_compare",
"expr_interval",
&["op_le", "op_ge", "op_lt", "op_gt"],
&Kind::NodeBinaryExpr,
None,
None,
None,
);
}
pub fn add_expr_equality(g: &mut sipha::builder::GrammarBuilder) {
expr::left_assoc_infix_level(
g,
"expr_equality",
"expr_compare",
&["op_strict_eq", "op_neq_or_strict", "op_eq"],
&Kind::NodeBinaryExpr,
Some(&Kind::NodeBinaryLevel),
Some("rhs"),
Some(&Kind::NodeExpr),
);
}
pub fn add_expr_in(g: &mut sipha::builder::GrammarBuilder) {
expr::left_assoc_infix_level(
g,
"expr_in",
"expr_equality",
&["in_kw"],
&Kind::NodeBinaryExpr,
None,
None,
None,
);
}
pub fn add_expr_instanceof(g: &mut sipha::builder::GrammarBuilder) {
expr::left_assoc_infix_level(
g,
"expr_instanceof",
"expr_in",
&["instanceof_kw"],
&Kind::NodeBinaryExpr,
Some(&Kind::NodeBinaryLevel),
Some("rhs"),
Some(&Kind::NodeExpr),
);
}
pub fn add_expr_and(g: &mut sipha::builder::GrammarBuilder) {
expr::left_assoc_infix_level(
g,
"expr_and",
"expr_instanceof",
&["op_amp_amp", "and_kw"],
&Kind::NodeBinaryExpr,
Some(&Kind::NodeBinaryLevel),
Some("rhs"),
Some(&Kind::NodeExpr),
);
}
pub fn add_expr_or(g: &mut sipha::builder::GrammarBuilder) {
expr::left_assoc_infix_level(
g,
"expr_or",
"expr_and",
&["op_pipe_pipe", "or_kw"],
&Kind::NodeBinaryExpr,
Some(&Kind::NodeBinaryLevel),
Some("rhs"),
Some(&Kind::NodeExpr),
);
}
pub fn add_expr_xor(g: &mut sipha::builder::GrammarBuilder) {
expr::left_assoc_infix_level(
g,
"expr_xor",
"expr_or",
&["xor_kw"],
&Kind::NodeBinaryExpr,
Some(&Kind::NodeBinaryLevel),
Some("rhs"),
Some(&Kind::NodeExpr),
);
}
pub fn add_expr_ternary(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("expr_ternary", |g: &mut sipha::builder::GrammarBuilder| {
g.choices(vec![
Box::new(|g| {
g.node(Kind::NodeExpr, |g| {
g.call("expr_xor");
g.call("op_question");
g.call("expr");
g.call("op_colon");
g.call("expr_ternary");
});
}),
Box::new(|g| {
g.call("expr_xor");
}),
]);
});
}
pub fn add_type_params(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("type_params", |g: &mut sipha::builder::GrammarBuilder| {
g.node(Kind::NodeTypeParams, |g| {
g.choices(vec![
Box::new(|g| {
g.call("arrow");
g.call("type_expr");
g.no_skip(|g| {
g.call("op_gt");
});
}),
Box::new(|g| {
g.call("type_expr");
g.choices(vec![
Box::new(|g| {
g.no_skip(|g| {
g.call("op_gt");
});
}),
Box::new(|g| {
g.call("comma");
g.call("type_expr");
g.no_skip(|g| {
g.call("op_gt");
});
}),
Box::new(|g| {
g.call("arrow");
g.call("type_expr");
g.no_skip(|g| {
g.call("op_gt");
});
}),
Box::new(|g| {
g.call("comma");
g.call("type_expr");
g.zero_or_more(|g| {
g.call("comma");
g.call("type_expr");
});
g.call("arrow");
g.call("type_expr");
g.no_skip(|g| {
g.call("op_gt");
});
}),
]);
}),
]);
});
});
}
pub fn add_type_primary(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("type_primary", |g: &mut sipha::builder::GrammarBuilder| {
g.call("keyword_or_ident");
g.optional(|g| {
g.call("op_lt");
g.call("type_params");
});
});
}
pub fn add_type_optional(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("type_optional", |g: &mut sipha::builder::GrammarBuilder| {
g.call("type_primary");
g.optional(|g| {
g.call("op_question");
});
});
}
pub fn add_type_expr(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("type_expr", |g: &mut sipha::builder::GrammarBuilder| {
g.node(Kind::NodeTypeExpr, |g| {
g.call("type_optional");
g.zero_or_more(|g| {
g.call("op_pipe");
g.call("type_optional");
});
});
});
}
pub fn add_expr_as(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("expr_as", |g: &mut sipha::builder::GrammarBuilder| {
g.call("expr_ternary");
g.zero_or_more(|g| {
g.node(Kind::NodeAsCast, |g| {
g.call("as_kw");
g.call("type_expr");
});
});
});
}
pub fn add_expr(g: &mut sipha::builder::GrammarBuilder) {
g.parser_rule("expr", |g: &mut sipha::builder::GrammarBuilder| {
g.choices(vec![
Box::new(|g| {
g.node(Kind::NodeExpr, |g| {
g.call("postfix");
g.call("op_assign");
g.call("expr");
});
}),
Box::new(|g| {
g.call("expr_as");
}),
]);
});
}