public bool CheckSyntax(IEnumerable <Token> tokens) { var precedenceTable = _helper.GetPrecedenceTable(Grammar); var tokensList = tokens as List <Token> ?? tokens.ToList(); var sharp = TokenEnum.Sharp; sharp.Line = tokensList[tokensList.Count - 1].Line; tokensList.Add(sharp); var tokensArray = tokensList.ToArray(); var array = tokensArray.Select(t => { if (t is TokenEnum) { return(t); } var tEnum = Grammar.SelectMany(x => x.CompositeToken) .Cast <TokenEnum>() .FirstOrDefault(x => x.IsTheSame(t))?.Clone() as TokenEnum; if (tEnum != null) { tEnum.Line = t.Line; } return(tEnum); }).ToArray(); if (array.Any(x => x == null)) { Logger.Error("Unknown token: {0}", tokensArray[Array.FindIndex(array, x => x == null)]); } var stack = new Stack <Token>(); stack.Push(TokenEnum.Sharp); var i = 0; var popped = new List <Token>(); Prn = new List <Token>(); while (stack.Peek().Type != TokenType.Axiom || array[i] != TokenEnum.Sharp) { try { var relation = precedenceTable[stack.Peek()][array[i]]; if (relation == PrecedenceRelation.More) { //Base search popped.Clear(); popped.Add(stack.Pop()); while (precedenceTable[stack.Peek()][popped.Last()] != PrecedenceRelation.Less) { popped.Add(stack.Pop()); } popped.Reverse(); try { var toReplace = Grammar.First(x => x.CompositeToken.SequenceEqual(popped)); toReplace.OnReplaceAction?.Invoke(tokensArray.Skip(i - popped.Count).Take(popped.Count).ToList(), Prn); PRNChanged?.Invoke(toReplace.Token, Prn); stack.Push(toReplace.Token); } catch (Exception exc) { Logger.Error("Can't replace sequence {0}, Line = {1}", popped, array[i].Line); return(false); } } else //Copy the symbol to stack { stack.Push(array[i++]); } OnStackChanged(stack, relation.Value, new ArraySegment <Token>(tokensArray, i, tokensArray.Length - i), Prn); } catch { Logger.Error("There is no relation for a pair {0}-{1}, Line = {2}", stack.Peek(), array[i], array[i].Line); return(false); } } return(true); }
protected virtual void OnPrnChanged(Token tokenReplaced, List <Token> prn) { PRNChanged?.Invoke(tokenReplaced, prn); }