F# fslex fsyacc 生产代码成熟吗?

发布于 2024-10-24 11:16:09 字数 215 浏览 4 评论 0原文

在阅读了一个 2 年历史的网页后,与 OCamel 同行相比,它确实存在 fslex/fsyacc、错误、缓慢、愚蠢等问题,我想知道满足词法解析需求的最佳选择是什么?

我之前曾将 ANTLR 与 C# 绑定一起使用,但目前正在学习 F#,当我看到它带有解析器生成器时,我感到很兴奋。由于 F# 现已正式发布,微软似乎确实打算支持和开发它。您认为 fslex 和 fsyacc 对于生产代码来说值得吗?

After reading a 2 year old webpage really ripping fslex/fsyacc, buggy, slow, stupid etc. compared to their OCamel counterparts i wonder what would be ones best bet for lexing parsing needs?

Ive used ANTLR before with C# bindings but am currently in the process of learning F# and was excited when i saw it came with a parser generator. Since F# is now officaly released and it seems something Microsoft is really aiming to support and develop. Would you say fslex and fsyacc is worth it for production code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小ぇ时光︴ 2024-10-31 11:16:09

Fslex 和 fsyacc 由 F# 编译器使用,因此它们可以工作。我几年前就用过它们,它足以满足我的需求。

然而,我的经验是,F# 中的 lex/yacc 远不如 OCaml 中成熟。 OCaml 社区中的许多人已经使用它们多年,包括许多学生(似乎用它们编写一个小型解释器/编译器是一种常见的练习)。我不认为很多 F# 开发人员使用过它们,而且我不认为 F# 团队最近在这些工具上做了很多工作(例如,VS 集成并不是优先考虑的事情)。如果您不是很迫切,Fslex 和 fsyacc 可能就足够了。

解决方案可能是调整 Menhir(具有几个不错功能的 camlyacc 替代品)以将其与 F# 一起使用。我不知道这会有多少工作量。

就个人而言,我现在每次需要编写解析器时都会使用 FParsec 。它的使用方式有很大不同,但它也更加灵活,并且可以生成良好的解析错误消息。我对它非常满意,当我有疑问时,它的作者总是非常有帮助。

Fslex and fsyacc are used by the F# compiler, so they kind of work. I have used them a few years ago, it was good enough for my needs.

However, my experience is that lex/yacc is much less mature in F# than in OCaml. Many people in the OCaml community have used them for years, including many students (it seems like writing a small interpreter/compiler with them is a common exercise). I don't think many F# developers have used them, and I don't think the F# team has done a lot of work on these tools recently (for instance, VS integration has not been a priority). If you're not very exigent, Fslex and fsyacc could be enough for you.

A solution could be to adapt Menhir (a camlyacc replacement with several nice features) to use it with F#. I have no idea how much work it would be.

Personally, I now use FParsec every time I need to write a parser. It's quite different to use, but it's also much more flexible and it generates good parse error messages. I've been very happy with it and its author has always been very helpful when I had questions.

最近可好 2024-10-31 11:16:09

Fslex 和 fsyacc 当然可以用于生产使用。毕竟,它们在 Microsoft Visual Studio 2010 中使用,因为 F# 词法分析器和解析器是使用它们编写的(F# 编译器源代码也是一个很好的例子,演示了如何有效地使用它们)。

我不确定 fslex/fsyacc 与 OCaml 等效项或 ANTLR 相比如何。然而,Frederik Holmstrom 有一篇文章将 ANTLR 与用 F# 编写的手写解析器进行了比较 在 IronJS 中使用。不幸的是,他没有fslex/fsyacc版本,所以没有直接比较。

为了回答一些特定的问题 - 您可以获得 MSBUILD 任务来运行 fslex/fsyacc 作为构建的一部分,因此它集成得很好。你没有得到语法突出显示,但我认为这没什么大不了的。它可能比 OCaml 版本慢,但这仅在更改解析器时影响编译 - 我对 F# 解析器进行了一些修改,但没有发现编译时间有问题。

Fslex and fsyacc are certainly ready for production use. After all, they are used in Microsoft Visual Studio 2010, because the F# lexer and parser are written using them (The F# compiler source code is also a good example that demonstrates how to use them efficiently).

I'm not sure how fslex/fsyacc compare to their OCaml equivalents or with ANTLR. However, Frederik Holmstrom has an article that compares ANTLR with hand-written parser written in F# used in IronJS. Unfortunatelly, he doesn't have fslex/fsyacc version, so there is no direct comparison.

