Skip to content

Instantly share code, notes, and snippets.

@JohnEarnest
Created December 13, 2019 21:40
Show Gist options
  • Save JohnEarnest/d4885a70a12055cebe388a4f00a5b495 to your computer and use it in GitHub Desktop.
Save JohnEarnest/d4885a70a12055cebe388a4f00a5b495 to your computer and use it in GitHub Desktop.
A Lisp(ish) S-Expression parser in ES6, supporting symbols, signed ints, lists, and line comments.
// S-Expression Parser
const token = /^\s*(?:;[^\n]*\n)*\s*(?:(-?\d+)|([a-z\-!?]+|[+\-*\/<>=()]))/
function parse(text) {
const term = _ => {
const x = token.exec(text)
if (!x) throw 'Reached the end of input while parsing!'
text = text.slice(x[0].length)
const here = x[1] ? +x[1] : x[2]
if (here != '(') return here
let ret = [], next
while (')' != (next = term())) ret.push(next)
return ret
}
return term()
}
// tests
function test(x, y) {
const a = JSON.stringify(x), b = JSON.stringify(y)
if (a != b) console.log(`got: ${a}\nexpected: ${b}`)
}
test(parse('(first (list 1 (+ 2 3) 9))'), ['first',['list',1,['+',2,3],9]])
test(parse('(-234 ; comment\ndashed-atom!)'), [-234,'dashed-atom!'])
test(parse('(3 (4 (5 6)) (7 8))'), [3,[4,[5,6]],[7,8]])
test(parse('bare-atom?'), 'bare-atom?')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment