Antlr4 控制前瞻深度或将令牌源与令牌消耗同步

Antlr4 控制前瞻深度或将令牌源与令牌消耗同步,antlr4,Antlr4,我正在将SystemVerilog语法从ANTLR2.7.7移植到ANTLR4.7 SystemVerilog从Verilog继承了大量指令。它们几乎可以出现在源代码的任何地方。因此,它们不能由 解析器。有些是由lexer解释的,永远不会深入(控制源代码加密),有些是用于预处理器(宏、条件编译等),但也有一些超出了该阶段。这些需要解析器和处理它们的直接令牌源之间的双向通信。当解析器遇到可能受这些指令影响的构造时(当访问者用于操作时,解析器需要请求这些信息以将其作为上下文的一部分记住),解析器会询

我正在将SystemVerilog语法从ANTLR2.7.7移植到ANTLR4.7

SystemVerilog从Verilog继承了大量指令。它们几乎可以出现在源代码的任何地方。因此,它们不能由 解析器。有些是由lexer解释的,永远不会深入(控制源代码加密),有些是用于预处理器(宏、条件编译等),但也有一些超出了该阶段。这些需要解析器和处理它们的直接令牌源之间的双向通信。当解析器遇到可能受这些指令影响的构造时(当访问者用于操作时,解析器需要请求这些信息以将其作为上下文的一部分记住),解析器会询问这些指令的状态。另一方面,令牌源在处理这些指令时需要向解析器询问当前作用域,因为有些指令不能在任何单元内使用

考虑以下示例:

`timescale 1ns/1ps
module m;
  `resetall
  initial $printtimescale; //Time scale of (m) is 1ns / 1ps
endmodule
在旧的ANTLR2中,在执行源代码和解析器之间通信的操作之前,我确切地知道何时以及从源代码中提取多少令牌。这一知识意味着不需要复杂的同步,令牌源可以在指令到达时解释指令,解析器可以在需要时请求指令状态,因为只要不使用语法谓词,令牌的创建和使用就会并行进行

据我所知,ANTLR4可以在执行任何操作之前提取任意数量的令牌。若解析器在处理模块头时提取过多的令牌,它将导致令牌源“执行”resetall指令,从而取消以前使用的时间刻度

如果没有其他选项,解决问题的方法很可能是让令牌源记住与它遇到的指令相关的令牌,并将它们与相关操作一起打包到某个函子。一旦它需要向解析器发出实际的标记,并且至少有一个函子尚未发出,它将创建一个正则标记的子类,该子类将在正则标记的基础上记住该函子。通过这种方式,解析器可以做任何它想做的事情——预测解析路径并从令牌源中提取新令牌——到目前为止,不会执行任何与指令相关的操作。最后一位是重新定义标准
消费
例程。它必须询问令牌是否属于“carying directive action”类型,并执行该操作——这样,指令操作(以及指令状态)将与令牌消费同步,而不是与令牌创建同步

问题是我目前无法测试上述解决方案,因为直到最终令牌发射点的所有内容都在新旧解析器之间共享。只有创建实际令牌的最后一位是不同的。这意味着,为了测试解决方案,我还需要将其应用于旧的解析器

最后,问题是:

  • 在ANTLR4中是否需要变通方法,或者是否有一些可靠的技术来控制前瞻,至少对于选定的规则是这样
  • 这种变通办法行得通吗?我最关心的是该解决方案的两个要素:重新定义
    消费
    是否足够,或者是否还有其他一些例程会干扰令牌流,这些例程也需要处理?此外,如果解析器内部使用其他令牌类重新创建流f.e.中的令牌,那么在这种情况下,我的特殊函子数据将丢失(这可能只是我的妄想症)