Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

I need help with this program. I need it to be able to sum strings and also when summing two decimal values, the result must

I need help with this program. I need it to be able to sum strings and also when summing two decimal values, the result must be decimal as well. It does identify the tokens, basicallyreads them and implement them through mathematical calculations, but with strings it doesn't work. C programs starts but once you input a statement it explodes, but when u use a word with assignment in the entrance, everything else works,ADD,SUB,etc. It alldepends on what u input at the beginning of the statement.

--------------------------------------------------------------------------------------------------------------------------------------------------------------

Assemblyinfo.cs

using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Interpreter")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Microsoft")] [assembly: AssemblyProduct("Interpreter")] [assembly: AssemblyCopyright("Copyright Microsoft 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("7fa6de18-36dd-4836-9c4a-c26a0f2abe25")]

// Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]

--------------------------------------------------------------------------------------------------------------------------------------------------------------

Program.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; usingSystem.IO; namespace Interpreter { class Program { private static Tokenizer tokenizer; private static StatementRecognizer statementRecognizer; private static Runner runner; private static string error = string.Empty; private static bool verbose = false; static void PrintError(string e) { Console.ForegroundColor =ConsoleColor.Red; Console.WriteLine(e); Console.ForegroundColor = ConsoleColor.White; }

static void Main(string[] args) { //args= new string[] { "test.lao" }; tokenizer = new Tokenizer(); statementRecognizer = new StatementRecognizer(); runner = new Runner(tokenizer); var ended = false; statementRecognizer.OnError += (e) => { error = e; }; if (args.Length == 1) { var filePath = args[0]; if (Directory.Exists(filePath) || File.Exists(filePath)) { var file = File.ReadAllLines(filePath); foreach (var sentence in file) { ended = MainRoutine(sentence); if (ended) return; } Console.Read(); return; }else verbose = args[0] == "-v";

}else if(args.Length == 2) { verbose = args[0] == "-v";

var filePath = args[1]; if (Directory.Exists(filePath) || File.Exists(filePath)) { var file = File.ReadAllLines(filePath); foreach (var sentence in file) { ended = MainRoutine(sentence); if (ended) return; } Console.Read(); return; } }

Console.WriteLine("LAO Interpreter"); Console.WriteLine("Enter 'quit' to exit."); var quitReg = new Regex(@"^QUIT${1}", RegexOptions.IgnoreCase); string line = string.Empty; while (!quitReg.IsMatch((line = Console.ReadLine()))) { ended = MainRoutine(line); if (ended) return; }

}

static bool MainRoutine(string line) { var words = ParseInput(line); var sentenceTokens =words.Select(w => new WordTokens(w, tokenizer.Verify(w))).ToArray(); var hasErrors = CheckForTokenErrors(sentenceTokens); if (!hasErrors) { var expresion = statementRecognizer.Verify(sentenceTokens); if (expresion != null) { var result =runner.Run(expresion); if (!result) { Console.WriteLine("Execution Terminated."); return true; } } else PrintError(error); } return false;

}

static string[] ParseInput(string input) { var splitOptions = StringSplitOptions.RemoveEmptyEntries; Func IsEven = (index) => { return index % 2 == 0; }; return input.Split('"') .Select((e, i) => IsEven(i) ? e.Split(new[] { ' ' }, splitOptions) : new string[] { e = "\"" + e + "\"" }) .SelectMany(e => e).ToArray(); }

static bool CheckForTokenErrors(WordTokens[] sentenceTokens) { var hasErrors = sentenceTokens?.Length < 1; if (!hasErrors && verbose) foreach(var wordToken in sentenceTokens) if (wordToken.tokens?.Length > 0 && verbose) { Console.ForegroundColor =ConsoleColor.Green; Console.WriteLine("Input: " + wordToken.value + " is a token"); Console.WriteLine("Possible Tokens:"); foreach (var token in wordToken.tokens) Console.WriteLine(token.type); Console.ForegroundColor = ConsoleColor.White; } else { Console.ForegroundColor =ConsoleColor.Red; Console.WriteLine("Error: " + wordToken.value + " not a token."); Console.ForegroundColor = ConsoleColor.White; return true; } return hasErrors; } } }

--------------------------------------------------------------------------------------------------------------------------------------------------------------

Runner.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace Interpreter { public class Runner { private Dictionary variables; private Tokenizer tokenizer;

public Runner(Tokenizer tokenizer) { this.tokenizer = tokenizer; variables = new Dictionary(); }

public bool Run(Statement expresion) { string result = string.Empty; TokenType resultType; var type = expresion.type; switch (type) { case StatementType.None: break; case StatementType.CommentStatement: break; case StatementType.AssignmentStatement: ((AssignmentStatement)expresion).Execute(variables,out result, out resultType, tokenizer); break; case StatementType.PrintStatement: ((PrintStatement)expresion).Execute(variables, out result, out resultType, tokenizer); break; case StatementType.ReadStatement: ((ReadStatement)expresion).Execute(variables, out result, out resultType, tokenizer); break; case StatementType.IfStatement: ((IfStatement)expresion).Execute(variables, out result, out resultType, tokenizer); break; case StatementType.EndStatement: return false; case StatementType.ConditionalStatement: ((ConditionStatement)expresion).Evaluate(variables); break; case StatementType.ArithmaticStatement: ((ArithmaticStatement)expresion).Execute(variables, out result, out resultType, tokenizer); break; case StatementType.ThenStatement: break; default: break; } return true; } } }

--------------------------------------------------------------------------------------------------------------------------------------------------------------

Statement.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

namespace Interpreter { public class Statement { private WordTokens[] tokens; public StatementType type; protected Statement subStatement;

public Statement(WordTokens[] tokens, Statement subStatement = null) { this.tokens = tokens; this.subStatement = subStatement; }

public void SetSubStatement(Statement statement) { if (subStatement == null) subStatement = statement; else subStatement.SetSubStatement(statement); }

public bool IsNumeric(WordTokens token) { return token.tokens.Any(tok => Token.NumericTypes.Any(t => tok.type == t)); }

public bool IsVariable(WordTokens token) { return token.tokens.Any(tok => Token.VariableTypes.Any(t => tok.type == t)); } }

public class IfStatement : Statement , ExpressionStatement { public ConditionStatement condition; public ExpressionStatement expression;

public IfStatement(WordTokens[] tokens, ConditionStatement condition, ExpressionStatement expression, StatementsubStatement = null) : base(tokens, subStatement) { this.condition = condition; this.expression = expression; type = StatementType.IfStatement; }

public void Execute(Dictionary variables, out string result, out TokenType resultType, Tokenizertokenizer = null) { resultType = TokenType.IfKeyword; result = string.Empty; if (condition.Evaluate(variables)) expression.Execute(variables, out result, out resultType, tokenizer); } } public interface ExpressionStatement { void Execute(Dictionary variables, out string result, out TokenType resultType, Tokenizer tokenizer = null); }

public interface ConditionStatement { bool Evaluate(Dictionary variables); }

public class RelationalStatement : Statement, ConditionStatement { private WordTokens op; private WordTokens left; private WordTokens right;

public RelationalStatement(WordTokens[] tokens, WordTokens op, WordTokens left, WordTokens right, StatementsubStatement = null) : base(tokens, subStatement) { this.left = left; this.right = right; this.op = op; this.type = StatementType.ConditionalStatement; }

public bool Evaluate(Dictionary variables) { var isNumeric = IsNumeric(left); var firstIsVariable = IsVariable(left); var secondIsVariable = IsVariable(right); var firstvalue = firstIsVariable ? variables[left.value] : left.value; var secondValue = secondIsVariable ? variables[right.value] : right.value; var result = false; if (isNumeric) { var firstParam = float.Parse(firstvalue); var secondParam = float.Parse(secondValue); switch (op.tokens.First().type) { case TokenType.EqualRelationalOperator: result = firstParam == secondParam; break; case TokenType.NotEqualRelationalOperator: result = firstParam != secondParam; break; case TokenType.GreaterThanRelationalOperator: result = firstParam > secondParam; break; case TokenType.LessThanRelationalOperator: result = firstParam < secondParam; break; case TokenType.EqualGreaterRelationalOperator: result = firstParam >= secondParam; break; case TokenType.EqualLessRelationalOperator: result = firstParam <= secondParam; break; default: break; } } else { var firstParam = firstvalue; var secondParam = secondValue; switch (op.tokens.First().type) { case TokenType.EqualRelationalOperator: result = firstParam == secondParam; break; case TokenType.NotEqualRelationalOperator: result = firstParam != secondParam; break; case TokenType.GreaterThanRelationalOperator: result = firstParam.Length > secondParam.Length; break; case TokenType.LessThanRelationalOperator: result = firstParam.Length < secondParam.Length; break; case TokenType.EqualGreaterRelationalOperator: result = firstParam.Length >= secondParam.Length; break; case TokenType.EqualLessRelationalOperator: result = firstParam.Length <= secondParam.Length; break; default: break; } } return result; }

}

public class LogicalStatement : Statement, ConditionStatement { private ConditionStatement left; private WordTokens op; private ConditionStatement right;

public LogicalStatement(WordTokens[] tokens, ConditionStatement left, ConditionStatement right, WordTokensop, Statement subStatement = null) : base(tokens, subStatement) { this.left = left; this.right = right; this.op = op; type = StatementType.ConditionalStatement; }

public bool Evaluate(Dictionary variables) { switch (op.tokens.First().type) { case TokenType.AndLogicalOperator: return left.Evaluate(variables) && right.Evaluate(variables); case TokenType.NotLogicalOperator: return !right.Evaluate(variables); case TokenType.OrLogicalOperator: return left.Evaluate(variables) || right.Evaluate(variables); default: return false; } throw new NotImplementedException(); } }

public class ArithmaticStatement : Statement, ExpressionStatement { private WordTokens op; private WordTokens left; private WordTokens right;

public ArithmaticStatement(WordTokens[] tokens, WordTokens left, WordTokens right, WordTokens op, StatementsubStatement = null) : base(tokens, subStatement) { this.left = left; this.right = right; this.op = op; this.type = StatementType.ArithmaticStatement; }

public void Execute(Dictionary variables, out string result, out TokenType resultType, Tokenizertokenizer = null) { var firstIsNumeric = IsNumeric(left); var secondIsNumeric = IsNumeric(right); var firstIsVariable = IsVariable(left); var secondIsVariable = IsVariable(right); var firstvalue = firstIsVariable ? variables[left.value] : left.value; var secondValue = secondIsVariable ? variables[right.value] : right.value; resultType = TokenType.Number; result = string.Empty; switch (op.tokens.First().type) { case TokenType.AddArithmaticOperator: if(firstIsNumeric && secondIsNumeric) { result = (float.Parse(firstvalue) + float.Parse(secondValue)).ToString(); resultType = TokenType.Number; }else if (firstIsNumeric || secondIsNumeric || (!firstIsNumeric && !secondIsNumeric)) { result = firstvalue + secondValue; resultType = TokenType.String; }

break; case TokenType.MulArithmaticOperator: result = (float.Parse(firstvalue) * float.Parse(secondValue)).ToString(); resultType = TokenType.Number; break; case TokenType.DivArithmaticOperator: var res = (float.Parse(firstvalue) / float.Parse(secondValue)); res = (int)res; result = res.ToString(); resultType = TokenType.Number; break; case TokenType.SubArithmaticOperator: result = (float.Parse(firstvalue) - float.Parse(secondValue)).ToString(); resultType = TokenType.Number; break; } } }

public class PrintStatement : Statement, ExpressionStatement { private WordTokens variable;

public PrintStatement(WordTokens[] tokens, WordTokens variable, Statement subStatement = null) : base(tokens,subStatement) { this.variable = variable; type = StatementType.PrintStatement; }

public void Execute(Dictionary variables, out string result, out TokenType resultType, Tokenizertokenizer = null) { if(variable == null && subStatement != null) { if(subStatement.GetType().GetInterfaces().Any(i => i == typeof(ExpressionStatement))) { var expression = (ExpressionStatement)subStatement; expression.Execute(variables, out result, out resultType, tokenizer); Console.WriteLine(result); result = string.Empty; resultType = TokenType.PrintKeyword;

} }else { if(variable != null) { if (variables.ContainsKey(variable.value)) { var variab = variables[variable.value]; Console.WriteLine(variab); } else if (variable.tokens.Any(t => Token.NumericTypes.Any(tt => tt == t.type))) Console.WriteLine(variable.value); else if (variable.tokens.Any(t => t.type == TokenType.String)) Console.WriteLine(variable.value.Replace('\"', ' ')); else Console.WriteLine("Error: Variable does not exist");

}else Console.WriteLine("");

} result = string.Empty; resultType = TokenType.PrintKeyword;

} }

public class ReadStatement : Statement, ExpressionStatement { private WordTokens variable;

public ReadStatement(WordTokens[] tokens, WordTokens variable, Statement subStatement = null) : base(tokens,subStatement) { this.variable = variable; type = StatementType.ReadStatement;

}

public void Execute(Dictionary variables, out string result, out TokenType resultType, Tokenizertokenizer = null) {

var input = Console.ReadLine(); var variableType = variable.tokens.FirstOrDefault(t => Token.VariableTypes.Any(vt => t.type == vt)); if (variableType != null) { var resultTokens = tokenizer.Verify(input); if (resultTokens?.Length > 0) { result = string.Empty; resultType = TokenType.ReadKeyword; if (!variables.ContainsKey(variable.value)) variables.Add(variable.value, resultTokens.First().value); else variables[variable.value] = resultTokens.First().value; }

}

resultType = TokenType.ReadKeyword; result = string.Empty; } }

public class AssignmentStatement : Statement, ExpressionStatement { private WordTokens variable; private WordTokens value;

public AssignmentStatement(WordTokens[] tokens, WordTokens variable, WordTokens value, Statement subStatement= null) : base(tokens, subStatement) { this.variable = variable; this.value = value; type = StatementType.AssignmentStatement;

}

public void Execute(Dictionary variables, out string result, out TokenType resultType, Tokenizertokenizer = null) { result = string.Empty; resultType = TokenType.AssignmentOperator;

if(subStatement != null) { if (subStatement.GetType().GetInterfaces().Any(i => i == typeof(ExpressionStatement))) { var expression = (ExpressionStatement)subStatement; expression.Execute(variables, out result, out resultType, tokenizer); if (variables.ContainsKey(variable.value)) { variables[variable.value] = result; } else { variables.Add(variable.value, result); }

} }else if

(value != null) { if(variables.ContainsKey(variable.value)) { variables[variable.value] = value.value; } else { variables.Add(variable.value, value.value); } } } }

}

--------------------------------------------------------------------------------------------------------------------------------------------------------------

StatementRecognizer.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions;

namespace Interpreter { public class StatementRecognizer { StatementRegex[] statementRegexes; public event Action OnError;

/* Token Type ENUM: * CommentKeyword = 0 * Assignment Operator = 1 * PrinterKeyword = 2 * ReadKeyword = 3 * IfKeyword = 4 * EndKeyWord = 5 * IntegerVariable = 6 * StringVariable = 7 * RealVariable = 8 * Integer = 9 * Number = 10 * UnsignedInteger = 11 * Real = 12 * String = 13 * GreaterThanRelationalOperator = 14 * LessThanRelationalOperator = 15 * EqualRelationalOperator = 16 * EqualGreaterRelationalOperator = 17 * EqualLessRelationalOperator = 18 * NotEqualRelationalOperator = 19 * AndLogicalOperator = 20 * OrLogicalOperator = 21 * NotLogicalOperator = 22 * AddArithmaticOperator = 23 * SubArithmaticOperator = 24 * MulArithmaticOperator = 25 * DivArithmaticOperator = 26 * ThenKeyword = 27 * */

public StatementRecognizer() { var commentStatement = new StatementRegex(@"^0",StatementType.CommentStatement); var printStatement = new StatementRegex(@"^2(-(13|10|6|8|7))?$", StatementType.PrintStatement); var readStatement = new StatementRegex(@"^3-(6|8|7)$", StatementType.ReadStatement); var endStatement = new StatementRegex(@"^5$", StatementType.EndStatement); var arithmaticStatement = new StatementRegex(@"^(((6|7|8|10|13)(-(23)-(6|7|8|10|13))+)|((6|8|10)(-(23|24|25|26)-(6|8|10))+))$", StatementType.ArithmaticStatement); //conditionalStatementneeds some fixes var conditionalStatement = new StatementRegex(@"^(22-)?(((13|7)(-(14|15|16|18|19)-(13|7)))|((6|8|10)(-(14|15|16|18|19)-(6|8|10))))((-(20|21)-(((13|7)(-(14|15|16|18|19)-(13|7)))|((6|8|10)(-(14|15|16|18|19)-(6|8|10)))))+)?$", StatementType.ConditionalStatement); //assignmentStatmentNeedsSomeFixesex: a = 3 .add. b var assignmentStatment = new StatementRegex(@"^((7-1-(7|13))|(6-1-(6|10))|(8-1-(8|10)))$", StatementType.AssignmentStatement); var thenStatement = new StatementRegex(@"^(27-)((3-(6|8|7))|(2(-(13|10|6|8|7))?$)|(((7-1-(7|13))|(6-1-(6|10))|(8-1-(8|10)))$))", StatementType.ThenStatement); var ifStatement = new StatementRegex(@"^(4-)(22-)?(((13|7)(-(14|15|16|18|19)-(13|7)))|((6|8|10)(-(14|15|16|18|19)-(6|8|10))))((-(20|21)-(((13|7)(-(14|15|16|18|19)-(13|7)))|((6|8|10)(-(14|15|16|18|19)-(6|8|10)))))+)?(-27-)((3-(6|8|7))|(2(-(13|10|6|8|7))?$)|(((7-1-(7|13))|(6-1-(6|10))|(8-1-(8|10)))$))$",StatementType.IfStatement); statementRegexes = new StatementRegex[] { commentStatement, printStatement, readStatement, endStatement, arithmaticStatement, conditionalStatement, assignmentStatment, thenStatement, ifStatement };

}

public Statement Verify(WordTokens[] wordTokens) {

var list = new List(); Statement expression = null; foreach(var token in wordTokens) { list.Add(token); var result = IdentifyStatements(list.ToArray()); if (result != null && (result.type == StatementType.PrintStatement && wordTokens.Count() > list.Count())) continue; else { if (result?.type == StatementType.IfStatement) { var statement = (IfStatement)result; var exp = (Statement)statement.expression; if ((exp.type == StatementType.PrintStatement || exp.type == StatementType.AssignmentStatement) && wordTokens.Count() > list.Count()) continue; } else if (result?.type == StatementType.AssignmentStatement && wordTokens.Count() > list.Count()) continue;

} if(result != null) { if (expression != null) { expression.SetSubStatement(result); } else expression = result; list = new List(); } } return expression; }

PrintStatement CheckForPrintStatement(WordTokens[] tokens) { var allowedTokenTypes = new TokenType[] { TokenType.String, TokenType.StringVariable, TokenType.Real, TokenType.RealVariable, TokenType.Integer, TokenType.IntegerVariable, TokenType.Number }; if (tokens == null || tokens.Length == 0 || tokens.First().tokens.First().type != TokenType.PrintKeyword) return null; if (tokens.Length == 1) return new PrintStatement(tokens,null); else if (tokens.Length == 2) { var secondToken = tokens[1]; if (allowedTokenTypes.Any(t => t == secondToken.tokens.First().type)) return new PrintStatement(tokens, secondToken); else { var errorString =allowedTokenTypes.Select(t => t.ToString()).Aggregate((current, next) => { return current + " " + next; }); errorString = "Error: Second token must be any of the following: " + 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; }

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; }

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; }

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 + " " + next; }); errorString = "Error: Second token must be any of the following: " + 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; }

IfStatement CheckForIfStatement(WordTokens[] tokens) { var firstToken = tokens.First(); var thenTokenPair =tokens.Select((value, index) => new { value, index }).FirstOrDefault(i => i.value.tokens.Any(t => t.type == TokenType.ThenKeyword)); if (thenTokenPair != null) { var thenIndex = thenTokenPair.index; var condition = tokens.Skip(1).Take(thenIndex - 1).ToArray(); var statment = tokens.Skip(thenIndex + 1).ToArray(); var isConditional = CheckForConditional(condition); var isRelational = CheckForRelational(condition); var conditionStatement = (ConditionStatement)isConditional == null ? (ConditionStatement)isRelational : (ConditionStatement)isConditional; if (conditionStatement != null) { var asisgnment = CheckForAssignment(statment); var print = CheckForPrintStatement(statment); var read = CheckForReadStatement(statment); var arithmatic = CheckForArithmaticStatement(tokens); if (arithmatic != null) return new IfStatement(tokens, conditionStatement, arithmatic); else if (asisgnment != null) return new IfStatement(tokens, conditionStatement, asisgnment); else if (print != null) return new IfStatement(tokens, conditionStatement, print); else if (read != null) return new IfStatement(tokens, conditionStatement, read);

} else if (isRelational != null) {

}

}

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; }

Statement CheckForArithmaticAssingmentRelationalConditional(WordTokens[] tokens) { var assignment = CheckForAssignment(tokens); var relational = CheckForRelational(tokens); var arithmatic = CheckForArithmaticStatement(tokens); var conditional = CheckForConditional(tokens);

if (assignment != null) return assignment; else if (relational != null) return relational; else if (arithmatic != null) return arithmatic; else return conditional; }

Statement CheckForArithmaticStatementRelationalConditional(WordTokens[] tokens) { var arithmatic = CheckForArithmaticStatement(tokens); var relational = CheckForRelational(tokens); var conditional = CheckForConditional(tokens); if (arithmatic != null) return arithmatic; else if (relational != null) return relational; else return conditional;

}

Statement IdentifyStatements(WordTokens[] tokens) { TokenType firstToken; WordTokens token;

if(tokens?.Length > 0 && (token = tokens.First()).tokens?.Length > 0) { firstToken = token.tokens.First().type; switch (firstToken) { case TokenType.CommentKeyword:

var commentStatement = new Statement(tokens); commentStatement.type = StatementType.CommentStatement; return commentStatement; case TokenType.AssignmentOperator: OnError?.Invoke("No statement starts with the Assignment Operator"); break; case TokenType.PrintKeyword: return CheckForPrintStatement(tokens); case TokenType.ReadKeyword: return CheckForReadStatement(tokens); case TokenType.IfKeyword: return CheckForIfStatement(tokens); case TokenType.EndKeyword: var statement = new Statement(tokens); statement.type = StatementType.EndStatement; return statement; case TokenType.IntegerVariable:

return CheckForArithmaticAssingmentRelationalConditional(tokens); case TokenType.StringVariable: return CheckForArithmaticAssingmentRelationalConditional(tokens); case TokenType.RealVariable: return CheckForArithmaticAssingmentRelationalConditional(tokens); case TokenType.Integer: return CheckForArithmaticStatementRelationalConditional(tokens); case TokenType.Number: return CheckForArithmaticStatementRelationalConditional(tokens); case TokenType.UnsignedInteger: return CheckForArithmaticStatementRelationalConditional(tokens); case TokenType.Real: return CheckForArithmaticStatementRelationalConditional(tokens); case TokenType.String: return CheckForArithmaticStatementRelationalConditional(tokens); case TokenType.GreaterThanRelationalOperator: OnError?.Invoke("No statement starts with the Greater Than Operator"); break; case TokenType.LessThanRelationalOperator: OnError?.Invoke("No statement starts with the Less Than Operator"); break; case TokenType.EqualRelationalOperator: OnError?.Invoke("No statement starts with the Equal Operator"); break; case TokenType.EqualGreaterRelationalOperator: OnError?.Invoke("No statement starts with the Equal Greater Than Operator"); break; case TokenType.EqualLessRelationalOperator: OnError?.Invoke("No statement starts with the Equal Less Than Operator"); break; case TokenType.NotEqualRelationalOperator: OnError?.Invoke("No statement starts with the Not Equal Operator"); break; case TokenType.AndLogicalOperator: OnError?.Invoke("No statement starts with the And Operator"); break; case TokenType.OrLogicalOperator: OnError?.Invoke("No statement starts with the Or Operator"); break; case TokenType.NotLogicalOperator: break; case TokenType.AddArithmaticOperator: OnError?.Invoke("No statement starts with the Add Operator"); break; case TokenType.SubArithmaticOperator: OnError?.Invoke("No statement starts with the Substract Operator"); break; case TokenType.MulArithmaticOperator: OnError?.Invoke("No statement starts with the Multiplication Operator"); break; case TokenType.DivArithmaticOperator: OnError?.Invoke("No statement starts with the Division Operator"); break; case TokenType.ThenKeyword: OnError?.Invoke("No statement starts with the Then Operator"); break; default: OnError?.Invoke("Undefined error ocurred."); break; } } return null; }

public string TranslateToString(WordTokens[] wordTokens) { //Thishas to change a bit. I am selecting the first token, i should test all. var result = wordTokens.Where(w => w.tokens?.Length > 0) .Select(w => ((int)w.tokens.First().type).ToString()) .Aggregate((current, next) => current.ToString() + "-" + next.ToString()); Console.WriteLine("Resulting REGEX STRING: " + result); return result;

}

}

}

--------------------------------------------------------------------------------------------------------------------------------------------------------------

StatementRegex.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions;

namespace Interpreter { public class StatementRegex { private Regex regEx; private StatementType type;

public StatementRegex(string regEx, StatementType type) { this.regEx = new Regex(regEx); this.type = type; }

public StatementType Verify(string sentence) { return regEx.IsMatch(sentence) ? type : StatementType.None; } }; }

--------------------------------------------------------------------------------------------------------------------------------------------------------------

StatementType.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

namespace Interpreter { public enum StatementType { None, CommentStatement, AssignmentStatement, PrintStatement, ReadStatement, IfStatement, EndStatement, ConditionalStatement, ArithmaticStatement, ThenStatement } }

--------------------------------------------------------------------------------------------------------------------------------------------------------------

Tokens.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

namespace Interpreter { public class Token { public string value; public TokenType type; public static TokenType[] NumericTypes { get { return numericTypes; } } public static TokenType[] StringTypes { get { return stringTypes; } }

public static TokenType[] VariableTypes { get { return variableTypes; } }

private static TokenType[] numericTypes = new TokenType[] { TokenType.Number, TokenType.Integer, TokenType.Real,TokenType.RealVariable, TokenType.IntegerVariable }; private static TokenType[] stringTypes = new TokenType[] { TokenType.String, TokenType.StringVariable }; private static TokenType[] variableTypes = new TokenType[] { TokenType.StringVariable, TokenType.RealVariable, TokenType.IntegerVariable };

public Token(string value, TokenType type) { this.value = value; this.type = type; } }

public enum TokenType { CommentKeyword, AssignmentOperator, PrintKeyword, ReadKeyword, IfKeyword, EndKeyword, IntegerVariable, StringVariable, RealVariable, Integer, Number, UnsignedInteger, Real, String, GreaterThanRelationalOperator, LessThanRelationalOperator, EqualRelationalOperator, EqualGreaterRelationalOperator, EqualLessRelationalOperator, NotEqualRelationalOperator, AndLogicalOperator, OrLogicalOperator, NotLogicalOperator, AddArithmaticOperator, SubArithmaticOperator, MulArithmaticOperator, DivArithmaticOperator, ThenKeyword, } }

--------------------------------------------------------------------------------------------------------------------------------------------------------------

Tokenizer.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions; namespace Interpreter { public class Tokenizer { TokenRegex[] tokenRegexes; public Tokenizer() { //VARIABLES var realVar = new TokenRegex(@"(?!(IF)$)(^[G-N]([A-Z]{0,8}){1}$)", TokenType.RealVariable); var stringVar = new TokenRegex("(?!(REM|READ|PRINT|THEN)$)(^[O-Z]([A-Z]{0,8}){1}$)", TokenType.StringVariable); var intVar = new TokenRegex("^[A-F]([A-Z]{0,8}){1}$", TokenType.IntegerVariable);

//LogicalOperators var andOP = new TokenRegex(@"^\.(AND)\.$", TokenType.AndLogicalOperator); var orOP = new TokenRegex(@"^\.(OR)\.$", TokenType.OrLogicalOperator); var notOp = new TokenRegex(@"^\.(NOT)\.$", TokenType.NotLogicalOperator);

//RelationalOperators var gtOP = new TokenRegex(@"^\.(GT)\.$", TokenType.GreaterThanRelationalOperator); var ltOP = new TokenRegex(@"^\.(LT)\.$", TokenType.LessThanRelationalOperator); var eqOP = new TokenRegex(@"^\.(EQ)\.$", TokenType.EqualRelationalOperator); var leOP = new TokenRegex(@"^\.(LE)\.$", TokenType.EqualLessRelationalOperator); var neOP = new TokenRegex(@"^\.(NE)\.$", TokenType.NotEqualRelationalOperator);

//ARITHMATICOPERATORS var addOP = new TokenRegex(@"^\.(ADD)\.$", TokenType.AddArithmaticOperator); var subOP = new TokenRegex(@"^\.(SUB)\.$", TokenType.SubArithmaticOperator); var mulOP = new TokenRegex(@"^\.(MUL)\.$", TokenType.MulArithmaticOperator); var divOP = new TokenRegex(@"^\.(DIV)\.$", TokenType.DivArithmaticOperator);

//ASIGNMENTOPERATORS var assignOP = new TokenRegex("^=$", TokenType.AssignmentOperator);

//KEYWORDS var comment = new TokenRegex("^REM$", TokenType.CommentKeyword); var end = new TokenRegex(@"^END\.$", TokenType.EndKeyword); var read = new TokenRegex("^READ$", TokenType.ReadKeyword); var ifReg = new TokenRegex("^IF$", TokenType.IfKeyword); var printReg = new TokenRegex("^PRINT$", TokenType.PrintKeyword); var thenReg = new TokenRegex("^THEN$", TokenType.ThenKeyword);

//TYPES var strng = new TokenRegex("^\"(.*)\"${1}", TokenType.String); var number = new TokenRegex(@"((^(\+|-)(\d{1,8}))|(^(\d{1,8})))(\.(\d{1,8}))$|((^(\+|-)(\d{1,8}))|(^(\d{1,8})))(\.(\d{1,8}))E(((\+|-)(\d{1,8}))|(((\d{1,8}))\.(\d{1,8})$)|((\d{1,8})$))|((^(\+|-)(\d{1,8})$)|(^(\d{1,8})$))", TokenType.Number); var unsignInteger = new TokenRegex(@"^(\d{1,8})$", TokenType.UnsignedInteger); var integer = new TokenRegex(@"((^(\+|-)(\d{1,8})$)|(^(\d{1,8})$))", TokenType.Integer); var real = new TokenRegex(@"((^(\+|-)(\d{1,8}))|(^(\d{1,8})))(\.(\d{1,8}))$|((^(\+|-)(\d{1,8}))|(^(\d{1,8})))(\.(\d{1,8}))E(((\+|-)(\d{1,8}))|(((\d{1,8}))\.(\d{1,8})$)|((\d{1,8})$))", TokenType.Real);

tokenRegexes = new TokenRegex[] { realVar, stringVar, intVar, andOP, orOP, notOp, gtOP, ltOP, eqOP, leOP, neOP, addOP, subOP, mulOP, divOP, assignOP, comment, end, read, ifReg, printReg, thenReg, strng, number, unsignInteger, integer, real, }; }

public Token[] Verify(string value) { var result =tokenRegexes.Select(t => t.Verify(value)) .Where(t => t != null) .ToArray(); return result; }

}

}

--------------------------------------------------------------------------------------------------------------------------------------------------------------

TokenRegex.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions;

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Students also viewed these Databases questions