Skip to content

Instantly share code, notes, and snippets.

@zthxxx
Last active April 19, 2022 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zthxxx/ae322a43f416bcbeacfe6513df6e8ec6 to your computer and use it in GitHub Desktop.
Save zthxxx/ae322a43f416bcbeacfe6513df6e8ec6 to your computer and use it in GitHub Desktop.
{
/**
* pegjs grammar:
* https://github.com/pegjs/pegjs/blob/7d13580855/docs/grammar/README.md
* https://github.com/pegjs/pegjs/blob/7d13580855/docs/grammar/action-execution-environment.md
*
* playground: https://pegjs.org/online
*
* > pegjs expression.pegjs -o parser.js --format es
*/
const calcBinary = ({ left, op, right }) => {
switch (op) {
case '+': return left + right; break
case '-': return left - right; break
case '*': return left * right; break
case '/': return left / right; break
case '^': return Math.pow(left, right); break
}
}
}
Expression = Sum
Sum = left:Product _ tail:(_ ('+' / '-') _ Product)* {
const { isAst } = options
return tail.reduce((left, [, op, , right]) => {
const node = { left, op, right }
return isAst ? node : calcBinary(node)
}, left)
}
Product = left:Power _ tail:(_ ('*' / '/') _ Power)* {
const { isAst } = options
return tail.reduce((left, [, op, , right]) => {
const node = { left, op, right }
return isAst ? node : calcBinary(node)
}, left)
}
Power = head: (left: Value _ '^' _)* _ right:Value {
const { isAst } = options
return head.reduceRight((right, [left]) => {
const node = { left, op: '^', right }
return isAst ? node : calcBinary(node)
}, right)
}
Value =
Decimal
/ Integer
/ '(' _ expr:Expression _ ')' { return expr; }
Sign 'sign' = '-' / '+' / ''
Decimal 'decimal' = head:Sign _ tail:([0-9]+'.'[0-9]+) {
return Number(`${head}${tail.flat().join('')}`)
}
Integer 'integer' = head:Sign _ tail:([0-9]+) {
return Number(`${head}${tail.join('')}`)
}
_ 'whitespace' = [ \t\n\r]*
@zthxxx
Copy link
Author

zthxxx commented Apr 19, 2022

npm i -g pegjs@0.11.0-master.b7b87ea

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment