You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaCC配置模式匹配预期令牌时抛出错误求助

解决JavaCC嵌套配置解析的语法错误

当前问题重现

定义的词法模式

| < CONFIGURATION_PATTERN: "(" ("\n")* (" ")* ((<LETTER>)+ " = " (<LETTER> | <DIGIT>)+ ("\n") (" ")*)+  (" ") ")" >
| < CONFIGURATION_SUB_PATTERN: "(" ("\n")* (" ")* ((<LETTER>)+ " = " (<LETTER> | <DIGIT> | <BOOLEAN>)+ ("\n") (" ")*)+  (" ") ")" >

待解析输入

CONFIGURATION (
    INSERTVALUE = 200
    PROPERTIES ( 
        MOVETABLE = false,
        DOWRITE = true
    )
)

报错信息

Parse error: Encountered " "(" "( "" at line 25, column 29.
Was expecting one of:
"SOMETOKEN" ...
"SOMETOKEN2" ...
"SOMETOKEN3" ...
<SOME_PATTERN> ...
<SOME_PATTERN2> ...

不含PROPERTIES嵌套块的输入可正常解析,尝试过调整模式、添加递归词法规则均无效。


问题根源分析

  1. 词法规则无法处理递归嵌套:你把嵌套配置定义成了词法TOKEN,但JavaCC的词法分析器是有限状态机,不支持递归结构(比如括号嵌套),必须用语法规则(递归下降解析)来处理这类嵌套场景。
  2. 强制换行约束不匹配输入:原模式要求每个键值对后必须跟换行符"\n",但实际输入中PROPERTIES后直接跟了(,不符合模式要求,导致匹配中断。
  3. 模式匹配逻辑僵化:原模式只支持平级键值对,没有考虑"值可以是另一个配置块"的情况,无法识别PROPERTIES后面的嵌套结构。

修正方案

1. 拆分词法与语法规则

首先定义基础词法单元,忽略空白字符:

TOKEN :
{
    < LETTER: ["a-zA-Z"] >
    | < DIGIT: ["0-9"] >
    | < BOOLEAN: "true" | "false" >
    | < WHITESPACE: (" " | "\t" | "\n" | "\r")+ > : SKIP  // 忽略所有空白
    | < EQUALS: "=" >
    | < COMMA: "," >
}

2. 定义递归语法规则处理嵌套

用语法规则实现递归解析,支持多层配置嵌套:

// 顶层配置入口
void configuration() :
{}
{
    "CONFIGURATION" "(" (configurationEntry())* ")"
}

// 配置项:可以是普通键值对,也可以是嵌套配置
void configurationEntry() :
{}
{
    // 普通键值对(如 INSERTVALUE = 200)
    <LETTER>+ EQUALS value() (COMMA)?
    // 嵌套配置(如 PROPERTIES (...))
    | <LETTER>+ configuration() (COMMA)?
}

// 合法值类型:字母串、数字、布尔值
void value() :
{}
{
    (<LETTER>)+ | (<DIGIT>)+ | BOOLEAN
}

方案说明

  • 递归语法规则:通过configuration()的递归调用,完美支持多层嵌套的配置结构。
  • 空白自动忽略:通过WHITESPACE的SKIP规则,无需手动处理换行、空格、制表符,简化模式逻辑。
  • 灵活的配置项:支持普通键值对和嵌套配置两种类型,适配输入格式。
  • 可选逗号:允许配置项末尾带逗号,兼容常见配置文件的书写习惯。

内容的提问来源于stack exchange,提问作者Eto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:23:12