-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
118 lines (96 loc) · 3.06 KB
/
server.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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* File : server.js
* Author : [email protected]
* Date : 03/04/2018
*
* Desc : NodeJs application
*/
var express = require('express')
var bodyParser = require('body-parser') // To handle post requisitons protocols
var app = express()
app.use(express.static(__dirname)) // To handle html file
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
app.post('/calculate', (req, res) => {
req.body.result = calc(req.body.expr) // Calculate
res.json(req.body)
})
var server = app.listen(3000, () => {
console.log('server is listening on port', server.address().port)
})
/*
* postfix - convert infix notation to reverse polish
*
* This is a simplified implementation of Shunting-yard with Postfix Calculator Algorithm
* Based on Edsger Dijkstra algorithm <https://en.wikipedia.org/wiki/Shunting-yard_algorithm>
* Return: array[]
*/
function postfix(expr) {
expr = expr.split('')
/* Shunting-yard is based on stack and queue data structures */
var stack = [], queue = []
var exp_function = '', exp_number = ''
var s_top, previousIsFunction = false
/* Operands precedence */
var precedence = {"*": 3, "/": 3, "+": 2, "-": 2 }
/*
* Parsing expression
*/
for (var i = 0; i < expr.length; i++) {
/* Is token an operand ? */
if ( isNaN(expr[i]) && expr[i] !== '.' && !previousIsFunction ) {
/* Handling negative numbers at start of expression */
if( expr[i] === '-' && i === 0 ) {
queue.push('0')
}
exp_function = expr[i]
previousIsFunction = true
// Checking precedence
if ( stack.length > 0 ) {
s_top = stack[stack.length-1]
if ( precedence[exp_function] <= precedence[s_top] ) {
while ( stack.length > 0 ) {
queue.push(stack.pop())
}
}
}
// add operand to stack
stack.push(exp_function)
}
else {
/* Is token a number? */
exp_number = "" + exp_number + expr[i]
if ( isNaN(expr[i+1]) && expr[i+1] !== '.' ) {
queue.push(exp_number)
exp_number = ""
}
previousIsFunction = false;
}
}
/* Ending postfix notation */
while ( stack.length > 0 ) {
queue.push(stack.pop())
}
return queue
}
/*
* calc - compute reverse polish expresion
* Valid operations *, /, +, -
* Return: float
*/
function calc(expr) {
// right and left operands
var rOp, lOp
var stack = [], queue = postfix(expr)
while ( queue.length > 0 ) {
token = queue.shift()
if ( isNaN(token) ) {
rOp = stack.pop();
lOp = stack.pop();
stack.push(eval(lOp + token + rOp))
}
else {
stack.push(token)
}
}
return stack.pop()
}