예제 #1
0
        private static CaseExpression reduceCaseExpression(WordCollection wc)
        {
            CaseExpression ret = new CaseExpression();
            IdentifierWord id  = wc.Current as IdentifierWord;

            if ((id != null) && (id.Code.Equals("IS", Config.SCVariable)))
            {
                wc.ShiftNext();
                ret.CaseType = CaseExpressionType.Is;
                OperatorWord opWT = wc.Current as OperatorWord;
                if (opWT == null)
                {
                    throw new CodeEE("ISキーワードの後に演算子がありません");
                }

                OperatorCode op = opWT.Code;
                if (!OperatorManager.IsBinary(op))
                {
                    throw new CodeEE("ISキーワードの後の演算子が2項演算子ではありません");
                }
                wc.ShiftNext();
                ret.Operator = op;
                ret.LeftTerm = reduceTerm(wc, false, TermEndWith.Comma, VariableCode.__NULL__);
                if (ret.LeftTerm == null)
                {
                    throw new CodeEE("ISキーワードの後に式がありません");
                }
                Type type = ret.LeftTerm.GetOperandType();
                return(ret);
            }
            ret.LeftTerm = reduceTerm(wc, true, TermEndWith.Comma, VariableCode.__NULL__);
            if (ret.LeftTerm == null)
            {
                throw new CodeEE("CASEの引数は省略できません");
            }
            id = wc.Current as IdentifierWord;
            if ((id != null) && (id.Code.Equals("TO", Config.SCVariable)))
            {
                ret.CaseType = CaseExpressionType.To;
                wc.ShiftNext();
                ret.RightTerm = reduceTerm(wc, true, TermEndWith.Comma, VariableCode.__NULL__);
                if (ret.RightTerm == null)
                {
                    throw new CodeEE("TOキーワードの後に式がありません");
                }
                id = wc.Current as IdentifierWord;
                if ((id != null) && (id.Code.Equals("TO", Config.SCVariable)))
                {
                    throw new CodeEE("TOキーワードが2度使われています");
                }
                if (ret.LeftTerm.GetOperandType() != ret.RightTerm.GetOperandType())
                {
                    throw new CodeEE("TOキーワードの前後の型が一致していません");
                }
                return(ret);
            }
            ret.CaseType = CaseExpressionType.Normal;
            return(ret);
        }
예제 #2
0
 public void Add(OperatorCode op)
 {
     if (state == 2 || state == 3)
     {
         throw new CodeEE("式が異常です");
     }
     if (state == 0)
     {
         if (!OperatorManager.IsUnary(op))
         {
             throw new CodeEE("式が異常です");
         }
         stack.Push(op);
         if (op == OperatorCode.Plus || op == OperatorCode.Minus || op == OperatorCode.BitNot)
         {
             state = 2;
         }
         else
         {
             state = 3;
         }
         return;
     }
     if (state == 1)
     {
         //後置単項演算子の場合は特殊処理へ
         if (OperatorManager.IsUnaryAfter(op))
         {
             if (hasAfter)
             {
                 hasAfter = false;
                 throw new CodeEE("後置の単項演算子が複数存在しています");
             }
             if (hasBefore)
             {
                 hasBefore = false;
                 throw new CodeEE("インクリメント・デクリメントを前置・後置両方同時に使うことはできません");
             }
             stack.Push(op);
             reduceUnaryAfter();
             //前置単項演算子が処理を待っている場合はここで解決
             if (waitAfter)
             {
                 reduceUnary();
             }
             hasBefore = false;
             hasAfter  = true;
             waitAfter = false;
             return;
         }
         if (!OperatorManager.IsBinary(op) && !OperatorManager.IsTernary(op))
         {
             throw new CodeEE("式が異常です");
         }
         //先に未解決の前置演算子解決
         if (waitAfter)
         {
             reduceUnary();
         }
         int priority = OperatorManager.GetPriority(op);
         //直前の計算の優先度が同じか高いなら還元。
         while (lastPriority() >= priority)
         {
             this.reduceLastThree();
         }
         stack.Push(op);
         state     = 0;
         waitAfter = false;
         hasBefore = false;
         hasAfter  = false;
         return;
     }
     throw new CodeEE("式が異常です");
 }