private TexlNode Parse(ref List <TexlError> errors) { Contracts.AssertValueOrNull(errors); _errors = errors; TexlNode node; Token firstToken = _curs.TokCur; _before = new SourceList(ParseTrivia()); if (_curs.TidCur == TokKind.Eof) { if (firstToken.Kind == TokKind.Comment && firstToken.As <CommentToken>().IsOpenBlock) { // This provides an error message for when a block comment missing a closing '*/' is the only token in the formula bar PostBlockCommentMissingClosingError(); errors = _errors; } ; node = new BlankNode(ref _idNext, _curs.TokCur); } else { node = ParseExpr(Precedence.None); if (_curs.TidCur != TokKind.Eof) { PostError(_curs.TokCur, TexlStrings.ErrBadToken); } _after = _after == null ? new SourceList(ParseTrivia()) : new SourceList(new SpreadSource(_after.Sources), new SpreadSource(ParseTrivia())); // This checks for and provides an error message for any block comments missing a closing '*/' PostBlockCommentMissingClosingError(); errors = _errors; } // The top node (of the parse tree) should end up with the biggest id. We use this fact when binding. Contracts.Assert(node.Id == _idNext - 1); return(node); }
private static DocumentToken TokenFactoryImpl(Token token, List<DocumentToken> previous) { var utToken = token.As<DocumentToken>(); DocumentTokenType? previousNonWhitespaceTokenType = null; for(var i = previous.Count-1;i >= 0; i--) { var current = previous[i]; if(string.IsNullOrWhiteSpace(current.Value) == false) { previousNonWhitespaceTokenType = current.TokenType; break; } } DocumentTokenType constantValueType; if(TryParseDocumentTokenType(token.Value, out constantValueType)) { utToken.TokenType = constantValueType; } else if (previousNonWhitespaceTokenType.HasValue && (previousNonWhitespaceTokenType.Value == DocumentTokenType.BeginReplacementSegment || previousNonWhitespaceTokenType.Value == DocumentTokenType.BeginTerminateReplacementSegment)) { utToken.TokenType = DocumentTokenType.ReplacementKey; } else if (previousNonWhitespaceTokenType.HasValue && (previousNonWhitespaceTokenType.Value == DocumentTokenType.ReplacementKey || previousNonWhitespaceTokenType.Value == DocumentTokenType.ReplacementParameter)) { utToken.TokenType = DocumentTokenType.ReplacementParameter; } else { utToken.TokenType = DocumentTokenType.PlainText; } return utToken; }
/// <summary> /// A method that can determine which type of token the given value is /// </summary> /// <param name="token">The token to classify</param> /// <param name="previous">Previously classified tokens in the source string</param> /// <returns>The classified token</returns> public static ObjectPathToken TokenFactoryImpl(Token token, List<ObjectPathToken> previous) { var ret = token.As<ObjectPathToken>(); if (ret.Value == "[") { ret.TokenType = ObjectPathTokenType.IndexerOpen; } else if (ret.Value == "]") { ret.TokenType = ObjectPathTokenType.IndexerClose; } else if (ret.Value == ".") { ret.TokenType = ObjectPathTokenType.NavigationElement; } else if (ret.Value.StartsWith("\"") && ret.Value.EndsWith("\"") && ret.Value.Length > 1) { ret.TokenType = ObjectPathTokenType.StringLiteral; } else if(string.IsNullOrWhiteSpace(ret.Value)) { ret.TokenType = ObjectPathTokenType.Whitespace; } else { ret.TokenType = ObjectPathTokenType.Identifier; } return ret; }