作为有限状态机的通用语言解析器

Posted

技术标签:

【中文标题】作为有限状态机的通用语言解析器【英文标题】:General language parser as a finite state machine 【发布时间】:2016-07-21 18:00:31 【问题描述】:

我为通用语言编写了性能非常低的下降递归解析器(开源,用于 EBNF 语法)。我想通过重写解析器来修复它的性能。

我阅读了有关词法分析、LL、LR、LALR 解析器和 LL(*) 等修改的内容,我阅读了 Dragon Book 的前 3 章(关于词法分析器和解析器),我探索了 ANTLR 等开源项目。

我想知道为什么没有描述这个算法。也许方法不对,我不知道。或者我重新发明了***。

假设我们有语法(e: end of file):

A: B? B 1? e
B: 0 | 1

转换后的语法:

A: B B 1 e | B B e | B e
B: 0 | 1

可能的情况:

[01] [01] [1] [e]
[01] [01] [e]
[01] [e]

我们可以构建类似 FSM 的东西:

Symbol #0:

[01]: continue

Symbol #1:

[01]: continue
[e]: parse as "B e"

Symbol #2:

[1]: parse as "B B 1 e"
[e]: parse as "B B e"

它将在 O(N) 时解析令牌流。对于真正的语法,它可以修改为不仅仅是简单的 FSM,但仍然是 O(N)。

所以我有这些问题:

    这种方法能产生积极的结果吗?

    与LL、LR等解析器有关系吗?目前我对那些算法还没有足够的了解,没有尝试过。

    哪种解析算法对于正确的输入字符串更快?我只对解析正确的输入字符串感兴趣,因为我正在制作与 IDE 一起使用的代码生成工具,它可以自己报告错误。所以我需要最快速的算法来完成这个非常具体的任务。

谢谢。

更新:

我最终使用了 ANTLRv4,我找到了我的语言 (Swift) 的目标和运行时,我非常满意。

【问题讨论】:

您在转换后的语法中忘记了B 1 e。但不清楚你在问什么。众所周知,上下文无关语言集是常规语言集的超集。您是否在问如何识别给定的语法实际上是否可以识别常规语言? ***.com/questions/559763/… 如果您希望有人告诉您是否正在重新发明一种算法,您应该尝试在 Stack Exchange 的计算机科学分支上询问。 FWIW,LR 解析使用状态机推广到下推自动机。 【参考方案1】:

LALR(k) 是 O(N),如果您将其简化为机器代码以“将状态中的令牌分支到下一个状态,堆叠令牌值”,则可以闪电般快速。 (见本文:https://web.archive.org/web/20170809025652id_/http://www.genesishistory.org/content/ProfPapers/VF-LRParsing.pdf)

目前还不清楚通过尝试发展自己的想法会获得什么;怎么会比那更快?

[最重要的不是解析;它通常是您可以构建词位的速率,尤其是。消除空白]。

如果您认真对待构建工具,则应该使用该工具并采用您可以获得的最佳技术,这样您就不必发明它们。

如果您坚持发明新技术,那么您最终将获得补丁/增强/调整它们,而永远不会有时间构建工具。也许你有一个好主意。您必须投入更多精力才能找到答案。

请确保您知道自己要实现的目标。

【讨论】:

我认为解析应该比标记化慢。哇。那改变了一切。所以我不必优化解析器。我必须使用一些好的算法(例如 LALR(k))并优化词法分析器。 解析通常比词法分析要慢一点(词法分析器不会将非终结符推入堆栈)。问题是词法分析器正在处理字符实体;解析器正在处理词法实体。作为一个草率的措施,您可以想象解析器对词法分析器执行的每 10 个实体操作执行一个实体操作。如果两者都付出相同的努力,那么成本占主导地位的是词法分析器。 我重写了我的解析器并使用了 LALR,但我只是很有趣。理论上是否可以在不堆叠非终结符的情况下生成状态机?如果我们有 N 个标记和 M 个非终结符,LARL 的复杂度可以是 O(N*M),理论上是否有可能得到 O(N*1)? 你可以做这个思想实验:对于通过堆栈解析器的每条路径,生成一个单独的分支。对于有限的输入,您可以这样做,并可能产生一组有限的分支。对于具有实体列表的任何语法,您可能会在分支数量上得到指数级增长,因此这似乎不是一个好方法。如果您可以这样做,您将拥有一个非常快速的解析器...但现在您会发现您的编译器还需要做其他事情,而且这么快可能不会让您买账整体性能上很多。所以,指数空间,小程序,没有收益......不。 @artyom.razinov 我一直在考虑一个双向词法分析器,因此您可以在匹配失败时向后运行词法分析器,而不是堆叠非终端。

以上是关于作为有限状态机的通用语言解析器的主要内容,如果未能解决你的问题,请参考以下文章

状态机的Go语言实现版本

试试用有限状态机的思路来定义javascript组件

如果在设计有限状态机时,未使用状态的下一个状态设置为初始状态,这种方法称为最小状态( )接近?

FSM有限状态机的实现

有限状态机的状态编码风格主要有哪三种

(有限)状态机