To answer some specific concerns - you can get MSBUILD tasks for running fslex/fsyacc as part of the build, so it integrates quite well. You don't get a syntax highlighting, but I don't think that's such a big deal. It may be slower than OCaml version, but that affects the compilation only when you change the parser - I did some modifications to the F# parser and didn't find the compilation time a problem.

草莓酥 2024-10-31 11:16:09

fslex 和 fsyacc 工具是专门为 F# 编译器编写的,并不适合更广泛的使用。也就是说,借助这些工具,我已经成功地将重要的代码库从 OCaml 移植到 F#,但由于 F# 端完全缺乏 VS 集成(OCaml 与语法优秀集成),这很费力。突出显示、跳转到定义和错误返回)。特别是,我将尽可能多的 F# 代码从词法分析器和解析器中移出。

我们经常需要编写解析器,并要求微软添加对 fslex 和 fsyacc 的官方支持,但我不相信这会发生。

我的建议是,仅当您需要翻译使用 ocamllex 和 ocamlyacc 的大型旧版 OCaml 代码库时,才使用 fslex 和 fsyacc。否则,从头开始编写解析器。

我个人不喜欢解析器组合器库,更喜欢使用类似于 s 表达式解析器的活动模式编写解析器:

let alpha = set['A'..'Z'] + set['a'..'z']
let numeric = set['0'..'9']
let alphanumeric = alpha + numeric

let (|Empty|Next|) (s: string, i) =
  if i < s.Length then Next(s.[i], (s, i+1)) else Empty

let (|Char|_|) alphabet = function
  | Empty -> None
  | s, i when Set.contains s.[i] alphabet -> Some(s, i+1)
  | _ -> None

let rec (|Chars|) alphabet = function
  | Char alphabet (Chars alphabet it)
  | it -> it

let sub (s: string, i0) (_, i1) =
  s.Substring(i0, i1-i0)

let rec (|SExpr|_|) = function
  | Next ((' ' | '\n' | '\t'), SExpr(f, it)) -> Some(f, it)
  | Char alpha (Chars alphanumeric it1) as it0 -> Some(box(sub it0 it1), it1)
  | Next ('(', SExprs(fs, Next(')', it))) -> Some(fs, it)
  | _ -> None
and (|SExprs|) = function
  | SExpr(f, SExprs(fs, it)) -> box(f, fs), it
  | it -> null, it

这种方法不需要任何 VS 集成,因为它只是普通的 F# 代码。我发现它易于阅读且易于维护。我的生产代码的性能已经足够了。

The fslex and fsyacc tools were specifically written for the F# compiler and were not intended for wider use. That said, I have managed to get significant code bases ported from OCaml to F# thanks to these tools but it was laborious due to the complete lack of VS integration on the F# side (OCaml has excellent integration with syntax highlighting, jump to definition and error throwback). In particular, I moved as much of the F# code out of the lexer and parser as possible.

We have often needed to write parsers and have asked Microsoft to add official support for fslex and fsyacc but I do not believe this will happen.

My advice would be to use fslex and fsyacc only if you are facing translating a large legacy OCaml code base that uses ocamllex and ocamlyacc. Otherwise, write a parser from scratch.

I am personally not a fan of parser combinator libraries and prefer to write parsers using active patterns that look something like this s-expression parser:

let alpha = set['A'..'Z'] + set['a'..'z']
let numeric = set['0'..'9']
let alphanumeric = alpha + numeric

let (|Empty|Next|) (s: string, i) =
  if i < s.Length then Next(s.[i], (s, i+1)) else Empty

let (|Char|_|) alphabet = function
  | Empty -> None
  | s, i when Set.contains s.[i] alphabet -> Some(s, i+1)
  | _ -> None

let rec (|Chars|) alphabet = function
  | Char alphabet (Chars alphabet it)
  | it -> it

let sub (s: string, i0) (_, i1) =
  s.Substring(i0, i1-i0)

let rec (|SExpr|_|) = function
  | Next ((' ' | '\n' | '\t'), SExpr(f, it)) -> Some(f, it)
  | Char alpha (Chars alphanumeric it1) as it0 -> Some(box(sub it0 it1), it1)
  | Next ('(', SExprs(fs, Next(')', it))) -> Some(fs, it)
  | _ -> None
and (|SExprs|) = function
  | SExpr(f, SExprs(fs, it)) -> box(f, fs), it
  | it -> null, it

This approach does not require any VS integration because it is just vanilla F# code. I find it easy to read and maintainable. Performance has been more than adequate in my production code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文