如何在JavaCC中将字符串变量与自定义令牌进行匹配?
在JavaCC中匹配字符串变量与自定义令牌
要实现你想要的逻辑,核心是理解JavaCC的令牌定义是词法分析阶段用于识别输入流中的标记,而内存中的字符串变量需要用Java的正则API来匹配——我们可以复用令牌的正则规则来做到这一点,具体步骤如下:
1. 先定义你的FUNCTIONNAME令牌
首先在你的.jj文件里,按照JavaCC的语法定义好FUNCTIONNAME令牌的匹配规则,这里用常见的标识符规则做示例,你可以换成自己的正则:
TOKEN : { <FUNCTIONNAME: [a-zA-Z_][a-zA-Z0-9_]*> }
2. 复用令牌正则匹配字符串变量
因为JavaCC不会直接暴露令牌的匹配逻辑给Java代码,我们需要把令牌的正则表达式拿出来,用Java的Pattern和Matcher来匹配字符串x。
为了避免重复维护正则(修改令牌规则时不用再改Java代码),推荐把正则定义成共享常量:
步骤2.1:定义共享正则常量
在.jj文件的开头,用Java代码块定义常量:
{ // 把FUNCTIONNAME的正则抽成常量,同时供令牌定义和Java代码使用 private static final String FUNCTIONNAME_REGEX = "[a-zA-Z_][a-zA-Z0-9_]*"; }
步骤2.2:修改令牌定义引用常量
这样令牌规则可以直接用这个常量,避免重复写正则:
TOKEN : { <FUNCTIONNAME: <FUNCTIONNAME_REGEX>> }
步骤2.3:在Java代码中匹配字符串
现在你就可以在需要判断的地方,用这个常量编译的Pattern来匹配字符串x了:
String x = ...; // 你的字符串变量 Matcher matcher = Pattern.compile(FUNCTIONNAME_REGEX).matcher(x); if (matcher.matches()) { // 匹配成功后的逻辑 System.out.println(x + " 是合法的FUNCTIONNAME"); }
关键说明
为什么不能直接用<FUNCTIONNAME>在Java代码里做判断?因为<FUNCTIONNAME>是JavaCC词法分析器用来扫描输入流、识别令牌的语法,它只能处理输入流中的字符序列,不能直接匹配内存中已有的字符串变量。所以必须通过复用正则规则,用Java原生的正则API来实现需求。
内容的提问来源于stack exchange,提问作者Ryan Grainger
相关产品推荐
相关产品推荐

