// Attempts to pop a Namespaced.TypeName or a TypeName from the token stream. // The values are applied to reusableRootNameParserOut and the number of values // parsed are returned as an integer. Possible values are 0, 1, and 2. // This method will update the token stream through the valid tokens. private static int ParseRootNameImpl(TokenStream tokens) { if (!tokens.HasMore) { return(0); } int zeroIndex = tokens.SnapshotState(); Token firstToken = tokens.Pop(); if (!PastelParser.IsValidName(firstToken.Value)) { tokens.RevertState(zeroIndex); return(0); } reusableRootNameParserOut[0] = firstToken; int oneIndex = tokens.SnapshotState(); if (!tokens.PopIfPresent(".")) { return(1); } if (!tokens.HasMore) { tokens.RevertState(oneIndex); return(1); } Token secondToken = tokens.Pop(); if (!PastelParser.IsValidName(secondToken.Value)) { tokens.RevertState(oneIndex); return(1); } reusableRootNameParserOut[1] = secondToken; return(2); }
private static PType ParseImpl(TokenStream tokens) { Token token = tokens.Pop(); switch (token.Value) { case "int": case "char": case "double": case "bool": case "void": case "string": case "object": return(new PType(token, token.Value)); default: if (!PastelParser.IsValidName(token.Value)) { return(null); } break; } int tokenIndex = tokens.SnapshotState(); bool isError = false; if (tokens.PopIfPresent("<")) { List <PType> generics = new List <PType>(); while (!tokens.PopIfPresent(">")) { if (generics.Count > 0) { if (!tokens.PopIfPresent(",")) { isError = true; break; } } PType generic = ParseImpl(tokens); if (generic == null) { return(null); } generics.Add(generic); } if (!isError) { return(new PType(token, token.Value, generics)); } // If there was an error while parsing generics, then this may still be a valid type. tokens.RevertState(tokenIndex); return(new PType(token, token.Value)); } else { return(new PType(token, token.Value)); } }