// a recognizer that also interprets ometa Calc { digit = ^digit:d -> d.digitValue(), number = number:n digit:d -> (n * 10 + d) | digit, addExpr = addExpr:x '+' mulExpr:y -> (x + y) | addExpr:x '-' mulExpr:y -> (x - y) | mulExpr, mulExpr = mulExpr:x '*' primExpr:y -> (x * y) | mulExpr:x '/' primExpr:y -> (x / y) | mulExpr:x '%' primExpr:y -> (x % y) | primExpr, primExpr = '(' expr:x ')' -> x | '"' expr:x '"' -> (parseInt(x) + 10) | number, expr = addExpr } Calc.matchAll('"4"+3', 'expr') ometa ActionScript <: Parser { keyword = "var " letter:x " is" -> [x] parse = keyword:word -> word } ActionScript.matchAll('var 5 is', 'parse') ometa BinaryStrings { num = '0' | ('1' '1'):x -> '11', expr = num+ } BinaryStrings.matchAll('011011hmm', 'expr') ometa Symbols { char = anything:x ?(x >= 'a' && x <= 'z') ->x, space = ' ', symbol = space* char+:x space* -> x.join(''), expr = symbol+:x -> x } Symbols.matchAll('hello there you person', 'expr') [hello, there, you, person] [[h, e, l, l, o], [t, h, e, r, e], [y, o, u], [p, e, r, s, o, n]] ometa Highlight { char = anything:x ?(x >= 'a' && x <= 'z') -> x, space = ' ', symbol = space* char+:x space* -> x.join(''), expr = symbol+:x -> x } Highlight.matchAll('var f = function(){ foo() }', 'expr') ometa Stringify <: Parser { space = ^space | ' ', fromTo :x :y = seq(x) (~seq(y) char)* seq(y), nameFirst = letter | '$' | '_', nameRest = nameFirst | digit, iName = firstAndRest(#nameFirst, #nameRest):r -> r.join(''), isKeyword :x = ?Stringify._isKeyword(x), name = iName:n ~isKeyword(n) -> [#name, n], keyword = iName:k isKeyword(k) -> ['keyword', k], hexDigit = char:x {this.hexDigits.indexOf(x.toLowerCase())}:v ?(v >= 0) -> v, hexLit = hexLit:n hexDigit:d -> (n * 16 + d) | hexDigit, number = ``0x'' hexLit:n -> [#number, n] | digit+:ws ('.' digit+ | empty -> []):fs -> [#number, parseFloat(ws.join('') + '.' + fs.join(''))], escapeChar = '\\' char:c -> unescape('\\' + c), str = '\'' (escapeChar | ~'\'' char)*:cs '\'' -> [#string, cs.join('')] | '"' (escapeChar | ~'"' char)*:cs '"' -> [#string, cs.join('')], special = ( '(' | ')' | '{' | '}' | '[' | ']' | ',' | ';' | '?' | ':' | ``!=='' | ``!='' | ``==='' | ``=='' | ``='' | ``>='' | '>' | ``<='' | '<' | ``++'' | ``+='' | '+' | ``--'' | ``-='' | '-' | ``*='' | '*' | ``/='' | '/' | ``%='' | '%' | ``&&='' | ``&&'' | ``||='' | ``||'' | '.' | '!' ):s -> ['operator', s], tok = spaces (name | keyword | number | str | special), toks = token*:ts spaces end -> ts, token :tt = tok:t ?(t[0] == tt) -> t[1], stmt = name | keyword | number | str | special, stmtSp = stmt:s spaces:ws -> ['stmt_ws', s, ws.join('')], srcElems = stmtSp*:ss end -> [#begin].concat(ss), topLevel = srcElems:r spaces end -> r } Stringify.hexDigits = "0123456789abcdef" Stringify.keywords = { } keywords = ["break", "case", "catch", "continue", "default", "delete", "do", "else", "finally", "for", "function", "if", "in", "instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with", "ometa"] for (var idx = 0; idx < keywords.length; idx++) Stringify.keywords[keywords[idx]] = true; Stringify._isKeyword = function(k) { return this.keywords.hasOwnProperty(k) }; var results = Stringify.matchAll('var s = "hi";\nvar q = 5;', 'srcElems') // [begin, [stmt_ws, [keyword, var], ], [stmt_ws, [name, s], ], [stmt_ws, [operator, =], ], [stmt_ws, [string, hi], ], [stmt_ws, [operator, ;], ], [stmt_ws, [keyword, var], ], [stmt_ws, [name, q], ], [stmt_ws, [operator, =], ], [stmt_ws, [number, 5], ], [stmt_ws, [operator, ;], ]] // [begin, [keyword, var], [name, s], [operator, =], [string, hi], [operator, ;], [keyword, var], [name, q], [operator, =], [number, 5], [operator, ;]] ometa HTMLator { trans = [:t apply(t):ans] -> ans, begin trans+:x end -> x, stmt_ws trans:x :y -> (x + y), keyword :w -> Span.wrap(w, 'keyword'), operator :o -> Span.wrap(o, 'operator'), string :s -> Span.wrap('"' + s + '"' + 'string'), number :n -> Span.wrap(n, 'number'), name :n -> Span.wrap(n, 'name') } Span = { wrap: function(s, c){ return '' + s + '' } } Span.wrap('if', 'keyword') var results3 = ['begin', ['stmt_ws', ['keyword', 'var'], ' '], ['stmt_ws', ['name', 's'], ' '], ['stmt_ws', ['operator', '='], ' '], ['stmt_ws', ['string', 'hi'], ''], ['stmt_ws', ['operator', ';'], '\n'], ['stmt_ws', ['keyword', 'var'], ' '], ['stmt_ws', ['name', 'q'], ' '], ['stmt_ws', ['operator', '='], ' '], ['stmt_ws', ['number', '5'], ''], ['stmt_ws', ['operator', ';'], '']]; var results2 = ['begin', ['keyword', 'var'], ['name', 's'], ['operator', '='], ['string', 'hi'], ['operator', ';'], ['keyword', 'var'], ['name', 'q'], ['operator', '='], ['number', '5'], ['operator', ';']]; var results = ['begin', ['keyword', 'var'], ['keyword', 'rar']]; HTMLator.match(results3, 'trans').join('')