m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2017-07-20 13:55:40 -0400
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2017-07-20 13:55:40 -0400
commit56d36c9129292cd0dd0b5e79eea14d79a4219a94 (patch)
treec188b58ceff63e0bbe137b7ed6ed4e2ff9eb3d59 /src
parent67f1369cb00d6a6dede39acd7675d91abcd9ed02 (diff)
Refactor parser
Diffstat (limited to 'src')
-rw-r--r--src/parser.js75
1 files changed, 28 insertions, 47 deletions
diff --git a/src/parser.js b/src/parser.js
index 5e9960a..fd974bc 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -6,21 +6,38 @@ let throwSyntaxError = () => {
throw new Error('Syntax error: unexpected token')
}
+let lexemeToToken = lexeme => {
+ let token = Object.create(symbols[lexeme.type])
+ token.value = lexeme.value
+ return token
+}
+
const dieBindingPower = 30
let newSymbol = (type, nud, lbp, led) => {
+ const symbol = symbols[type] || {}
symbols[type] = {
type,
- nud: nud || throwSyntaxError,
- lbp,
- led: led || throwSyntaxError
+ nud: nud || symbol.nud || throwSyntaxError,
+ lbp: symbol.lbp || lbp,
+ led: led || symbol.led || throwSyntaxError
}
}
-let lexemeToToken = lexeme => {
- let token = Object.create(symbols[lexeme.type])
- token.value = lexeme.value
- return token
+const newInfix = (symbol, lbp, options) => {
+ const type = options.type || symbol
+ const rbp = options.rbp || lbp
+ newSymbol(symbol, null, lbp, (left, parser) => {
+ return {
+ type: type,
+ left: left,
+ right: parser.expression(rbp)
+ }
+ })
+}
+
+const newDieOperation = (symbol) => {
+ newInfix(symbol, dieBindingPower, { rbp: dieBindingPower - 1 })
}
newSymbol('constant', function() {
@@ -35,59 +52,24 @@ newSymbol('(', function(parser) {
newSymbol(')')
-const newDieOperation = (symbol, nud = null) => {
- newSymbol(symbol, nud, dieBindingPower, (left, parser) => {
- return {
- type: symbol,
- left: left,
- right: parser.expression(dieBindingPower - 1)
- }
- })
-}
-
+newDieOperation('d')
newSymbol('d', (parser) => {
return {
type: 'd',
left: { type: 'constant', value: 1 },
right: parser.expression(29)
}
-}, 30, (left, parser) => {
- return {
- type: 'd',
- left: left,
- right: parser.expression(29)
- }
})
-
-newSymbol('E', null, 30, (left, parser) => {
- return {
- type: 'E',
- left: left,
- right: parser.expression(29)
- }
-})
-
+newDieOperation('E')
newDieOperation('K')
-newSymbol('+', null, 20, (left, parser) => {
- return {
- type: 'add',
- left: left,
- right: parser.expression(20)
- }
-})
-
+newInfix('+', 20, { type: 'add' })
+newInfix('-', 20, { type: 'subtract' })
newSymbol('-', (parser) => {
return {
type: 'negative',
value: parser.expression(40)
}
-}, 20, (left, parser) => {
- return {
- type: 'subtract',
- left: left,
- right: parser.expression(20)
- }
})
newSymbol('end', null, -1)
@@ -132,5 +114,4 @@ const parse = expressionString => {
return expression
}
-
exports.parse = parse