PDA

View Full Version : string.replace(/.../,str) won't replace!!!



mr.jsnerd
12-20-2009, 03:30 AM
i am trying to make an online graphing calculator with javascript. dont ask how because i dont know. but there is an annoying error in a do...while loop. although it should break out of the loop when the |'s (absolute value signs) are replaced with Math.abs( and ). here is the code.


var initec = function(){
var rg = {
}
;
rg.matc = false;
rg.i = 0;
rg.change = function(equ){
if (typeof(equ) != "string"){
alert('Equation must be a string');
return;
}
alert("starting equation: "+ equ);
rg.i = 0;
do{
rg.matc = equ.match(/\|/);
if(rg.i === 0){
equ.replace(/\|/, " Math.abs(");
rg.i = 1;
alert("1 "+equ);
}
else {
equ.replace(/\|/, " ) ");
rg.i = 0;
alert("0 "+equ);
}
}while(rg.matc)
alert("finished equation: " + equ);
}
return rg;
}

rg=initec();
rg.change("|8/x+7|-2");


the last 2 lines and the alerts are for debugging. as you can see, it is not finished. but still, it should work.

Trinithis
12-20-2009, 04:18 AM
String.prototype.replace doesn't modify the string; it returns a new string.

mr.jsnerd
12-20-2009, 04:20 AM
thanks!!! i though it would work differently. happy holidays!

mr.jsnerd
12-20-2009, 05:18 AM
know how will i replace carats (^) with the Math.pow? i have no clue

Old Pedant
12-20-2009, 05:47 AM
Hmmm....

Well, let's start by rethinking your absolute value code;


txt = txt.replace( /\|([^\|]+)\|/g, "Math.abs($1)" );

Done. Replaces all your code.

And you can try this:

<script>
function stringToFormula( txt )
{
txt = txt.replace( /\|([^\|]+)\|/g, "Math.abs($1)" );
txt = txt.replace( /([a-z0-9\.\-]+)\s*\^\s*([a-z0-9\.\-]+)/, "Math.pow($1,$2)" );
return txt;
}

alert( stringToFormula("3 * 27 ^ 4") );
alert( stringToFormula("|8 * 4 ^ 7| * -2 ") );
alert( stringToFormula("3 * 27 ^ | x - 5 | ") );

</script>


And it works great for the first two but then falls flat on its face for the third.

I think if you are going to do this you need to build a *real* expression evaluator and not rely upon simple string replacement. Sorry.

Old Pedant
12-20-2009, 05:54 AM
See, you haven't even started taking into account the effect of operator precedence and parentheses.

Consider:

3 * 2 ^ 4 * 2

versus

( 3 * 2 ) ^ ( 4 * 2 )

versus

| 3 * 2 | ^ | 4 * 2 |

and so on.

I know it's a pain, but I think in the long run you'll be ahead of the game if you build an expression parser and evaluator.

What do you do about things such as

x * sin y + 7

When you see the parentheses omitted, do you add them in? (Of course.) WHERE do you add them in?

mr.jsnerd
12-20-2009, 03:37 PM
my idea was to convert the string into code, and eval() it (only if it didnt have any letters other than x, Math.abs, Math.pow, Math.sin and so on). how would i make a expression parser? wouldn't that be like making a new programming language? if you could, just give me a pseudo code or beginning of one.

Old Pedant
12-20-2009, 08:32 PM
Oh man...yes, it's kind of like the beginnings of creating a compiler.

You have to parse the string for "tokens" and then push them on either the operator or argument stack (two stacks) and then what you do depends on the precedence of the current operator compared to the precedence of the operator on the top of the stack.


Example: ( 3 + 4 ) * 5
stack empty, push (
push 3
operator +, top of stack (, push +
push 4
operator ), top of stack +, so
execute operator + on top two arguments of arg stack
push result back on arg stack
remove operator +
operator ), top of stack (, so simply remove ( and continue
operator *, stack empty, push *
push 5
[end of expression], * on top of stack, so
execute operator * on top two arguments of arg stack
push result back on arg stack
remove operator *
[end of expression] with nothing on argument stack: answer is on top of stack

But ugh...you don't want to do that every time through a graphing loop. So instead what you have to do it turn it into a set of JS code to be executed.

Fun stuff. Not sure what I would do here. Would be tempted to require the expression in JS notation. <grin/>

mr.jsnerd
12-21-2009, 05:37 PM
thanks, but i'm stupid. i still don't understand... and if it had a parser, wouldn't it be interpreted? oh well.:confused:

Old Pedant
12-21-2009, 09:03 PM
Yeah, it's pretty complicated. That's why I said what you would really want to do it convert the thing to a JS string that you can use eval() on. Or similar.

It's *NOT* an easy task. I use to write BASIC interpreters for a living, and in some ways this is tougher.