1 using System;
  
    2 
  
    3 namespace Calculator
  
    4 {
  
    5     public Result<bool> Parse(const ustring& input)
  
    6     {
  
    7         Scanner scanner(input);
  
    8         auto nextTokenResult = scanner.NextToken();
  
    9         if (nextTokenResult.Error())
  
   10         {
  
   11             return nextTokenResult;
  
   12         }
  
   13         if (scanner.CurrentToken() is PrintToken*)
  
   14         {
  
   15             SymbolTable.Instance().Print();
  
   16             return Result<bool>(true);
  
   17         }
  
   18         else if (scanner.CurrentToken() is VariableNameToken*)
  
   19         {
  
   20             VariableNameToken* token = cast<VariableNameToken*>(scanner.CurrentToken());
  
   21             ustring variableName = token->VariableName();
  
   22             auto nextTokenResult = scanner.NextToken();
  
   23             if (nextTokenResult.Error())
  
   24             {
  
   25                 return nextTokenResult;
  
   26             }
  
   27             if (scanner.CurrentToken() is OperatorToken*)
  
   28             {
  
   29                 OperatorToken* token = cast<OperatorToken*>(scanner.CurrentToken());
  
   30                 if (token->Char() == '=')
  
   31                 {
  
   32                     auto nextTokenResult = scanner.NextToken();
  
   33                     if (nextTokenResult.Error())
  
   34                     {
  
   35                         return nextTokenResult;
  
   36                     }
  
   37                     auto expr = Expr(scanner);
  
   38                     if (expr.Error())
  
   39                     {
  
   40                         return Result<bool>(ErrorId(expr.GetErrorId()));
  
   41                     }
  
   42                     double value = expr.Value();
  
   43                     Token* token = scanner.CurrentToken();
  
   44                     if (token is EndToken*)
  
   45                     {
  
   46                         SymbolTable.Instance().SetVariable(variableName, value);
  
   47                         Console.Out() << variableName << " = " << value << endl();
  
   48                         return Result<bool>(true);
  
   49                     }
  
   50                     else
  
   51                     {
  
   52                         int errorId = AllocateError("invalid input");
  
   53                         return Result<bool>(ErrorId(errorId));
  
   54                     }
  
   55                 }
  
   56             }
  
   57         }
  
   58         scanner.Rewind();
  
   59         nextTokenResult = scanner.NextToken();
  
   60         if (nextTokenResult.Error())
  
   61         {
  
   62             return nextTokenResult;
  
   63         }
  
   64         auto expr = Expr(scanner);
  
   65         if (expr.Error())
  
   66         {
  
   67             return Result<bool>(ErrorId(expr.GetErrorId()));
  
   68         }
  
   69         Token* token = scanner.CurrentToken();
  
   70         if (token is EndToken*)
  
   71         {
  
   72             Console.Out() << "= " << expr.Value() << endl();
  
   73         }
  
   74         else
  
   75         {
  
   76             int errorId = AllocateError("invalid input");
  
   77             return Result<bool>(ErrorId(errorId));
  
   78         }
  
   79         return Result<bool>(true);
  
   80     }
  
   81 
  
   82     internal Result<double> Expr(Scanner& scanner)
  
   83     {
  
   84         auto term = Term(scanner);
  
   85         if (term.Error())
  
   86         {
  
   87             return Result<double>(ErrorId(term.GetErrorId()));
  
   88         }
  
   89         double value = term.Value();
  
   90         Token* token = scanner.CurrentToken();
  
   91         OperatorToken* op = token as OperatorToken*;
  
   92         while (op != null && op->IsAdditiveOperator())
  
   93         {
  
   94             uchar opChar = op->Char();
  
   95             auto nextTokenResult = scanner.NextToken();
  
   96             if (nextTokenResult.Error())
  
   97             {
  
   98                 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
  
   99             }
  
  100             auto rightTerm = Term(scanner);
  
  101             if (rightTerm.Error())
  
  102             {
  
  103                 return Result<double>(ErrorId(rightTerm.GetErrorId()));
  
  104             }
  
  105             double right = rightTerm.Value();
  
  106             if (opChar == '+')
  
  107             {
  
  108                 value = value + right;
  
  109             }
  
  110             else if (opChar == '-')
  
  111             {
  
  112                 value = value - right;
  
  113             }
  
  114             else
  
  115             {
  
  116                 int errorId = AllocateError("logic error");
  
  117                 return Result<double>(ErrorId(errorId));
  
  118             }
  
  119             token = scanner.CurrentToken();
  
  120             op = token as OperatorToken*;
  
  121         }
  
  122         return value;
  
  123     }
  
  124 
  
  125     internal Result<double> Term(Scanner& scanner)
  
  126     {
  
  127         auto factor = Factor(scanner);
  
  128         if (factor.Error())
  
  129         {
  
  130             return factor;
  
  131         }
  
  132         double value = factor.Value();
  
  133         Token* token = scanner.CurrentToken();
  
  134         OperatorToken* op = token as OperatorToken*;
  
  135         while (op != null && op->IsMultiplicativeOperator())
  
  136         {
  
  137             uchar opChar = op->Char();
  
  138             auto nextTokenResult = scanner.NextToken();
  
  139             if (nextTokenResult.Error())
  
  140             {
  
  141                 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));;
  
  142             }
  
  143             auto rightFactor = Factor(scanner);
  
  144             if (rightFactor.Error())
  
  145             {
  
  146                 return rightFactor;
  
  147             }
  
  148             double right = rightFactor.Value();
  
  149             if (opChar == '*')
  
  150             {
  
  151                 value = value * right;
  
  152             }
  
  153             else if (opChar == '/')
  
  154             {
  
  155                 if (right == 0)
  
  156                 {
  
  157                     int errorId = AllocateError("division by zero");
  
  158                     return Result<double>(ErrorId(errorId));
  
  159                 }
  
  160                 value = value / right;
  
  161             }
  
  162             else
  
  163             {
  
  164                 int errorId = AllocateError("logic error");
  
  165                 return Result<double>(ErrorId(errorId));
  
  166             }
  
  167             token = scanner.CurrentToken();
  
  168             op = token as OperatorToken*;
  
  169         }
  
  170         return value;
  
  171     }
  
  172 
  
  173     internal Result<double> Factor(Scanner& scanner)
  
  174     {
  
  175         Token* token = scanner.CurrentToken();
  
  176         OperatorToken* op = token as OperatorToken*;
  
  177         bool neg = false;
  
  178         if (op != null && op->IsAdditiveOperator())
  
  179         {
  
  180             if (op->Char() == '-')
  
  181             {
  
  182                 neg = true;
  
  183             }
  
  184             auto nextTokenResult = scanner.NextToken();
  
  185             if (nextTokenResult.Error())
  
  186             {
  
  187                 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
  
  188             }
  
  189         }
  
  190         auto primary = Primary(scanner);
  
  191         if (primary.Error())
  
  192         {
  
  193             return primary;
  
  194         }
  
  195         double value = primary.Value();
  
  196         if (neg)
  
  197         {
  
  198             return -value;
  
  199         }
  
  200         return Result<double>(value);
  
  201     }
  
  202 
  
  203     internal Result<double> Primary(Scanner& scanner)
  
  204     {
  
  205         Token* token = scanner.CurrentToken();
  
  206         if (token is NumberToken*)
  
  207         {
  
  208             NumberToken* number = cast<NumberToken*>(token);
  
  209             double value = number->Value();
  
  210             auto nextTokenResult = scanner.NextToken();
  
  211             if (nextTokenResult.Error())
  
  212             {
  
  213                 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
  
  214             }
  
  215             return Result<double>(value);
  
  216         }
  
  217         else if (token is VariableNameToken*)
  
  218         {
  
  219             VariableNameToken* variableNameToken = cast<VariableNameToken*>(token);
  
  220             auto variableResult = SymbolTable.Instance().GetVariableValue(variableNameToken->VariableName());
  
  221             if (variableResult.Error())
  
  222             {
  
  223                 return variableResult;
  
  224             }
  
  225             double value = variableResult.Value();
  
  226             auto nextTokenResult = scanner.NextToken();
  
  227             if (nextTokenResult.Error())
  
  228             {
  
  229                 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
  
  230             }
  
  231             return Result<double>(value);
  
  232         }
  
  233         else if (token is OperatorToken*)
  
  234         {
  
  235             OperatorToken* op = cast<OperatorToken*>(token);
  
  236             if (op->Char() == '(')
  
  237             {
  
  238                 auto nextTokenResult = scanner.NextToken();
  
  239                 if (nextTokenResult.Error())
  
  240                 {
  
  241                     return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
  
  242                 }
  
  243                 auto expr = Expr(scanner);
  
  244                 if (expr.Error())
  
  245                 {
  
  246                     return expr;
  
  247                 }
  
  248                 double value = expr.Value();
  
  249                 token = scanner.CurrentToken();
  
  250                 if (token is OperatorToken*)
  
  251                 {
  
  252                     op = cast<OperatorToken*>(token);
  
  253                     if (op->Char() == ')')
  
  254                     {
  
  255                         auto nextTokenResult = scanner.NextToken();
  
  256                         if (nextTokenResult.Error())
  
  257                         {
  
  258                             return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
  
  259                         }
  
  260                         return Result<double>(value);
  
  261                     }
  
  262                     else
  
  263                     {
  
  264                         int errorId = AllocateError("\')\' expected");
  
  265                         return Result<double>(ErrorId(errorId));
  
  266                     }
  
  267                 }
  
  268             }
  
  269         }
  
  270         int errorId = AllocateError("number, variable name or subexpression expected");
  
  271         return Result<double>(ErrorId(errorId));
  
  272     }