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

使用Antlr4解析PGN走子报错:输入'Ng'匹配Moving_Piece失败

错误原因分析

ANTLR词法分析器遵循最长匹配优先原则:当多个规则都能匹配输入时,优先选择匹配长度最长的;若长度相同,则优先选择先定义的规则。

你的Chars规则定义为[a-zA-Z]*,可以匹配任意长度的字母序列(比如输入Ng时,会被完整匹配为一个Chars token),而Moving_Piece仅能匹配单个大写字母。当输入Ng4时,词法分析器会优先将Ng识别为Chars token,而非拆分为Moving_Piece(N)和Moving_File(g)。后续语法解析时,standard_move规则期望第一个token是Moving_Piece,但实际收到的是Chars,因此触发mismatched input 'Ng' expecting Moving_Piece错误。

另外,Chars规则使用*(允许0个字符)不符合PGN标签的规范(标签名不能为空),但这不是当前错误的直接原因。

解决方案

使用ANTLR的**词法模式(Lexer Modes)**区分标签上下文和走子上下文,让Chars等标签相关规则仅在[...]内部生效,避免与走子规则冲突。修改后的语法如下:

grammar PGN;

// 解析规则
annotations: annotation+;
annotation  : Open_Bracket tag value Close_Bracket Newline ; 
value: String;
tag: Chars;
move_time: Move_time Newline;
move_number: Move_Number Newline;
standard_move: moving_Piece moving_File moving_Rank Newline;
moving_Piece: Moving_Piece ;
moving_File: Moving_File;
moving_Rank: Moving_Rank;

// 词法规则 - 默认模式(走子相关规则)
Moving_Piece: ('K'|'Q'|'R'|'B'|'N') ;
Moving_File: [a-h];
Moving_Rank: [1-8];
Move_Number: [0-9]+ '.';
Move_time: '{[%emt' ~']'* ']}'; // 精准匹配时间注释,避免非贪婪匹配歧义
Open_Bracket : '[' -> pushMode(TAG_MODE); // 进入标签模式
Newline: [\n]; 
WHITESPACE : ' ' -> skip ;

// 词法模式 - 标签内部
mode TAG_MODE;
Chars: [a-zA-Z]+; // 修改为+,确保标签名非空
String : '"' ~["]* '"';
Close_Bracket : ']' -> popMode; // 回到默认模式
TAG_WHITESPACE : ' ' -> skip ;

修改说明

  1. 新增TAG_MODE词法模式:仅在遇到[时进入该模式,遇到]时退出,确保标签相关规则仅在[...]内部生效。
  2. 调整Chars规则为[a-zA-Z]+:符合PGN标签名非空的规范。
  3. 优化Move_time匹配规则:使用~']'*替代.*?,避免ANTLR词法规则中非贪婪匹配的歧义,精准匹配{[%emt...]}格式的时间注释。

修改后,解析Ng4时,词法分析器会在默认模式下将N识别为Moving_Piece、g识别为Moving_File、4识别为Moving_Rank,符合预期解析结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 19:23:15