-
Notifications
You must be signed in to change notification settings - Fork 0
/
lambda_parser.js
30 lines (23 loc) · 931 Bytes
/
lambda_parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const { terminal, choice, sequence } = require('./parser_combinator.js')
const { lexer } = require('./lexer.js')
// node constructors
const App = ([ , expr1, expr2, ]) => ({ type: 'app', expr1, expr2 })
const Abs = ([ , , bindVar, , expr, ]) => ({ type: 'abs', bindVar, expr })
const Var = (name) => ({ type: 'var', name })
/*
* var ::= [a-z]+
* expr ::= var
* expr ::= (\const.expr)
* expr ::= (expr expr)
*/
const lparen =()=> terminal(/\(/)
const rparen =()=> terminal(/\)/)
const slash =()=> terminal(/\\/)
const period =()=> terminal(/\./)
const variable =()=> terminal(/[a-z]+/, Var)
const app =()=> sequence([lparen, expr, expr, rparen], App)
const abs =()=> sequence([lparen, slash, variable, period, expr, rparen], Abs)
const expr =()=> choice([variable, app, abs])
// example parse
const tokens = lexer("((\\x.(x y)) p)")
console.log(JSON.stringify(expr()(tokens), null, 2))