private static ParseResult TryParseIdentifier <TChars>( ExpandedTokenData <TChars> token, PipExecutionContext context, ref int position, out TChars identifier, bool logErrors = true) where TChars : struct, ICharSpan <TChars> { Contract.Requires(token.IsValid); Contract.RequiresNotNull(context); var pathTable = context.PathTable; var text = token.Text; if (text.Length == 0 || position == text.Length) { var updateToken = token.UpdateLineInformationForPosition(position); identifier = default(TChars); return(new ParseResult() { Status = ParseStatus.UnexpectedEmptyIdentifier, Path = updateToken.Path.ToString(pathTable), Line = updateToken.Line, Position = updateToken.Position, }); } int firstPosition = position; char firstChar = text[position]; if (!SymbolCharacters.IsValidStartChar(firstChar)) { var updateToken = token.UpdateLineInformationForPosition(position); identifier = default(TChars); return(new ParseResult() { Status = ParseStatus.UnexpectedCharacterAtStartOfIdentifier, Path = updateToken.Path.ToString(pathTable), Line = updateToken.Line, Position = updateToken.Position, Text = firstChar.ToString(), }); } position++; for (; position < text.Length; position++) { char ch = text[position]; if (!SymbolCharacters.IsValidChar(ch)) { break; } } identifier = text.Subsegment(firstPosition, position - firstPosition); return(new ParseResult { Status = ParseStatus.Success }); }
/// <summary> /// Parses a dotted identifier. All error logging is the responsibility of the caller /// </summary> /// <param name="token">The token to parse</param> /// <param name="context">Context with tables.</param> /// <param name="identifier">The parsed identifier if successful, null if not.</param> public static ParseResult TryParse <TChars>( ExpandedTokenData <TChars> token, PipExecutionContext context, out DottedIdentifier identifier) where TChars : struct, ICharSpan <TChars> { Contract.Requires(token.IsValid); Contract.RequiresNotNull(context); PathTable pathTableForError = context.PathTable; SymbolTable symbolTable = context.SymbolTable; int position = 0; var text = token.Text; int textLength = text.Length; identifier = null; if (text.Length == 0) { return(new ParseResult() { Status = ParseStatus.InvalidDottedIdentifierCannotBeEmpty, Path = token.Path.ToString(pathTableForError), Line = token.Line, Position = token.Position, }); } TChars id; var parseIdenfierResult = TryParseIdentifier(token, context, ref position, out id); if (parseIdenfierResult.Status != ParseStatus.Success) { return(parseIdenfierResult); } identifier = DottedIdentifier.Create(symbolTable, id); DottedIdentifier currentIdentifier = identifier; while (position < textLength) { if (text[position] == '.') { if (position == textLength - 1) { // Last char is a dot. var updateToken = token.UpdateLineInformationForPosition(position); identifier = null; return(new ParseResult() { Status = ParseStatus.InvalidDottedIdentifierUnexpectedDot, Path = updateToken.Path.ToString(pathTableForError), Line = updateToken.Line, Position = updateToken.Position, Text = currentIdentifier != null?currentIdentifier.Head.ToString(symbolTable.StringTable) : string.Empty, }); } position++; TChars currentId; parseIdenfierResult = TryParseIdentifier(token, context, ref position, out currentId); if (parseIdenfierResult.Status != ParseStatus.Success) { identifier = null; return(parseIdenfierResult); } var tail = DottedIdentifier.Create(symbolTable, currentId); currentIdentifier.m_tail = tail; currentIdentifier = tail; } else { break; } } if (position < textLength) { var updateToken = token.UpdateLineInformationForPosition(position); identifier = null; return(new ParseResult() { Status = ParseStatus.InvalidDottedIdentifierUnexpectedCharacter, Path = updateToken.Path.ToString(pathTableForError), Line = updateToken.Line, Position = updateToken.Position, Text = text[position].ToString(), }); } return(new ParseResult() { Status = ParseStatus.Success }); }