I would start with a concrete definition of the abstract syntax.
Term ::= RDFTerm | Var
Triple ::= (Term, IRI | Var, Term)
RuleElement ::= TriplePatternElem(Triple)
| ConditionElem(Expr)
| NegationElem(Triple+)
| AssignmentElem(Var, Expr)
RuleBody ::= RuleElement*
RuleHead ::= Triple+
Rule ::= (RuleHead, RuleBody)
RuleSetMember ::= Rule | DataBlock | RuleImport
RuleSet ::= RuleSetMember*
Part of #1194