示例#1
0
        private void ParseTypedef(LinkedListStream <IBaseToken> stream)
        {
            CppToken typedefToken = stream.Peek <CppToken>();

            Debug.Assert(typedefToken.Kind == CppTokenKind.ReservedKeyword && "typedef".Equals(typedefToken.Value));
            stream.Next();

            var reservedKeywordResult = Search(stream, SearchMode.Current, CppTokenKind.ReservedKeyword);

            if (reservedKeywordResult != null)
            {
                var    reservedKeywordToken = reservedKeywordResult.Token;
                string keyword = reservedKeywordToken.Value;
                switch (keyword)
                {
                case "union":
                case "struct":
                    ParseStruct(stream);
                    return;

                case "enum":
                    ParseEnum(stream, reservedKeywordToken.Position);
                    return;
                }
            }

            // Normal typedef
            CppEntityKind kind            = CppEntityKind.Typedef;
            var           semicolonResult = Search(stream, SearchMode.Forward, CppTokenKind.Semicolon);

            if (semicolonResult != null)
            {
                stream.Seek(semicolonResult.Node);
                stream.Next();

                SearchResult <CppToken> identResult = null;
                var prevResult = Search(semicolonResult, SearchMode.Prev, CppTokenKind.RightParen, CppTokenKind.IdentLiteral);
                if (prevResult != null)
                {
                    if (prevResult.Token.Kind == CppTokenKind.RightParen)
                    {
                        // Function typedef
                        var leftParenResult = Search(prevResult, SearchMode.Backward, CppTokenKind.LeftParen);
                        if (leftParenResult != null)
                        {
                            var rightParentResult = Search(leftParenResult, SearchMode.Prev, CppTokenKind.RightParen);
                            if (rightParentResult != null)
                            {
                                leftParenResult = Search(rightParentResult, SearchMode.Backward, CppTokenKind.LeftParen);
                                if (leftParenResult != null)
                                {
                                    identResult = Search(leftParenResult, SearchMode.Next, CppTokenKind.IdentLiteral);
                                    kind        = CppEntityKind.FunctionTypedef;
                                }
                            }
                            else
                            {
                                // Typedef on define
                                // #define MY_TYPEDEF(name)
                                // typedef MY_TYPEDEF(my_typedef);
                                //Debug.WriteLine("Right paren not found!");
                            }
                        }
                    }
                    else
                    {
                        // Type typedef
                        Debug.Assert(prevResult.Token.Kind == CppTokenKind.IdentLiteral);
                        identResult = prevResult;
                    }
                }

                if (identResult != null)
                {
                    var       identToken    = identResult.Token;
                    string    typedefIdent  = identToken.Value;
                    CppEntity typedefEntity = new CppEntity(kind, identToken, typedefIdent)
                    {
                        DocumentationNode = FindDocumentationNode(identResult.Node, 1),
                    };
                    var typedefNode = new CppNode(Top, typedefEntity);
                    Add(typedefNode);
                    SymbolCache.AddSource(Tag, typedefIdent, new SourceSymbol(SourceSymbolKind.CppType, identToken.Range));
                }
            }
        }
示例#2
0
        private bool ParseFunction(LinkedListStream <IBaseToken> stream)
        {
            var      functionIdentNode  = stream.CurrentNode;
            CppToken functionIdentToken = functionIdentNode.Value as CppToken;

            Debug.Assert(functionIdentToken.Kind == CppTokenKind.IdentLiteral);
            var functionName = functionIdentToken.Value;

            CppTokenKind[] funcCallKinds =
            {
                CppTokenKind.EqOp,
                CppTokenKind.Comma,
                CppTokenKind.LeftParen,
                CppTokenKind.AddOp,
                CppTokenKind.AddAssign,
                CppTokenKind.SubOp,
                CppTokenKind.SubAssign,
                CppTokenKind.DivOp,
                CppTokenKind.DivAssign,
                CppTokenKind.MulAssign,
                CppTokenKind.XorOp,
                CppTokenKind.XorAssign,
                CppTokenKind.LeftShiftOp,
                CppTokenKind.LeftShiftAssign,
                CppTokenKind.RightShiftOp,
                CppTokenKind.RightShiftAssign,
            };

            var           funcCallResult = Search(stream, SearchMode.Prev, funcCallKinds);
            CppEntityKind kind           = CppEntityKind.FunctionCall;

            // Skip ident
            stream.Next();

            // Skip parameters
            CppToken openParenToken = stream.Peek <CppToken>();

            Debug.Assert(openParenToken.Kind == CppTokenKind.LeftParen);
            stream.Next();
            var closeParenResult = Search(stream, SearchMode.Forward, CppTokenKind.RightParen);

            if (closeParenResult == null)
            {
                AddError(openParenToken.Position, $"Unterminated function '{functionName}'", "Function", functionName);
                return(true);
            }
            stream.Seek(closeParenResult.Node);
            stream.Next();

            if (funcCallResult == null)
            {
                var endingTokenResult = Search(stream, SearchMode.Current, CppTokenKind.Semicolon, CppTokenKind.LeftBrace);
                if (endingTokenResult != null)
                {
                    stream.Next();
                    if (endingTokenResult.Token.Kind == CppTokenKind.LeftBrace)
                    {
                        kind = CppEntityKind.FunctionBody;
                        if (Configuration.SkipFunctionBlocks)
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        kind = CppEntityKind.FunctionDefinition;
                    }
                }
            }

            CppEntity functionEntity = new CppEntity(kind, functionIdentToken, functionName)
            {
                DocumentationNode = FindDocumentationNode(functionIdentNode, 1),
            };
            CppNode functionNode = new CppNode(Top, functionEntity);

            Add(functionNode);

            if (kind == CppEntityKind.FunctionDefinition)
            {
                SymbolCache.AddSource(Tag, functionName, new SourceSymbol(SourceSymbolKind.CppFunctionDefinition, functionIdentToken.Range, functionNode));
            }
            else if (kind == CppEntityKind.FunctionBody)
            {
                SymbolCache.AddSource(Tag, functionName, new SourceSymbol(SourceSymbolKind.CppFunctionBody, functionIdentToken.Range, functionNode));
            }
            else if (Configuration.FunctionCallSymbolsEnabled)
            {
                SymbolCache.AddReference(Tag, functionName, new ReferenceSymbol(ReferenceSymbolKind.CppFunction, functionIdentToken.Range, functionNode));
            }

            return(true);
        }
示例#3
0
        private void ParseEnumValues(LinkedListStream <IBaseToken> stream, CppNode rootNode)
        {
            CppToken leftBraceToken = stream.Peek <CppToken>();

            Debug.Assert(leftBraceToken.Kind == CppTokenKind.LeftBrace);
            stream.Next();
            while (!stream.IsEOF)
            {
                var rightBraceResult = Search(stream, SearchMode.Current, CppTokenKind.RightBrace);
                if (rightBraceResult != null)
                {
                    // Enum complete
                    stream.Next();
                    break;
                }
                var identResult = Search(stream, SearchMode.Current, CppTokenKind.IdentLiteral);
                if (identResult != null)
                {
                    stream.Seek(identResult.Node);

                    // Enum value
                    var    enumValueToken = identResult.Token;
                    string enumValueName  = enumValueToken.Value;
                    stream.Next();

                    CppEntity enumValueEntity = new CppEntity(CppEntityKind.EnumValue, enumValueToken, enumValueName)
                    {
                        DocumentationNode = FindDocumentationNode(identResult.Node, 1),
                    };
                    CppNode enumValueNode = new CppNode(rootNode, enumValueEntity);
                    rootNode.AddChild(enumValueNode);
                    SymbolCache.AddSource(Tag, enumValueName, new SourceSymbol(SourceSymbolKind.CppMember, enumValueToken.Range, enumValueNode));

                    var equalsResult = Search(stream, SearchMode.Current, CppTokenKind.EqOp);
                    if (equalsResult != null)
                    {
                        stream.Next();

                        // Skip until comma or right brace
                        var tmpResult = Search(stream, SearchMode.Forward, CppTokenKind.Comma, CppTokenKind.RightBrace);
                        if (tmpResult != null)
                        {
                            stream.Seek(tmpResult.Node);
                        }
                        else
                        {
                            AddError(equalsResult.Token.Position, $"Expect assignment token, but got token '{stream.Peek()}' for enum member '{enumValueName}'", "Enum", enumValueName);
                            break;
                        }
                    }

                    var commaOrRightBraceResult = Search(stream, SearchMode.Current, CppTokenKind.Comma, CppTokenKind.RightBrace);
                    if (commaOrRightBraceResult != null)
                    {
                        stream.Seek(commaOrRightBraceResult.Node);
                        if (commaOrRightBraceResult.Token.Kind == CppTokenKind.Comma)
                        {
                            stream.Next();
                        }
                        continue;
                    }
                    else
                    {
                        var tok = stream.Peek <CppToken>();
                        if (tok != null)
                        {
                            AddError(tok.Position, $"Unexpected token '{tok.Kind}'", "EnumValue");
                        }
                        break;
                    }
                }
                stream.Next();
            }
        }