对不起,对不起标题。我想不出更好的了
我正在尝试使用具有以下要求的 pyparsing 实现 DSL:
- 变量:它们都以 v_ 开头
- 一元运算符:+、-
- 二元运算符:+、-、*、/、%
- 常数
- 函数,就像只有一个变量的普通函数一样
- 函数需要像这样工作:
foo(v_1+v_2) = foo(v_1) + foo(v_2)
,foo(bar(10*v_6))=foo(bar(10))*foo(bar(v_6))
. 任何二进制操作都应该是这种情况
我可以让 1-5 个工作
这是我到目前为止的代码
from pyparsing import *
exprstack = []
#~ @traceParseAction
def pushFirst(tokens):
exprstack.insert(0,tokens[0])
# define grammar
point = Literal( '.' )
plusorminus = Literal( '+' ) | Literal( '-' )
number = Word( nums )
integer = Combine( Optional( plusorminus ) + number )
floatnumber = Combine( integer +
Optional( point + Optional( number ) ) +
Optional( integer )
)
ident = Combine("v_" + Word(nums))
plus = Literal( "+" )
minus = Literal( "-" )
mult = Literal( "*" )
div = Literal( "/" )
cent = Literal( "%" )
lpar = Literal( "(" ).suppress()
rpar = Literal( ")" ).suppress()
addop = plus | minus
multop = mult | div | cent
expop = Literal( "^" )
band = Literal( "@" )
# define expr as Forward, since we will reference it in atom
expr = Forward()
fn = Word( alphas )
atom = ( ( floatnumber | integer | ident | ( fn + lpar + expr + rpar ) ).setParseAction(pushFirst) |
( lpar + expr.suppress() + rpar ))
factor = Forward()
factor << atom + ( ( band + factor ).setParseAction( pushFirst ) | ZeroOrMore( ( expop + factor ).setParseAction( pushFirst ) ) )
term = factor + ZeroOrMore( ( multop + factor ).setParseAction( pushFirst ) )
expr << term + ZeroOrMore( ( addop + term ).setParseAction( pushFirst ) )
print(expr)
bnf = expr
pattern = bnf + StringEnd()
def test(s):
del exprstack[:]
bnf.parseString(s,parseAll=True)
print exprstack
test("avg(+10)")
test("v_1+8")
test("avg(v_1+10)+10")
这是我想要的。
我的功能属于这种类型:
foo(v_1+v_2) = foo(v_1) + foo(v_2)
任何其他二进制操作也应有相同的行为。我不知道如何让解析器自动执行此操作。