-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmath_parser.js
26 lines (21 loc) · 1004 Bytes
/
math_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
const { terminal, choice, sequence } = require('./parser_combinator.js')
const { lexer } = require('./lexer.js')
// node constructors
const Group = ([ , expr, ]) => ({ type: 'group', expr })
const Sum = ([atom1, , atom2]) => ({ type: 'sum', atom1, atom2 })
const Product = ([atom1, , atom2]) => ({ type: 'product', atom1, atom2 })
const Number_ = ([number]) => ({ type: 'number', value: number })
// parser
const lparen =()=> terminal(/\(/)
const rparen =()=> terminal(/\)/)
const add =()=> terminal(/\+/)
const multiply =()=> terminal(/\*/)
const number =()=> terminal(/[0-9]+/, Number_)
const groupExpr =()=> sequence([lparen, expr, rparen], Group)
const atom =()=> choice([number, groupExpr])
const sum =()=> sequence([atom, add, atom], Sum)
const product =()=> sequence([atom, multiply, atom], Product)
const expr =()=> choice([sum, product, number])
// example parsing
const tokens = lexer('(4 + 3) * 2')
console.log(JSON.stringify(expr()(tokens), null, 2))