2

I am in a process of designing relational calculator.

If a user supplied a string like -3.33+44*456/2.2-3+4....

I want to store it in string array as

-3.33

+44

*

456

/

2.2

-3

+4

...... (that is *, /, +ve value, -ve value separately and in serial order into an string array)

This is the code I wrote:

string a = "-3.33+44*456/2.2-3";

string[] ip = new string[25];
        int k = 0;


            for (int i = 0; i < a.Length; i++)
            {
                if (a.Substring(i, 1) == "+" || a.Substring(i, 1) == "-" || a.Substring(i, 1) == "*" || a.Substring(i, 1) == "/" || a.Substring(i, 1) == "^")
                {
                    for (int j = i + 1; j < a.Length; j++)
                    {
                        if (a.Substring(j, 1) == "+" || a.Substring(j, 1) == "-" || a.Substring(j, 1) == "*" || a.Substring(j, 1) == "/" || a.Substring(j, 1) == "^")
                        {
                            if (a.Substring(i, 1) == "+" || a.Substring(i, 1) == "-")
                            {
                                ip[k] = a.Substring(i, j-i);
                                k++;
                            }
                            else
                            {
                                ip[k] = a.Substring(i, 1);
                                k++;
                                ip[k] = a.Substring(i + 1, (j -i)-1);
                                k++;
                            }
                            i = j;
                            break;
                        }
                    }
                }

            }

But its not working properly: Its storing only one element in the array.

From last two days I am braking my head. Please help me. Thank You.

4 Answers 4

14

You're approaching the problem from a completely wrong end. What you need is a tokenizer and a parser. You can write those by hand, or you can use one of many so-called "Compiler-Compilers".

You can also try Irony:

namespace Irony.Samples {
  // This grammar describes programs that consist of simple expressions and assignments
  // for ex:
  // x = 3
  // y = -x + 5
  //  the result of calculation is the result of last expression or assignment.
  //  Irony's default  runtime provides expression evaluation. 
  //  supports inc/dec operators (++,--), both prefix and postfix,
  //  and combined assignment operators like +=, -=, etc.

  [Language("ExpressionEvaluator", "1.0", "Multi-line expression evaluator")]
  public class ExpressionEvaluatorGrammar : Irony.Parsing.Grammar {
    public ExpressionEvaluatorGrammar() {

      // 1. Terminals
      var number = new NumberLiteral("number");
      //Let's allow big integers (with unlimited number of digits):
      number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt };
      var identifier = new IdentifierTerminal("identifier");
      var comment = new CommentTerminal("comment", "#", "\n", "\r"); 
      //comment must to be added to NonGrammarTerminals list; it is not used directly in grammar rules,
      // so we add it to this list to let Scanner know that it is also a valid terminal. 
      base.NonGrammarTerminals.Add(comment);

      // 2. Non-terminals
      var Expr = new NonTerminal("Expr");
      var Term = new NonTerminal("Term");
      var BinExpr = new NonTerminal("BinExpr", typeof(BinExprNode));
      var ParExpr = new NonTerminal("ParExpr");
      var UnExpr = new NonTerminal("UnExpr", typeof(UnExprNode));
      var UnOp = new NonTerminal("UnOp");
      var BinOp = new NonTerminal("BinOp", "operator");
      var PostFixExpr = new NonTerminal("PostFixExpr", typeof(UnExprNode));
      var PostFixOp = new NonTerminal("PostFixOp");
      var AssignmentStmt = new NonTerminal("AssignmentStmt", typeof(AssigmentNode));
      var AssignmentOp = new NonTerminal("AssignmentOp", "assignment operator");
      var Statement = new NonTerminal("Statement");
      var ProgramLine = new NonTerminal("ProgramLine");
      var Program = new NonTerminal("Program", typeof(StatementListNode));

