public TokenList Tokenize(string template) { //var x = ClassificationRegistry.GetClassificationType(Constants.KeywordClassificationType); var stream = new TemplateStream(template); var tokens = new TokenList(); var context = new ContextStack(tokens); var scope = new ScopeStack(); var brace = new BraceStack(); while (true) { if (ParseComment(stream, tokens, context)) continue; if (ParseDollar(stream, tokens, context, scope)) continue; if (ParseStatement(stream, tokens, context, scope)) continue; if (ParseFilter(stream, tokens, context, scope)) continue; if (ParseOther(stream, tokens, context, scope, brace)) continue; if (stream.Advance() == false) break; } context.Clear(stream.Position); return tokens; }
private bool ParseOther(TemplateStream stream, TokenList tokens, ContextStack context, ScopeStack scope, BraceStack brace) { switch (stream.Current) { case '[': brace.Push(tokens.Add(new Token(stream.Position, 1, stream.Line, TokenType.OpenBrace, context.Current)), scope.Changed); stream.Advance(); return true; case ']': var openBrace = brace.Pop(TokenType.OpenBrace); var token = tokens.Add(new Token(stream.Position, 1, stream.Line, TokenType.CloseBrace, context.Current, null, openBrace.Token)); if (openBrace.Token != null) { openBrace.Token.MatchingToken = token; } stream.Advance(); if (openBrace.ScopeChanged) { var current = scope.Pop(); if (current == Scope.Template) { context.Pop(stream.Position); if (stream.Current == '[') scope.Push(Scope.Separator); } else if (current == Scope.True) { context.Pop(stream.Position); if (stream.Current == '[') scope.Push(Scope.False); } } return true; case '{': //tokens.Add(new Token(stream.Position - 1, 2, TokenType.OpenBlock, context.Current)); brace.Push(tokens.Add(new Token(stream.Position, 1, stream.Line, TokenType.OpenCurlyBrace, context.Current)), scope.Changed); stream.Advance(); return true; case '}': var openCurlyBrace = brace.Pop(TokenType.OpenCurlyBrace); token = tokens.Add(new Token(stream.Position, 1, stream.Line, TokenType.CloseCurlyBrace, context.Current, null, openCurlyBrace.Token)); if (openCurlyBrace.Token != null) { openCurlyBrace.Token.MatchingToken = token; } //tokens.Add(new Token(stream.Position, 1, TokenType.CloseBlock, context.Current)); stream.Advance(); if (openCurlyBrace.ScopeChanged) { scope.Pop(); } return true; case '(': brace.Push(tokens.Add(new Token(stream.Position, 1, stream.Line, TokenType.OpenFunctionBrace, context.Current)), scope.Changed); stream.Advance(); return true; case ')': var openFunctionBrace = brace.Pop(TokenType.OpenFunctionBrace); token = tokens.Add(new Token(stream.Position, 1, stream.Line, TokenType.CloseFunctionBrace, context.Current, null, openFunctionBrace.Token)); if (openFunctionBrace.Token != null) { openFunctionBrace.Token.MatchingToken = token; } stream.Advance(); if (openFunctionBrace.ScopeChanged) { scope.Pop(); } return true; } if (scope.Current == Scope.Block) return false; var name = stream.PeekWord(); if (name == null) return false; if (keywords.Contains(name)) { tokens.Add(new Token(stream.Position, name.Length, stream.Line, TokenType.Keyword, context.Current)); } stream.Advance(name.Length); return true; }