ArithmaticStatement CheckForArithmaticStatement(WordTokens[] tokens) { if (tokens?.Length == 0) { return(null); } var typesForAdd = new TokenType[] { TokenType.String, TokenType.StringVariable, TokenType.RealVariable, TokenType.IntegerVariable, TokenType.Number, TokenType.Real, TokenType.Integer }; var typesForRest = new TokenType[] { TokenType.RealVariable, TokenType.IntegerVariable, TokenType.Number, TokenType.Real, TokenType.Integer }; var firstToken = tokens.First().tokens.First(); var arithmaticOperators = new TokenType[] { TokenType.AddArithmaticOperator, TokenType.SubArithmaticOperator, TokenType.MulArithmaticOperator, TokenType.DivArithmaticOperator }; if (tokens.Length > 2) { var secondToken = tokens[1].tokens.First(); var thirdToken = tokens[2].tokens.First(); if (arithmaticOperators.Any(op => secondToken.type == op)) { switch (secondToken.type) { case TokenType.AddArithmaticOperator: if (typesForAdd.Any(t => t == firstToken.type) && typesForAdd.Any(t => t == thirdToken.type)) { return(new ArithmaticStatement(tokens, tokens.First(), tokens[2], tokens[1])); } break; case TokenType.SubArithmaticOperator: if (typesForRest.Any(t => t == firstToken.type) && typesForRest.Any(t => t == thirdToken.type)) { return(new ArithmaticStatement(tokens, tokens.First(), tokens[2], tokens[1])); } break; case TokenType.MulArithmaticOperator: if (typesForRest.Any(t => t == firstToken.type) && typesForRest.Any(t => t == thirdToken.type)) { return(new ArithmaticStatement(tokens, tokens.First(), tokens[2], tokens[1])); } break; case TokenType.DivArithmaticOperator: if (typesForRest.Any(t => t == firstToken.type) && typesForRest.Any(t => t == thirdToken.type)) { return(new ArithmaticStatement(tokens, tokens.First(), tokens[2], tokens[1])); } break; } } else { OnError?.Invoke("Second argument must be an arithmatic operator"); return(null); } } OnError?.Invoke("Not enough arguments for Arithmatic Statement"); return(null); }
ReadStatement CheckForReadStatement(WordTokens[] tokens) { var allowedTokenTypes = new TokenType[] { TokenType.StringVariable, TokenType.RealVariable, TokenType.IntegerVariable }; if (tokens.Length == 2) { var secondToken = tokens[1]; if (allowedTokenTypes.Any(t => t == secondToken.tokens.First().type)) { return(new ReadStatement(tokens, secondToken)); } else { var errorString = allowedTokenTypes.Select(t => t.ToString()).Aggregate((current, next) => { return(current + "\n" + next); }); errorString = "Error: Second token must be any of the following:\n" + errorString; OnError?.Invoke(errorString); return(null); } } else if (tokens.Length > 2) { OnError?.Invoke("Too many arguments for print statement."); return(null); } OnError?.Invoke("Unidentified Error."); return(null); }
RelationalStatement CheckForRelational(WordTokens[] tokens) { var conditionalOperators = new TokenType[] { TokenType.EqualRelationalOperator, TokenType.NotEqualRelationalOperator, TokenType.GreaterThanRelationalOperator, TokenType.LessThanRelationalOperator, TokenType.EqualGreaterRelationalOperator, TokenType.EqualLessRelationalOperator, }; var stringTypes = new TokenType[] { TokenType.String, TokenType.StringVariable }; var realTypes = new TokenType[] { TokenType.Real, TokenType.RealVariable }; var intTypes = new TokenType[] { TokenType.Integer, TokenType.IntegerVariable, TokenType.UnsignedInteger }; var firstToken = tokens.First(); bool isRelational = false; if (tokens.Length >= 3) { var op = tokens.Select((value, index) => new { value, index }).FirstOrDefault(t => t.value.tokens.Any(to => conditionalOperators.Any(o => o == to.type))); if (op != null) { var index = op.index; var before = tokens[index - 1]; if (index + 1 >= tokens.Length) { return(null); } var after = tokens[index + 1]; var isStrings = (stringTypes.Any(t => before.tokens.Any(tk => tk.type == t)) && stringTypes.Any(t => after.tokens.Any(tk => tk.type == t))); var isReals = (realTypes.Any(t => before.tokens.Any(tk => tk.type == t)) && realTypes.Any(t => after.tokens.Any(tk => tk.type == t))); var isInts = (intTypes.Any(t => before.tokens.Any(tk => tk.type == t)) && intTypes.Any(t => after.tokens.Any(tk => tk.type == t))); isRelational = isStrings || isReals || isInts; if (isRelational) { return(new RelationalStatement(tokens, op.value, before, after)); } } } return(null); }
LogicalStatement CheckForConditional(WordTokens[] tokens) { var firstToken = tokens.First(); var validOperators = new TokenType[] { TokenType.AndLogicalOperator, TokenType.OrLogicalOperator }; if (tokens.First().tokens.Any(t => t.type == TokenType.NotLogicalOperator)) { var statement = tokens.Skip(1).ToArray(); var isConditional = CheckForConditional(statement); var isRelational = CheckForRelational(statement); if (isConditional != null) { return(new LogicalStatement(tokens, null, isConditional, tokens.First())); } if (isRelational != null) { return(new LogicalStatement(tokens, null, isRelational, tokens.First())); } } else { var op = tokens.Select((value, index) => new { value, index }).FirstOrDefault(t => t.value.tokens.Any(to => validOperators.Any(vOp => vOp == to.type))); if (op != null) { var index = op.index; var firstStatement = tokens.Take(index).ToArray(); var secondStatement = tokens.Skip(index + 1).ToArray(); var firstConditional = CheckForConditional(firstStatement); var firstRelational = CheckForRelational(firstStatement); var secondConditional = CheckForConditional(secondStatement); var secondRelational = CheckForRelational(secondStatement); ConditionStatement first = ((ConditionStatement)firstConditional) == null ? (ConditionStatement)firstRelational : (ConditionStatement)firstConditional; ConditionStatement second = ((ConditionStatement)secondConditional) == null ? (ConditionStatement)secondRelational : (ConditionStatement)secondConditional; if (first != null && second != null) { return(new LogicalStatement(tokens, first, second, op.value)); } } } return(null); }
AssignmentStatement CheckForAssignment(WordTokens[] tokens) { var intTypes = new TokenType[] { TokenType.Integer, TokenType.IntegerVariable, TokenType.UnsignedInteger }; var realTypes = new TokenType[] { TokenType.Real, TokenType.RealVariable }; var stringTypes = new TokenType[] { TokenType.String, TokenType.StringVariable }; if (tokens.Length > 2) { var firstTokenType = tokens.First().tokens.First().type; var firstToken = tokens.First(); var secondTokenType = tokens[1].tokens.First().type; var thirdTokenType = tokens[2].tokens; if (secondTokenType == TokenType.AssignmentOperator) { var isArithmatic = CheckForArithmaticStatement(tokens.Skip(2).ToArray()); switch (firstTokenType) { case TokenType.IntegerVariable: if (isArithmatic == null && thirdTokenType.Any(t => intTypes.Any(type => t.type == type))) { return(new AssignmentStatement(tokens, firstToken, tokens[2])); } else if (isArithmatic != null && thirdTokenType.Any(t => intTypes.Any(type => t.type == type))) { return(new AssignmentStatement(tokens, firstToken, tokens[2], isArithmatic)); } break; case TokenType.RealVariable: if (isArithmatic == null && thirdTokenType.Any(t => realTypes.Any(type => t.type == type))) { return(new AssignmentStatement(tokens, firstToken, tokens[2])); } else if (isArithmatic != null && thirdTokenType.Any(t => realTypes.Any(type => t.type == type))) { return(new AssignmentStatement(tokens, firstToken, tokens[2], isArithmatic)); } break; case TokenType.StringVariable: if (isArithmatic == null && thirdTokenType.Any(t => stringTypes.Any(type => t.type == type))) { return(new AssignmentStatement(tokens, firstToken, tokens[2])); } else if (isArithmatic != null && thirdTokenType.Any(t => intTypes.Any(type => t.type == type))) { return(new AssignmentStatement(tokens, firstToken, tokens[2], isArithmatic)); } break; default: OnError?.Invoke("First token type is not a variable."); return(null); } } else { OnError?.Invoke("Second argument has to be an assignment operator."); return(null); } } OnError?.Invoke("Not enough arguments for Assignment Statement"); return(null); }