示例#1
0
        public PolyglotSyntaxTree Parse()
        {
            var tree = new PolyglotSyntaxTree(_sourceText);

            _tokens = new PolyglotLexer(_sourceText, tree).Lex();

            var rootNode = new PolyglotSubmissionNode(
                DefaultLanguage,
                _sourceText,
                tree);

            tree.RootNode = rootNode;

            ParseSubmission(rootNode);

            return(tree);
        }
示例#2
0
        private void ParseSubmission(PolyglotSubmissionNode rootNode)
        {
            var currentLanguage = DefaultLanguage;

            for (var i = 0; i < _tokens !.Count; i++)
            {
                var currentToken = _tokens[i];

                switch (currentToken)
                {
                case DirectiveToken directiveToken:

                    DirectiveNode directiveNode;

                    if (IsLanguageDirective(directiveToken))
                    {
                        directiveNode   = new KernelDirectiveNode(directiveToken, _sourceText, rootNode.SyntaxTree);
                        currentLanguage = directiveToken.DirectiveName;
                    }
                    else
                    {
                        directiveNode = new DirectiveNode(
                            directiveToken,
                            _sourceText,
                            rootNode.SyntaxTree);
                    }

                    if (_tokens.Count > i + 1 &&
                        _tokens[i + 1] is TriviaToken triviaNode)
                    {
                        i += 1;

                        directiveNode.Add(triviaNode);
                    }

                    if (_tokens.Count > i + 1 &&
                        _tokens[i + 1] is DirectiveArgsToken directiveArgs)
                    {
                        i += 1;

                        directiveNode.Add(directiveArgs);
                    }

                    var directiveName = directiveNode.First().Text;

                    if (_rootKernelDirectiveParser
                        .Configuration
                        .RootCommand
                        .Children
                        .Any(c => c.HasAlias(directiveName)))
                    {
                        directiveNode.DirectiveParser = _rootKernelDirectiveParser;
                    }
                    else if (_subkernelDirectiveParsersByLanguageName != null &&
                             _subkernelDirectiveParsersByLanguageName.TryGetValue(currentLanguage, out var getParser))
                    {
                        directiveNode.DirectiveParser = getParser();
                    }

                    if (directiveNode.DirectiveParser != null)
                    {
                        if (directiveToken.Text == "#r")
                        {
                            var parseResult = directiveNode.GetDirectiveParseResult();

                            if (parseResult.Errors.Count == 0)
                            {
                                var value = parseResult.CommandResult.GetArgumentValueOrDefault <PackageReferenceOrFileInfo>("package");

                                if (value.Value is FileInfo)
                                {
                                    // #r <file> is treated as a LanguageNode to be handled by the compiler

                                    AddAsLanguageNode(directiveNode);

                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        AddAsLanguageNode(directiveNode);
                        break;
                    }

                    rootNode.Add(directiveNode);

                    break;

                case LanguageToken languageToken:
                {
                    var languageNode = new LanguageNode(
                        currentLanguage,
                        _sourceText,
                        rootNode.SyntaxTree);
                    languageNode.Add(languageToken);

                    rootNode.Add(languageNode);
                }
                break;

                case TriviaToken trivia:
                    rootNode.Add(trivia);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(currentToken));
                }
            }

            void AddAsLanguageNode(DirectiveNode directiveNode)
            {
                var languageNode = new LanguageNode(
                    currentLanguage,
                    _sourceText,
                    rootNode.SyntaxTree);

                languageNode.Add(directiveNode);

                rootNode.Add(languageNode);
            }
        }
示例#3
0
        private void ParseSubmission(PolyglotSubmissionNode rootNode)
        {
            var currentLanguage = DefaultLanguage;

            for (var i = 0; i < _tokens !.Count; i++)
            {
                var currentToken = _tokens[i];

                switch (currentToken)
                {
                case DirectiveToken directiveToken:

                    DirectiveNode directiveNode;

                    if (IsChooseKernelDirective(directiveToken))
                    {
                        directiveNode   = new KernelNameDirectiveNode(directiveToken, _sourceText, rootNode.SyntaxTree);
                        currentLanguage = directiveToken.DirectiveName;
                    }
                    else
                    {
                        directiveNode = new ActionDirectiveNode(
                            directiveToken,
                            _sourceText,
                            currentLanguage,
                            rootNode.SyntaxTree);
                    }

                    if (_tokens.Count > i + 1 &&
                        _tokens[i + 1] is TriviaToken triviaNode)
                    {
                        i += 1;

                        directiveNode.Add(triviaNode);
                    }

                    if (_tokens.Count > i + 1 &&
                        _tokens[i + 1] is DirectiveArgsToken directiveArgs)
                    {
                        i += 1;

                        directiveNode.Add(directiveArgs);
                    }

                    var directiveName = directiveNode.ChildNodesAndTokens.First().Text;

                    if (IsDefinedInRootKernel(directiveName))
                    {
                        directiveNode.DirectiveParser = _rootKernelDirectiveParser;
                    }
                    else if (_subkernelDirectiveParsersByLanguageName != null &&
                             _subkernelDirectiveParsersByLanguageName.TryGetValue(currentLanguage, out var getParser))
                    {
                        directiveNode.DirectiveParser = getParser();
                    }
                    else
                    {
                        directiveNode.DirectiveParser = _rootKernelDirectiveParser;
                    }

                    if (directiveToken.Text == "#r")
                    {
                        var parseResult = directiveNode.GetDirectiveParseResult();

                        if (parseResult.Errors.Count == 0)
                        {
                            var value = parseResult.CommandResult.GetArgumentValueOrDefault <PackageReferenceOrFileInfo>("package");

                            if (value?.Value is FileInfo)
                            {
                                // #r <file> is treated as a LanguageNode to be handled by the compiler
                                AppendAsLanguageNode(directiveNode);

                                break;
                            }
                        }
                    }

                    rootNode.Add(directiveNode);

                    break;

                case LanguageToken languageToken:
                    AppendAsLanguageNode(languageToken);
                    break;

                case TriviaToken trivia:
                    rootNode.Add(trivia);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(currentToken));
                }
            }

            void AppendAsLanguageNode(SyntaxNodeOrToken nodeOrToken)
            {
                if (rootNode.ChildNodes.LastOrDefault() is LanguageNode previousLanguageNode &&
                    previousLanguageNode.Language == currentLanguage)
                {
                    previousLanguageNode.Add(nodeOrToken);
                }