protected virtual string ReadIdent() { var sb = new StringBuilder(); char ch = _reader.NextChar; sb.Append(ch); ch = _reader.Next(); while (CommandStream.IsAlpha(ch) || CommandStream.IsDigit(ch)) { sb.Append(ch); ch = _reader.Next(); } return(sb.ToString()); }
protected virtual bool IsIdentStart(char ch) { return(CommandStream.IsAlpha(ch)); }
public ExpressionParser(CommandStream reader) : base(reader) { }
protected virtual void ScanNextToken() { char ch = _reader.NextChar; if (IsToken("||", false, false)) { _state._detailToken = ETokenType.XOrSy; return; } if (IsToken("<<", false, false)) { _state._detailToken = ETokenType.BitShiftLeftSy; return; } if (IsToken(">>", false, false)) { _state._detailToken = ETokenType.BitShiftRightSy; return; } if (IsToken("==", false, false)) { _state._detailToken = ETokenType.EqualSy; return; } if (IsToken("!=", false, false)) { _state._detailToken = ETokenType.UnEqualSy; return; } if (IsToken(">=", false, false)) { _state._detailToken = ETokenType.GreaterEqualSy; return; } if (IsToken("<=", false, false)) { _state._detailToken = ETokenType.LessEqualSy; return; } if (ch == LeftParenthesis) { _state._detailToken = ETokenType.LeftParenthesisSy; _reader.Next(); return; } if (ch == RightParenthesis) { _state._detailToken = ETokenType.RightParenthesisSy; _reader.Next(); return; } switch (ch) { case '>': _state._detailToken = ETokenType.GreaterSy; _reader.Next(); return; case '<': _state._detailToken = ETokenType.LessSy; _reader.Next(); return; case '&': _state._detailToken = ETokenType.AndSy; _reader.Next(); return; case '|': _state._detailToken = ETokenType.OrSy; _reader.Next(); return; case '-': _state._detailToken = ETokenType.MinusSy; _reader.Next(); return; case '+': _state._detailToken = ETokenType.PlusSy; _reader.Next(); return; case '*': _state._detailToken = ETokenType.MultiplySy; _reader.Next(); return; case '/': _state._detailToken = ETokenType.DivideSy; _reader.Next(); return; case '%': _state._detailToken = ETokenType.ModuloSy; _reader.Next(); return; case '^': _state._detailToken = ETokenType.PowSy; _reader.Next(); return; case '!': _state._detailToken = ETokenType.FactorialSy; _reader.Next(); return; case '=': _state._detailToken = ETokenType.AssignSy; _reader.Next(); return; } // check for a value if (CommandStream.IsNumber(ch)) { _state._detailToken = ETokenType.FloatSy; _state._number = _reader.GetDouble(out bool istFloatingPoint); return; } // check for variables or functions if (IsIdentStart(ch)) { var start = ReadIdent(); ch = _reader.SkipSpaces(); // check if this is a variable or a function. // a function has a parenthesis '(' open after the name if (ch == LeftParenthesis) { switch (start.ToUpper()) { case "ABS": _state._detailToken = ETokenType.AbsSy; return; case "EXP": _state._detailToken = ETokenType.ExpSy; return; case "SIGN": _state._detailToken = ETokenType.SignSy; return; case "SQRT": _state._detailToken = ETokenType.SqrtSy; return; case "LOG": _state._detailToken = ETokenType.LogSy; return; case "LOG10": _state._detailToken = ETokenType.Log10Sy; return; case "SIN": _state._detailToken = ETokenType.SinSy; return; case "COS": _state._detailToken = ETokenType.CosSy; return; case "TAN": _state._detailToken = ETokenType.TanSy; return; case "ASIN": _state._detailToken = ETokenType.AsinSy; return; case "ACOS": _state._detailToken = ETokenType.AcosSy; return; case "ATAN": _state._detailToken = ETokenType.AtanSy; return; case "FACTORIAL": _state._detailToken = ETokenType.FactorialFncSy; return; case "FIX": _state._detailToken = ETokenType.FixSy; return; case "FUP": _state._detailToken = ETokenType.FupSy; return; case "ROUND": _state._detailToken = ETokenType.RoundSy; return; default: Error(MESSAGE_EXPR_UNKNOWN_FUNCTION); return; } } else { _state._detailToken = ETokenType.VariableSy; _state._variableOK = EvalVariable(start, ref _state._number); } return; } // something unknown is found, wrong characters -> a syntax error _state._detailToken = ETokenType.UnknownSy; Error(MESSAGE_EXPR_SYNTAX_ERROR); }