4 # Copyright (C) 2002 Jörg Lehmann <joergl@users.sourceforge.net>
5 # Copyright (C) 2002 André Wobst <wobsta@users.sourceforge.net>
7 # This file is part of PyX (http://pyx.sourceforge.net/).
9 # PyX is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # PyX is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with PyX; if not, write to the Free Software
21 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 import string
, re
, math
29 def __init__(self
, StrToParse
, Pos
= 0):
30 self
.StrToParse
= StrToParse
34 return "ParseStr('" + self
.StrToParse
+ "', " + str(self
.Pos
) + ")"
36 def __str__(self
, Indent
= ""):
38 for i
in range(self
.Pos
):
39 WhiteSpaces
= WhiteSpaces
+ " "
40 return Indent
+ self
.StrToParse
+ "\n" + Indent
+ WhiteSpaces
+ "^"
42 def NextNonWhiteSpace(self
, i
= None):
45 while self
.StrToParse
[i
] in string
.whitespace
:
49 def MatchStr(self
, Str
):
51 i
= self
.NextNonWhiteSpace()
52 if self
.StrToParse
[i
: i
+ len(Str
)] == Str
:
53 self
.Pos
= i
+ len(Str
)
58 def MatchStrParenthesis(self
, Str
):
60 i
= self
.NextNonWhiteSpace()
61 if self
.StrToParse
[i
: i
+ len(Str
)] == Str
:
63 i
= self
.NextNonWhiteSpace(i
)
64 if self
.StrToParse
[i
: i
+ 1] == "(":
70 def MatchPattern(self
, Pat
):
72 i
= self
.NextNonWhiteSpace()
73 Match
= Pat
.match(self
.StrToParse
[i
:])
75 self
.Pos
= i
+ Match
.end()
82 self
.NextNonWhiteSpace()
88 class ArgCountError(Exception): pass
89 class DerivativeError(Exception): pass
93 def __init__(self
, ArgCount
, *Args
):
94 self
.ArgCount
= ArgCount
99 def __repr__(self
, depth
= 0):
102 for i
in range(depth
):
103 indent
= indent
+ SingleIndent
104 result
= indent
+ self
.__class
__.__name
__ + "(\n"
105 for SubTree
in self
.Args
:
106 if isinstance(SubTree
, MathTree
):
107 result
= result
+ SubTree
.__repr
__(depth
+ 1)
109 result
= result
+ indent
+ SingleIndent
+ repr(SubTree
)
111 if SubTree
!= self
.Args
[-1]:
112 result
= result
+ ",\n"
114 result
= result
+ ")"
117 def AddArg(self
, Arg
, Last
=0, NotLast
=0):
118 if len(self
.Args
) == self
.ArgCount
:
120 self
.Args
.append(Arg
)
121 if NotLast
and len(self
.Args
) == self
.ArgCount
:
123 if Last
and len(self
.Args
) != self
.ArgCount
:
126 def DependOn(self
, arg
):
127 for Arg
in self
.Args
:
128 if Arg
.DependOn(arg
):
132 def Derivative(self
, arg
):
133 if not self
.DependOn(arg
):
134 return MathTreeValConst(0.0)
135 return self
.CalcDerivative(arg
)
139 for Arg
in self
.Args
:
140 newlist
= Arg
.VarList()
147 class MathTreeVal(MathTree
):
149 def __init__(self
, *args
):
150 MathTree
.__init
__(self
, 1, *args
)
153 return str(self
.Args
[0])
156 ConstPattern
= re
.compile(r
"-?\d*((\d\.?)|(\.?\d))\d*(E[+-]?\d+)?",
159 class MathTreeValConst(MathTreeVal
):
161 def InitByParser(self
, arg
):
162 Match
= arg
.MatchPattern(ConstPattern
)
164 self
.AddArg(string
.atof(Match
))
167 def CalcDerivative(self
, arg
):
168 raise DerivativeError("expression doesn't depend on \"%s\"" % arg
)
170 def Derivative(self
, arg
):
171 return MathTreeValConst(0.0)
173 def DependOn(self
, arg
):
179 def Calc(HIDDEN_self
, **args
):
180 return HIDDEN_self
.Args
[0]
183 VarPattern
= re
.compile(r
"[a-z_][a-z0-9_]*", re
.IGNORECASE
)
184 MathConst
= {"pi": math
.pi
, "e": math
.e
}
186 class MathTreeValVar(MathTreeVal
):
188 def InitByParser(self
, arg
):
189 Match
= arg
.MatchPattern(VarPattern
)
194 def CalcDerivative(self
, arg
):
195 if arg
!= self
.Args
[0]:
196 raise DerivativeError("expression doesn't depend on \"%s\"" % arg
)
197 return MathTreeValConst(1.0)
199 def DependOn(self
, arg
):
200 if arg
== self
.Args
[0]:
205 if self
.Args
[0] in MathConst
.keys():
207 return [self
.Args
[0]]
209 def Calc(HIDDEN_self
, **args
):
210 if HIDDEN_self
.Args
[0] in args
.keys():
211 return float(args
[HIDDEN_self
.Args
[0]])
212 return MathConst
[HIDDEN_self
.Args
[0]]
215 class MathTreeFunc(MathTree
):
217 def __init__(self
, name
, ArgCount
, *args
):
219 MathTree
.__init
__(self
, ArgCount
, *args
)
221 def InitByParser(self
, arg
):
222 return arg
.MatchStrParenthesis(self
.name
)
226 for SubTree
in self
.Args
:
227 args
= args
+ str(SubTree
)
228 if SubTree
!= self
.Args
[-1]:
230 return self
.name
+ "(" + args
+ ")"
233 class MathTreeFunc1(MathTreeFunc
):
235 def __init__(self
, name
, *args
):
236 MathTreeFunc
.__init
__(self
, name
, 1, *args
)
239 class MathTreeFunc1Neg(MathTreeFunc1
):
241 def __init__(self
, *args
):
242 MathTreeFunc1
.__init__(self
, "neg", *args
)
244 def CalcDerivative(self
, arg
):
245 return MathTreeFunc1Neg(self
.Args
[0].CalcDerivative(arg
))
247 def Calc(HIDDEN_self
, **args
):
248 return -HIDDEN_self
.Args
[0].Calc(**args
)
251 class MathTreeFunc1Abs(MathTreeFunc1
):
253 def __init__(self
, *args
):
254 MathTreeFunc1
.__init__(self
, "abs", *args
)
256 def CalcDerivative(self
, arg
):
257 return MathTreeOpMul(
258 MathTreeFunc1Sgn(self
.Args
[0]),
259 self
.Args
[0].CalcDerivative(arg
))
261 def Calc(HIDDEN_self
, **args
):
262 return abs(HIDDEN_self
.Args
[0].Calc(**args
))
265 class MathTreeFunc1Sgn(MathTreeFunc1
):
267 def __init__(self
, *args
):
268 MathTreeFunc1
.__init__(self
, "sgn", *args
)
270 def CalcDerivative(self
, arg
):
271 return MathTreeValConst(0.0)
273 def Calc(HIDDEN_self
, **args
):
274 if HIDDEN_self
.Args
[0].Calc(**args
) < 0:
279 class MathTreeFunc1Sqrt(MathTreeFunc1
):
281 def __init__(self
, *args
):
282 MathTreeFunc1
.__init__(self
, "sqrt", *args
)
284 def CalcDerivative(self
, arg
):
285 return MathTreeOpMul(
287 MathTreeValConst(0.5),
289 self
.Args
[0].CalcDerivative(arg
))
291 def Calc(HIDDEN_self
, **args
):
292 return math
.sqrt(HIDDEN_self
.Args
[0].Calc(**args
))
295 class MathTreeFunc1Exp(MathTreeFunc1
):
297 def __init__(self
, *args
):
298 MathTreeFunc1
.__init__(self
, "exp", *args
)
300 def CalcDerivative(self
, arg
):
301 return MathTreeOpMul(self
, self
.Args
[0].CalcDerivative(arg
))
303 def Calc(HIDDEN_self
, **args
):
304 return math
.exp(HIDDEN_self
.Args
[0].Calc(**args
))
307 class MathTreeFunc1Log(MathTreeFunc1
):
309 def __init__(self
, *args
):
310 MathTreeFunc1
.__init__(self
, "log", *args
)
312 def CalcDerivative(self
, arg
):
313 return MathTreeOpDiv(self
.Args
[0].CalcDerivative(arg
), self
.Args
[0])
315 def Calc(HIDDEN_self
, **args
):
316 return math
.log(HIDDEN_self
.Args
[0].Calc(**args
))
319 class MathTreeFunc1Sin(MathTreeFunc1
):
321 def __init__(self
, *args
):
322 MathTreeFunc1
.__init__(self
, "sin", *args
)
324 def CalcDerivative(self
, arg
):
325 return MathTreeOpMul(
326 MathTreeFunc1Cos(self
.Args
[0]),
327 self
.Args
[0].CalcDerivative(arg
))
329 def Calc(HIDDEN_self
, **args
):
330 return math
.sin(HIDDEN_self
.Args
[0].Calc(**args
))
333 class MathTreeFunc1Cos(MathTreeFunc1
):
335 def __init__(self
, *args
):
336 MathTreeFunc1
.__init__(self
, "cos", *args
)
338 def CalcDerivative(self
, arg
):
339 return MathTreeOpMul(
340 MathTreeFunc1Neg(MathTreeFunc1Sin(self
.Args
[0])),
341 self
.Args
[0].CalcDerivative(arg
))
343 def Calc(HIDDEN_self
, **args
):
344 return math
.cos(HIDDEN_self
.Args
[0].Calc(**args
))
347 class MathTreeFunc1Tan(MathTreeFunc1
):
349 def __init__(self
, *args
):
350 MathTreeFunc1
.__init__(self
, "tan", *args
)
352 def CalcDerivative(self
, arg
):
353 return MathTreeOpDiv(
354 self
.Args
[0].CalcDerivative(arg
),
356 MathTreeFunc1Cos(self
.Args
[0]),
357 MathTreeValConst(2.0)))
359 def Calc(HIDDEN_self
, **args
):
360 return math
.tan(HIDDEN_self
.Args
[0].Calc(**args
))
363 class MathTreeFunc1ASin(MathTreeFunc1
):
365 def __init__(self
, *args
):
366 MathTreeFunc1
.__init__(self
, "asin", *args
)
368 def CalcDerivative(self
, arg
):
369 return MathTreeOpDiv(
370 self
.Args
[0].CalcDerivative(arg
),
373 MathTreeValConst(1.0),
376 MathTreeValConst(2.0)))))
378 def Calc(HIDDEN_self
, **args
):
379 return math
.asin(HIDDEN_self
.Args
[0].Calc(**args
))
382 class MathTreeFunc1ACos(MathTreeFunc1
):
384 def __init__(self
, *args
):
385 MathTreeFunc1
.__init__(self
, "acos", *args
)
387 def CalcDerivate(self
, arg
):
388 return MathTreeOpDiv(
389 MathTreeFunc1Neg(self
.Args
[0].CalcDerivative(arg
)),
392 MathTreeValConst(1.0),
395 MathTreeValConst(2.0)))))
397 def Calc(HIDDEN_self
, **args
):
398 return math
.acos(HIDDEN_self
.Args
[0].Calc(**args
))
401 class MathTreeFunc1ATan(MathTreeFunc1
):
403 def __init__(self
, *args
):
404 MathTreeFunc1
.__init__(self
, "atan", *args
)
406 def CalcDerivate(self
, arg
):
407 return MathTreeOpDiv(
408 self
.Args
[0].CalcDerivative(arg
),
410 MathTreeValConst(1.0),
413 MathTreeValConst(2.0))))
415 def Calc(HIDDEN_self
, **args
):
416 return math
.atan(HIDDEN_self
.Args
[0].Calc(**args
))
419 class MathTreeFunc1SinD(MathTreeFunc1
):
421 def __init__(self
, *args
):
422 MathTreeFunc1
.__init__(self
, "sind", *args
)
424 def CalcDerivative(self
, arg
):
425 return MathTreeOpMul(
426 MathTreeFunc1CosD(self
.Args
[0]),
428 MathTreeValConst(math
.pi
/180.0),
429 self
.Args
[0].CalcDerivative(arg
)))
431 def Calc(HIDDEN_self
, **args
):
432 return math
.sin(math
.pi
/180.0*HIDDEN_self
.Args
[0].Calc(**args
))
435 class MathTreeFunc1CosD(MathTreeFunc1
):
437 def __init__(self
, *args
):
438 MathTreeFunc1
.__init__(self
, "cosd", *args
)
440 def CalcDerivative(self
, arg
):
441 return MathTreeOpMul(
442 MathTreeFunc1Neg(MathTreeFunc1Sin(self
.Args
[0])),
444 MathTreeValConst(math
.pi
/180.0),
445 self
.Args
[0].CalcDerivative(arg
)))
447 def Calc(HIDDEN_self
, **args
):
448 return math
.cos(math
.pi
/180.0*HIDDEN_self
.Args
[0].Calc(**args
))
451 class MathTreeFunc1TanD(MathTreeFunc1
):
453 def __init__(self
, *args
):
454 MathTreeFunc1
.__init__(self
, "tand", *args
)
456 def CalcDerivative(self
, arg
):
457 return MathTreeOpDiv(
459 MathTreeValConst(math
.pi
/180.0),
460 self
.Args
[0].CalcDerivative(arg
)),
462 MathTreeFunc1Cos(self
.Args
[0]),
463 MathTreeValConst(2.0)))
465 def Calc(HIDDEN_self
, **args
):
466 return math
.tan(math
.pi
/180.0*HIDDEN_self
.Args
[0].Calc(**args
))
469 class MathTreeFunc1ASinD(MathTreeFunc1
):
471 def __init__(self
, *args
):
472 MathTreeFunc1
.__init__(self
, "asind", *args
)
474 def CalcDerivative(self
, arg
):
475 return MathTreeOpDiv(
477 MathTreeValConst(180.0/math
.pi
),
478 self
.Args
[0].CalcDerivative(arg
)),
481 MathTreeValConst(1.0),
484 MathTreeValConst(2.0)))))
486 def Calc(HIDDEN_self
, **args
):
487 return 180.0/math
.pi
*math
.asin(HIDDEN_self
.Args
[0].Calc(**args
))
490 class MathTreeFunc1ACosD(MathTreeFunc1
):
492 def __init__(self
, *args
):
493 MathTreeFunc1
.__init__(self
, "acosd", *args
)
495 def CalcDerivate(self
, arg
):
496 return MathTreeOpDiv(
499 MathTreeValConst(180.0/math
.pi
),
500 self
.Args
[0].CalcDerivative(arg
))),
503 MathTreeValConst(1.0),
506 MathTreeValConst(2.0)))))
508 def Calc(HIDDEN_self
, **args
):
509 return 180.0/math
.pi
*math
.acos(HIDDEN_self
.Args
[0].Calc(**args
))
512 class MathTreeFunc1ATanD(MathTreeFunc1
):
514 def __init__(self
, *args
):
515 MathTreeFunc1
.__init__(self
, "atand", *args
)
517 def CalcDerivate(self
, arg
):
518 return MathTreeOpDiv(
520 MathTreeValConst(180.0/math
.pi
),
521 self
.Args
[0].CalcDerivative(arg
)),
523 MathTreeValConst(1.0),
526 MathTreeValConst(2.0))))
528 def Calc(HIDDEN_self
, **args
):
529 return 180.0/math
.pi
*math
.atan(HIDDEN_self
.Args
[0].Calc(**args
))
532 class MathTreeFunc2(MathTreeFunc
):
534 def __init__(self
, name
, *args
):
535 MathTreeFunc
.__init
__(self
, name
, 2, *args
)
538 class MathTreeFunc2Norm(MathTreeFunc2
):
540 def __init__(self
, *args
):
541 MathTreeFunc2
.__init__(self
, "norm", *args
)
543 def CalcDerivative(self
, arg
):
544 if self
.Args
[0].DependOn(arg
):
545 if self
.Args
[1].DependOn(arg
):
546 return MathTreeOpDiv(
550 self
.Args
[0].CalcDerivative(arg
)),
553 self
.Args
[1].CalcDerivative(arg
))),
556 return MathTreeOpDiv(
559 self
.Args
[0].CalcDerivative(arg
)),
562 if self
.Args
[1].DependOn(arg
):
563 return MathTreeOpDiv(
566 self
.Args
[1].CalcDerivative(arg
)),
569 def Calc(HIDDEN_self
, **args
):
570 return math
.sqrt(HIDDEN_self
.Args
[0].Calc(**args
) ** 2 +
571 HIDDEN_self
.Args
[1].Calc(**args
) ** 2)
574 FuncExternPattern
= re
.compile(r
"([a-z_][a-z0-9_]*)\s*\(", re
.IGNORECASE
)
576 class MathTreeFuncExtern(MathTreeFunc
):
578 def __init__(self
, *args
):
579 MathTreeFunc
.__init
__(self
, None, -1, *args
)
581 def InitByParser(self
, arg
):
582 Match
= arg
.MatchPattern(FuncExternPattern
)
584 self
.name
= Match
[:-1].strip()
587 def Calc(HIDDEN_self
, **args
):
588 return args
[HIDDEN_self
.name
](*[arg
.Calc(**args
) for arg
in HIDDEN_self
.Args
])
591 class MathTreeOp(MathTree
):
593 def __init__(self
, level
, symbol
, *args
):
594 self
.ParenthesisBarrier
= 0
597 MathTree
.__init
__(self
, 2, *args
)
601 if isinstance(self
.Args
[0], MathTreeOp
) and\
602 self
.level
> self
.Args
[0].level
:
603 result
= result
+ "(" + str(self
.Args
[0]) + ")"
605 result
= result
+ str(self
.Args
[0])
606 result
= result
+ self
.symbol
607 if isinstance(self
.Args
[1], MathTreeOp
) and\
608 self
.level
>= self
.Args
[1].level
:
609 result
= result
+ "(" + str(self
.Args
[1]) + ")"
611 result
= result
+ str(self
.Args
[1])
614 def InitByParser(self
, arg
):
615 return arg
.MatchStr(self
.symbol
)
618 class MathTreeOpAdd(MathTreeOp
):
620 def __init__(self
, *args
):
621 MathTreeOp
.__init
__(self
, 1, "+", *args
)
623 def CalcDerivative(self
, arg
):
624 if self
.Args
[0].DependOn(arg
):
625 if self
.Args
[1].DependOn(arg
):
626 return MathTreeOpAdd(
627 self
.Args
[0].CalcDerivative(arg
),
628 self
.Args
[1].CalcDerivative(arg
))
630 return self
.Args
[0].CalcDerivative(arg
)
632 if self
.Args
[1].DependOn(arg
):
633 return self
.Args
[1].CalcDerivative(arg
)
635 def Calc(HIDDEN_self
, **args
):
636 return HIDDEN_self
.Args
[0].Calc(**args
) + HIDDEN_self
.Args
[1].Calc(**args
)
639 class MathTreeOpSub(MathTreeOp
):
641 def __init__(self
, *args
):
642 MathTreeOp
.__init
__(self
, 1, "-", *args
)
644 def CalcDerivative(self
, arg
):
645 if self
.Args
[0].DependOn(arg
):
646 if self
.Args
[1].DependOn(arg
):
647 return MathTreeOpSub(
648 self
.Args
[0].CalcDerivative(arg
),
649 self
.Args
[1].CalcDerivative(arg
))
651 return self
.Args
[0].CalcDerivative(arg
)
653 if self
.Args
[1].DependOn(arg
):
654 return MathTreeFunc1Neg(self
.Args
[1].CalcDerivative(arg
))
656 def Calc(HIDDEN_self
, **args
):
657 return HIDDEN_self
.Args
[0].Calc(**args
) - HIDDEN_self
.Args
[1].Calc(**args
)
660 class MathTreeOpMul(MathTreeOp
):
662 def __init__(self
, *args
):
663 MathTreeOp
.__init
__(self
, 2, "*", *args
)
665 def CalcDerivative(self
, arg
):
666 if self
.Args
[0].DependOn(arg
):
667 if self
.Args
[1].DependOn(arg
):
668 return MathTreeOpAdd(
671 self
.Args
[1].CalcDerivative(arg
)),
673 self
.Args
[0].CalcDerivative(arg
),
676 return MathTreeOpMul(
677 self
.Args
[0].CalcDerivative(arg
),
680 if self
.Args
[1].DependOn(arg
):
681 return MathTreeOpMul(
683 self
.Args
[1].CalcDerivative(arg
))
685 def Calc(HIDDEN_self
, **args
):
686 return HIDDEN_self
.Args
[0].Calc(**args
) * HIDDEN_self
.Args
[1].Calc(**args
)
689 class MathTreeOpDiv(MathTreeOp
):
691 def __init__(self
, *args
):
692 MathTreeOp
.__init
__(self
, 2, "/", *args
)
694 def CalcDerivative(self
, arg
):
695 if self
.Args
[0].DependOn(arg
):
696 if self
.Args
[1].DependOn(arg
):
697 return MathTreeOpMul(
700 self
.Args
[0].CalcDerivative(arg
),
704 self
.Args
[1].CalcDerivative(arg
))),
707 MathTreeValConst(-2.0)))
709 return MathTreeOpDiv(
710 self
.Args
[0].CalcDerivative(arg
),
713 if self
.Args
[1].DependOn(arg
):
714 return MathTreeOpMul(
716 MathTreeFunc1Neg(self
.Args
[0]),
719 MathTreeValConst(-2.0))),
720 self
.Args
[1].CalcDerivative(arg
))
722 def Calc(HIDDEN_self
, **args
):
723 return HIDDEN_self
.Args
[0].Calc(**args
) / HIDDEN_self
.Args
[1].Calc(**args
)
726 class MathTreeOpPow(MathTreeOp
):
728 def __init__(self
, *args
):
729 MathTreeOp
.__init
__(self
, 3, "^", *args
)
731 def InitByParser(self
, arg
):
732 pos
= arg
.MatchStr("^")
736 return arg
.MatchStr("**")
738 def CalcDerivative(self
, arg
):
739 if self
.Args
[0].DependOn(arg
):
740 if self
.Args
[1].DependOn(arg
):
741 return MathTreeOpMul(
747 MathTreeFunc1Log(self
.Args
[0]),
748 self
.Args
[1].CalcDerivative(arg
)),
752 self
.Args
[0].CalcDerivative(arg
),
755 return MathTreeOpMul(
762 MathTreeValConst(1.0))),
763 self
.Args
[0].CalcDerivative(arg
)))
765 if self
.Args
[1].DependOn(arg
):
766 return MathTreeOpMul(
771 MathTreeFunc1Log(self
.Args
[0])),
772 self
.Args
[1].CalcDerivative(arg
))
774 def Calc(HIDDEN_self
, **args
):
775 return HIDDEN_self
.Args
[0].Calc(**args
) ** HIDDEN_self
.Args
[1].Calc(**args
)
779 class UndefinedMathTreeParseError(Exception):
781 def __init__(self
, ParseStr
, MathTree
):
782 self
.ParseStr
= ParseStr
783 self
.MathTree
= MathTree
786 return "\n" + str(self
.ParseStr
)
789 class RightParenthesisExpectedMathTreeParseError(UndefinedMathTreeParseError
): pass
790 class RightParenthesisFoundMathTreeParseError(UndefinedMathTreeParseError
): pass
791 class CommaExpectedMathTreeParseError(UndefinedMathTreeParseError
): pass
792 class CommaFoundMathTreeParseError(UndefinedMathTreeParseError
): pass
793 class OperatorExpectedMathTreeParseError(UndefinedMathTreeParseError
): pass
794 class OperandExpectedMathTreeParseError(UndefinedMathTreeParseError
): pass
797 DefaultMathTreeOps
= (MathTreeOpPow
, MathTreeOpDiv
, MathTreeOpMul
, MathTreeOpSub
, MathTreeOpAdd
)
798 DefaultMathTreeFuncs
= (MathTreeFunc1Neg
, MathTreeFunc1Abs
, MathTreeFunc1Sgn
, MathTreeFunc1Sqrt
,
799 MathTreeFunc1Exp
, MathTreeFunc1Log
,
800 MathTreeFunc1Sin
, MathTreeFunc1Cos
, MathTreeFunc1Tan
,
801 MathTreeFunc1ASin
, MathTreeFunc1ACos
, MathTreeFunc1ATan
,
802 MathTreeFunc1SinD
, MathTreeFunc1CosD
, MathTreeFunc1TanD
,
803 MathTreeFunc1ASinD
, MathTreeFunc1ACosD
, MathTreeFunc1ATanD
,
806 DefaultMathTreeVals
= (MathTreeValConst
, MathTreeValVar
)
810 def __init__(self
, MathTreeOps
=DefaultMathTreeOps
,
811 MathTreeFuncs
=DefaultMathTreeFuncs
,
812 MathTreeVals
=DefaultMathTreeVals
):
813 self
.MathTreeOps
= MathTreeOps
814 self
.MathTreeFuncs
= MathTreeFuncs
815 self
.MathTreeVals
= MathTreeVals
817 def parse(self
, str):
818 return self
.ParseMathTree(ParseStr(str))
820 def ParseMathTree(self
, arg
):
822 Match
= arg
.MatchPattern(re
.compile(r
"\s*-(?![0-9\.])"))
824 Tree
= MathTreeFunc1Neg()
826 i
= arg
.MatchStr("(")
829 self
.ParseMathTree(arg
)
830 raise RightParenthesisExpectedMathTreeParseError(arg
, Tree
)
831 except RightParenthesisFoundMathTreeParseError
, e
:
832 if isinstance(e
.MathTree
, MathTreeOp
):
833 e
.MathTree
.ParenthesisBarrier
= 1
835 SubTree
= Tree
# XXX: four lines code dublication
836 while isinstance(SubTree
, MathTreeOp
) and len(SubTree
.Args
) == 2:
837 SubTree
= SubTree
.Args
[1]
838 SubTree
.AddArg(e
.MathTree
)
842 for FuncClass
in self
.MathTreeFuncs
:
844 if Func
.InitByParser(arg
):
846 SubTree
= Tree
# XXX: four lines code dublication
847 while isinstance(SubTree
, MathTreeOp
) and len(SubTree
.Args
) == 2:
848 SubTree
= SubTree
.Args
[1]
854 self
.ParseMathTree(arg
)
855 raise RightParenthesisExpectedMathTreeParseError(arg
, Tree
)
856 except CommaFoundMathTreeParseError
, e
:
858 Func
.AddArg(e
.MathTree
, NotLast
=1)
859 except ArgCountError
:
860 raise RightParenthesisExpectedMathTreeParseError(arg
, Tree
)
862 except RightParenthesisFoundMathTreeParseError
, e
:
864 Func
.AddArg(e
.MathTree
, Last
=1)
865 except ArgCountError
:
866 raise CommaExpectedMathTreeParseError(arg
, Tree
)
870 FuncExtern
= MathTreeFuncExtern()
871 if FuncExtern
.InitByParser(arg
):
873 SubTree
= Tree
# XXX: four lines code dublication
874 while isinstance(SubTree
, MathTreeOp
) and len(SubTree
.Args
) == 2:
875 SubTree
= SubTree
.Args
[1]
876 SubTree
.AddArg(FuncExtern
)
881 self
.ParseMathTree(arg
)
882 raise RightParenthesisExpectedMathTreeParseError(arg
, Tree
)
883 except CommaFoundMathTreeParseError
, e
:
884 FuncExtern
.AddArg(e
.MathTree
)
886 except RightParenthesisFoundMathTreeParseError
, e
:
887 FuncExtern
.AddArg(e
.MathTree
)
890 for ValClass
in self
.MathTreeVals
:
892 if Val
.InitByParser(arg
):
894 SubTree
= Tree
# XXX: four lines code dublication
895 while isinstance(SubTree
, MathTreeOp
) and len(SubTree
.Args
) == 2:
896 SubTree
= SubTree
.Args
[1]
902 raise OperandExpectedMathTreeParseError(arg
, Tree
)
905 i
= arg
.MatchStr(")")
907 raise RightParenthesisFoundMathTreeParseError(arg
, Tree
)
908 i
= arg
.MatchStr(",")
910 raise CommaFoundMathTreeParseError(arg
, Tree
)
911 for OpClass
in self
.MathTreeOps
:
913 if Op
.InitByParser(arg
):
916 while isinstance(SubTree
, MathTreeOp
) and\
917 Op
.level
> SubTree
.level
and\
918 not SubTree
.ParenthesisBarrier
:
919 SubTreeRoot
= SubTree
920 SubTree
= SubTree
.Args
[1]
923 SubTreeRoot
.Args
[1] = Op
929 raise OperatorExpectedMathTreeParseError(arg
, Tree
)