internal RecursiveCodeLog Analyse(SyntaxGroup code) { Assignee = code.Component.text; Operator = code.Operator.text; Line = code.Component.line; //If we can detect at least one code block List <SyntaxGroup> list = code.Operand as List <SyntaxGroup>; if (list != null) { try { CodeBlock block = new CodeBlock(Level + 1); RecursiveCodeLog log = block.Analyse(list); if (log != null) { log.AddToRecursiveChain("Error during analysis chain", Assignee, Line.ToString()); return(log); } Value = block; } catch (Exception) { //TODO: Add language support RecursiveCodeLog log = new RecursiveCodeLog(); log.AddToRecursiveChain("Impossible to analyze associated code", Assignee, Line.ToString()); return(log); } } //If we get pure text else if (code.Operand is Token) { Value = new CodeValue(((Token)code.Operand).text); } //If we got a list of tokens, a chain of pure text else if (code.Operand is List <Token> ) { Value = new CodeBlock(); ((CodeBlock)Value).Analyse((List <Token>)code.Operand); } return(null); }
public object GroupTokensByBlocks(List <Token> tokens, bool first = true) { List <SyntaxGroup> list = new List <SyntaxGroup>(); //Check if the list contains anything and is the first recursive call if (!tokens.Any() && first) { return(list); } //Check if the list contains any delimiters or can be considered a valid script if (!ContainsDelimiters(tokens) || DetectAnyErrors(tokens)) { //if not, return the list as the operand, it is a list of text return(tokens); } while (tokens.Any()) { SyntaxGroup group = new SyntaxGroup(); //First token should be the component try { //Check if there is enough elements if (tokens.Count < 3) { //If yes, incomplete expression Logger.Errors.Add(new SyntaxError(tokens.First()?.text, tokens.First()?.line, tokens.First()?.column, new IncompleteExpressionException())); return(null); } group.Component = tokens.First(); tokens.Remove(tokens.First()); //second token should be the operator if (tokens.First().text == "=" || tokens.First().text == "<" || tokens.First().text == ">") { group.Operator = tokens.First(); tokens.RemoveAt(0); } else { Logger.Errors.Add(new SyntaxError(group.Component?.text, group.Component?.line, group.Component?.column, new OperatorExpectedException(tokens.First().text))); //Load it anyway with = as the operator group.Operator = new Token { text = "=", line = group.Component.line, column = group.Component.column + group.Component.text.Length }; } //Third token should be the operand switch (tokens.First().text) { case "{": tokens.RemoveAt(0); int closePos = getIndexOfClosingBracket(tokens) - 1; if (closePos < 0) { Logger.Errors.Add(new SyntaxError(group.Component?.text, group.Component?.line, group.Component?.column, new ClosingBracketExpectedException())); continue; } group.Operand = GroupTokensByBlocks(tokens.GetRange(0, closePos), false); tokens.RemoveRange(0, closePos + 1); break; case "}": Logger.Errors.Add(new SyntaxError(group.Component?.text, group.Component?.line, group.Component?.column, new OpeningBracketExpectedException(tokens.First().text))); break; case "\"": //If we hit a string literal, malformed string Logger.Errors.Add(new SyntaxError(group.Component?.text, group.Component?.line, group.Component?.column, new StringLiteralException())); break; default: //Check if it is empty if (string.IsNullOrWhiteSpace(tokens.First().text)) { //If yes, create and error Logger.Errors.Add(new SyntaxError(group.Component?.text, group.Component?.line, group.Component?.column, new IncompleteExpressionException())); } group.Operand = tokens.First(); tokens.RemoveAt(0); break; } } catch (System.InvalidOperationException) { //Critical incomplete expression, this will also log Logger.Errors.Add(new SyntaxError(group.Component?.text, group.Component?.line, group.Component?.column, new IncompleteExpressionException())); } list.Add(group); } return(list); }
internal void Analyse(SyntaxGroup code, int line = -1) { //Can't analyse }