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); }
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("式が異常です"); }