public static INumerable BuildNumericTernary(List <Token> tokens) { IBoolable condition = BoolableBuilder.Build(GetTernaryCondition(tokens)); if (condition.IsNull()) { return(null); } INumerable confirmationCase = NumerableBuilder.Build(GetTernaryConfirmation(tokens)); if (confirmationCase.IsNull()) { return(null); } INumerable negationCase = NumerableBuilder.Build(GetTernaryNegation(tokens)); if (negationCase.IsNull()) { return(null); } return(new NumericTernary(condition, confirmationCase, negationCase)); }
public static IStringable BuildListElement(List <Token> tokens) { if (Brackets.ContainsIndependentBracketsPairs(tokens, BracketsType.Square)) { return(null); } string name = tokens[0].GetContent(); tokens.RemoveAt(tokens.Count - 1); tokens.RemoveAt(0); tokens.RemoveAt(0); if (!InterVariables.GetInstance().Contains(name, InterVarType.List)) { throw new SyntaxErrorException("ERROR! List " + name + " not found. Impossible to take element from it."); } INumerable inu = NumerableBuilder.Build(tokens); if (inu.IsNull()) { throw new SyntaxErrorException("ERROR! Impossible to take element from list " + name + ". Index identificator cannot be read as number."); } else { return(new ListElementRefer(name, inu)); } }
public static ISubcommand BuildNumeric(List <Token> tokens, TokenType type) { INumerable inu = NumerableBuilder.Build(tokens); if (inu.IsNull()) { throw new SyntaxErrorException("ERROR! In list declaration there is something wrong with expression: " + GetName(type) + "."); } else { return(new NumericSubcommand(inu, GetNumericType(type))); } }
private static IBoolable BuildBetweenNumbers(INumerable num, List <Token> left, List <Token> right) { INumerable numLeft = NumerableBuilder.Build(left); INumerable numRight = NumerableBuilder.Build(right); if (numLeft.IsNull() || numRight.IsNull()) { return(null); } else { return(new BetweenNumbers(num, numLeft, numRight)); } }
private static IBoolable BuildBetween(List <Token> tokens) { int betweenIndex = TokenGroups.IndexOfTokenOutsideBrackets(tokens, TokenType.Between); int andIndex = TokenGroups.IndexOfTokenOutsideBrackets(tokens, TokenType.And); if (andIndex < betweenIndex) { return(null); } if (betweenIndex == andIndex - 1) { throw new SyntaxErrorException("ERROR! Expression 'between' do not contain definition of value of left boundary."); } if (betweenIndex == 0) { throw new SyntaxErrorException("ERROR! Expression 'between' starts with keyword 'between' and thus do not contain comparing value."); } if (andIndex == tokens.Count - 1) { throw new SyntaxErrorException("ERROR! Expression 'between' ends with keyword 'and' and thus do not contain definition of value of right boundary."); } List <Token> valueTokens = tokens.Take(betweenIndex).ToList(); List <Token> leftTokens = tokens.GetRange(betweenIndex + 1, andIndex - betweenIndex - 1); List <Token> rightTokens = tokens.Skip(andIndex + 1).ToList(); INumerable inum = NumerableBuilder.Build(valueTokens); if (!inum.IsNull()) { return(BuildBetweenNumbers(inum, leftTokens, rightTokens)); } ITimeable itim = TimeableBuilder.Build(valueTokens); if (!itim.IsNull()) { return(BuildBetweenTimes(itim, leftTokens, rightTokens)); } return(null); }
private static IClock BuildClock(List <Token> tokens) { int semicolons = NumberOfColonsOutsideOfBrackets(tokens); if (semicolons == 1) { List <Token> leftPart = new List <Token>(); List <Token> rightPart = new List <Token>(); int level = 0; bool pastSemicolon = false; foreach (Token tok in tokens) { if (tok.GetTokenType().Equals(TokenType.BracketOn)) { level++; } if (tok.GetTokenType().Equals(TokenType.BracketOff)) { level--; } if (tok.GetTokenType().Equals(TokenType.Colon) && level == 0) { pastSemicolon = true; } else { if (pastSemicolon) { rightPart.Add(tok); } else { leftPart.Add(tok); } } } INumerable inumLeft = NumerableBuilder.Build(leftPart); if (inumLeft.IsNull()) { return(null); } INumerable inumRight = NumerableBuilder.Build(rightPart); if (inumRight.IsNull()) { return(null); } if (inumLeft is NumericConstant && inumRight is NumericConstant) { return(new ClockConstant(inumLeft.ToNumber(), inumRight.ToNumber(), 0)); } return(new ClockWithoutSeconds(inumLeft, inumRight)); } else { List <Token> leftPart = new List <Token>(); List <Token> middlePart = new List <Token>(); List <Token> rightPart = new List <Token>(); int level = 0; int currentPart = 1; foreach (Token tok in tokens) { if (tok.GetTokenType().Equals(TokenType.BracketOn)) { level++; } if (tok.GetTokenType().Equals(TokenType.BracketOff)) { level--; } if (tok.GetTokenType().Equals(TokenType.Colon) && level == 0) { currentPart++; } else { if (currentPart == 1) { leftPart.Add(tok); } else if (currentPart == 2) { middlePart.Add(tok); } else { rightPart.Add(tok); } } } INumerable inumLeft = NumerableBuilder.Build(leftPart); if (inumLeft.IsNull()) { return(null); } INumerable inumMiddle = NumerableBuilder.Build(middlePart); if (inumMiddle.IsNull()) { return(null); } INumerable inumRight = NumerableBuilder.Build(rightPart); if (inumRight.IsNull()) { return(null); } if (inumLeft is NumericConstant && inumMiddle is NumericConstant && inumRight is NumericConstant) { return(new ClockConstant(inumLeft.ToNumber(), inumMiddle.ToNumber(), inumRight.ToNumber())); } return(new ClockNumerables(inumLeft, inumMiddle, inumRight)); } }
private static ITimeable BuildFromDate(List <Token> tokens) { decimal month = 1; List <Token> leftPart = new List <Token>(); List <Token> rightPart = new List <Token>(); bool pastMonth = false; foreach (Token tok in tokens) { if (IsMonth(tok)) { pastMonth = true; month = StringToMonth(tok.GetContent()); } else { if (pastMonth) { rightPart.Add(tok); } else { leftPart.Add(tok); } } } if (leftPart.Count == 0) { return(null); } INumerable day = NumerableBuilder.Build(leftPart); if (day.IsNull()) { return(null); } // try to build date without year if (rightPart.Count == 0) { if (day is NumericConstant) { return(new Time(new ClockEmpty(), new DayConstant(day.ToNumber()), month, new YearNow())); } else { return(new Time(new ClockEmpty(), new DayNumerable(day), month, new YearNow())); } } INumerable year = NumerableBuilder.Build(rightPart); if (year.IsNull()) { return(null); } if (day is NumericConstant) { if (year is NumericConstant) { return(new Time(new ClockEmpty(), new DayConstant(day.ToNumber()), month, new YearConstant(year.ToNumber()))); } else { return(new Time(new ClockEmpty(), new DayConstant(day.ToNumber()), month, new YearNumerable(year))); } } else { if (year is NumericConstant) { return(new Time(new ClockEmpty(), new DayNumerable(day), month, new YearConstant(year.ToNumber()))); } else { return(new Time(new ClockEmpty(), new DayNumerable(day), month, new YearNumerable(year))); } } }
private static RelativeTimeStruct BuildSingleRTS(List <Token> tokens, Token tok, TimeDirection direction) { if (IsSingleKeyword(tok)) { if (tokens.Count == 1 && tokens[0].GetTokenType().Equals(TokenType.NumericConstant) && tokens[0].GetNumericContent() == 1) { switch (tok.GetContent().ToLower()) { case "century": return(new RelativeTimeStruct(RelativeTimeType.Centuries, new NumericConstant(1), direction)); case "decade": return(new RelativeTimeStruct(RelativeTimeType.Decades, new NumericConstant(1), direction)); case "year": return(new RelativeTimeStruct(RelativeTimeType.Years, new NumericConstant(1), direction)); case "month": return(new RelativeTimeStruct(RelativeTimeType.Months, new NumericConstant(1), direction)); case "week": return(new RelativeTimeStruct(RelativeTimeType.Weeks, new NumericConstant(1), direction)); case "day": return(new RelativeTimeStruct(RelativeTimeType.Days, new NumericConstant(1), direction)); case "hour": return(new RelativeTimeStruct(RelativeTimeType.Hours, new NumericConstant(1), direction)); case "minute": return(new RelativeTimeStruct(RelativeTimeType.Minutes, new NumericConstant(1), direction)); case "second": return(new RelativeTimeStruct(RelativeTimeType.Seconds, new NumericConstant(1), direction)); } } else { return(null); } } else { INumerable inum = NumerableBuilder.Build(tokens); if (inum.IsNull()) { return(null); } else { switch (tok.GetContent().ToLower()) { case "centuries": return(new RelativeTimeStruct(RelativeTimeType.Centuries, inum, direction)); case "decades": return(new RelativeTimeStruct(RelativeTimeType.Decades, inum, direction)); case "years": return(new RelativeTimeStruct(RelativeTimeType.Years, inum, direction)); case "months": return(new RelativeTimeStruct(RelativeTimeType.Months, inum, direction)); case "weeks": return(new RelativeTimeStruct(RelativeTimeType.Weeks, inum, direction)); case "days": return(new RelativeTimeStruct(RelativeTimeType.Days, inum, direction)); case "hours": return(new RelativeTimeStruct(RelativeTimeType.Hours, inum, direction)); case "minutes": return(new RelativeTimeStruct(RelativeTimeType.Minutes, inum, direction)); case "seconds": return(new RelativeTimeStruct(RelativeTimeType.Seconds, inum, direction)); } } } return(null); }
public static IStringable Build(List <Token> tokens) { // try to build Numerable INumerable inu = NumerableBuilder.Build(tokens); if (!inu.IsNull()) { return(inu as IStringable); } // try to build Timeable ITimeable itim = TimeableBuilder.Build(tokens); if (!itim.IsNull()) { return(itim as IStringable); } // remove first and last bracket if it is there while (tokens[0].GetTokenType().Equals(TokenType.BracketOn) && tokens[tokens.Count - 1].GetTokenType().Equals(TokenType.BracketOff) && !Brackets.ContainsIndependentBracketsPairs(tokens, BracketsType.Normal)) { List <Token> tokensCopy = tokens.Select(t => t.Clone()).ToList(); tokensCopy.RemoveAt(tokens.Count - 1); tokensCopy.RemoveAt(0); tokens = tokensCopy; } // try to build simple one-token Stringable if (tokens.Count == 1) { if (tokens[0].GetTokenType().Equals(TokenType.Variable)) { string str = tokens[0].GetContent(); if (InterVariables.GetInstance().Contains(str, InterVarType.String)) { return(new StringVariableRefer(str)); } else { // try to build reference to date or clock time IStringable istr = BuildTimeVariableRefer(tokens[0]); if (!istr.IsNull()) { return(istr); } } } if (tokens[0].GetTokenType().Equals(TokenType.StringConstant)) { return(new StringConstant(tokens[0].GetContent())); } } //try to build string function if (Functions.IsPossibleFunction(tokens)) { IStringable istr = StringFunction.Build(tokens); if (!istr.IsNull()) { return(istr); } } // try to build string ternary if (TernaryBuilder.IsPossibleTernary(tokens)) { IStringable istr = TernaryBuilder.BuildStringTernary(tokens); if (!istr.IsNull()) { return(istr); } } // try to build reference to n-th element of list of strings if (tokens.Count > 3 && tokens[0].GetTokenType().Equals(TokenType.Variable) && tokens[1].GetTokenType().Equals(TokenType.SquareBracketOn) && tokens[tokens.Count - 1].GetTokenType().Equals(TokenType.SquareBracketOff)) { IStringable istr = BuildListElement(tokens); if (!istr.IsNull()) { return(istr); } } // try to build concatenated string -> text merged by + if (TokenGroups.ContainsTokenOutsideBrackets(tokens, TokenType.Plus) && !TokenGroups.ContainsTokenOutsideBrackets(tokens, TokenType.Comma)) { return(BuildConcatenated(tokens)); } else { return(null); } }
// string concatenation // considers numeric expressions inside with signs '+' public static IStringable BuildConcatenated(List <Token> tokens) { List <Token> currentTokens = new List <Token>(); List <Token> reserve = new List <Token>(); List <IStringable> elements = new List <IStringable>(); int level = 0; for (int i = 0; i < tokens.Count; i++) { if (tokens[i].GetTokenType().Equals(TokenType.BracketOn)) { level++; } if (tokens[i].GetTokenType().Equals(TokenType.BracketOff)) { level--; } if (tokens[i].GetTokenType().Equals(TokenType.Plus) && level == 0) { if (currentTokens.Count > 0) { IStringable ist = StringableBuilder.Build(currentTokens); if (ist.IsNull()) { return(null); } if (ist is INumerable || ist is IBoolable) { reserve.AddRange(currentTokens); reserve.Add(tokens[i]); currentTokens.Clear(); } else { if (reserve.Count > 0) { reserve.RemoveAt(reserve.Count - 1); elements.Add(NumerableBuilder.Build(reserve) as IStringable); reserve.Clear(); } elements.Add(ist); currentTokens.Clear(); } } } else { currentTokens.Add(tokens[i]); } } if (currentTokens.Count > 0) { IStringable ist = StringableBuilder.Build(currentTokens); if (reserve.Count > 0) { if (ist is INumerable || ist is IBoolable) { reserve.AddRange(currentTokens); elements.Add(NumerableBuilder.Build(reserve) as IStringable); } else { reserve.RemoveAt(reserve.Count - 1); elements.Add(NumerableBuilder.Build(reserve) as IStringable); elements.Add(ist); } } else { if (ist.IsNull()) { return(null); } else { elements.Add(ist); } } } if (elements.Count > 0) { return(new StringExpression(elements)); } return(null); }
private static INumerable BuildExpression(List <Token> tokens) { // turn list of tokens into list of NumericExpressionElements // they are in usual infix notation // when this is done, their order is changed to Reverse Polish Notation // meanwhile check, if it all can be represented as simple one negated INumerable // finally build NumericExpression List <INumericExpressionElement> infixList = new List <INumericExpressionElement>(); List <Token> currentTokens = new List <Token>(); bool readingFunction = false; Token previousToken = new Token(TokenType.Null); // first, merge many tokens into fewer number of INumericExpressionElements foreach (Token tok in tokens) { bool actionDone = false; if (TokenGroups.IsArithmeticSign(tok.GetTokenType())) { if (readingFunction) { if (Brackets.AllBracketsClosed(currentTokens)) { INumerable ibo = NumerableBuilder.Build(currentTokens); if (!ibo.IsNull()) { infixList.Add(ibo); } else { return(null); } currentTokens.Clear(); readingFunction = false; infixList.Add(new NumericExpressionOperator(GetNEOT(tok.GetTokenType()))); } else { currentTokens.Add(tok); } } else { if (currentTokens.Count > 0) { INumerable ibo = NumerableBuilder.Build(currentTokens); if (!ibo.IsNull()) { infixList.Add(ibo); } else { return(null); } currentTokens.Clear(); } infixList.Add(new NumericExpressionOperator(GetNEOT(tok.GetTokenType()))); } actionDone = true; } if (tok.GetTokenType().Equals(TokenType.BracketOn)) { if (readingFunction) { currentTokens.Add(tok); } else { if (currentTokens.Count == 1 && previousToken.GetTokenType().Equals(TokenType.Variable)) { currentTokens.Add(tok); readingFunction = true; } else { if (currentTokens.Count > 0) { INumerable ibo = NumerableBuilder.Build(currentTokens); if (!ibo.IsNull()) { infixList.Add(ibo); } else { return(null); } currentTokens.Clear(); } infixList.Add(new NumericExpressionOperator(NumericExpressionOperatorType.BracketOn)); } } actionDone = true; } if (tok.GetTokenType().Equals(TokenType.BracketOff)) { if (readingFunction) { if (Brackets.AllBracketsClosed(currentTokens)) { INumerable ibo = NumerableBuilder.Build(currentTokens); if (!ibo.IsNull()) { infixList.Add(ibo); } else { return(null); } currentTokens.Clear(); readingFunction = false; infixList.Add(new NumericExpressionOperator(NumericExpressionOperatorType.BracketOff)); } else { currentTokens.Add(tok); } } else { if (currentTokens.Count > 0) { INumerable ibo = NumerableBuilder.Build(currentTokens); if (!ibo.IsNull()) { infixList.Add(ibo); } else { return(null); } currentTokens.Clear(); } infixList.Add(new NumericExpressionOperator(NumericExpressionOperatorType.BracketOff)); } actionDone = true; } if (!actionDone) { currentTokens.Add(tok); } previousToken = tok; } if (currentTokens.Count > 0) { INumerable ibo = NumerableBuilder.Build(currentTokens); if (!ibo.IsNull()) { infixList.Add(ibo); } else { return(null); } } // try to build inversion of one INumerable if (infixList.Count == 2 && (infixList[0] is NumericExpressionOperator) && (infixList[1] is INumerable) && (infixList[0] as NumericExpressionOperator).IsMinus()) { return(BuildNegated(infixList[1] as INumerable)); } // change unary minuses to new type to avoid mistaking them with subtraction sign infixList = IdentifyUnaryMinuses(infixList); // check if value of infixlist can be computed (check order of elements) if (!CheckExpressionComputability(infixList)) { throw new SyntaxErrorException("ERROR! Wrong syntax of numeric expression."); } // if everything is right, finally build NumericExpression in RPN return(new NumericExpression(ReversePolishNotation(infixList))); }