Javacc如何使扫描器和解析器能够访问变量

Javacc如何使扫描器和解析器能够访问变量,java,javacc,Java,Javacc,我正在尝试创建一个包含所有函数名的映射。我可以在扫描阶段或解析阶段执行此操作,但似乎无法使两个阶段都可以访问相同的变量 我需要的是在开始解析之前将所有函数名保存在映射中,因为函数可以在调用它的点下方声明。所以我需要检查这个函数是否存在 我已经尝试使用token mgr声明,它允许我在每次看到地图时将标记添加到地图中。但是我需要解析器看到funcs变量,这样它就可以检查函数是否存在 TOKEN_MGR_DECLS : { public static Map funcs =

我正在尝试创建一个包含所有函数名的映射。我可以在扫描阶段或解析阶段执行此操作,但似乎无法使两个阶段都可以访问相同的变量

我需要的是在开始解析之前将所有函数名保存在映射中,因为函数可以在调用它的点下方声明。所以我需要检查这个函数是否存在

我已经尝试使用token mgr声明,它允许我在每次看到地图时将标记添加到地图中。但是我需要解析器看到funcs变量,这样它就可以检查函数是否存在

    TOKEN_MGR_DECLS : {
        public static Map funcs = new HashMap();
    }
    TOKEN : { 
       <FNAME: (["A"-"Z"])+ > { funcs.put(matchedToken.image, "..");}
    }
TOKEN\u MGR\u DECLS:{
public static Map funcs=new HashMap();
}
令牌:{
{funcs.put(matchedToken.image,“…”;}
}
这是我得到的最接近的一个,我在.jj文件中尝试了一个全局变量,就在PARSER_BEGIN(..)下面,并且在main函数中声明了它。这两种情况都会导致在尝试向映射添加函数名时出现“找不到符号”错误


感谢您的帮助。

首先,我要说的是,我建议不要在解析器和词法分析器之间共享任何变量。这是因为lexer可以远远领先于解析器,这意味着:

  • 如果变量是由lexer编写并由解析器读取的,那么在解析器读取时,该信息可能已过期(即被覆盖)

  • 如果变量是由解析器编写并由lexer读取的,那么lexer需要的信息可能不是在lexer需要时由解析器编写的

也就是说。如果你需要的话。这里有一个方法。在令牌管理器中声明变量,如下所示

TOKEN_MGR_DECLS : {
    Map funcs = new HashMap();
}
然后,在解析器中,您可以作为
token\u source.funcs
访问变量


如果使用
STATIC=true
选项,那么变量应该是
STATIC

,以明确您想要了解javacc解析器的流程

实际的JavaCC进程从parser部分开始,该部分调用TokenManager,通过调用getNextToken()方法将令牌返回给进程。哪个实习生调用字符流(SimpleCharStream或JavaCharStream)将字符逐个返回给TokenManager

   Parser
    /|\
     | getNextToken()
    \|/
TokenManager
    /|\
     | readChar()
    \|/
SimpleCharStream

请记住,扫描和解析是在同一过程中完成的。