Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem With Strings

Tags:

c#

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.

like image 986
Arjun Avatar asked Jul 12 '26 21:07

Arjun


1 Answers

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
like image 113
Anton Gogolev Avatar answered Jul 14 '26 11:07

Anton Gogolev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!