Last active
January 12, 2017 07:35
-
-
Save rikschennink/ea453f9050aeb8e060ebf93dfade26f6 to your computer and use it in GitHub Desktop.
Parsing strings with JavaScript
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
const arrow = (str, i) => str[i] === '-' && str[i+1] === '>'; | |
const string = (c) => c === "'" || c === '"'; | |
const comma = (c) => c === ','; | |
const opener = (c) => c === '('; | |
const closer = (c) => c === ')'; | |
const parse = (i, str, result) => { | |
let value = ''; | |
let quote = null; | |
while (i < str.length) { | |
// character reference | |
let c = str[i]; | |
// enter level | |
if (opener(c)) { | |
let fn = [value.trim()]; | |
i = parse(i + 1, str, fn); | |
result.push(fn); | |
value = ''; | |
} | |
// exit level | |
else if (closer(c)) { | |
if (value.trim().length) { | |
result.push(value.trim()); | |
} | |
return i+1; | |
} | |
// function names or arguments | |
else { | |
// we're in a string | |
// as long as the exit has not been found add to value | |
if (quote !== null && c !== quote) { | |
// accept any value | |
value += c; | |
} | |
// we've found the string exit | |
else if (c === quote) { | |
quote = null; | |
} | |
// we're not in a string and we found a string opener | |
else if (string(c)) { | |
quote = c; | |
} | |
// we're not in a string | |
else { | |
// we've found an arrow | |
if (arrow(str, i)) { | |
// we might have finished a function without parenthesis | |
if (value.trim().length) { | |
result.push([value.trim()]); | |
value = ''; | |
} | |
// skip two additional characters because arrow is of length 2 | |
i+=2; | |
} | |
// we've reached an argument separator | |
else if (comma(c)) { | |
// push value | |
if (value.trim().length) { | |
result.push(value.trim()); | |
} | |
value = ''; | |
} | |
else { | |
value += c; | |
} | |
} | |
// next character | |
i++; | |
} | |
} | |
if (value.trim().length) { | |
result.push([value.trim()]); | |
} | |
return i; | |
}; | |
export const parseTransformChain = string => { | |
let result = []; | |
parse(0, string, result); | |
return result; | |
}; |
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
"foo" | |
// [["foo"]] | |
"foo -> bar" | |
// [ ["foo"], ["bar"] ] | |
"foo(a, b)" | |
// [ ["foo", "a", "b"], ["bar"] ] | |
"foo(a, 'a, b')" | |
// [ ["foo", "a", "a, b"] ] | |
"foo -> bar(baz(a, b))" | |
// [ ["foo"], ["bar", ["baz", "a", "b"] ] ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment