There's a very steep tradeoff between the approachability of a macro and that of its expander code. Look at Rust macro_rules!, or Scala macros, or Template Haskell. A formal grammar can define a strongly-typed deeply hierarchical data structure, but the code to drill in and map to a different deeply hierarchical data structure by hand seems to become a nightmare. Even Scheme hygenic macros are noticeably harder than "take a macro call as a list, use quasiquote to return a list that starts with PROGN" which makes it actually feasible (if risky!) to start cranking out macro expanders.