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); }
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); } }
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); }