解析器生成器不需要扫描程序。但如果您不使用扫描程序,那么您就相当疯狂。
由解析器生成器构建的解析器不关心您输入什么,只要您称其为标记即可。
如果要在没有扫描程序的情况下使用解析器生成器,请将语法定义到字符级别,并将单个字符作为标记提供给解析器。
这种做法之所以疯狂,是因为解析比词法分析更复杂。您可以将词法分析程序构建为有限状态机,这些有限状态机基本上会转换成“比较并跳转到下一个状态”的机器代码。就速度而言,这很难被超越。解析器生成器构造的解析器则执行递归下降预测解析(对于大多数LL生成器,例如ANTLR),或通过哈希、二进制或线性搜索等进行表查找。因此,与字符词法分析相比,解析器对标记的处理要花费更多的能量。
如果将字符作为标记提供给解析器,则解析器会花费与等效词法分析程序相比更多的能量来处理字符。如果您处理大量输入文本,这最终会产生影响,无论是在数百万个小输入流还是在几个非常大的输入流上进行。
所谓的无扫描GLR解析器相对于设计用于使用标记的GLR解析器而言具有这种性能问题。
我的公司开发了一款工具,DMS软件重构工具包,它使用GLR分析器(并成功解析了您知道的所有常见语言和许多您不知道的奇怪语言,因为它具有GLR分析器)。我们知道无扫描仪解析器,但由于速度差异,我们选择不实现它们,我们拥有经典风格(但极其强大)的类似LEX子系统来定义词汇标记。在DMS与处理相同输入的基于XT(具有无扫描仪GLR分析器的工具)的工具进行对比的一个案例中,DMS似乎比XT包快10倍。公平地说,所做的实验是临时的而未被重复,但与我的怀疑相匹配,我认为没有理由再次进行测试。YMMV。
当然,如果我们想进入无扫描仪领域,那么使用字符终端符号编写语法就相当容易了,正如我已经指出的那样。
GLR无扫描仪解析器确实具有另一个对大多数人无关紧要但非常好的属性。您可以针对无扫描仪解析器编写两个单独的语法,并将它们直接连接起来,仍然可以获得一个解析器(通常具有许多歧义)。当您正在构建嵌入在另一种语言中的语言时,这很重要。如果这不是您正在进行的操作,则这只是一种学术好奇心。
至于Elkhound是否无扫描仪,据我所知,不是。(编辑:2/10:看起来我错了。这不会是我生命中的第一次错误:)
<testarea></textarea>
中,甚至空格也很重要。当遇到<textarea>
时,可以动态地交换扫描器,但我认为这是一种丑陋的hack。(SableCC支持此功能) - Meinersbur