将手写解析器转换为 ANTLR
Convert Hand-Written Parser to ANTLR
我目前正在研究一种编程语言,大约 9 个月来我一直在使用手写的词法分析器和解析器。我现在要做的是将其转换为 ANTLR 解析器。 parser system of the compiler 的结构大致如下:
- 将输入流转换为双向链接的标记列表(由词法分析器完成)。
- 设置某种具有变量
currentParser
并且可以执行 reparse()
或 skip(n tokens)
之类的助手
- 开始解析
Parser
的特定子类(使用方法 parse(ParserManager pm, Token token)
)
- 根据当前标记,当前解析器可能
push
new Parser
在 解析器堆栈 上,或者从解析器堆栈弹出自身,这意味着堆栈中的下一个解析器将解析下一个标记。
- 整个编译器建立在像
ITypeList
这样的接口上,这些接口也作为单个参数传递给解析器。
一个例子 Parser
子类是 TypeParser
public TypeParser(ITyped typed) { ... }
或TypeListParser
:
public TypeListParser(ITypeList typeList) { ... }
这个简单的结构适用于每个 单个Parser
实现。有没有办法在 ANTLR 中使用这些接口?
您的描述看起来像是解析器组合器模式的变体。
要将这样的设计转换为 ANTLR:
- 将令牌映射到 ANTLR 令牌。这很容易,因为 ANTLR-Tokens 的界面和您的令牌是相似的。它们可能被包装或映射。
- 将每个解析器子类映射到一个 ANTLR 解析规则(或多个规则)。您将需要此解析器中的操作和语义谓词,因为您的解析器不仅仅由语法驱动
ANTLR4不创建AST,所以你的AST节点可以完全回收,你只需要从语法上决定如何创建AST:
- 将 AST 创建为语法(动作)的一部分,这很有效,但会使您的语法严重依赖 AST-类 和实现语言
- 要在第二遍中使用解析树访问者创建 AST,这会分离解析和 AST 构造,但会构建中间解析树,这会花费一些时间。
我目前正在研究一种编程语言,大约 9 个月来我一直在使用手写的词法分析器和解析器。我现在要做的是将其转换为 ANTLR 解析器。 parser system of the compiler 的结构大致如下:
- 将输入流转换为双向链接的标记列表(由词法分析器完成)。
- 设置某种具有变量
currentParser
并且可以执行reparse()
或skip(n tokens)
之类的助手
- 开始解析
Parser
的特定子类(使用方法parse(ParserManager pm, Token token)
) - 根据当前标记,当前解析器可能
push
new Parser
在 解析器堆栈 上,或者从解析器堆栈弹出自身,这意味着堆栈中的下一个解析器将解析下一个标记。 - 整个编译器建立在像
ITypeList
这样的接口上,这些接口也作为单个参数传递给解析器。
一个例子 Parser
子类是 TypeParser
public TypeParser(ITyped typed) { ... }
或TypeListParser
:
public TypeListParser(ITypeList typeList) { ... }
这个简单的结构适用于每个 单个Parser
实现。有没有办法在 ANTLR 中使用这些接口?
您的描述看起来像是解析器组合器模式的变体。
要将这样的设计转换为 ANTLR:
- 将令牌映射到 ANTLR 令牌。这很容易,因为 ANTLR-Tokens 的界面和您的令牌是相似的。它们可能被包装或映射。
- 将每个解析器子类映射到一个 ANTLR 解析规则(或多个规则)。您将需要此解析器中的操作和语义谓词,因为您的解析器不仅仅由语法驱动
ANTLR4不创建AST,所以你的AST节点可以完全回收,你只需要从语法上决定如何创建AST:
- 将 AST 创建为语法(动作)的一部分,这很有效,但会使您的语法严重依赖 AST-类 和实现语言
- 要在第二遍中使用解析树访问者创建 AST,这会分离解析和 AST 构造,但会构建中间解析树,这会花费一些时间。