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 static IOperandTerm ReduceBinaryTerm(OperatorCode op, IOperandTerm left, IOperandTerm right) { OperatorMethod method = null; if ((left.GetOperandType() == typeof(Int64)) && (right.GetOperandType() == typeof(Int64))) { if (binaryIntIntDic.ContainsKey(op)) { method = binaryIntIntDic[op]; } } else if ((left.GetOperandType() == typeof(string)) && (right.GetOperandType() == typeof(string))) { if (binaryStrStrDic.ContainsKey(op)) { method = binaryStrStrDic[op]; } } else if (((left.GetOperandType() == typeof(Int64)) && (right.GetOperandType() == typeof(string))) || ((left.GetOperandType() == typeof(string)) && (right.GetOperandType() == typeof(Int64)))) { if (op == OperatorCode.Mult) { method = binaryMultIntStr; } } if (method != null) { return(new FunctionMethodTerm(method, new IOperandTerm[] { left, right })); } string errMes = ""; if (left.GetOperandType() == typeof(Int64)) { errMes += "数値型と"; } else if (left.GetOperandType() == typeof(string)) { errMes += "文字列型と"; } else { errMes += "不定型と"; } if (right.GetOperandType() == typeof(Int64)) { errMes += "数値型の"; } else if (right.GetOperandType() == typeof(string)) { errMes += "文字列型の"; } else { errMes += "不定型の"; } errMes += "演算に二項演算子\'" + OperatorManager.ToOperatorString(op) + "\'は適用できません"; throw new CodeEE(errMes); }
private int lastPriority() { if (stack.Count < 3) { return(-1); } object temp = (object)stack.Pop(); OperatorCode opCode = (OperatorCode)stack.Peek(); int priority = OperatorManager.GetPriority(opCode); stack.Push(temp); return(priority); }
private int lastPriority() { if (stack.Count < 3) { return(-1); } var temp = stack.Pop(); var opCode = (OperatorCode)stack.Peek(); var priority = OperatorManager.GetPriority(opCode); stack.Push(temp); return(priority); }
public static IOperandTerm ReduceUnaryTerm(OperatorCode op, IOperandTerm o1) { OperatorMethod method = null; if (op == OperatorCode.Increment || op == OperatorCode.Decrement) { VariableTerm var = o1 as VariableTerm; if (var == null) { throw new CodeEE("変数以外をインクリメントすることはできません"); } if (var.Identifier.IsConst) { throw new CodeEE("変更できない変数をインクリメントすることはできません"); } } if (o1.GetOperandType() == typeof(Int64)) { if (op == OperatorCode.Plus) { return(o1); } OperatorMethod operator_method = null; if (unaryDic.TryGetValue(op, out operator_method)) { method = operator_method; } } if (method != null) { return(new FunctionMethodTerm(method, new IOperandTerm[] { o1 })); } string errMes = ""; if (o1.GetOperandType() == typeof(Int64)) { errMes += "数値型"; } else if (o1.GetOperandType() == typeof(string)) { errMes += "文字列型"; } else { errMes += "不定型"; } errMes += "に単項演算子\'" + OperatorManager.ToOperatorString(op) + "\'は適用できません"; throw new CodeEE(errMes); }
public static IOperandTerm ReduceUnaryAfterTerm(OperatorCode op, IOperandTerm o1) { OperatorMethod method = null; if (op == OperatorCode.Increment || op == OperatorCode.Decrement) { var var = o1 as VariableTerm; if (var == null) { throw new CodeEE("変数以外をインクリメントすることはできません"); } if (var.Identifier.IsConst) { throw new CodeEE("変更できない変数をインクリメントすることはできません"); } } if (o1.GetOperandType() == typeof(long)) { if (unaryAfterDic.ContainsKey(op)) { method = unaryAfterDic[op]; } } if (method != null) { return(new FunctionMethodTerm(method, new[] { o1 })); } var errMes = ""; if (o1.GetOperandType() == typeof(long)) { errMes += "数値型"; } else if (o1.GetOperandType() == typeof(string)) { errMes += "文字列型"; } else { errMes += "不定型"; } errMes += "に後置単項演算子\'" + OperatorManager.ToOperatorString(op) + "\'は適用できません"; throw new CodeEE(errMes); }
private void reduceLastThree() { //if (stack.Count < 2) // throw new ExeEE("不正な時期の呼び出し"); IOperandTerm right = (IOperandTerm)stack.Pop();//後から入れたほうが右側 OperatorCode op = (OperatorCode)stack.Pop(); IOperandTerm left = (IOperandTerm)stack.Pop(); if (OperatorManager.IsTernary(op)) { if (stack.Count > 1) { reduceTernary(left, right, op); return; } throw new CodeEE("式の数が不足しています"); } IOperandTerm newTerm = OperatorMethodManager.ReduceBinaryTerm(op, left, right); stack.Push(newTerm); }
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("式が異常です"); }