Python SLY开发简单DSL遇SKIN token语法错误 解析结果异常
问题根因
报错和结果不符合预期由两个核心问题导致:
- 语法规则缺少递归定义:现有规则仅能匹配「单个动物名+单个属性」的结构,解析完
{MAMMALS}后的第一个BLOOD = WARM后,没有规则能承接后续的SKINtoken,直接触发语法错误。 - 状态变量复用逻辑错误:全局共用同一个
self.dict_attribute字典存储所有动物的属性,就算语法跑通,后续解析的动物属性会覆盖之前的内容,所有动物条目最终都会指向同一个字典对象,结果完全错误。
修正方案
1. 词法分析器说明
你现有Lexer逻辑基本可用,SLY会优先匹配排在前面的token,只要保证关键字(ANIMALS/BLOOD/SKIN/BREATHE)定义在VALUE正则之前,就不会出现关键字被误识别为VALUE的问题,原有Lexer无需大改。
2. 重写语法分析器规则
补充递归规则支持连续匹配多个动物块、多个属性,同时通过规则返回值传递解析结果,避免全局变量复用导致的覆盖问题:
from sly import Parser class ConfigParser(Parser): tokens = ConfigLexer.tokens def __init__(self): self.config = dict() # 顶层规则:匹配ANIMALS关键字后接的所有动物块 @_("ANIMALS animal_block_list") def start(self, p): pass # 动物块列表:递归匹配多个动物条目 @_("animal_block animal_block_list") def animal_block_list(self, p): pass @_("") def animal_block_list(self, p): # 空规则,匹配列表终止场景 pass # 单个动物块:动物名 + 该动物下的所有属性 @_("ANIMAL_NAME attr_list") def animal_block(self, p): animal_name = p.ANIMAL_NAME.strip("{}") self.config[animal_name] = p.attr_list # 属性列表:递归匹配多个属性键值对 @_("attr attr_list") def attr_list(self, p): p.attr_list.update(p.attr) return p.attr_list @_("") def attr_list(self, p): # 空规则,属性列表终止时返回空字典 return dict() # 三类属性的匹配规则,统一返回键值对字典 @_("BLOOD ASSIGN VALUE") def attr(self, p): return {p.BLOOD: p.VALUE} @_("SKIN ASSIGN VALUE") def attr(self, p): return {p.SKIN: p.VALUE} @_("BREATHE ASSIGN VALUE") def attr(self, p): return {p.BREATHE: p.VALUE} def get_config(self): return self.config
运行结果
用原有测试代码运行修正后的解析器,可得到符合预期的输出:
{ "MAMMALS": { "BLOOD": "WARM", "SKIN": "FUR", "BREATHE": "LUNGS" }, "FISH": { "BLOOD": "COLD", "SKIN": "SCALY", "BREATHE": "GILLS" } }
注:你给出的预期结果里的
WAMR属于笔误,输出会和实际输入的WARM保持一致。
内容的提问来源于stack exchange,提问作者Iwan Prayitno
相关产品推荐
相关产品推荐

