示例#1
0
        /*
         * public void CheckTypesAdd()//если оператор плюс или минус
         * {
         *  switch (FirstOperand.MainVariable.Type)
         *  {
         *      case "int":
         *          {
         *              switch (SecondOperand.MainVariable.Type)
         *              {
         *                  case "int":
         *                      {
         *                          MainVariable.Type = "int";
         *                          break;
         *                      }
         *                  case "float":
         *                      {
         *                          MainVariable.Type = "float";
         *                          break;
         *                      }
         *                  default: { throw new IncompatibleTypesException(LineNumber, "int", SecondOperand.MainVariable.Type); }
         *              }
         *              break;
         *          }
         *      case "float":
         *          {
         *              switch (SecondOperand.MainVariable.Type)
         *              {
         *                  case "int":
         *                  case "float":
         *                      {
         *                          MainVariable.Type = "float";
         *                          /*if (IsConst)
         *                          {
         *                              float first = float.Parse(FirstOperand.MainVariable.Value);
         *                              float second = float.Parse(SecondOperand.MainVariable.Value);
         *                              if (Value == "+")
         *                                  MainVariable.Value = (first + second).ToString();
         *                              else //если минус
         *                                  MainVariable.Value = (first - second).ToString();
         *                          }
         *                          break;
         *                      }
         *                  default: { throw new IncompatibleTypesException(LineNumber, "int", SecondOperand.MainVariable.Type); }
         *              }
         *              break;
         *          }
         *      case "string":
         *          {
         *              if (Value == "-")
         *                  throw new InvalidTypeException(LineNumber, "string", "-");
         *              switch (SecondOperand.MainVariable.Type)
         *              {
         *                  case "string":
         *                  case "char": {
         *                          MainVariable.Type = "string";
         *                          //if (IsConst)
         *                             // MainVariable.Value = FirstOperand.MainVariable.Value + SecondOperand.MainVariable.Value;
         *                          break;
         *                      }
         *                  default: { throw new IncompatibleTypesException(LineNumber, "string", SecondOperand.MainVariable.Type); }
         *              }
         *              break;
         *          }
         *      case "char":
         *          {
         *              if (Value == "-")
         *                  throw new InvalidTypeException(LineNumber, "string", "-");
         *              switch (SecondOperand.MainVariable.Type)
         *              {
         *                  case "string":
         *                  case "char": {
         *                          MainVariable.Type = "string";
         *                          //if (IsConst)
         *                            //  MainVariable.Value = FirstOperand.MainVariable.Value + SecondOperand.MainVariable.Value;
         *                          break;
         *                      }
         *                  default: { throw new IncompatibleTypesException(LineNumber, "string", SecondOperand.MainVariable.Type); }
         *              }
         *              break;
         *          }
         *      case "bool":
         *          {
         *              throw new InvalidTypeException(LineNumber, "bool", Value);
         *          }
         *  }
         * }
         *
         * public void CheckTypesMul() //умножение и деление
         * {
         *  //bool IsConst = FirstOperand.MainVariable.IsConst && SecondOperand.MainVariable.IsConst;
         *  switch (FirstOperand.MainVariable.Type)
         *  {
         *      case "int":
         *          {
         *              switch (SecondOperand.MainVariable.Type)
         *              {
         *                  case "int":
         *                      {
         *                          MainVariable.Type = "int";
         *                          /*if (IsConst)
         *                          {
         *                              int first = int.Parse(FirstOperand.MainVariable.Value);
         *                              int second = int.Parse(SecondOperand.MainVariable.Value);
         *                              switch (Value)
         *                              {
         *                                  case ("*"):
         *                                      {
         *                                          MainVariable.Value = (first * second).ToString();
         *                                          break;
         *                                      }
         *                                  case ("/"):
         *                                      {
         *                                          try
         *                                          {
         *                                              if (second == 0)
         *                                                  throw new DividingByZeroWarning(LineNumber);
         *                                              MainVariable.Value = (first / second).ToString();
         *                                          }
         *                                          catch (WarningMessage e)
         *                                          {
         *                                              Console.WriteLine(e.Message);
         *                                          }
         *                                          break;
         *                                      }
         *                                  case ("%"):
         *                                      {
         *                                          try
         *                                          {
         *                                              if (second == 0)
         *                                                  throw new DividingByZeroWarning(LineNumber);
         *                                              MainVariable.Value = (first / second).ToString();
         *                                          }
         *                                          catch (WarningMessage e)
         *                                          {
         *                                              Console.WriteLine(e.Message);
         *                                          }
         *                                          break;
         *                                      }
         *                              }
         *                          }
         *                          break;
         *                      }
         *                  case "float":
         *                      {
         *                          MainVariable.Type = "float";
         *                          /*if (IsConst)
         *                          {
         *                              float first = float.Parse(FirstOperand.MainVariable.Value);
         *                              float second = float.Parse(SecondOperand.MainVariable.Value);
         *                              switch (Value)
         *                              {
         *                                  case ("*"):
         *                                      {
         *                                          MainVariable.Value = (first * second).ToString();
         *                                          break;
         *                                      }
         *                                  case ("/"):
         *                                      {
         *                                          try
         *                                          {
         *                                              if (second == 0)
         *                                                  throw new DividingByZeroWarning(LineNumber);
         *                                              MainVariable.Value = (first / second).ToString();
         *                                          }
         *                                          catch (WarningMessage e)
         *                                          {
         *                                              Console.WriteLine(e.Message);
         *                                          }
         *                                          break;
         *                                      }
         *                                  case ("%"):
         *                                      {
         *                                          try
         *                                          {
         *                                              if (second == 0)
         *                                                  throw new DividingByZeroWarning(LineNumber);
         *                                              MainVariable.Value = (first / second).ToString();
         *                                          }
         *                                          catch (WarningMessage e)
         *                                          {
         *                                              Console.WriteLine(e.Message);
         *                                          }
         *                                          break;
         *                                      }
         *                              }
         *                          }
         *                          break;
         *                      }
         *                  default: { throw new IncompatibleTypesException(LineNumber, "int", SecondOperand.MainVariable.Type); }
         *              }
         *              break;
         *          }
         *      case "float":
         *          {
         *              switch (SecondOperand.MainVariable.Type)
         *              {
         *                  case "int":
         *                  case "float":
         *                      {
         *                          MainVariable.Type = "float";
         *                          /*if (IsConst)
         *                          {
         *                              float first = float.Parse(FirstOperand.MainVariable.Value);
         *                              float second = float.Parse(SecondOperand.MainVariable.Value);
         *                              switch (Value)
         *                              {
         *                                  case ("*"):
         *                                      {
         *                                          MainVariable.Value = (first * second).ToString();
         *                                          break;
         *                                      }
         *                                  case ("/"):
         *                                      {
         *                                          try
         *                                          {
         *                                              if (second == 0)
         *                                                  throw new DividingByZeroWarning(LineNumber);
         *                                              MainVariable.Value = (first / second).ToString();
         *                                          }
         *                                          catch (WarningMessage e)
         *                                          {
         *                                              Console.WriteLine(e.Message);
         *                                          }
         *                                          break;
         *                                      }
         *                                  case ("%"):
         *                                      {
         *                                          try
         *                                          {
         *                                              if (second == 0)
         *                                                  throw new DividingByZeroWarning(LineNumber);
         *                                              MainVariable.Value = (first / second).ToString();
         *                                          }
         *                                          catch (WarningMessage e)
         *                                          {
         *                                              Console.WriteLine(e.Message);
         *                                          }
         *                                          break;
         *                                      }
         *                              }
         *                          }
         *                          break;
         *                      }
         *                  default: { throw new IncompatibleTypesException(LineNumber, "float", SecondOperand.MainVariable.Type); }
         *              }
         *              break;
         *          }
         *      default:
         *          { throw new InvalidTypeException(LineNumber, FirstOperand.MainVariable.Type, Value); }
         *  }
         * }
         *
         * public void CheckTypesComparison()//сравнивать можно число с числом, строку со строкой или bool с bool
         * {
         *  string type1 = FirstOperand.MainVariable.Type, type2 = SecondOperand.MainVariable.Type;
         *  if (((type1 == "int" || type1 == "float") && (type2 == "int" || type2 == "float"))//если оба числа
         || ((type1 == "char" || type1 == "string") && (type2 == "char" || type2 == "string"))//или оба строковые
         || (type1 == "bool" && type2 == "bool"))
         || {
         ||     MainVariable.Type = "bool";
         ||     bool IsConst = FirstOperand.MainVariable.IsConst && SecondOperand.MainVariable.IsConst;
         ||     /*if (IsConst)
         ||     {
         ||         if (type1=="int" || type1=="float")
         ||         {
         ||             float first = float.Parse(FirstOperand.MainVariable.Value);
         ||             float second = float.Parse(SecondOperand.MainVariable.Value);
         ||             switch (Value)
         ||             {
         ||                 case (">"):
         ||                     {
         ||                         MainVariable.Value = (first > second).ToString();
         ||                         break;
         ||                     }
         ||                 case (">="):
         ||                     {
         ||                         MainVariable.Value = (first >= second).ToString();
         ||                         break;
         ||                     }
         ||                 case ("<"):
         ||                     {
         ||                         MainVariable.Value = (first < second).ToString();
         ||                         break;
         ||                     }
         ||                 case ("<="):
         ||                     {
         ||                         MainVariable.Value = (first <= second).ToString();
         ||                         break;
         ||                     }
         ||                 case ("=="):
         ||                     {
         ||                         MainVariable.Value = (first == second).ToString();
         ||                         break;
         ||                     }
         ||                 case ("!="):
         ||                     {
         ||                         MainVariable.Value = (first != second).ToString();
         ||                         break;
         ||                     }
         ||             }
         ||         }
         ||         else if (type1=="char" || type1=="string")
         ||         {
         ||             string first = FirstOperand.MainVariable.Value;
         ||             string second = SecondOperand.MainVariable.Value;
         ||             switch (Value)
         ||             {
         ||                 case (">"):
         ||                     {
         ||                         MainVariable.Value = (String.Compare(first,second)>0).ToString();
         ||                         break;
         ||                     }
         ||                 case (">="):
         ||                     {
         ||                         MainVariable.Value = (String.Compare(first, second) >= 0).ToString();
         ||                         break;
         ||                     }
         ||                 case ("<"):
         ||                     {
         ||                         MainVariable.Value = (String.Compare(first, second)<0).ToString();
         ||                         break;
         ||                     }
         ||                 case ("<="):
         ||                     {
         ||                         MainVariable.Value = (String.Compare(first, second) <= 0).ToString();
         ||                         break;
         ||                     }
         ||                 case ("=="):
         ||                     {
         ||                         MainVariable.Value = (String.Equals(first, second)).ToString();
         ||                         break;
         ||                     }
         ||                 case ("!="):
         ||                     {
         ||                         MainVariable.Value = (!String.Equals(first, second)).ToString();
         ||                         break;
         ||                     }
         ||             }
         ||         }
         ||         else //иначе булевский
         ||         {
         ||             bool first = bool.Parse(FirstOperand.MainVariable.Value);
         ||             bool second = bool.Parse(SecondOperand.MainVariable.Value);
         ||             switch (Value)
         ||             {
         ||                 case (">"):
         ||                     {
         ||                         MainVariable.Value = (first && !second).ToString();
         ||                         break;
         ||                     }
         ||                 case (">="):
         ||                     {
         ||                         MainVariable.Value = (first).ToString();
         ||                         break;
         ||                     }
         ||                 case ("<"):
         ||                     {
         ||                         MainVariable.Value = (!first && second).ToString();
         ||                         break;
         ||                     }
         ||                 case ("<="):
         ||                     {
         ||                         MainVariable.Value = (second).ToString();
         ||                         break;
         ||                     }
         ||                 case ("=="):
         ||                     {
         ||                         MainVariable.Value = ((first && second) || (!first && !second)).ToString();
         ||                         break;
         ||                     }
         ||                 case ("!="):
         ||                     {
         ||                         MainVariable.Value = ((!first && second) || (first && !second)).ToString();
         ||                         break;
         ||                     }
         ||             }
         ||         }
         ||     }
         || }
         || else throw new IncompatibleTypesException(LineNumber, type1, type2);
         ||}
         ||
         ||public void CheckTypesBit()//побитовые операции, допустимы только целые числа и логические значения
         ||{
         || if (FirstOperand.MainVariable.Type == "bool" && SecondOperand.MainVariable.Type == "bool")
         ||     MainVariable.Type = "bool";
         || else
         || if ((FirstOperand.MainVariable.Type == "int" || FirstOperand.MainVariable.Type == "bool") &&
         ||     (SecondOperand.MainVariable.Type == "int" || SecondOperand.MainVariable.Type == "bool"))
         ||     MainVariable.Type = "int";
         || else throw new IncompatibleTypesException(LineNumber, FirstOperand.MainVariable.Type, SecondOperand.MainVariable.Type);
         ||}
         ||
         ||public void CheckTypesLogical()//логические операции
         ||{
         || string type1 = FirstOperand.MainVariable.Type, type2 = FirstOperand.MainVariable.Type;
         || if (((type1 == "int") || (type1 == "float") || (type1 == "bool")) || ((type2 == "int") || (type2 == "float") || (type2 == "bool")))
         ||     MainVariable.Type = "bool";
         || else throw new IncompatibleTypesException(LineNumber, FirstOperand.MainVariable.Type, SecondOperand.MainVariable.Type);
         ||}*/
        #endregion


        public override bool SemanticAnalysis()
        {
            //будем считать, что определено
            MainVariable = new Variable();
            MainVariable.WasIdentified = true;

            try
            {
                IsSemanticCorrect = FirstOperand.SemanticAnalysis();
                FirstOperand.MainVariable.WasUsed = true;
                IsSemanticCorrect = FirstOperand.SemanticAnalysis();
                FirstOperand.MainVariable.WasNewValueUsed = true;
                if (!FirstOperand.MainVariable.WasIdentified)
                {
                    throw new UnidentifiedVariableException(FirstOperand.LineNumber, FirstOperand.MainVariable.Name);
                }
            }
            catch (SemanticException e)
            {
                Console.WriteLine(e.Message);
                IsSemanticCorrect = false;
            }

            if (IsUnary)
            {
                if (IsSemanticCorrect)
                {
                    if (Value == "-")
                    {
                        if (FirstOperand.MainVariable.Type == "int")
                        {
                            MainVariable.Type = FirstOperand.MainVariable.Type; //если унарный, то тип совпадает с типом операнда
                            return(true);
                        }
                        else
                        {
                            throw new InvalidTypeException(LineNumber, FirstOperand.MainVariable.Type, Value);
                        }
                    }
                    if (Value == "!")
                    {
                        if (FirstOperand.MainVariable.Type == "bool")
                        {
                            MainVariable.Type = FirstOperand.MainVariable.Type; //если унарный, то тип совпадает с типом операнда
                            return(true);
                        }
                        else
                        {
                            throw new InvalidTypeException(LineNumber, FirstOperand.MainVariable.Type, Value);
                        }
                    }
                    return(false);//просто чтоб компилятор не ругался, он сюда никогда не дойдёт
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                try
                {
                    IsSemanticCorrect &= SecondOperand.SemanticAnalysis();
                    SecondOperand.MainVariable.WasUsed         = true;
                    SecondOperand.MainVariable.WasNewValueUsed = true;
                    if (!SecondOperand.MainVariable.WasIdentified)
                    {
                        throw new UnidentifiedVariableException(SecondOperand.LineNumber, SecondOperand.MainVariable.Name);
                    }
                }
                catch (SemanticException e)
                {
                    Console.WriteLine(e.Message);
                    IsSemanticCorrect = false;
                }
                if (IsSemanticCorrect)
                {
                    try
                    {
                        switch (TypeOfNode)
                        {
                        case NodeType.ArithmeticOperator:
                        {
                            if (FirstOperand.MainVariable.Type != "int" || SecondOperand.MainVariable.Type != "int")
                            {
                                throw new IncompatibleTypesException(LineNumber, FirstOperand.MainVariable.Type, SecondOperand.MainVariable.Type);
                            }
                            MainVariable.Type = "int";
                            break;
                        }

                        case NodeType.ComparisonOperator:
                        {
                            if (FirstOperand.MainVariable.Type != "int" || SecondOperand.MainVariable.Type != "int")
                            {
                                throw new IncompatibleTypesException(LineNumber, FirstOperand.MainVariable.Type, SecondOperand.MainVariable.Type);
                            }
                            MainVariable.Type = "bool";
                            break;
                        }

                        case NodeType.BitOperator:
                        {
                            if (FirstOperand.MainVariable.Type != "int" || SecondOperand.MainVariable.Type != "int")
                            {
                                throw new IncompatibleTypesException(LineNumber, FirstOperand.MainVariable.Type, SecondOperand.MainVariable.Type);
                            }
                            MainVariable.Type = "int";
                            break;
                        }

                        case NodeType.LogicalOperator:
                        {
                            if (FirstOperand.MainVariable.Type != "bool" || SecondOperand.MainVariable.Type != "bool")
                            {
                                throw new IncompatibleTypesException(LineNumber, FirstOperand.MainVariable.Type, SecondOperand.MainVariable.Type);
                            }
                            MainVariable.Type = "bool";
                            break;
                        }
                        }
                        return(true);
                    }
                    catch (SemanticException e)
                    {
                        Console.WriteLine(e.Message);
                        IsSemanticCorrect = false;
                        return(false);
                    }
                }
                else
                {
                    IsSemanticCorrect = false;
                    return(false);
                }
            }
        }