internal RightValue ParseValue(string value, Location loc) { //TODO: 类型歧义问题 if (intValuePattern.IsMatch(value)) { IntConst result = new IntConst(); result.Value = int.Parse(value); return result; } else if (floatValuePattern.IsMatch(value)) { FloatConst result = new FloatConst(); result.Value = double.Parse(value); return result; } else if (boolValuePattern.IsMatch(value)) { BoolConst result = new BoolConst(); result.Value = bool.Parse(value); return result; } else { StringConst result = new StringConst(); result.Value = value; return result; } }
public void Visit(AddExpr addExpr, object[] args) { addExpr.FirstOp.Accept(this); addExpr.SecondOp.Accept(this); RightValue v1 = readRightValue(addExpr.FirstOp); RightValue v2 = readRightValue(addExpr.SecondOp); if (v1 is StringConst || v2 is StringConst) { StringConst result = new StringConst(); result.Value = v1.ToString() + v2.ToString(); addExpr.RightValue = result; //addExpr.DataType = DataType.String; } else { DataType resultType = readAlgoOperand(v1, v2, addExpr.Location); if (resultType == DataType.Int) { IntConst result = new IntConst(); result.Value = Convert.ToInt32(v1.GetValueObject()) + Convert.ToInt32(v2.GetValueObject()); addExpr.RightValue = result; //addExpr.DataType = DataType.Int; } else if (resultType == DataType.Float) { FloatConst result = new FloatConst(); result.Value = Convert.ToDouble(v1.GetValueObject()) + Convert.ToDouble(v2.GetValueObject()); addExpr.RightValue = result; //addExpr.DataType = DataType.Float; } else throw new Exception(); } }
/// <summary> /// end表示字符串最后一个字符的后一个位置 /// </summary> /// <param name="begin"></param> /// <param name="end"></param> /// <returns></returns> private Expression parse(int begin, int end) { if (begin >= end) { kernel.IssueError(ErrorType.ExpressionSyntaxError, loc.Offset(begin)); return null; } while (isWhiteSpace(expr[begin])) begin++; while (isWhiteSpace(expr[end - 1])) end--; int currentParenLevel; bool hasSideParren = true; while (expr[begin] == '(' && hasSideParren) { currentParenLevel = 0; int currentPos; for (currentPos = begin; currentPos < end; currentPos++) { if (expr[currentPos] == '(') currentParenLevel++; else if (expr[currentPos] == ')') { currentParenLevel--; if (currentParenLevel == 0) { if (currentPos == end - 1) { begin++; end--; } else hasSideParren = false; break; } } } if (currentPos == end && currentParenLevel > 0) { kernel.IssueError(ErrorType.SingleParen, loc.Offset(begin)); return null; } } currentParenLevel = 0; OpLevel currentLevel = OpLevel.Null; OpLevel minLevel = OpLevel.Null; int minPos = -1; int minOpLength = 0; bool findOp = false; string op = null; MatchTokenResult matchTokenResult; //找到当前应处理的操作符 for (int currentPos = begin; currentPos < end; currentPos = matchTokenResult.EndPos) { //if (expr[currentPos] == ' ' || expr[currentPos] == '\t' || expr[currentPos] == '\n' // || Environment.NewLine.IndexOf(expr[currentPos]) != -1) //{ // op = null; // continue; //} matchTokenResult = MatchToken(currentPos, end); if (matchTokenResult.TokenType == TokenType.Error) return null; if (matchTokenResult.TokenType != TokenType.Operator) continue; op = matchTokenResult.Matched; if (op != "(" && op != ")") findOp = true; if (op == "(") { currentParenLevel++; continue; } else if (op == ")") { currentParenLevel--; continue; } else if (currentParenLevel > 0) { continue; } else if (currentParenLevel < 0) { kernel.IssueError(ErrorType.SingleParen, loc.Offset(currentPos)); return null; } if (currentParenLevel == 0 &&( (int)(currentLevel = getOpLevel(op)) < (int)minLevel) || ((int)currentLevel == (int)minLevel && op != "=") //=为右结合 ) { minLevel = currentLevel; minPos = matchTokenResult.BeginPos; minOpLength = op.Length; } } if (currentParenLevel != 0) { kernel.IssueError(ErrorType.SingleParen, loc.Offset(begin)); return null; } if (!findOp) //单个数据 { string str = expr.Substring(begin, end - begin); int currentPos = begin; matchTokenResult = MatchToken(currentPos, end); switch (matchTokenResult.TokenType) { case TokenType.Int: RightValueExpr intResult = new RightValueExpr(); IntConst intConst = new IntConst(); intConst.Value = int.Parse(matchTokenResult.Matched); intResult.DataType = DataType.Int; intResult.RightValue = intConst; intResult.Location = loc.Offset(begin); return intResult; case TokenType.Float: RightValueExpr floatResult = new RightValueExpr(); FloatConst floatConst = new FloatConst(); floatConst.Value = float.Parse(matchTokenResult.Matched); floatResult.DataType = DataType.Int; floatResult.RightValue = floatConst; floatResult.Location = loc.Offset(begin); return floatResult; case TokenType.String: RightValueExpr strResult = new RightValueExpr(); StringConst strConst = new StringConst(); strConst.Value = matchTokenResult.Matched; strResult.DataType = DataType.String; strResult.RightValue = strConst; strResult.Location = loc.Offset(begin); return strResult; case TokenType.Bool: RightValueExpr boolResult = new RightValueExpr(); BoolConst boolConst = new BoolConst(); boolConst.Value = bool.Parse(matchTokenResult.Matched); boolResult.DataType = DataType.Bool; boolResult.RightValue = boolConst; boolResult.Location = loc.Offset(begin); return boolResult; case TokenType.Variable: VarRef varRef = new VarRef(); varRef.VarName = matchTokenResult.Matched; LeftValueExpr leftValueResult = new LeftValueExpr(); leftValueResult.DataType = DataType.Unknown; leftValueResult.Location = loc.Offset(begin); leftValueResult.LeftValue = varRef; return leftValueResult; default: kernel.IssueError(ErrorType.ExpressionSyntaxError, loc.Offset(begin)); return null; } } Expression left; Expression right; matchTokenResult = MatchToken(minPos, end); op = matchTokenResult.Matched; left = (begin != minPos) ? parse(begin, minPos) : null; //null表示单目运算符 right = parse(matchTokenResult.EndPos, end); Location currentLoc = loc.Offset(begin); if (right == null) return null; switch (op) { case "=": if (!(left is LeftValueExpr)) { kernel.IssueError(ErrorType.NotLeftValue, currentLoc); return null; } AssignExpr assignExpr = new AssignExpr(); assignExpr.LeftExpr = left as LeftValueExpr; assignExpr.RightExpr = right; assignExpr.DataType = right.DataType; assignExpr.Location = currentLoc; return assignExpr; case "&&": return processBinaryLogicExpr( new AndExpr(), left, right, currentLoc); case "||": return processBinaryLogicExpr( new OrExpr(), left, right, currentLoc); case "==": return processBinaryCmpExpr(new EquExpr(), left, right, currentLoc); case "!=": return processBinaryCmpExpr(new NeqExpr(), left, right, currentLoc); case ">": return processBinaryCmpExpr(new GreatExpr(), left, right, currentLoc); case ">=": return processBinaryCmpExpr(new GreatEquExpr(), left, right, currentLoc); case "<": return processBinaryCmpExpr(new LessExpr(), left, right, currentLoc); case "<=": return processBinaryCmpExpr(new LessEquExpr(), left, right, currentLoc); case "+": return processBinaryAlgoExpr(new AddExpr(), left, right, currentLoc); case "-": if (left == null) { NegativeExpr negExpr = new NegativeExpr(); if (right.DataType == DataType.Bool || right.DataType == DataType.String) { kernel.IssueError(ErrorType.OprandTypeError, currentLoc); return null; } else if (right.DataType == DataType.Int) { negExpr.DataType = DataType.Int; } else if (right.DataType == DataType.Float) { negExpr.DataType = DataType.Float; } else { negExpr.DataType = DataType.Unknown; } negExpr.Op = right; negExpr.Location = currentLoc; return negExpr; } else { return processBinaryAlgoExpr(new SubExpr(), left, right, currentLoc); } case "*": return processBinaryAlgoExpr(new MulExpr(), left, right, currentLoc); case "/": return processBinaryAlgoExpr(new DivExpr(), left, right, currentLoc); case "^": return processBinaryAlgoExpr(new PowExpr(), left, right, currentLoc); case "!": if (left != null) { kernel.IssueError(ErrorType.ExpressionSyntaxError, currentLoc); return null; } else { NotExpr notExpr = new NotExpr(); notExpr.DataType = DataType.Bool; notExpr.Op = right; notExpr.Location = currentLoc; return notExpr; } } return null; }
public void Visit(SubExpr subExpr, object[] args) { subExpr.FirstOp.Accept(this); subExpr.SecondOp.Accept(this); RightValue v1 = readRightValue(subExpr.FirstOp); RightValue v2 = readRightValue(subExpr.SecondOp); DataType resultType = readAlgoOperand(v1, v2, subExpr.Location); if (resultType == DataType.Int) { IntConst result = new IntConst(); result.Value = Convert.ToInt32(v1.GetValueObject()) - Convert.ToInt32(v2.GetValueObject()); subExpr.RightValue = result; //subExpr.DataType = DataType.Int; } else if (resultType == DataType.Float) { FloatConst result = new FloatConst(); result.Value = Convert.ToDouble(v1.GetValueObject()) - Convert.ToDouble(v2.GetValueObject()); subExpr.RightValue = result; //subExpr.DataType = DataType.Float; } else { throw new Exception(); } }
public void Visit(NegativeExpr negativeExpr, object[] args) { negativeExpr.Op.Accept(this); RightValue v = readRightValue(negativeExpr); if (v is IntConst) { IntConst result = new IntConst(); result.Value = -(v as IntConst).Value; negativeExpr.RightValue = result; } else if (v is FloatConst) { FloatConst result = new FloatConst(); result.Value = -(v as FloatConst).Value; negativeExpr.RightValue = result; } else { throw new RuntimeException(new Error(ErrorType.OprandTypeError, negativeExpr.Location)); } }
public void Visit(DivExpr divExpr, object[] args) { divExpr.FirstOp.Accept(this); divExpr.SecondOp.Accept(this); RightValue v1 = readRightValue(divExpr.FirstOp); RightValue v2 = readRightValue(divExpr.SecondOp); DataType resultType = readAlgoOperand(v1, v2, divExpr.Location); if (resultType == DataType.Int) { IntConst result = new IntConst(); if (Convert.ToInt32(v2.GetValueObject()) == 0) { throw new RuntimeException(new Error(ErrorType.DivisorZero, divExpr.Location)); } result.Value = Convert.ToInt32(v1.GetValueObject()) / Convert.ToInt32(v2.GetValueObject()); divExpr.RightValue = result; //divExpr.DataType = DataType.Int; } else if (resultType == DataType.Float) { FloatConst result = new FloatConst(); if (Convert.ToDouble(v2.GetValueObject()) == 0) { throw new RuntimeException(new Error(ErrorType.DivisorZero, divExpr.Location)); } result.Value = Convert.ToDouble(v1.GetValueObject()) / Convert.ToDouble(v2.GetValueObject()); divExpr.RightValue = result; //divExpr.DataType = DataType.Float; } else { throw new Exception(); } }
internal RightValue ParseValue(string value, DataType type, Location loc) { switch (type) { case DataType.Int: int intParsed; if (!int.TryParse(value, out intParsed)) { kernel.IssueError(ErrorType.ParseTypeError, loc, value, type.ToString()); return null; } IntConst intResult = new IntConst(); intResult.Value = intParsed; return intResult; case DataType.Float: float floatParsed; if (!float.TryParse(value, out floatParsed)) { kernel.IssueError(ErrorType.ParseTypeError, loc, value, type.ToString()); return null; } FloatConst floatResult = new FloatConst(); floatResult.Value = floatParsed; return floatResult; case DataType.Bool: bool boolParsed; int boolIntParsed; double boolFloatParsed; BoolConst boolResult = new BoolConst(); if (bool.TryParse(value, out boolParsed)) { boolResult.Value = boolParsed; return boolResult; } else if (int.TryParse(value, out boolIntParsed)) { boolResult.Value = (boolIntParsed != 0); return boolResult; } else if (double.TryParse(value, out boolFloatParsed)) { boolResult.Value = (boolFloatParsed != 0); return boolResult; } else { kernel.IssueError(ErrorType.ParseTypeError, loc, value, type.ToString()); return null; } case DataType.String: StringConst strConst = new StringConst(); strConst.Value = value; return strConst; } return null; }
internal RightValue ParseValue(object value, DataType type, Location loc) { //TODO: 完整实现 switch (type) { case DataType.Int: IntConst intResult = new IntConst(); intResult.Value = (int)value; return intResult; case DataType.Float: FloatConst floatResult = new FloatConst(); floatResult.Value = (double)value; return floatResult; case DataType.Bool: BoolConst boolResult = new BoolConst(); boolResult.Value = (bool)value; return boolResult; case DataType.String: StringConst strResult = new StringConst(); strResult.Value = (string)value; return strResult; } return null; }