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

如何用ANTLR构建支持单选项不重复的查询语法?

解决ANTLR语法中限制to/from/subject仅出现一次的问题

需求回顾

需要构建的ANTLR语法需满足:

  • 支持toAddress、fromAddress、subject三个可选部分
  • 每个部分最多出现一次,顺序不受限制
  • 同时支持纯自由文本输入(无上述三个关键字的内容)

原语法的核心问题

原规则(toAddress | fromAddress | subject)*使用通配符*,会允许同一部分重复出现(比如多次输入to:),违反了"每个部分仅能出现一次"的要求。此外,词法规则NAME和ANYTHING存在定义重叠,会导致词法分析冲突;addressValue的可选定义可能允许无内容的关键字输入(如to:后面空着)。

修正后的完整语法

grammar SearchQuery;

// 主规则:覆盖所有合法的无重复组合,或纯自由文本
searchQueryLang
    : ( toAddress (fromAddress subject? | subject fromAddress?)?
      | fromAddress (toAddress subject? | subject toAddress?)?
      | subject (toAddress fromAddress? | fromAddress toAddress?)?
      )?
    | freeText
    ;

// 各关键字规则,确保后面跟着对应的值
toAddress: TO addressValue;
fromAddress: FROM addressValue;
subject: SUBJECT subjectValue;

// 自由文本:任意非关键字开头的内容
freeText: FREE_TEXT+;

// 词法规则:关键字(忽略大小写)
TO: T O ':';
FROM: F R O M ':';
SUBJECT: S U B J E C T ':';

// 空格跳过
SPACES: [ \u000B\t\r\n] -> skip;

// 地址值:支持邮箱等格式,禁止包含关键字前缀
addressValue: (CHARACTERS)+;

// 主题值:支持带双引号的内容,处理内部不含未转义引号的情况
subjectValue: QUOTED_STRING | CHARACTERS+;

// 通用字符集(排除关键字开头的情况,避免与关键字冲突)
CHARACTERS: ~[ \t\r\n"]+;

// 带引号的字符串
QUOTED_STRING: '"' (~["\\] | ESCAPE_SEQUENCE)* '"';
ESCAPE_SEQUENCE: '\\' ["\\];

// 忽略大小写的字符定义
fragment A: [aA];
fragment B: [bB];
fragment C: [cC];
fragment E: [eE];
fragment F: [fF];
fragment H: [hH];
fragment J: [jJ];
fragment M: [mM];
fragment O: [oO];
fragment R: [rR];
fragment S: [sS];
fragment T: [tT];
fragment U: [uU];

关键修改说明

  1. 主规则重构:通过枚举所有合法的无重复组合,确保to/from/subject每个最多出现一次,且顺序任意。同时保留了空输入的合法性(对应全自由文本的情况)。
  2. 词法规则优化:
    • 合并了原NAME和ANYTHING的重叠定义,用CHARACTERS统一处理通用文本
    • 增加了QUOTED_STRING和转义序列,支持带引号的主题内容
    • 关键字使用片段定义,支持大小写不敏感的输入(如TO:/to:都合法)
  3. 值规则修正:将addressValue改为必填,避免关键字后无内容的无效输入;subjectValue同时支持带引号和普通文本两种格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:05:26