编译器中的窄解析 我正在研究一种C++语言编译器(假设我们现在编译C++,不考虑)。到目前为止,从stream到lexer的阶段可能比较窄;解析器调用getToken,这可能会调用getCharacter。这与“广泛”技术形成对比,后者将整个流加载到内存中,然后将流完全转换为令牌,然后再进行解析

编译器中的窄解析 我正在研究一种C++语言编译器(假设我们现在编译C++,不考虑)。到目前为止,从stream到lexer的阶段可能比较窄;解析器调用getToken,这可能会调用getCharacter。这与“广泛”技术形成对比,后者将整个流加载到内存中,然后将流完全转换为令牌,然后再进行解析,c++,parsing,compiler-construction,C++,Parsing,Compiler Construction,现在我有了一个狭窄的lexer和stream,但我想知道是否也可以创建一个狭窄的解析器。特别是使用可重入的LL(1)解析器。在任何情况下,从解析器进入语义分析器(函数语法树、整个文件、单个语句树)的最小单元是什么?解析器将输出一个解析树。解析器应该输出不同的东西吗 更清楚地说: 词法分析器语义分析 lexer将令牌逐个发送到解析器,解析器解析它们。每当解析器请求令牌时,lexer就会提供它。现在我想对语义分析器进行同样的尝试。假设语义分析器正在运行:getTree()。它使解析器充分解析,从而生

现在我有了一个狭窄的lexer和stream,但我想知道是否也可以创建一个狭窄的解析器。特别是使用可重入的LL(1)解析器。在任何情况下,从解析器进入语义分析器(函数语法树、整个文件、单个语句树)的最小单元是什么?解析器将输出一个解析树。解析器应该输出不同的东西吗

更清楚地说: 词法分析器语义分析

lexer将令牌逐个发送到解析器,解析器解析它们。每当解析器请求令牌时,lexer就会提供它。现在我想对语义分析器进行同样的尝试。假设语义分析器正在运行:getTree()。它使解析器充分解析,从而生成可分析的树以进行语义分析。问题是如何确定成功进行语义分析所需的最小树


想一想:也许我在要求一个可重入的语义分析器。

如果您将编译器中的所有数据类型(词素、AST节点、符号表、符号表条目、控制流图节点、生成的三元组)设置为, 根据定义,您将“尽可能早地”从编译器的每个阶段获得下一个阶段的信息

如果您的语言是多线程的,或者您可以伪造它,那么您甚至可能获得一些并行性。目前还不清楚您可以获得多少并行性,因为这些对象中的大多数都很小,并且每个对象上花费的计算可能不足以克服所有调度的开销

(我们这样做是为了一个Java解析器,将符号空间变成未来。这些空间非常大,因此同步成本得到很好的分摊。当读取数千个Java源文件时,这会产生很大的差异)


如果您没有获得太多的并行性,那么可能会因为开销而损失总体性能。一般来说,当您想要提高效率时,您需要对事情进行批处理,以避免“获取下一件事情”中的同步。

我非常确定“黄金解析器”系统也可以在流上工作。。。不确定我是否理解了这个问题。@atlaste我试图在不首先解析整个程序的情况下,通过管道将输出从解析器传递到语义分析器。我想在语法分析器提供给语义分析器时立即尝试从语法分析器获取信息。没有人将整个流加载到内存中,并在继续进行语法分析之前将其全部转换为标记。@EJP,没有,但它是一种公认的方法,属于“广泛”编译。这只是为了举例说明我的意思。附:你不需要lexer黑客。我们来关注一下AST。这是否意味着语义分析器可以逐渐验证AST(小片段)?在这种情况下;AST的碎片有多大。这就是我的意思。使用期货的想法看起来很有希望(双关语的意思),但这并不完全是我的想法;我们只是在争论这些片段的大小以及如何实现未来比特。首先,无论您选择了什么大小的粒度(变量、表达式、语句、块),在将控制权交还给解析器之前,您仍然必须管理解析器在获取该大小片段时处理该大小片段,以及“语义分析器”获取控制权并执行其操作。这就是未来会做的事,,,。。。。您将发现,没有任何真正“整洁”的切入点,语义分析器只需查看您手中的内容。当它必须从树的顶端伸出手时,最好有一个策略来防止它接触到还不存在的东西(C++著名地允许类成员函数引用尚未声明的类成员变量)。即使你交出了整个函数,它们仍然会互相调用。一直向前,确保没有人在可用之前访问某个内容:-}这是人们倾向于在可能的情况下构建整个AST的原因之一:突然,没有人在可用之前访问某个内容:-}显然,人们构建的编译器会像函数一样处理块,只要付出组织上的代价,这就是我一直担心的。语义分析器似乎需要整个AST(或者只是一个功能节点加上一个符号表)来检查语义(但它必须以某种方式阻止未发现的标识符)。我想知道你到底是如何在语义分析器中使用futures的。它更像是从语义分析器调用解析器来获取整个AST,或者这是错误的?