本项目起初是一个意外,或者说是一个实验。有时候,这两者之间的差别非常小。它起源于用来教读者如何编写LL解析器的代码库。 目标是LL(k)解析,这是迈向那个目标的一步。在使用源代码演示解析时,发现它也非常适合进行实验。 它在DebugLL1Parser和DebugTokenizer中使用字符串,因此在调试会话中非常容易检查。 一直将其作为一个平台来实验LL(k)算法。
这个项目本身作为一个解析器生成器也很有用,因为它为LL(1)语法生成高效的表解析器。它优于Newt,并且更可靠。语法略有改进,属性系统已经扩展。 总体上,它使用相同的语法系统。更多关于Newt的信息可以在这里找到,但不要使用Newt。使用这个。
请注意,这个解析器仍然是LL(1)。为了使用这个代码库不仅仅是生成解析器,需要熟悉在这里使用的代码库,因为这只是一个演变。 语法格式正如所说的,类似于Newt。这里是结构。
这个代码库包含了几个项目:
DebugLL1Parser和DebugTokenizer类仅使用字符串作为内部信息,因此在调试器中看到它们的行为很容易。使用这些来原型化解析器和词法分析器算法的更改,然后再将这些更改固化到LL1TableParser和TableTokenizer类中。 Cfg和Ebnf都是相当庞大的,包含操作CFG和EBNF文档的API。后者公开了一个完整的DOM对象模型。
lltree的Main()函数向展示了如何执行一个基本的解析,而不需要生成一个解析器。一切都是在运行时进行的。
生成一个解析器有点复杂,但使用一个生成的解析器比使用运行时的解析器更容易。要初始化一个,只需要做以下事情:
var parser = new MyParser(new MyTokenizer(inputSource));
使用它们的方式完全相同,除了明显的性能差异。然而,运行时解析器的运行速度几乎和生成的解析器一样快,但调试解析器显然要慢得多。