Beispiel #1
0
        /// <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);
        }
Beispiel #4
0
 public static string GetDisplayName(OperatorKind op)
 {
     Debug.Assert(HasDisplayName(op));
     return(TokenFacts.GetText(GetInfo(op).iToken));
 }
Beispiel #5
0
        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);
Beispiel #7
0
        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);
        }