如何在Parsimonious中定义满足必含1个foo、最多1个bar的语法并触发正确解析错误
如何在Parsimonious中定义满足必含1个foo、最多1个bar的语法并触发正确解析错误
我来帮你搞定这个Parsimonious语法的问题!你需要的是必须包含恰好1个foo,同时可以包含0或1个bar,两者顺序任意的规则,而且要让不符合条件的输入直接解析失败对吧?
先说说你原来的语法问题:之前写的(foo / bar)+规则太宽松了——它允许任意数量的foo和bar随便组合,所以才会出现多个bar或者没有foo也能通过的情况,完全不符合你的要求。
下面是调整后的正确语法定义,我会给你逐句解释:
from parsimonious.grammar import Grammar g = Grammar(r""" text = ws* "section" ws* content ws* content = (foo ws* bar?) | (bar ws* foo) foo = ws* "foo" ws* bar = ws* "bar" ws* ws = ~"\s*" """)
规则解释:
text:最外层规则,匹配以section开头的内容,前后允许任意空白,中间必须是合法的content部分content:核心规则,直接枚举所有合法的组合:- 要么是
foo后面跟0个或1个bar(对应foo ws* bar?) - 要么是
bar后面跟恰好1个foo(对应bar ws* foo)
这样就从根源上确保了:必须有1个foo,bar最多只能出现1次,而且两者顺序任意
- 要么是
foo/bar:匹配带前后空白的关键词,允许关键词前后有任意空白ws:匹配任意空白字符(包括空格、换行、制表符等)
测试验证:
现在你再跑测试代码,就会得到你想要的结果:
g.parse("section foo")→ 正常解析(合法:只有foo)g.parse("section foo bar bar")→ 解析失败(非法:多个bar,剩余的bar无法匹配规则)g.parse("section bar")→ 解析失败(非法:缺少必须的foo,没有任何content分支能匹配)g.parse("section bar foo")→ 正常解析(合法:bar+foo的顺序)g.parse("section foo bar")→ 正常解析(合法:foo+bar的顺序)
这样就完美符合你的需求啦!
备注:内容来源于stack exchange,提问作者hm-distro
相关产品推荐
相关产品推荐

