f# - 如何使用 FSharp.Compiler.Service 从 F# 字符串中获取 F# A

假设我有一个 F# 字符串,如 let x = 1 + 1,我如何为这个字符串生成 AST?

我正在寻找具有如下签名的函数:

String -> Result<FSharpAst, CompilerError>

理想情况下,我想避免写入临时文件。

这可以使用 FSharp.Compiler.Service 吗?

最佳答案

以下 F# 脚本演示了如何执行此操作。

#r "nuget: FSharp.Compiler.Service, 41.0.1"

open FSharp.Compiler.Syntax
open FSharp.Compiler.Text
open FSharp.Compiler.CodeAnalysis

let tryParseExpression (input : string) =
  async {
    let checker = FSharpChecker.Create()

    let filename = "snippet.fsx"

    let sourceText = SourceText.ofString input

    let opts =
      {
        FSharpParsingOptions.Default with
          SourceFiles = [| filename |]
      }

    let! parseResults = checker.ParseFile(filename, sourceText, opts)

    if parseResults.ParseHadErrors then
      return Error parseResults.Diagnostics
    else
      match parseResults.ParseTree with
      | ParsedInput.ImplFile (ParsedImplFileInput (fn, true, _, _, _, [ m ], _)) when fn = filename ->
        return Ok m
      | _ ->
        return failwithf "Unexpected parse tree: %A" parseResults.ParseTree
  }

module Result =

  let get =
    function
    | Ok x -> x
    | Error e -> failwithf "%A" e

"let x = 1 + 1"
|> tryParseExpression
|> Async.RunSynchronously
|> Result.get
|> printfn "%A"

(*

SynModuleOrNamespace
  ([Snippet], false, AnonModule,
   [Let
      (false,
       [SynBinding
          (None, Normal, false, false, [],
           PreXmlDoc ((1,4), FSharp.Compiler.Xml.XmlDocCollector),
           SynValData
             (None, SynValInfo ([], SynArgInfo ([], false, None)), None),
           Named (x, false, None, snippet.fsx (1,4--1,5)), None,
           App
             (NonAtomic, false,
              App
                (NonAtomic, true, Ident op_Addition,
                 Const (Int32 1, snippet.fsx (1,8--1,9)),
                 snippet.fsx (1,8--1,11)),
              Const (Int32 1, snippet.fsx (1,12--1,13)), snippet.fsx (1,8--1,13)),
           snippet.fsx (1,4--1,5), Yes snippet.fsx (1,0--1,13))],
       snippet.fsx (1,0--1,13));
    Let
      (false,
       [SynBinding
          (None, Normal, false, false, [],
           PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector),
           SynValData
             (None, SynValInfo ([], SynArgInfo ([], false, None)), None),
           Named (y, false, None, snippet.fsx (2,4--2,5)), None,
           Const (Int32 2, snippet.fsx (2,8--2,9)), snippet.fsx (2,4--2,5),
           Yes snippet.fsx (2,0--2,9))], snippet.fsx (2,0--2,9))],
   PreXmlDocEmpty, [], None, snippet.fsx (1,0--2,9))

*)

关于f# - 如何使用 FSharp.Compiler.Service 从 F# 字符串中获取 F# AST?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64502701/

相关文章:

google-sheets - 如何让条形图数据标签在谷歌表格中显示值和百分比(总数)?

amazon-web-services - 连接到 appsync 的 Lambda 总是返回 La

ansible - 错误!操作中的意外参数类型 :

html - 打破 PDF 中的 html 表格

django - 如何使用 Django Rest Framework 将上传进度条与 s3 存储桶

assembly - grub 似乎没有正确加载我的内核

ios - Fabric Crashlytics 不工作。 iOS 14 应用/XCode 12

angular - 如何限制angular app在iframe中加载

spring-boot - 线程 "main"java.lang.NoSuchMethodError

python - Vscode - .env 文件中的变量扩展