Language agnostic 无扫描分析器生成器
序言:尽管解析器识别的语言集(上下文无关语法)严格大于扫描器(常规语法),但大多数解析器生成器都需要扫描器 (请不要试图解释背后的原因,我很清楚) 我见过解析器,它不需要像这样的扫描仪Language agnostic 无扫描分析器生成器,language-agnostic,parser-generator,Language Agnostic,Parser Generator,序言:尽管解析器识别的语言集(上下文无关语法)严格大于扫描器(常规语法),但大多数解析器生成器都需要扫描器 (请不要试图解释背后的原因,我很清楚) 我见过解析器,它不需要像这样的扫描仪 (可选,Tomita/GLR) (Tomita/GLR) (Tomita/GLR) 不使用扫描仪有某些优点: 只有一个概念(上下文无关语法)而不是两个 在一个文件中解析多种语言(如HTML/Javascript) 解析没有保留关键字的语言(如) 通常,使用“变通方法”就像根据解析器的请求切换扫描器一样 问
- (可选,Tomita/GLR)
- (Tomita/GLR)
- (Tomita/GLR)
- 只有一个概念(上下文无关语法)而不是两个
- 在一个文件中解析多种语言(如HTML/Javascript)
- 解析没有保留关键字的语言(如)
- 借
- 通过解析表达式语法(用于Lua)
- 借
- 借
- 借
- 不需要lexer,尽管您可以将其用作前端。从介绍
boost::spirit::lex
:
事实上,灵气允许你写作
不使用lexer的解析器,解析
直接输入字符流,
在大多数情况下,这是一种方式
Spirit自发布以来一直在使用
发明
boost::spirit
(原始版本)实际上可以完全按照您的要求工作,但它已被移动到boost::spirit::classic
<代码>spirit::qi,spirit::lex
是spirit的新设计,所以我省略了经典版本:)解析器生成器不需要扫描仪。但是如果你不使用它,你会非常疯狂
解析器生成器构建的解析器不关心您向它们提供什么,只要您将它们称为令牌
要使用不带扫描器的解析器生成器进行构建,只需将语法定义到字符级别,并将单个字符作为标记提供给解析器
这种做法之所以疯狂,是因为解析比词法分析更复杂。您可以将lexer构建为有限状态机,将其转换为机器代码,就像“比较并跳转到下一个状态”。就速度而言,这真的很难打败。解析器生成器构造的解析器可以执行递归下降预测解析(对于大多数LL生成器,如ANTLR),或者通过哈希、二进制或线性搜索等进行表查找。因此,解析器在标记上花费的精力要比词法分析器在字符上花费的精力多得多
如果您将字符作为标记提供给解析器,那么它将相应地在字符上花费比等效lexer更多的精力。如果你处理了大量的输入文本,不管你是为了无数的小输入流还是为了几个真正大的输入流,这最终都会很重要
与设计为使用令牌的GLR解析器相比,所谓的无扫描GLR解析器存在此性能问题
我的公司构建了一个使用GLR解析器的工具(并且成功地解析了所有你知道的常见语言和很多你不知道的奇怪语言,因为它有一个GLR解析器)。我们知道无扫描解析器,并选择不实现它们,因为速度差;我们有一个经典风格(但非常强大)的类LEX子系统,用于定义词法标记。在一个例子中,DMS与一个处理相同输入的基于XT(无扫描GLR解析器的工具)的工具针锋相对,DMS的速度似乎是XT包的10倍。公平地说,所做的实验是临时性的,没有重复,但由于它符合我的怀疑,我认为没有理由重复它。YMMV。
当然,如果我们想实现无扫描,那么,正如我已经指出的,用字符终端编写语法非常容易
GLR无扫描解析器还有一个非常好的特性,这对大多数人来说并不重要。对于一个无扫描解析器,您可以使用两个单独的语法,并将它们逐字连接起来,仍然可以得到一个解析器(通常有很多歧义)。当您构建一种嵌入到另一种语言中的语言时,这非常重要。如果这不是你正在做的,这只是一个学术好奇心
而且,阿福,艾尔康德并不是没有扫描能力的。(这一点我可能错了)。
(编辑:2/10:看起来我错了。这不是我有生以来第一次:)另外两个:
- 布莱恩·福特的解析表达式语法(PEG)不需要扫描仪。高效、懒惰的“packrat解析器”是可选的。我对Lua版本只有很好的经验,它可以编译成高效的字节码机器。很实用
- 看起来非常有趣,尽管它显然仍处于预发布状态。他们正在使用他们声称是Earley解析算法的有效变体
最后,我个人没有与埃尔克胡德打交道的经验,但我听到的二手报道令人印象深刻。我想说,毫无疑问,一些无扫描解析器生成器非常实用。很抱歉发了一篇帖子。您可以试一试-用于.NET的可嵌入PEG/Packrat实现:
:基于(PEG)的无扫描解析器。我已经编写了一个“按需扫描”解析器。 它是带扫描程序的解析器和无扫描程序的解析器之间的一种折衷 它允许“无保留关键字”,并允许一种语言嵌入/嵌套在另一种语言中 这种嵌套的一个很好的例子是graphviz中的点语法,其中XML/HTML可以嵌入到外部图形语言中 您可以看到我的解析器和