Parsing an arithmetic expression

Hi,
I'd like to get the result of an arithmetic expression. I found some algorithms which describe how to get the result of an expression with parens and the four basic operations (+, -, *, /). Now I want to do this to an expression with all the operations you can find on a scientific calculator, for example sin, cos, log, ^, sqrt, nCr, ! ...
I mean something like this:
sin(2x)*sqrt(8.5x/1.25)+5/x^3-x^(2-5x)-5!
The algorithm would have to return -123.1322 in this case.
Does anyone know how normal calculators does this? I am more interested in the basic idea and not the coding itself.
I thought about something like this:
solve(expression)
   do until there is a result:
      if there are no other operations in the expression than +, -, *,/ and parens, then:
         calculate the result and return it
      else:
         search the first operation which is not +, -, * or / , for example sin(...)
         get the caption in the brackets
         solve(caption in the brackets)      <--- recursive functionDo you have a better idea? I am nor sure this is a good algorithm.
DrummerB
Edited by: DrummerB on Feb 28, 2008 5:30 PM

Hello DrummerB,
I reckon that without getting into the theory (which I recommend), the simplest way to achieve the goal is using cascading.
1. Order all operations by precedence, example:
operators | precedence
     +, - | 0
     *, / | 1
        ! | 2
        - | 3 (unary minus)2. Create a parsing/solving algorithm, example:
solveExpr(e)
    ts := token stream for e
    return solveAdditiveExpr(ts)
solveAdditiveExpr(ts)
    left := solveMultiplicativeExpr(ts)
    while next token in ts is "+" or "-"
        right := solveMultiplicativeExpr(ts)
        if next token in ts is "+"
            left := left + right
        else
            left := left - right
        consume next token in ts
    return left
solveMultiplicativeExpr(ts)
    left := solveFacultyExpr(ts)
    while next token in ts is "*" or "/"
        right := solveFacultyExpr(ts)
        if next token in ts is "*"
            left := left * right
        else
            left := left / right
        consume next token in ts
    return left
solveFacultyExpr(ts)
    left := solveUnaryMinusExpr(ts)
    while next token in ts is "!"
        left := faculty of left
        consume next token in ts
    return left
solveUnaryMinusExpr(ts)
    negative := false
    while next token in ts is "-"
        negative := !negative
        consume next token in ts
    if negative
        return -number(ts)
    else
        return number(ts)
number(ts)
    the next token in ts must be a number, consume and return itExample:
e := "10 + -5 / 3 * 5! - - - - -7"
=> ts := <10, "+", "-", 5, "/", 3, "*", 5, "!", "-", "-", "-", "-", "-", 7>
solveExpr(e) = (10 + (((-5) / 3) * (5!))) - 7 = -197With kind regards
Ben

Similar Messages

  • Regular expressions to parse arithmetic expression

    Hello,
    I would like to parse arithmetic expressions like the following
    "5.2 + cos($PI/2) * -5"where valid expression entities are numbers, operations, variables and paranthesis. Until now I have figured out some regular expressions to match every type of entities that I need, and combine them into one big regex supplied to a pattern and matcher. I will paste some code now to see what I wrote:
    public class RegexTest {
        /** A regular expression matching numeric expressions (floating point numbers) */
        private static final String REGEX_NUMERIC = "(-?[0-9]+([0-9]*|[\\.]?[0-9]+))";
        /** A regular expression matching a valid variable name */
        private static final String REGEX_VARIABLE = "(\\$[a-zA-Z][a-zA-Z0-9]*)";
        /** A regular expression matching a valid operation string */
        public static final String REGEX_OPERATION = "(([a-zA-Z][a-zA-Z0-9]+)|([\\*\\/\\+\\-\\|\\?\\:\\@\\&\\^<>'`=%#]{1,2}))";
        /** A regular expression matching a valid paranthesis */
        private static final String REGEX_PARANTHESIS = "([\\(\\)])";
        public static void main(String[] args) {
            String s = "5.2 + cos($PI/2) * -5".replaceAll(" ", "");
            Pattern p = Pattern.compile(REGEX_OPERATION + "|" + REGEX_NUMERIC + "|" + REGEX_VARIABLE + "|" + REGEX_PARANTHESIS);
            Matcher m = p.matcher(s);
            while (m.find()) {
                System.out.println(m.group());
    }The output is
    5
    2
    +
    cos
    $PI
    2
    5There are a few problems:
    1. It splits "5.2" into "5" and "2" instead of keeping it together (so there might pe a problem with REGEX_NUMERIC although "5.2".matches(REGEX_NUMERIC) returns true)
    2. It interprets "... * -5" as the operation " *- " and the number "5" instead of " * " and "-5".
    Any solution to solve these 2 problems are greately appreciated. Thank you in advance.
    Radu Cosmin.

    cosminr wrote:
    So, I've written some concludent examples and the output after parsing (separated by " , " ):
    String e1 = "abs(-5) + -3";
    // output now: abs , ( , - , 5 , ) , + , - , 3 ,
    // should be:  abs , ( , -5 , ) , + , - , 3 , (Notice the -5)
    I presume that should also be "-3" instead of ["-", "3"].
    String e2 = "sqrt(abs($x=1 + -10))";
    // output now: sqrt , ( , abs , ( , $x , = , 1 , + , - , 10 , ) , ) ,
    // should be:  sqrt , ( , abs , ( , $x , = , 1 , + , -10 , ) , ) ,   (Notice the -10)
    String e3 = "$e * -1 + (2 - sqrt(4))";
    // output now: $e , * , - , 1 , + , ( , 2 , - , sqrt , ( , 4 , ) , ) ,
    // should be:  $e , * , -1 , + , ( , 2 , - , sqrt , ( , 4 , ) , ) ,
    String e4 = "sin($PI/4) - 3";
    // output now: sin , ( , $PI , / , 4 , ) , - , 3 , (This one is correct)
    String e5 = "sin($PI/4) - -3 - (-4)";
    // output now: sin , ( , $PI , / , 4 , ) , - , - , 3 , - , ( , - , 4 , ) ,
    // should be:  sin , ( , $PI , / , 4 , ) , - , -3 , - , ( , -4 , ) ,  (Notice -3 and -4)I hope they are relevant, If not I will supply some more.I made a small change to REGEX_NUMERIC and also put REGEX_NUMERIC at the start of the "complete pattern" when the Matcher is created:
    import java.util.regex.*;
    class Test {
        private static final String REGEX_NUMERIC = "(((?<=[-+*/(])|(?<=^))-)?\\d+(\\.\\d+)?";
        private static final String REGEX_VARIABLE = "\\$[a-zA-Z][a-zA-Z0-9]*";
        public static final String REGEX_OPERATION = "[a-zA-Z][a-zA-Z0-9]+|[-*/+|?:@&^<>'`=%#]";
        private static final String REGEX_PARANTHESIS = "[()]";
        public static void main(String[] args) {
            String[] tests = {
                "abs(-5) + -3",
                "sqrt(abs($x=1 + -10))",
                "$e * -1 + (2 - sqrt(4))",
                "sin($PI/4) - 3",
                "sin($PI/4) - -3 - (-4)",
                "-2-4" // minus sign at the start of the expression
            Pattern p = Pattern.compile(REGEX_NUMERIC + "|" + REGEX_OPERATION + "|" + REGEX_VARIABLE + "|" + REGEX_PARANTHESIS);
            for(String s: tests) {
                s = s.replaceAll("\\s", "");
                Matcher m = p.matcher(s);
                System.out.printf("%-21s-->", s);
                while (m.find()) {
                    System.out.printf("%6s", m.group());
                System.out.println();
    }Note that since Java's regex engine does not support "variable length look behinds", you will need to remove the white spaces from your expression, otherwise REGEX_NUMERIC will go wrong if a String looks like this:
    "1 - - 1"Good luck!

  • Regex for arithmetic expressions

    Hi all,
    I am new to Java. I was wondering if anyone can help me understand how regular expressions work. My problem is how to come up with a regular expression that would match a simple arithmetic expression like:
    a + b + c + d
    And I want to capture things by groups. I largely suspect that I should use something like:
    (\\w+)(\\s\\+\\s(\\w+))*
    (I use the \\s here because \\b doesn't seem to work)
    would work by capturing the first word like sequence with (\\w+), and the succeeding repeats of the plus sign and another word being captured by (\\s\\+\\s(\\w+))*. Didn't work though. Can anyone tell me what's wrong and how to think of a better way of handling these sort of expressions?
    The code I tried goes like:
    String patt = "(\\w+)(\\s\\+\\s(\\w+))*";
    String feed = "a + b + c + d";
    Pattern p = Pattern.compile(patt);
    Matcher m = p.matcher(feed);
    /* here I want to see if the groupings work somehow*/
    if(m.find()){
    for(int i=0; i<=m.groupCount(); i++)
    System.out.println(m.group(i));
    Thanks

    Sorry about that. Here's the correctly formatted post:
    So, with a simple arithmetic expression like:
    a + b + c + dI want to capture things by groups and I thought of using something like:
    (\\w+)(\\s\\+\\s(\\w+))*(I use the \\s here because \\b doesn't seem to work)
    with the idea of capturing the first word like sequence with (\\w+), and the succeeding repeats of the plus sign and another word being captured by (\\s\\+\\s(\\w+))*. As this didn't work, can anyone tell me what's wrong and how to think of a better way of handling these sort of expressions?
    The code I tried goes like:
    String patt = "(\\w+)(\\s\\+\\s(\\w+))*";
    String feed = "a + b + c + d";
    Pattern p = Pattern.compile(patt);
    Matcher m = p.matcher(feed);then I want to see if the groupings work somehow
    if(m.find()){
    for(int i=0; i<=m.groupCount(); i++)
    System.out.println(m.group(i));
    }and yes, I am wondering if arithmetic parsing would be possible with regex. I have implemented something similar before using combinations of simple tokenization and character checks, but I want to make cleaner looking code. Would using regular expressions be a bad choice? What if I feed something like:
    (a + b) + (c + d)

  • Thread to evaluate arithmetic expressions

    I'm trying to write a program that evalutaes arithmetic expression concurrently using Java concurency primitives. The idea behind the threading is to avoid multiple evaluations of common subexpression. I have attached the code that I have written so far but was hoping someone could offer me a hand with the evaluate() and run() methods contained at the end of the program. Thanks.
    public class Example {
         public static void main(String[] args) {
              BinaryOp plus = new BinaryOp() {
                   public int apply(int n1, int n2) {
                        return n1 + n2;
              BinaryOp times = new BinaryOp() {
                   public int apply(int n1, int n2) {
                        return n1 * n2;
              Arith e1 = new Operator(plus, new Number(4), new Number(5));
              Arith e2 = new Operator(plus,new Operator(times, new Number(3), e1),
                   new Operator(plus, e1, new Number(6)));
              Arith e3 = new Operator(times, e2, e2);
              System.out.println(e3.evaluate());
    interface BinaryOp {
         // An operator that can be applied to two numbers
         int apply(int n1, int n2);
    interface Arith {
         // An arithmetic expression that can be evaluated.
         int evaluate();
    class Number implements Arith {
         private int n;
         Number(int n) {
              this.n = n;
         public int evaluate() { // A number evaluates to itself.
              return n;
    class Operator implements Arith, Runnable {
         private BinaryOp op;
         private Arith e1;
         private Arith e2;
         private boolean done = false;
         private int result = 0; // holds the result of previous evaluation
         Operator(BinaryOp op, Arith e1, Arith e2) {
              this.op = op;
              this.e1 = e1;
              this.e2 = e2;
              (new Thread(this)).start();
         public int evaluate() {
         public void run() {
    }

    I'm trying to write a program that evalutaes arithmetic expression
    concurrently using Java concurency primitives. The idea behind the
    threading is to avoid multiple evaluations of common subexpression. Interesting ... the main problem however is to find those common
    subexpressions. Most of the evaluation of those common subexpressions
    can be done in the parse/compile phase though, effectively elliminating
    the need for threads, e.g. (foo+bar)-(foo+bar) can be deduced to be
    equal to zero if both 'foo' and 'bar' happen to referential transparent,
    i.e. they don't have side effects.
    What you're doing now is just starting a new thread for every binary operator.
    This is, most likely, not what you want. The strategy of what thread to
    start for which subexpression must have layed out the sequence of
    threads to start before actual evaluation is started (also see above).
    kind regards,
    Jos

  • "ABAP Basics" Book - arithmetic expression error in the sample code

    Hi all,
    I have just started learning ABAP on mini SAP system (NW7.01) by following "ABAP Basics" book.
    This question might be a FAQ, but I have spent a few days searching a right answer without success.
    I appreciate if you could help me on this.
    On the page 162, there is a function module sample, which contains the line as following:
    e_amount = i_km * '0.3'.
    Here l_km (import) is type of i, and e_amount (export) is type of f.
    Though I do not think of any problem with this line, it throws an arithmetic expression error when executed directly for testing as well as when called from a program.
    When I tried a similar thing in a program, it was fine.
    However within a function module it throws this error.
    Thanks in advance.
    Terry

    Like I said before, I do not think any problem about the code itself.
    I suspect some environmental things?
    I should have mentioned SAP mini system NW7.01 is running on Vista Business?
    To be specifc, I receive this message:
    Arithmetic operations are only expected for operands that can be converted to numbers.
    (numeric operands). - (numeric operands). - - - -
    with the following function module:
    [code]
    FUNCTION ZPTB00_CALCULATE_TRAVEL_EXPENS.
    ""Local Interface:
    *"  IMPORTING
    *"     VALUE(I_KM) TYPE REF TO  I
    *"  EXPORTING
    *"     VALUE(E_AMOUNT) TYPE REF TO  F
    *"  EXCEPTIONS
    *"      FAILED
    e_amount = i_km * '0.3'.
    IF sy-subrc <> 0.
      RAISE failed.
    ENDIF.
    ENDFUNCTION.
    [/code]

  • Need help regarding Arithmetic Expressions

    Hi Experts,
    I have a requirement where in I need to pass Arithmetic Expressions (+,-,/) as constants to a subroutine.For ex:
    constants:c_p   type char1 value '+',
                     c_m   type char1 value '-',
    data:v_a type char1 value '2',
             v_b type char1 value '6',
            v_r    type string.
    v_r = v_ a   + v_b.
    In the above instead of + I want use c_p.Please help me out is there any other way in defining Arithmetic expresiions where I could use constants or variables instead of directly using these expressions(+,-).Thanks in advance.
    With Regards,
    Srini..

    Hello Srini,
    I think you must have a look at the FMs belonging to FuGr. CALC.
    For e.g.,  EVAL_FORMULA which evaluates Literal or Variable formulas
    CONSTANTS:
    C_P TYPE CHAR1 VALUE '+',
    C_M TYPE CHAR1 VALUE '-'.
    DATA:
    V_A TYPE CHAR1 VALUE '2',
    V_B TYPE CHAR1 VALUE '6',
    V_FORMULA TYPE STRING,
    V_RES_F   TYPE F,
    V_RES_P   TYPE P.
    CONCATENATE V_A C_P V_B INTO V_FORMULA SEPARATED BY SPACE.
    CALL FUNCTION 'EVAL_FORMULA'
      EXPORTING
        FORMULA                 = V_FORMULA
      IMPORTING
        VALUE                   = V_RES_F
      EXCEPTIONS
        DIVISION_BY_ZERO        = 1
        EXP_ERROR               = 2
        FORMULA_TABLE_NOT_VALID = 3
        INVALID_EXPRESSION      = 4
        INVALID_VALUE           = 5
        LOG_ERROR               = 6
        PARAMETER_ERROR         = 7
        SQRT_ERROR              = 8
        UNITS_NOT_VALID         = 9
        MISSING_PARAMETER       = 10
        OTHERS                  = 11.
    IF SY-SUBRC = 0.
      MOVE V_RES_F TO V_RES_P.
      WRITE: V_RES_P .
    ENDIF.
    BR,
    Suhas

  • Add spaces in arithmetic expressions

    Hi experts,
    i have to insert spaces in arithmetical expressions written by users.
    For example:
    INPUT (by USERS): A+B-SQRT(C)/(D**2)
    OUTPUT (by Program): A + B - SQRT( C ) / ( D ** 2 )
    Possible arithmetic operators are:
    +; - ; *; /; **; SQRT()
    Any hints will be rewarded.
    Thanks in advance.
    Fabio.

    Thanks to all guys!
    the right code is a mixt of yours hints:
      l_len = STRLEN( tb_mzcatc-/bic/zformatc ).
      DO.
        l_char = input+n(1).
        CASE l_char.
          WHEN 'Q' OR
               'R'.
            CONCATENATE formula l_char INTO formula.
          WHEN 'T'.
            l_char = input+n(2).
            CONCATENATE formula l_char INTO formula.
            n = n + 1.
          WHEN '*'.
            IF input+n(2) = '**'.
              l_char = input+n(2).
              CONCATENATE formula l_char INTO formula SEPARATED BY ' '.
              n = n + 1.
            ELSE.
              CONCATENATE formula l_char INTO formula SEPARATED BY ' '.
            ENDIF.
          WHEN OTHERS.
            CONCATENATE formula l_char INTO formula SEPARATED BY ' '.
        ENDCASE.
        n = n + 1.
        IF n GT l_len.
          EXIT.
        ENDIF.
      ENDDO.
    Message was edited by:
            Fabio Cappabianca

  • Parsing a java expression

    Write a program in Java that can parse a mathematical expression
    String, calculate the expression, and produce a numeric result.
    For example, given the string: "2.5+3*4+6/12-7" produce the result 8.0
    Requirements: Parser
    * expression can contain Integers or floating-point numbers
    * expression can contain Operators for addition, subtraction, division
    and multiplication
    * parser should throw an Exception when the expression is invalid
    Requirements: Solution
    * Implement the solution in Java
    * Compile and test the solution
    * The solution should demonstrate good modularity, be self-contained,
    reusable and extensible.
    * The solution should be clearly written, easy to read, documented, and
    production-quality.
    Requirements: quality
    * This is a timed exercise and should be completed quickly, however you
    should take sufficient time to produce a quality result
    * A quality solution is simple, concise, complete, well documented,
    readable, adaptable, reusable, testable and robust.

    If your assignment was to:
    1) figure out how to create a login on the forums
    2) cut-and-paste verbiage given to you by someone
    3) create a topic in the forums with the above
    then you get an 'A'. Congratulations!

  • Arithmetic Expression validation

    Can somebody help me in giving me a java program which can
    validate an arithmetic expression.
    For eg ( A + b1 ) / (2 * c) + d
    If someone already has a code snippet which takes an expression String
    and returns a boolean which tells if the expression is valid or not, please post it..... My project is running out of coding time :))))

    With due respect....Its not the question of not trying
    it.. I just thought it would not be judicious to
    re-invent the wheel. Depends on what you are doing.
    If you are working in industry, or are doing a final year project, code re-use is an excellent time saver.
    If you are doing homework which asks you to write an equation validator, code re-use is pretty much cheating. If you did this, you might as welll let the brightets person in the class write the code, and everyone else hand in the same code.

  • Parsing an Algebraic Expression

    Hi ,
    Can any body provide me an idea to parse an algebraic expression in Java.Are there any built in classes for parsing an expression and evaluating after substituting the values for variables in the expression?
    If no classes are availble,plz provide me any algorithm for doing that.
    Thanks in Advance

    Observe:
    Parsing an expression is essentially the act of converting the expression from infix notation to postfix notation. Infix requires parens and precedence to specify order of operations but post fix unambiguously specifies them by the order of the tokens
    So something like
    "a+b*c" becomes "a b c * +"
    "a*b+c" becomes "a b * c +"
    "(a+b)*c" becomes "a b + c *"
    notice that arguments (variables and numbers, the leaves of the implied expression tree) occur in the same sequence in both the infix and the postfix notation. Thus you can view the parsing as a filtering process that passes arguments directly from input to output and all the filter is doing is re-arranging the order of the operators.
    All this rearranging of operators can be done with a single stack and it is all based on this observation:
    When you saw a string like "a op1 b op2 c" you run across the token for the first operator before you have even collected its right argument. You must put that operator somewhere and a OpStack is the place to put it. You don't know whether to emit op1 until you have had a look at the next operator, op2. If op2 was higher priority than op1, then op2 gets to consume the argument b first. In that case op2 just gets added to the stack on top of op1.
    However if op2 was less than or equal in precedence to op1, well then op1 can now be flowed to the output stream and allowed to act on the b argument that is already out on the output stream.
    This means that the fundamental operation of the expression parser is the business of pushing an opertor token onto the stack, but first spewing to the output all the other operators on the stack that had a higher or equal priority. If we give this function a name like opStack.pushSpew(token) it could look something like this:
    class OpStack{
      Stack s = new Stack();
      void pushSpew(List out, Token t){
        Token tos;
        while(!s.empty() && (tos = peek()).priority >= t.priority){out.add(pop());}
        push(t);
    }Next thing to observe is that a grouper, like open and close parens, behaves in the following way. An open paren acts like a very high priority operator when pushed to the stack in that it spews nothing. The previous op is NOT allowed to eat the argument that is about to come right after the open paren. However once the open paren marks the stack, the open should be a lower priority than any real op that gets pushed onto the stack above it because it must delay going out until every real op in the group had its shot. The close paren should also act like a very low priority op. It should spew every op upto but not including the open paren that started this group.
    As a computation trick, if you set the priority of an open lowest of all, and the priority of a close just above that, and you just push the open onto the stack instead of pushSpewing it onto the stack, you will get the desired behavior. You with then pushSpew the close paren and it will dump everything from the stack to the output up to but not including the open. At this point it is easy to check the balance. If you do not have an open/close pair sitting as the top two elements on the stack then the parens (or the brackets or the braces) were not properly nested.
    We are almost done. There are post fix operators like factorial and prefix operators like minus that we need to deal with. It only makes sense to evaluate these suckers from the inside out i.e. if you had a string of prefixs on an arg
    op1 op2 op3 arg
    the only sensible order is defined by parens like this
    (op1 (op2 (op3 arg) ) )
    and in post fix that would be
    arg op3 op2 op1
    that is exactly what you would get if you just pushed each prefix op onto the stack in the order you saw them and then popped them off after you dumped out the argument.
    Post ops should also work from the inside out
    arg op1 op2
    being
    ( (arg op1) op2 )
    and you get this behavior by just dumping a post op to the output when you see it.
    There is only one special concern. What should you do if you saw, both pre ops and post ops on the same arg?
    is "op1 arg op2" done like this: "(op1 arg) op2" or "op1 (arg op2)"? Well, why should these be any different from regular diadic ops, let precdence decide. An espression like minus three factorial "-3!" should be interpreted as take the factorial of 3 and then negate it (and not the other way around!) so let the priority of factorial be greater than that of minus and just do the standard pushSpew with post ops to let them spew out any high priority pre ops before they go onto the stack, but then unlike binary ops, the post op immediately comes off the stack and goes to the output because post ops bind up right away.
    Now if you are not careful with your precedences you could get "wierd" behavior. If for example you did not assign a high priority to a factorial, you could write expressions like "3+4!" and the priority would treat that like "(3+4)!" the plus would bind tighter than the factorial. It is hard for me to imagine a language where you would want the effects of either a postfix or a prefix operator to span across multiple arguments combined by single diadic operator, but that is really up to you. You certainly could have a language where you gave a very low precedence to ~ which could mean the boolean NOT, a lower precedence than the diadic operator >= which would allow you to write "~ a >= b" which would mean "~(a>=b)"
    After all it is your language, do what you want. None the less I would advise against alowing ANY pre or post op to have a priority LESS than that of ANY diadic operator.
    Lots of talk here but to recap, the code is quite simple:
    while((t = getNextToken()) != null){
      switch (t.type()){
        case ARG:  out.add(t); break; // arguments pass straight to output
        case PRE:  stack.push(t); break; // pre ops are just pushed (binding them to the next arg)
        case OPEN: stack.push(t); break; // Opens just push, they don't spew to output
        case DI: stack.pushSpew(out,t); break; // Diadic ops do the standard pushSpew
        case POST: stack.pushSpew(out,t); out.add(stack.pop()); break; //spew and then go out
        case CLOSE: stack.pushSpew(out,t); stack.removeOCpair(); // spew all ops in group
          // and then check if you had a balancing open
    }That just about does the entire parse. If you can find the tokens in the input you can rearrange them into the output. You do need to flush the opStack when you are done with the input stream and there is a convenient trick to doing that. The trick is this. Invent an invisible Open and Close pair, invisible meaning that they never show up in any input stream, you just made them up and pretended that that expression started with an invisible OpenExp and at the end it closed with a CloseExp.
    The CloseExp at the end will act like any grouper, it will flush the stack looking for the corresponding opener. IF there was any unbalanced grouper, like say an extra unbalanced open paren somewhere in the expression, the CloseExp will spew its way down to that unbalanced paren and then fail when it discovers that it does not match the open in the call to remove the OC pair. The is a way to do error detection. Use a fictional group on the entire expression to both flush the remainder of the opStack and to do a final check for unbalanced groupers.
    In fact, while we are on the topic of error checking there is another one that is very good to include. Basically in a real expression if you ignore the parens, the progression should be an alternation between args and diadic ops, with an occasional pre or post op thrown in.
    A simple count tells you where you are. Go up to 1 when you pass an argument, go back down to zero when you see a diadic operator. You should start at zero, because there have been no arguments or ops yet. In state zero the only legal things to do are to put in a pre op or an arg. Once you have an arg out there the only legal things to do are to have a post op or a diadic op. This little state machine will tell you if and when you have got either a pair of arguments together with no op between them, or a pair of ops with no argument between them. You should start at state = 0 and you should end at state = 1 (unless you allow empty expressions) So we can beef up the error checking with a very simple addition. The guts of the parse will now look like this:
    state = 0
    stack.push(Token.OpenExp); // start off with an open of the expression
    while((t = getNextToken()) != null){
      switch (t.type()){
        case ARG:  assertStateIs(0); out.add(t); state = 1; break;
        case PRE:  assertStateIs(0); stack.push(t); break;
        case OPEN: stack.push(t); break;
        case DI: assertStateIs(1); stack.pushSpew(out,t); state =0; break;
        case POST: assertStateIs(1);stack.pushSpew(out,t); out.add(stack.pop()); break;
        case CLOSE: stack.pushSpew(out,t); stack.removeOCpair();
    stack.pushSpew(out,Token.CloseExp); stack.removeOCpair();
    assertState(1);
    return out;So - there it is, in outline form the way that you parse an expression.You build 3 classes, Token, ExpressionParser, and OpStack
    Token is just a bucket that holds a name, a type (ARG, PRE, OPEN, DI, ...) and a precedence.
    OpStack is just a wrapper for a reqular stack that will hold Tokens and allow for a pushSpew function.
    ExpressionParser is little other than a Map full of all your Tokens. This map allows the parser to map substrings, tokens, that it finds in the input like >= to actual Tokens with a capital T. It will have two main methods:
    1) the parse method which I have almost completly written for you. It takes an input string and will fill up an output list placing the Tokens in post fix order, which is your parse tree.
    2) the routine getNextToken which will walk the input string, skipping white space when appropriate, looking for names, numbers, and operators and building each chunk that it finds into a Token.
    One last complexity note. If you want to allow functional notation like sqrt(3) you are using parens in a fundamentally different way than was described above (ditto when you use brackets to represent array indexing like x[5]) the fundamentally different thing that you are doing is that you are allowing an argument (a name) like "sqrt" to sit right next to another argument like "3" with no binary op in between. You are using an "implied" binary op at that point. You have saved the user from typing "sqrt FUNCTIONCALL (3)" or "x ARRAYINDEX 5"
    I will leave it as an exercise to the reader to see how you make a small modification to the OPEN case to detect and deal with an implied operation. Don't forget that you must tell the state error checker what you are doing.
    And now that I have shown you how fundamentally simple it is to build an expression parser let me comment on why you do not find a standard library routine for doing this.
    The primary reason is that there is no such thing as a "standard" math expression. Parsing is based on a language and there is no one language. Are you going to allow hex numbers in your expressions? How about scientific notation? Is = equality or assignment? Do you allow functional notation? Array indexing? Multi-dimensional array (like x[2,3])? How about string constants like "foobar"? How do you embed quotes in your quoted strings? Are you allowing comments, block comments, statements, code, Lisp expressions, complex numbers, implicit type conversion, type casting? At what point does it stop being a simple expression and start being a full computer language?
    Furthermore, most of the work you will quickly see if you use what I have suggested to build an expression parser, it how to give your user feedback that the expression that he typed had problems and where. There is no stardard UI for error feedback in things that don't parse correctly. Are you just going to dump cryptic strings to the console or are you going to highlight something in a text box somewhere?
    All the work turns out to be that of defining your language and determining your set of tokens and what precedence you will employ. Once you get that all worked out, parsing the expressions only takes the ten or fifteen lines of code that I outlined.
    And look, it only took several thousands of words to explain why it only takes about 15 lines of code to parse expressions once you have decided upon your language and written your tokenizer.
    Enjoy

  • Fully parentized arithmetic expression

    Hi,
    Would any one be able to tell how does following fully parentized arithmetic expression turns 28?
    I don't get it.
    As an example of using identifiers and assignment, consider the FPAE
    (x0 = ((3 + (x1 = 4)) * x1))
    This expression evaluates to 28 and has the side effects of making the values associated to x0 and x1 28 and 4, respectively. Hence, if the next FPAE to be evaluated were
    (x1 = (x0 - x1))
    the result would be 28 - 4, or 24, and, as a side effect, the value of x1 would be changed to 24. The intent, then, is for identifiers to retain their values (or to have them changed, via assignment) as evaluation continues from one FPAE to another.
    Thanks

    (x0 = ((3 + (x1 = 4)) * x1))
    3+(x1=4)At this point x1 = 4 so the value is 7.
    (3+(x1=4))*x1x1 is still 4, so 7 x 4 = 28.
    Operands are evaluated strictly left to right.

  • Arithmetic expression performance

    Hi,
    Is there any difference in arithmetic expression evaluation performance between one big expression and several smaller that save their partial results in variables?
    For example: Which solution will work faster:
    1)
    int i;
    for(i=1000000; i>=0; i--)
      x=i*a+b*c; //a, b, c - some variables
    }2) int i,p1, p2;
    for(i=1000000; i>=0; i--)
    //a, b, c - some variables
    p1 = i*a;
    p2 = b*c;
    x[i] = p1+p2;

    I some cases I can replace a division with a multiplication.
    Instead of:
    for(int i=0; i<1000; i++)
      tab=tab[i]/5;
    }I can use:int scale = (1<<16)/5;
    for(int i=0; i<1000; i++)
    tab[i]=(tab[i] * scale)>>16;
    }The second solution gives the same result and avoids division by replacing it with multiplication and very fast bit shift operation.
    I can see that my problem is wider that I  thought. Processor manuals are quite precise, but I'm programming in java, not in assebler. So most important issue for me is the way the JVM implementation will execute each bytecode operation. I think that various JVM for various platforms may execute instructions differently. So I'm looking for general tips which operations should be avoided when performance is the key issue.
    I'm writing image processing aplication for mobile devices, so any milisecond counts for me.
    I found some java performance tips on the inernet, but, frankly, I don't trust them. For example: It is recommended to avoid 2-dimensional tables and implement them as 1D table. So instead of:int[][] tab = new int[100][100];
    tab[x][y] = c;one should use:int[] tab = new int[10000];
    tab[y*100+x]=c;It seems reasonable, but the second solution needs multiplication. In the first solution compiler can generate code that store pointers to "second dimension tables" in "first dimension" (table with references to tables). Pointers (references, i mean) have size of 2^n. Integers in second dimension are also of size 2^n. So theoretically compiler may produce byte code that will need no multiplication but only very fast bit-shift operations.
    My question is - how does the compiler cope with 2d arrays.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Not showing error in dual while using it as arithmetic expression

    Hi,
    I have a requirement to throw error if two consecutive numbers or two consecutive operators are given. For this I would like to use dual table.
    It is throwing error if two numbers are given, but not throwing error if it has two operators.
    Error thrown for -> select 2 4 - 7 from dual;
    Error not thrown for -> select 2 + - 7 from dual;
    or
    select 2 - + 7 from dual;
    I am expecting an error in later case too. Can we do any changes to the query to throw the error?
    Thanks!

    Hi,
    If str is a string, then this expression
    REGEXP_LIKE ( str
             , '(\d\s+\d)'     || -- digits, separated by 1 or more whitespace characters
               '|'          || -- or
               '([+*/-]\s*[+*/-]'   -- operators, separated by 0 or more whitespace characters
             )will return TRUE if (and only if) str contains either two consecutive digits (separated by at least 1 space character) or str contains two consectuive arithmetic operators (not necessaily separated by space characters).
    You can include other operator symbols, by including them in both of the lists enclosed in square brackets. The hyphen ('-') must be the very first character or the very last character in the list; aside from that, the order of the symbols makes no difference.
    I hope this answers your question.
    If not, post a little sample data (CREATE TABLE and INSERT statements, relevant columns only) for all tables involved, and also post the results you want from that data.
    Explain, using specific examples, how you get those results from that data.
    Always say which version of Oracle you're using.
    See the forum FAQ {message:id=9360002}

  • Java parser for regular expression to java program

    Hi All,
    I am very new to parser technologies .I am looking for a (java)parser which can read the "regular expression" and can convert it into "java program".Please let me know is there any thing related to this.
    Thanks in advance.
    Your will be appriciate.
    Regards,
    Sai.

    Hi Jos,
    Thank you for your quick response .You're welcome.
    If you have any sample code or simple example for how to use those
    classes (Pattern,Match) ,will you please send me .It will be helpful for me.Jverd gave you two nice links already in his reply #3
    If there is any "open source" for parsering regular expressions.
    Please send me I am very new to parser technologies.Note that that Pattern class take care of all the parsing of REs, i.e. there's
    nothing 'interesting' left for you to do any parsing whatsoever. Can you
    elaborate a bit on what you exactly want to do and learn?
    kind regards,
    Jos

  • Parsing with regular expressions

    Hi
    I'm developing an application that is trying to parse a text in a text file. It's looking for strings like
    " 0551 TIMERHIN, S.L. "
    Then I think I could lok with matches method for a string with many white chars followed by 4 numbers...
    I did
    line.matches("^\\s+[0-9]{4}")
    but it didn't work...
    Any help will be appreciated.
    <jl>

    The String.matches tries to match the regular express against the whole string.
    You regex pattern "^\\s+[0-9]{4}" will match
    "                          0551"but not
    "                          0551 TIMERHIN, S.L. "You can do it using this code:
    import java.sql.*;
    import java.io.*;
    import java.util.regex.*;
    import java.util.*;
    public class RegExTest {
    public static void main (String args[]) {
       Pattern pat = null;
       Matcher m = null;
       String patternToMatch = "^\\s+[0-9]{4}";
       pat = Pattern.compile(patternToMatch);
       System.out.println("Pattern to match = " + patternToMatch);
       String line = "                          0551 TIMERHIN, S.L. ";
       m = pat.matcher(line);
       if (m.find()) { System.out.println("Line matched"); }
    } // end main
    } //End Class Test
      

Maybe you are looking for