I've been working on my math expression parser. Consider this:
You have to get all the operators without grabbing unary operators ex: 1 * -2. In this example I need the * but not the -. Now there are a lot of stupid ways to do this and they all involve attempting to pick and choose via a loop. My eval() is regexp driven so, with some genius I don't have to write loops for this stuff.
first let's consider a regex that knows what a unary operator is or more specifically knows what ISNT a unary.
/(?<![-+/*]|[0-9.]E)(?<=[0-9a-z]|\))[-+/*]/g
I posted some regex on some other thread on here and that example was simple stuff. This is a bit more complicated.
Let's skip to the end and come back. The below is what we are actually trying to find. Any of these characters in the brackets.
[-+/*]
This means "if I look behind the found character and it IS what is in this group". For this group I am looking for numbers, letters or a close parenthesis
(?<= )
This means "if I look behind the found character and it's NOT what is in this group". In this group I am looking for operators and handling E possibilities
(?<! )
So if we read my regex from end to beginning it says
find [*/+-] that IS preceded by [0-9a-z] or ) and is NOT preceded by [*/+-]
The E thing is in there too but I don't feel like explaining it. What I explained is good enough.
Now, we have a regex that when used with string.split() will create an array of everything to the sides of the operator
ex (1 * -2) becomes [1,-2]
But how do we get the operators back? We still need them to eventually start doing the math. THis is the genius part
I simply rejoin the array with | (or) symbols and reformat it a little bit with more regex. What I end up with is the exact opposite regex of the one I used to remove the operators.
blink, blink, done...no loops.
I ran a test and so far my evaluator runs about 2200 times a second. It's almost entirely regex.
You have to get all the operators without grabbing unary operators ex: 1 * -2. In this example I need the * but not the -. Now there are a lot of stupid ways to do this and they all involve attempting to pick and choose via a loop. My eval() is regexp driven so, with some genius I don't have to write loops for this stuff.
first let's consider a regex that knows what a unary operator is or more specifically knows what ISNT a unary.
/(?<![-+/*]|[0-9.]E)(?<=[0-9a-z]|\))[-+/*]/g
I posted some regex on some other thread on here and that example was simple stuff. This is a bit more complicated.
Let's skip to the end and come back. The below is what we are actually trying to find. Any of these characters in the brackets.
[-+/*]
This means "if I look behind the found character and it IS what is in this group". For this group I am looking for numbers, letters or a close parenthesis
(?<= )
This means "if I look behind the found character and it's NOT what is in this group". In this group I am looking for operators and handling E possibilities
(?<! )
So if we read my regex from end to beginning it says
find [*/+-] that IS preceded by [0-9a-z] or ) and is NOT preceded by [*/+-]
The E thing is in there too but I don't feel like explaining it. What I explained is good enough.
Now, we have a regex that when used with string.split() will create an array of everything to the sides of the operator
ex (1 * -2) becomes [1,-2]
But how do we get the operators back? We still need them to eventually start doing the math. THis is the genius part
Code:
//create an array of evrything except actual operators res_stack = (child.expr).split(re.infix); //reformat the res_stack values into a regex stack_str = res_stack.join("|").replace(/\(/g, "\\("); stack_str = stack_str.replace(/\)/g, "\\)"); stack_str = stack_str.replace(/\|E/g, "|(?<=[-+/*])E"); //create an array of only actual operators op_stack = (child.expr).split(new RegExp(stack_str, "g"));
blink, blink, done...no loops.
I ran a test and so far my evaluator runs about 2200 times a second. It's almost entirely regex.

Comment