/// <summary> /// Совершает обход префиксного дерева токенов с помощью указанного лексера. /// </summary> /// <param name="lexer">Лексер исходного текста.</param> /// <param name="start">Стартовый узел дерева.</param> /// <returns>Последний узел и контейнер значений. Если обход закончен неудачно, контейнер значений будет являться <see langword="null"/>.</returns> internal static (CommandTreeNode endNode, ValueContainer container) Traverse(ISourceLexer lexer, CommandTreeNode start) { var currentNode = start; var stack = new Stack <int>(); var values = new List <object>(); var isSequenceRepeat = false; while (true) { var token = lexer.NextSourceToken(); if (!currentNode.NextNodes.TryGetValue(token, out var reference)) { break; } currentNode = reference.Node; if (token.Type == TokenType.EndOfText) { return(currentNode, new ValueContainer(values.ToArray())); } if (reference.IsBack) { isSequenceRepeat = true; } var startCount = currentNode.InGroupStartCount; if (isSequenceRepeat) { if (startCount > 0) { stack.Push(values.Count); } } else { while (startCount > 0) { stack.Push(values.Count); startCount--; } } if (TokenFacts.IsPlaceholder(currentNode.TokenPrototype.Type)) { values.Add(token); } if (currentNode.IsGroupEnd) { Debug.Assert(stack.Count > 0); var index = stack.Pop(); var newContainerToken = ReduceToIterationContainer(values, index); if (isSequenceRepeat) { var groupContainerToken = values[^ 1] as TokenWithValue <GroupContainer>;
IEnumerator <object[]> GetEnumerator() { foreach (var type in TokenFacts.GetAllTokenTypes()) { foreach (var(exampleInput, exampleLiteral) in type.GetLiteralExamples()) { yield return(new object[] { exampleInput, type, exampleLiteral }); } } }
private static Dictionary <Name, string> GetOperatorByName() { Dictionary <Name, string> dict = new Dictionary <Name, string>(28) { { NameManager.GetPredefinedName(PredefinedName.PN_OPEQUALS), "equals" }, { NameManager.GetPredefinedName(PredefinedName.PN_OPCOMPARE), "compare" } }; foreach (OperatorInfo opInfo in s_operatorInfos) { PredefinedName predefName = opInfo.MethodName; TokenKind token = opInfo.TokenKind; if (predefName != PredefinedName.PN_COUNT && token != TokenKind.Unknown) { dict.Add(NameManager.GetPredefinedName(predefName), TokenFacts.GetText(token)); } } return(dict); }
public static string GetDisplayName(OperatorKind op) { Debug.Assert(HasDisplayName(op)); return(TokenFacts.GetText(GetInfo(op).iToken)); }
private void ErrAppendType(CType pType, SubstContext pctx, bool fArgs) { if (pctx != null) { if (!pctx.FNop()) { pType = GetTypeManager().SubstType(pType, pctx); } // We shouldn't use the SubstContext again so set it to NULL. pctx = null; } switch (pType.GetTypeKind()) { case TypeKind.TK_AggregateType: { AggregateType pAggType = pType.AsAggregateType(); // Check for a predefined class with a special "nice" name for // error reported. string text = PredefinedTypes.GetNiceName(pAggType.getAggregate()); if (text != null) { // Found a nice name. ErrAppendString(text); } else if (pAggType.getAggregate().IsAnonymousType()) { ErrAppendPrintf("AnonymousType#{0}", GetTypeID(pAggType)); break; } else { if (pAggType.outerType != null) { ErrAppendType(pAggType.outerType, pctx); ErrAppendChar('.'); } else { // In a namespace. ErrAppendParentSym(pAggType.getAggregate(), pctx); } ErrAppendName(pAggType.getAggregate().name); } ErrAppendTypeParameters(pAggType.GetTypeArgsThis(), pctx, true); break; } case TypeKind.TK_TypeParameterType: if (null == pType.GetName()) { // It's a standard type variable. if (pType.AsTypeParameterType().IsMethodTypeParameter()) { ErrAppendChar('!'); } ErrAppendChar('!'); ErrAppendPrintf("{0}", pType.AsTypeParameterType().GetIndexInTotalParameters()); } else { ErrAppendName(pType.GetName()); } break; case TypeKind.TK_ErrorType: if (pType.AsErrorType().HasParent()) { Debug.Assert(pType.AsErrorType().nameText != null && pType.AsErrorType().typeArgs != null); ErrAppendParentType(pType, pctx); ErrAppendName(pType.AsErrorType().nameText); ErrAppendTypeParameters(pType.AsErrorType().typeArgs, pctx, true); } else { // Load the string "<error>". Debug.Assert(null == pType.AsErrorType().typeArgs); ErrAppendId(MessageID.ERRORSYM); } break; case TypeKind.TK_NullType: // Load the string "<null>". ErrAppendId(MessageID.NULL); break; case TypeKind.TK_OpenTypePlaceholderType: // Leave blank. break; case TypeKind.TK_BoundLambdaType: ErrAppendId(MessageID.AnonMethod); break; case TypeKind.TK_UnboundLambdaType: ErrAppendId(MessageID.Lambda); break; case TypeKind.TK_MethodGroupType: ErrAppendId(MessageID.MethodGroup); break; case TypeKind.TK_ArgumentListType: ErrAppendString(TokenFacts.GetText(TokenKind.ArgList)); break; case TypeKind.TK_ArrayType: { CType elementType = pType.AsArrayType().GetBaseElementType(); if (null == elementType) { Debug.Assert(false, "No element type"); break; } ErrAppendType(elementType, pctx); for (elementType = pType; elementType != null && elementType.IsArrayType(); elementType = elementType.AsArrayType().GetElementType()) { int rank = elementType.AsArrayType().rank; // Add [] with (rank-1) commas inside ErrAppendChar('['); // known rank. if (rank == 1) { if (!elementType.AsArrayType().IsSZArray) { ErrAppendChar('*'); } } else { for (int i = rank; i > 1; --i) { ErrAppendChar(','); } } ErrAppendChar(']'); } break; } case TypeKind.TK_VoidType: ErrAppendName(GetNameManager().Lookup(TokenFacts.GetText(TokenKind.Void))); break; case TypeKind.TK_ParameterModifierType: // add ref or out ErrAppendString(pType.AsParameterModifierType().isOut ? "out " : "ref "); // add base type name ErrAppendType(pType.AsParameterModifierType().GetParameterType(), pctx); break; case TypeKind.TK_PointerType: // Generate the base type. ErrAppendType(pType.AsPointerType().GetReferentType(), pctx); { // add the trailing * ErrAppendChar('*'); } break; case TypeKind.TK_NullableType: ErrAppendType(pType.AsNullableType().GetUnderlyingType(), pctx); ErrAppendChar('?'); break; case TypeKind.TK_NaturalIntegerType: default: // Shouldn't happen. Debug.Assert(false, "Bad type kind"); break; } }
public static string GetDisplayName(OperatorKind op) => TokenFacts.GetText(GetInfo(op).TokenKind);
public Token NextToken() { var tok = new Token(); skipWhitespace(); switch (ch) { case '=': if (peekChar() == '=') { var ch = this.ch; readChar(); tok = new Token(TokenType.EQUALS_EQUALS, $"{ch}{this.ch}"); } else { tok = makeToken(TokenType.EQUALS); } break; case '+': tok = makeToken(TokenType.PLUS); break; case ';': tok = makeToken(TokenType.SEMICOLON); break; case ',': tok = makeToken(TokenType.COMMA); break; case '(': tok = makeToken(TokenType.LPAREN); break; case ')': tok = makeToken(TokenType.RPAREN); break; case '{': tok = makeToken(TokenType.LBRACE); break; case '}': tok = makeToken(TokenType.RBRACE); break; case '!': if (peekChar() == '=') { var ch = this.ch; readChar(); tok = new Token(TokenType.BANG_EQUALS, $"{ch}{this.ch}"); } else { tok = makeToken(TokenType.BANG); } break; case '-': tok = makeToken(TokenType.MINUS); break; case '/': tok = makeToken(TokenType.SLASH); break; case '*': tok = makeToken(TokenType.ASTERISK); break; case '<': tok = makeToken(TokenType.LT); break; case '>': tok = makeToken(TokenType.GT); break; case '"': tok.Type = TokenType.STRING; tok.Literal = readString(); break; case '[': tok = makeToken(TokenType.LBRACKET); break; case ']': tok = makeToken(TokenType.RBRACKET); break; case ':': tok = makeToken(TokenType.COLON); break; case '\0': tok.Literal = ""; tok.Type = TokenType.EOF; break; default: if (ch.IsLetter()) { tok.Literal = readIdentifier(); tok.Type = TokenFacts.LookupIdent(tok.Literal); return(tok); } else if (ch.IsDigit()) { tok.Literal = readNumber(); tok.Type = TokenType.INT; return(tok); } else { tok = makeToken(TokenType.ILLEGAL); } break; } readChar(); return(tok); }