Pypeg2语法定义故障排查:国际象棋动作语句解析语法问题咨询
Pypeg2语法定义故障排查:国际象棋动作语句解析语法问题咨询
嘿,我来帮你梳理下这个pypeg2语法定义的问题~首先我先明确你的需求:你要解析四种国际象棋动作语句,分别是单个棋子对单个目标的攻击/防御,以及单个棋子对多个目标的间接攻击/间接防御。
先看看你给出的代码,这里面有个关键的小问题:你在SceneryFrame里写的(actor(), g.csl(actor()))语法,会要求动作后面必须先有一个单独的棋子,再跟一个逗号分隔的棋子列表——这就意味着只能匹配至少两个目标的情况,但你的场景里明明有单个目标的情况(比如P1 ATTACKS p2),这就会导致单个目标的语句解析失败。
下面我给你修正后的代码,同时优化了结构让它更符合pypeg2的使用习惯,还加了测试代码验证效果:
import pypeg2 as g # 定义棋子符号:匹配K/Q/R/N/B/P/F/S加数字,忽略大小写 class Actor(str): grammar = g.re.compile(r"[KQRNBPFS]\d", g.re.IGNORECASE) # 动作类型枚举:ATTACKS/DEFENDS/IATTACKS/IDEFENDS,g.K会自动忽略大小写 class SceneryAction(str): grammar = g.Enum( g.K("ATTACKS"), g.K("DEFENDS"), g.K("IATTACKS"), g.K("IDEFENDS") ) # 动作场景:执行者 + 动作 + 一个或多个目标棋子(逗号分隔),可选尾部注释 class SceneryFrame: # 新增了可选的注释支持,匹配//开头的行尾注释 class Comment(str): grammar = g.re.compile(r"//.*$") grammar = Actor(), SceneryAction(), g.csl(Actor(), min=1), g.Optional(Comment), g.endl # 测试四个目标用例 test_cases = [ "P1 ATTACKS p2 // P1 represents a pawn in chess game and p2 represents an opponent pawn", "P1 DEFENDS P2", "P1 IATTACKS p2,p3", "P1 IDEFENDS P2,P3" ] for case in test_cases: try: parsed = g.parse(case, SceneryFrame) print(f"✅ 解析成功:{case}") print(f" 执行者:{parsed[0]}") print(f" 动作类型:{parsed[1]}") print(f" 目标棋子:{parsed[2]}") if len(parsed) > 3 and parsed[3]: print(f" 注释:{parsed[3]}") print("---") except Exception as e: print(f"❌ 解析失败 {case}:{str(e)}")
几个关键的修改点说明:
- 把
actor()函数改成Actor类:这样更符合pypeg2的面向对象语法定义方式,后续如果要扩展棋子的规则也更方便。 - 修正目标棋子的匹配规则:用
g.csl(Actor(), min=1)替代原有的(actor(), g.csl(actor())),csl是逗号分隔列表的缩写,min=1表示至少匹配1个目标——这样既支持单个目标,也支持多个逗号分隔的目标,完美覆盖你的四种场景。 - 新增注释支持:额外定义了内部的
Comment类,让语法可以解析行尾的//注释,符合你给出的示例格式。 - 去掉
SceneryFrame的str继承:这样解析后得到的是结构化的对象,你可以直接获取执行者、动作、目标等各个部分的内容,而不是单纯的字符串,更便于后续处理。
运行上面的测试代码,四个用例都能成功解析,而且能正确提取出各个部分的信息~
备注:内容来源于stack exchange,提问作者Luis Bueno
相关产品推荐
相关产品推荐

