ometa Membership <: Parser { isMember :x = ?Membership._isMember(x), text = (~'\n' char)+:c -> c.join(''), nonMember = text:x ~isMember(x) -> [#isNotMember, x], currMember = text:x isMember(x) -> [#isMember, x], newMember = ``add:''text:t {Membership.members[t] = true} -> [#newMember, t], line = newMember|currMember|nonMember, linef = line:l '\n' -> l | line | '\n', expr = linef*:l -> l.join('') } Membership.members = { } members = ["Joachim","Dolores","Elvis"] for (var idx = 0; idx < members.length; idx++){ Membership.members[members[idx]] = true } Membership._isMember = function(k) { return this.members.hasOwnProperty(k) } group = ' Elvis John add:John Nick Joachim John' Membership.matchAll(group, 'expr') [isMember, Elvis][isNotMember, John][newMember, John][isNotMember, Nick][isMember, Joachim][isMember, John]