无扫描器分析器

时间:2010-02-08 19:45:02

标签: language-agnostic parser-generator

Prologue:虽然解析器识别的语言集(无上下文语法)严格大于扫描程序(常规语法),但大多数解析器生成器都需要扫描程序。

(请不要试图解释它背后的原因,我非常了解它们。)

我见过解析器,不需要像

这样的扫描仪

使用无扫描仪有一些优点:

  • 只有一个概念(无上下文语法)而不是两个
  • 在一个文件中解析多种语言(如HTML / Javascript)
  • 解析没有保留关键字的语言(例如PL/1

通常,使用“变通办法”就像在解析器请求中切换扫描程序一样。

问题:您知道其他任何无扫描器解析器生成器(任何语言)吗?这些是实用的(或纯粹的学术性的)?除了Tomita / GLR之外还有其他方法吗?

数目:

6 个答案:

答案 0 :(得分:11)

另外两个人:

  • Bryan Ford的Parsing Expression Grammars(PEG)不需要扫描仪。高效,懒惰的“packrat解析器”是可选的。我对Lua LPEG版本没有什么经验,它编译成一个高效的字节码机器。非常实用。

  • YAKKER看起来非常有趣,尽管它仍处于释放前的状态。他们正在使用他们声称的对Earley解析算法的有效变体。

我实际上是无扫描器解析器的忠实粉丝;它们极大地简化了配置。温和地说,典型的扫描仪发生器使用起来并不是很有趣。从Lex的手册页:

  

The asteroid to kill this dinosaur is still in orbit.

最后,我对Elkhound没有亲身经历,但我听到的二手报道令人印象深刻。我想说毫无疑问,一些无扫描器解析器生成器非常实用。

答案 1 :(得分:8)

分析器生成器不需要扫描器。但如果你不使用它,你就会非常疯狂。

解析器生成器构建的解析器不关心你提供它们的内容,只要你称它们为令牌。

要构建使用不带扫描程序的解析器生成器,只需将语法定义到字符级别,然后将单个字符作为标记提供给解析器。

这是疯狂的原因是解析是一个比lexing更复杂的活动。您可以将词法分析器构建为有限状态机,它将机器代码转换为“比较并跳转到下一个状态”。对于速度,这真的很难被击败。解析器生成器构造解析器,执行递归下降预测解析(对于大多数LL生成器,如ANTLR)或通过散列,二进制或线性搜索等进行表查找。因此解析器在令牌上花费的能量比词法分析器花费的更多。字符。

如果您将字符作为标记提供给解析器,那么它将在字符上花费相应的能量,而不是相同的词法分析器。如果你处理大量的输入文本,这最终会很重要,无论你是为数以万计的小输入流还是为一些非常大的输入流做的。

相对于设计使用令牌的GLR解析器,所谓的无扫描器GLR解析器会遇到此性能问题。

我的公司构建了一个工具 the DMS Software Reengineering Toolkit,它使用了一个GLR解析器(并且成功地解析了你知道的所有常见语言,以及你没有的许多常见语言,因为它有一个GLR解析器)。我们知道无扫描器解析器,并且由于速度差异而选择不实现它们;我们有一个经典风格(但非常强大)的LEX类子系统,用于定义词法标记。在一个案例中,DMS对XT(一种具有无扫描器GLR解析器的工具)基于工具处理相同输入进行了鼻子对鼻子,DMS的速度似乎是XT包的10倍。公平地说,所做的实验是临时的,不会重复,但因为它符合我的怀疑,我认为没有理由重复它。因人而异。 当然,如果我们想要无扫描,那么,正如我已经指出的那样,很容易用字符终端编写一个语法。

GLR Scannerless解析器有另一个非常好的属性,对大多数人来说无关紧要。您可以为无扫描器解析器提供两个单独的语法,并逐字地连接它们,并且仍然可以获得解析器(通常具有很多歧义)。当你在另一个语言中嵌入一种语言时,这很重要。如果这不是你在做什么,这只是学术上的好奇心。

而且,AFAIK,Elkhound不是无扫描仪的。 (我可能错了)。 (编辑:2/10:看起来我错了。这不是我生命中的第一次:)

答案 2 :(得分:3)

boost::spirit::qi不需要词法分析器,但您可以使用boost::spirit::lex作为前端。从boost::spirit::lex

的介绍
  

事实上,Spirit.Qi允许你写   解析器没有使用词法分析器,解析   直接输入字符流,   在大多数情况下,这就是方法   精神从此被使用   发明。

boost::spirit(原始版本)实际上按照您的要求完成,但已移至boost::spirit::classicspirit::qispirit::lex是精神的新设计,因此我将经典版本排除在外:)

答案 3 :(得分:3)

Waxeye:基于parsing expression grammars(PEGs)的无扫描器解析器。

答案 4 :(得分:1)

抱歉是一个坏死的人。您可以尝试这一点 - .NET的嵌入式PEG / Packrat实现:

http://www.meta-alternative.net/pfdoc.pdf

http://www.meta-alternative.net/mbase.html

答案 5 :(得分:0)

我写了一个“按需扫描”解析器。 这是带扫描器的解析器和无扫描器的解析器之间的一种折衷。

它允许“没有保留的关键字”,并使一种语言可以嵌入/嵌套在另一种语言中。

这种嵌套的一个很好的例子是来自graphviz https://graphviz.gitlab.io/的Dot语法,其中XML / HTML可以嵌入外部图形语言中。

您可以在https://info.itemis.com/demo/agl/editor

上看到我的解析器和点语法的演示。

有关解析器的更多详细信息,请参见https://medium.com/@dr.david.h.akehurst/a-kotlin-multi-platform-parser-usable-from-a-jvm-or-javascript-59e870832a79