PetitParser无法解析带括号的FHIRPath表达式问题求助
问题原因及解决方案
核心原因
说白了就是解析规则的优先级和递归逻辑搞反了:
- 你原来写的括号表达式规则
char('(') & _expression & char(')')里,如果_expression的定义没把括号表达式放在最优先匹配的位置,或者_expression会硬着头皮继续解析右括号(甚至把右括号当成表达式的一部分),就会导致解析器匹配完括号里的1.2 / 1.8后,还在等_expression继续输出,根本没去匹配右括号,最后输入结束了还没完成匹配,就抛出"end of input expected"。 - 去掉右括号后,规则变成
(char('(') & _expression)),解析器匹配完左括号和内部表达式就收手,自然不会报错,但这明显不符合FHIRPath的语法要求。
解决方案
要搞定这个问题,得严格按表达式优先级分层写规则,把括号表达式当成最高优先级的原子分支:
分层定义解析规则
照着FHIRPath的语法优先级从高到低来:- 先写原子表达式(数字、括号表达式这类最基础的)
- 再写乘法/除法这类高优先级运算
- 最后写加法/减法、其他低优先级表达式
给你个伪代码示例:
"原子表达式:先匹配括号表达式,匹配不上再匹配数字" _atomic := (char('(') & _expression & char(')')) / _number. "乘法/除法运算:基于原子表达式做递归匹配" _multiplicative := _atomic separatedBy: (char('/') / char('*')). "加法/减法运算:基于乘法表达式递归" _additive := _multiplicative separatedBy: (char('+') / char('-')). "最终的_expression指向最低优先级的运算规则" _expression := _additive.确保递归能停下来
括号表达式的规则必须依赖优先级更低的_expression,不能反过来。这样解析到括号里的内容时,解析器会先处理完高优先级的运算,然后乖乖回到括号规则去匹配右括号,不会死循环或者瞎匹配。用调试工具排查
可以用PetitParser的trace功能看解析过程,比如跑parse: '(1.2 / 1.8)' trace,就能清楚看到每一步匹配了啥:- 先匹配左括号
( - 然后进入
_expression,把1.2 / 1.8匹配完 - 最后匹配右括号
),整个解析就完成了
- 先匹配左括号
关键提醒
表达式解析的核心就是优先级分层,括号必须是最高优先级的原子表达式,这样解析器才会先处理括号里的内容,再回头匹配右括号,别搞反了递归逻辑。
内容的提问来源于stack exchange,提问作者Grey
相关产品推荐
相关产品推荐

