Last active
December 17, 2015 17:28
-
-
Save gmac/5645879 to your computer and use it in GitHub Desktop.
Simple lexical analysis for a JavaScript expression. Written as a prototype for pre-parsing JavaScript bindings (Epoxy.js). Will alphabetically sort the order of object property lists while removing all non-string whitespace. Example expression: 'text: all("a", "x", "c"), css:{fontWeight:"bold", color:["#f00, \\"#fee", "#00f"]}, html:firstName'
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function parseBindings(bindings, sorted) { | |
var attrs = []; | |
var token = ''; | |
bindings += ','; | |
for (var i = 0, len = bindings.length; i < len; i++) { | |
var c = bindings.charAt(i); | |
// Comma: chunk off tokens at list delimiter. | |
if (c == ',') { | |
attrs.push(token); | |
token = ''; | |
continue; | |
} | |
// Space: skip whitespace. | |
if (c == ' ') { | |
continue; | |
} | |
// String: open at quote character, close at unescaped match. | |
if (c == "'" || c == '"') { | |
var string = ''; | |
for (i = i+1; i < len; i++) { | |
var q = bindings.charAt(i); | |
if (q == c) break; | |
if (q == '\\') q = bindings.charAt(i+=1); | |
string += q; | |
} | |
c = c + string + c; | |
} | |
// Block: chunk out block scope and parse it. | |
else if (c == '{' || c == '[' || c == '(') { | |
var opener = c; | |
var closer = c == '{' ? '}' : c == '[' ? ']' : ')'; | |
var io = i; | |
var ic = i; | |
while (io >= i && io <= ic) { | |
io = bindings.indexOf(opener, io+1); | |
ic = bindings.indexOf(closer, ic+1); | |
} | |
c = opener + parseBindings(bindings.slice(i+1, ic), c == '{') + closer; | |
i = ic; | |
} | |
token += c; | |
} | |
if (sorted) attrs.sort(); | |
return attrs.join(','); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment