用函数调用解析算术表达式

2024-09-27 07:27:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用pyparsing,发现它非常适合开发一个简单的DSL,它允许我从MongoDB中提取数据字段并对其进行简单的算术运算。我现在正在尝试扩展我的工具,以便可以应用form Rank的函数[人:身高]并可能包含简单表达式作为函数调用的参数。我正在努力让解析语法正常工作。以下是我目前所掌握的情况:

# Define parser
expr = Forward()
integer = Word(nums).setParseAction(EvalConstant)
real = Combine(Word(nums) + "." + Word(nums)).setParseAction(EvalConstant)

# Handle database field references that are coming out of Mongo, 
# accounting for the fact that some fields contain whitespace
dbRef = Combine(Word(alphas) + ":" + Word(printables) + \
    Optional(" " + Word(alphas) + " " + Word(alphas)))
dbRef.setParseAction(EvalDBref)

# Handle function calls
functionCall = (Keyword("Rank") | Keyword("ZS") | Keyword("Ntile")) + "[" + expr + "]"
functionCall.setParseAction(EvalFunction)
operand =  functionCall | dbRef | (real | integer) 

signop = oneOf('+ -')
multop = oneOf('* /')
plusop = oneOf('+ -')

# Use parse actions to attach Eval constructors to sub-expressions
expr << operatorPrecedence(operand,
    [
     (signop, 1, opAssoc.RIGHT, EvalSignOp),
     (multop, 2, opAssoc.LEFT, EvalMultOp),
     (plusop, 2, opAssoc.LEFT, EvalAddOp),
    ])

我的问题是当我测试像Rank这样的简单表达式时[人:身高]我得到一个解析异常:

^{pr2}$

如果我使用一个float或算术表达式作为参数,比如Rank[3+1.1],那么解析就正常了;如果我简化了dbRef语法,那么它也可以工作。我的语法不能把我的生活搞得一团糟。我尝试过重新排列操作数的顺序以及简化函数调用语法,但都没有成功。有人能看出我做错了什么吗?在

一旦我完成了这项工作,我想做最后一步,在表达式中引入对变量赋值的支持。。在

编辑:在进一步的测试中,如果我从dbRef语法中删除了可打印文件,那么一切正常:

 dbRef = Combine(Word(alphas) + OneOrMore(":") + Word(alphanums) + \
      Optional("_" + Word(alphas)))

但是,如果我将字符“-”添加到dbRef(对于DB字段,我需要这个字符,比如等级:S-N),则解析器再次失败。我想“-”正在被我的操作员或接收人使用?在


Tags: 表达式语法算术keywordwordrankexprcombine
2条回答

可能发生的情况是,测试字符串(Rank[Person:Height])末尾的]字符作为dbRef标记的一部分被使用,因为该标记中超过初始:的部分被声明为由Word(可打印文件)组成(不幸的是,这个字符集包括方括号字符)

然后解析器试图生成一个functionCall,但是缺少结束的],因此出现了错误消息。在

一个暂时的解决办法是使用不包括方括号的字符集,可能是更明确的,例如:

dbRef = Combine(Word(alphas) + ":" + Word(alphas, alphas+"-_./") + \
    Optional(" " + Word(alphas) + " " + Word(alphas)))

编辑
仔细看,上面的内容大致正确,但令牌层次结构是错误的(例如,解析器试图将functionCall作为an expr的一个操作数等)
另外,由于-符号的模糊性,我建议的修复方法也不起作用,因为在dbRef内,它应该被理解为一个普通字符,而在expr中则应该理解为plusOp。不过,pym的语法分析方法并不常见。在

找到了解决方案-问题是我的dbRef语法使用了函数规范中的一些字符。正确运行的新语法:

dbRef = Combine(Word(alphas) + OneOrMore(":") + Word(alphanums) + \
    Optional(oneOf("_ -") + Word(alphas)))

相关问题 更多 >

    热门问题