      // 3. BNF rules
      Expr.Rule = Term | UnExpr | BinExpr | PostFixExpr;
      Term.Rule = number | ParExpr | identifier;
      ParExpr.Rule = "(" + Expr + ")";
      UnExpr.Rule = UnOp + Term;
      UnOp.Rule = ToTerm("+") | "-" | "++" | "--";
      BinExpr.Rule = Expr + BinOp + Expr;
      BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**";
      PostFixExpr.Rule = Term + PostFixOp;
      PostFixOp.Rule = ToTerm("++") | "--";
      AssignmentStmt.Rule = identifier + AssignmentOp + Expr;
      AssignmentOp.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/=";
      Statement.Rule = AssignmentStmt | Expr | Empty;
      ProgramLine.Rule = Statement + NewLine;
      Program.Rule = MakeStarRule(Program, ProgramLine);
      this.Root = Program;       // Set grammar root

      // 4. Operators precedence
      RegisterOperators(1, "+", "-");
      RegisterOperators(2, "*", "/");
      RegisterOperators(3, Associativity.Right, "**");

      // 5. Punctuation and transient terms
      RegisterPunctuation("(", ")");
      RegisterBracePair("(", ")"); 
      MarkTransient(Term, Expr, Statement, BinOp, UnOp, PostFixOp, AssignmentOp, ProgramLine, ParExpr);

      //automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source
      this.LanguageFlags = LanguageFlags.CreateAst | LanguageFlags.NewLineBeforeEOF | LanguageFlags.CanRunSample; 

    }
  }
}//namespace
Sign up to request clarification or add additional context in comments.

2 Comments

How to use this code? How can we integrate it into windows forms?
A little over the top don't you think?
2

This is my take on this question, it works for the testcase and are easy to expand/change:

    {

        string InputString = "-3.33+44*456/2.2-3+4";
        string[] RetArray = InputString.Replace("-", " -").Replace("+", " +").Replace("*", " * ").Replace("/", " / ").Split(new Char[] { ' ' });

    }

Just one row.

Edit: Fixed and verified.

4 Comments

In my system strings is not getting recognized. This code is giving error. I am using VS2008
Error 1 'System.Linq.Strings' is inaccessible due to its protection level
I think you are looking for sth. like string[] retarray = ("-3.33+44*456/2.2-3+4".Replace("-", " -").Replace("+", " +").Replace("*", " * ").Replace("/", " / ").Split(' '));
Note to myself, 1. dont trust online vb.net->C# converters, and 2. test code in C# before posting.
0

Rather than rewrite your code for you, I'll just point out where you have a few bugs (see comments):

string a = "-3.33+44*456/2.2-3"; 

string[] ip = new string[25]; 
    int k = 0; 


        for (int i = 0; i < a.Length; i++) 
        { 
            if (a.Substring(i, 1) == "+" || a.Substring(i, 1) == "-" || a.Substring(i, 1) == "*" || a.Substring(i, 1) == "/" || a.Substring(i, 1) == "^") 
            { 
                for (int j = i + 1; j <= a.Length; j++) // a.Length has to be included so the last element gets added
                { 
                    // allow the end of the string as an option
                    if (j == a.Length || a.Substring(j, 1) == "+" || a.Substring(j, 1) == "-" || a.Substring(j, 1) == "*" || a.Substring(j, 1) == "/" || a.Substring(j, 1) == "^") 
                    { 
                        if (a.Substring(i, 1) == "+" || a.Substring(i, 1) == "-") 
                        { 
                            ip[k] = a.Substring(i, j-i); 
                            k++; 
                        } 
                        else 
                        { 
                            ip[k] = a.Substring(i, 1); 
                            k++; 
                            ip[k] = a.Substring(i + 1, (j -i)-1); 
                            k++; 
                        }
                        i = j - 1; // i gets incremented in the for loop, so subract 1 here
                        break; 
                    } 
                } 
            } 

        } 

Comments

0

If you're just trying to execute arbitrary mathematical expressions stored in a string, you should definitely take a look at dotMath - Brief how-to.

Hope this helps! If I didn't understand your question and you're trying to do something much more complicated that this wouldn't solve, let me know!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.