Skip to content

Instantly share code, notes, and snippets.

@dmitry-vsl
Last active August 29, 2015 14:26
Show Gist options
  • Save dmitry-vsl/68f2e83ff7b83e54f861 to your computer and use it in GitHub Desktop.
Save dmitry-vsl/68f2e83ff7b83e54f861 to your computer and use it in GitHub Desktop.
/*
E -> M [+ M]
M -> B [* B]
B -> Num | (E)
*/
function calc(str){
str = str.replace(/\s/g,'');
var pos = 0;
function whatNext(){
if(pos >= str.length){
return null;
}else{
return str[pos];
}
}
function next(){
var result = whatNext();
pos++;
return result;
}
function assertNext(s){
if(s != whatNext()){
throw new Error();
}
}
function E(){
var result = M();
while(whatNext() == '+'){
next();
result += M();
}
return result;
}
function M(){
var result = B();
while(whatNext() == '*'){
next();
result *= B();
}
return result;
}
function B(){
if(whatNext() == '('){
next();
var result = E();
assertNext(')');
next();
return result;
}else{
return Num();
}
}
function Num(){
var numStr = '';
var symbol;
while(/[0-9]/.test(symbol = whatNext())){
next();
numStr += symbol;
}
if(numStr === ''){
throw new Error('expected number');
}else{
return parseInt(numStr);
}
}
var result = E();
assertNext(null);
return result;
}
calc('(((1 + 2 + 3)*4 + 1) * 10)')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment