ometa someother { isKeyword :x = ?someother._isKeyword(x), isTerm :x = ?someother._isTerm(x), isVerb :x = ?someother._isVerb(x), letters = letter+:l -> l.join(''), keyword = letters:k isKeyword(k) -> {kind: 'keyword', value: k}, term = letters:t isTerm(t) -> {kind: 'term', value: t}, verb = (letters|space):v isVerb(v) -> {kind: 'verb', value: v}, word = letters:w -> {kind: 'word', value: w}, num = digit+:n -> {kind: 'num', value: parseInt(n.join(''))}, scanner = (~'\n' space)* (keyword | term | verb| word | num), token :k = scanner:t ?(t.kind==k || t.value==k) -> (t.kind == 'word' ? t.value : [t.kind, t.value]), existq = "term":t "verb":v "a" "term":e -> [#exists, t, v, e], atmostn = "term":t "verb":v "at" "most" "num":n "term":e -> [#atmostn, n, t, v, e], univq = "each" (existq|atmostn):e -> [#forall, e], modRule = ``It is obligatory that'' univq:u -> [#obligation, u], newRule = ``R:''modRule:r -> [#rule, r], FTpart = "word"+:f "term":e {this.verbs[f.join(' ')] = true;} -> [[#verb, f.join(' ')], e], newFactTypeB = ``F:''"term":t (FTpart)+:v {for(var i=1;i ['fact type', [t].concat(v)], newfactTypeA = ``F:''"term":t "word"+:f -> ['fact type', t, [#verb, f.join('')]], newFactType = newFactTypeB | newfactTypeA, newTerm = ``T:'' "word"+:t {this.terms[t[0]] = true} -> [#newterm, t], line = newTerm | newFactType | newRule, linef = line:l '\n' -> l | line | '\n', expr = linef*:l -> ('\n' + l.join('\n')), exprox = "word"*:w "a":k "word"*:o -> [w.join(', '), k, o.join(', ')] } someother.keywords = {} someother.terms = {} someother.verbs = {} keywords = ["a", "each"] for (var idx = 0; idx < keywords.length; idx++){someother.keywords[keywords[idx]] = true} someother._isKeyword = function(k) { return this.keywords.hasOwnProperty(k) } someother._isTerm = function(k) { return this.terms.hasOwnProperty(k) } someother._isVerb = function(k) { return this.verbs.hasOwnProperty(k) } model = ' T:course T:lecturer T:student F:student has course F:course has lecturer R:It is obligatory that each course has a lecturer R:It is obligatory that each student has at most 5 courses' someother.matchAll(model, 'expr') [newterm, [course]] [newterm, [lecturer]] [newterm, [student]] [fact type, [[term, student], [verb, has], [term, course]]]