2 # -*- coding: ISO-8859-1 -*-
5 # Copyright (C) 2002 Jörg Lehmann <joergl@users.sourceforge.net>
6 # Copyright (C) 2002 André Wobst <wobsta@users.sourceforge.net>
8 # This file is part of PyX (http://pyx.sourceforge.net/).
10 # PyX is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # PyX is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with PyX; if not, write to the Free Software
22 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 import string
, re
, math
30 def __init__(self
, StrToParse
, Pos
= 0):
31 self
.StrToParse
= StrToParse
35 return "ParseStr('" + self
.StrToParse
+ "', " + str(self
.Pos
) + ")"
37 def __str__(self
, Indent
= ""):
39 for i
in range(self
.Pos
):
40 WhiteSpaces
= WhiteSpaces
+ " "
41 return Indent
+ self
.StrToParse
+ "\n" + Indent
+ WhiteSpaces
+ "^"
43 def NextNonWhiteSpace(self
, i
= None):
46 while self
.StrToParse
[i
] in string
.whitespace
:
50 def MatchStr(self
, Str
):
52 i
= self
.NextNonWhiteSpace()
53 if self
.StrToParse
[i
: i
+ len(Str
)] == Str
:
54 self
.Pos
= i
+ len(Str
)
59 def MatchStrParenthesis(self
, Str
):
61 i
= self
.NextNonWhiteSpace()
62 if self
.StrToParse
[i
: i
+ len(Str
)] == Str
:
64 i
= self
.NextNonWhiteSpace(i
)
65 if self
.StrToParse
[i
: i
+ 1] == "(":
71 def MatchPattern(self
, Pat
):
73 i
= self
.NextNonWhiteSpace()
74 Match
= Pat
.match(self
.StrToParse
[i
:])
76 self
.Pos
= i
+ Match
.end()
83 self
.NextNonWhiteSpace()
89 class ArgCountError(Exception): pass
90 class DerivativeError(Exception): pass
94 def __init__(self
, ArgCount
, *Args
):
95 self
.ArgCount
= ArgCount
100 def __repr__(self
, depth
= 0):
103 for i
in range(depth
):
104 indent
= indent
+ SingleIndent
105 result
= indent
+ self
.__class
__.__name
__ + "(\n"
106 for SubTree
in self
.Args
:
107 if isinstance(SubTree
, MathTree
):
108 result
= result
+ SubTree
.__repr
__(depth
+ 1)
110 result
= result
+ indent
+ SingleIndent
+ repr(SubTree
)
112 if SubTree
!= self
.Args
[-1]:
113 result
= result
+ ",\n"
115 result
= result
+ ")"
118 def AddArg(self
, Arg
, Last
=0, NotLast
=0):
119 if len(self
.Args
) == self
.ArgCount
:
121 self
.Args
.append(Arg
)
122 if NotLast
and len(self
.Args
) == self
.ArgCount
:
124 if Last
and len(self
.Args
) != self
.ArgCount
:
127 def DependOn(self
, arg
):
128 for Arg
in self
.Args
:
129 if Arg
.DependOn(arg
):
133 def Derivative(self
, arg
):
134 if not self
.DependOn(arg
):
135 return MathTreeValConst(0.0)
136 return self
.CalcDerivative(arg
)
140 for Arg
in self
.Args
:
141 newlist
= Arg
.VarList()
148 class MathTreeVal(MathTree
):
150 def __init__(self
, *args
):
151 MathTree
.__init
__(self
, 1, *args
)
154 return str(self
.Args
[0])
157 ConstPattern
= re
.compile(r
"-?\d*((\d\.?)|(\.?\d))\d*(E[+-]?\d+)?",
160 class MathTreeValConst(MathTreeVal
):
162 def InitByParser(self
, arg
):
163 Match
= arg
.MatchPattern(ConstPattern
)
165 self
.AddArg(string
.atof(Match
))
168 def CalcDerivative(self
, arg
):
169 raise DerivativeError("expression doesn't depend on \"%s\"" % arg
)
171 def Derivative(self
, arg
):
172 return MathTreeValConst(0.0)
174 def DependOn(self
, arg
):
180 def Calc(HIDDEN_self
, **args
):
181 return HIDDEN_self
.Args
[0]
184 VarPattern
= re
.compile(r
"[a-z_][a-z0-9_]*", re
.IGNORECASE
)
185 MathConst
= {"pi": math
.pi
, "e": math
.e
}
187 class MathTreeValVar(MathTreeVal
):
189 def InitByParser(self
, arg
):
190 Match
= arg
.MatchPattern(VarPattern
)
195 def CalcDerivative(self
, arg
):
196 if arg
!= self
.Args
[0]:
197 raise DerivativeError("expression doesn't depend on \"%s\"" % arg
)
198 return MathTreeValConst(1.0)
200 def DependOn(self
, arg
):
201 if arg
== self
.Args
[0]:
206 if self
.Args
[0] in MathConst
.keys():
208 return [self
.Args
[0]]
210 def Calc(HIDDEN_self
, **args
):
211 if HIDDEN_self
.Args
[0] in args
.keys():
212 return float(args
[HIDDEN_self
.Args
[0]])
213 return MathConst
[HIDDEN_self
.Args
[0]]
216 class MathTreeFunc(MathTree
):
218 def __init__(self
, name
, ArgCount
, *args
):
220 MathTree
.__init
__(self
, ArgCount
, *args
)
222 def InitByParser(self
, arg
):
223 return arg
.MatchStrParenthesis(self
.name
)
227 for SubTree
in self
.Args
:
228 args
= args
+ str(SubTree
)
229 if SubTree
!= self
.Args
[-1]:
231 return self
.name
+ "(" + args
+ ")"
234 class MathTreeFunc1(MathTreeFunc
):
236 def __init__(self
, name
, *args
):
237 MathTreeFunc
.__init
__(self
, name
, 1, *args
)
240 class MathTreeFunc1Neg(MathTreeFunc1
):
242 def __init__(self
, *args
):
243 MathTreeFunc1
.__init__(self
, "neg", *args
)
245 def CalcDerivative(self
, arg
):
246 return MathTreeFunc1Neg(self
.Args
[0].CalcDerivative(arg
))
248 def Calc(HIDDEN_self
, **args
):
249 return -HIDDEN_self
.Args
[0].Calc(**args
)
252 class MathTreeFunc1Abs(MathTreeFunc1
):
254 def __init__(self
, *args
):
255 MathTreeFunc1
.__init__(self
, "abs", *args
)
257 def CalcDerivative(self
, arg
):
258 return MathTreeOpMul(
259 MathTreeFunc1Sgn(self
.Args
[0]),
260 self
.Args
[0].CalcDerivative(arg
))
262 def Calc(HIDDEN_self
, **args
):
263 return abs(HIDDEN_self
.Args
[0].Calc(**args
))
266 class MathTreeFunc1Sgn(MathTreeFunc1
):
268 def __init__(self
, *args
):
269 MathTreeFunc1
.__init__(self
, "sgn", *args
)
271 def CalcDerivative(self
, arg
):
272 return MathTreeValConst(0.0)
274 def Calc(HIDDEN_self
, **args
):
275 if HIDDEN_self
.Args
[0].Calc(**args
) < 0:
280 class MathTreeFunc1Sqrt(MathTreeFunc1
):
282 def __init__(self
, *args
):
283 MathTreeFunc1
.__init__(self
, "sqrt", *args
)
285 def CalcDerivative(self
, arg
):
286 return MathTreeOpMul(
288 MathTreeValConst(0.5),
290 self
.Args
[0].CalcDerivative(arg
))
292 def Calc(HIDDEN_self
, **args
):
293 return math
.sqrt(HIDDEN_self
.Args
[0].Calc(**args
))
296 class MathTreeFunc1Exp(MathTreeFunc1
):
298 def __init__(self
, *args
):
299 MathTreeFunc1
.__init__(self
, "exp", *args
)
301 def CalcDerivative(self
, arg
):
302 return MathTreeOpMul(self
, self
.Args
[0].CalcDerivative(arg
))
304 def Calc(HIDDEN_self
, **args
):
305 return math
.exp(HIDDEN_self
.Args
[0].Calc(**args
))
308 class MathTreeFunc1Log(MathTreeFunc1
):
310 def __init__(self
, *args
):
311 MathTreeFunc1
.__init__(self
, "log", *args
)
313 def CalcDerivative(self
, arg
):
314 return MathTreeOpDiv(self
.Args
[0].CalcDerivative(arg
), self
.Args
[0])
316 def Calc(HIDDEN_self
, **args
):
317 return math
.log(HIDDEN_self
.Args
[0].Calc(**args
))
320 class MathTreeFunc1Sin(MathTreeFunc1
):
322 def __init__(self
, *args
):
323 MathTreeFunc1
.__init__(self
, "sin", *args
)
325 def CalcDerivative(self
, arg
):
326 return MathTreeOpMul(
327 MathTreeFunc1Cos(self
.Args
[0]),
328 self
.Args
[0].CalcDerivative(arg
))
330 def Calc(HIDDEN_self
, **args
):
331 return math
.sin(HIDDEN_self
.Args
[0].Calc(**args
))
334 class MathTreeFunc1Cos(MathTreeFunc1
):
336 def __init__(self
, *args
):
337 MathTreeFunc1
.__init__(self
, "cos", *args
)
339 def CalcDerivative(self
, arg
):
340 return MathTreeOpMul(
341 MathTreeFunc1Neg(MathTreeFunc1Sin(self
.Args
[0])),
342 self
.Args
[0].CalcDerivative(arg
))
344 def Calc(HIDDEN_self
, **args
):
345 return math
.cos(HIDDEN_self
.Args
[0].Calc(**args
))
348 class MathTreeFunc1Tan(MathTreeFunc1
):
350 def __init__(self
, *args
):
351 MathTreeFunc1
.__init__(self
, "tan", *args
)
353 def CalcDerivative(self
, arg
):
354 return MathTreeOpDiv(
355 self
.Args
[0].CalcDerivative(arg
),
357 MathTreeFunc1Cos(self
.Args
[0]),
358 MathTreeValConst(2.0)))
360 def Calc(HIDDEN_self
, **args
):
361 return math
.tan(HIDDEN_self
.Args
[0].Calc(**args
))
364 class MathTreeFunc1ASin(MathTreeFunc1
):
366 def __init__(self
, *args
):
367 MathTreeFunc1
.__init__(self
, "asin", *args
)
369 def CalcDerivative(self
, arg
):
370 return MathTreeOpDiv(
371 self
.Args
[0].CalcDerivative(arg
),
374 MathTreeValConst(1.0),
377 MathTreeValConst(2.0)))))
379 def Calc(HIDDEN_self
, **args
):
380 return math
.asin(HIDDEN_self
.Args
[0].Calc(**args
))
383 class MathTreeFunc1ACos(MathTreeFunc1
):
385 def __init__(self
, *args
):
386 MathTreeFunc1
.__init__(self
, "acos", *args
)
388 def CalcDerivate(self
, arg
):
389 return MathTreeOpDiv(
390 MathTreeFunc1Neg(self
.Args
[0].CalcDerivative(arg
)),
393 MathTreeValConst(1.0),
396 MathTreeValConst(2.0)))))
398 def Calc(HIDDEN_self
, **args
):
399 return math
.acos(HIDDEN_self
.Args
[0].Calc(**args
))
402 class MathTreeFunc1ATan(MathTreeFunc1
):
404 def __init__(self
, *args
):
405 MathTreeFunc1
.__init__(self
, "atan", *args
)
407 def CalcDerivate(self
, arg
):
408 return MathTreeOpDiv(
409 self
.Args
[0].CalcDerivative(arg
),
411 MathTreeValConst(1.0),
414 MathTreeValConst(2.0))))
416 def Calc(HIDDEN_self
, **args
):
417 return math
.atan(HIDDEN_self
.Args
[0].Calc(**args
))
420 class MathTreeFunc1SinD(MathTreeFunc1
):
422 def __init__(self
, *args
):
423 MathTreeFunc1
.__init__(self
, "sind", *args
)
425 def CalcDerivative(self
, arg
):
426 return MathTreeOpMul(
427 MathTreeFunc1CosD(self
.Args
[0]),
429 MathTreeValConst(math
.pi
/180.0),
430 self
.Args
[0].CalcDerivative(arg
)))
432 def Calc(HIDDEN_self
, **args
):
433 return math
.sin(math
.pi
/180.0*HIDDEN_self
.Args
[0].Calc(**args
))
436 class MathTreeFunc1CosD(MathTreeFunc1
):
438 def __init__(self
, *args
):
439 MathTreeFunc1
.__init__(self
, "cosd", *args
)
441 def CalcDerivative(self
, arg
):
442 return MathTreeOpMul(
443 MathTreeFunc1Neg(MathTreeFunc1Sin(self
.Args
[0])),
445 MathTreeValConst(math
.pi
/180.0),
446 self
.Args
[0].CalcDerivative(arg
)))
448 def Calc(HIDDEN_self
, **args
):
449 return math
.cos(math
.pi
/180.0*HIDDEN_self
.Args
[0].Calc(**args
))
452 class MathTreeFunc1TanD(MathTreeFunc1
):
454 def __init__(self
, *args
):
455 MathTreeFunc1
.__init__(self
, "tand", *args
)
457 def CalcDerivative(self
, arg
):
458 return MathTreeOpDiv(
460 MathTreeValConst(math
.pi
/180.0),
461 self
.Args
[0].CalcDerivative(arg
)),
463 MathTreeFunc1Cos(self
.Args
[0]),
464 MathTreeValConst(2.0)))
466 def Calc(HIDDEN_self
, **args
):
467 return math
.tan(math
.pi
/180.0*HIDDEN_self
.Args
[0].Calc(**args
))
470 class MathTreeFunc1ASinD(MathTreeFunc1
):
472 def __init__(self
, *args
):
473 MathTreeFunc1
.__init__(self
, "asind", *args
)
475 def CalcDerivative(self
, arg
):
476 return MathTreeOpDiv(
478 MathTreeValConst(180.0/math
.pi
),
479 self
.Args
[0].CalcDerivative(arg
)),
482 MathTreeValConst(1.0),
485 MathTreeValConst(2.0)))))
487 def Calc(HIDDEN_self
, **args
):
488 return 180.0/math
.pi
*math
.asin(HIDDEN_self
.Args
[0].Calc(**args
))
491 class MathTreeFunc1ACosD(MathTreeFunc1
):
493 def __init__(self
, *args
):
494 MathTreeFunc1
.__init__(self
, "acosd", *args
)
496 def CalcDerivate(self
, arg
):
497 return MathTreeOpDiv(
500 MathTreeValConst(180.0/math
.pi
),
501 self
.Args
[0].CalcDerivative(arg
))),
504 MathTreeValConst(1.0),
507 MathTreeValConst(2.0)))))
509 def Calc(HIDDEN_self
, **args
):
510 return 180.0/math
.pi
*math
.acos(HIDDEN_self
.Args
[0].Calc(**args
))
513 class MathTreeFunc1ATanD(MathTreeFunc1
):
515 def __init__(self
, *args
):
516 MathTreeFunc1
.__init__(self
, "atand", *args
)
518 def CalcDerivate(self
, arg
):
519 return MathTreeOpDiv(
521 MathTreeValConst(180.0/math
.pi
),
522 self
.Args
[0].CalcDerivative(arg
)),
524 MathTreeValConst(1.0),
527 MathTreeValConst(2.0))))
529 def Calc(HIDDEN_self
, **args
):
530 return 180.0/math
.pi
*math
.atan(HIDDEN_self
.Args
[0].Calc(**args
))
533 class MathTreeFunc2(MathTreeFunc
):
535 def __init__(self
, name
, *args
):
536 MathTreeFunc
.__init
__(self
, name
, 2, *args
)
539 class MathTreeFunc2Norm(MathTreeFunc2
):
541 def __init__(self
, *args
):
542 MathTreeFunc2
.__init__(self
, "norm", *args
)
544 def CalcDerivative(self
, arg
):
545 if self
.Args
[0].DependOn(arg
):
546 if self
.Args
[1].DependOn(arg
):
547 return MathTreeOpDiv(
551 self
.Args
[0].CalcDerivative(arg
)),
554 self
.Args
[1].CalcDerivative(arg
))),
557 return MathTreeOpDiv(
560 self
.Args
[0].CalcDerivative(arg
)),
563 if self
.Args
[1].DependOn(arg
):
564 return MathTreeOpDiv(
567 self
.Args
[1].CalcDerivative(arg
)),
570 def Calc(HIDDEN_self
, **args
):
571 return math
.sqrt(HIDDEN_self
.Args
[0].Calc(**args
) ** 2 +
572 HIDDEN_self
.Args
[1].Calc(**args
) ** 2)
575 FuncExternPattern
= re
.compile(r
"([a-z_][a-z0-9_]*)\s*\(", re
.IGNORECASE
)
577 class MathTreeFuncExtern(MathTreeFunc
):
579 def __init__(self
, *args
):
580 MathTreeFunc
.__init
__(self
, None, -1, *args
)
582 def InitByParser(self
, arg
):
583 Match
= arg
.MatchPattern(FuncExternPattern
)
585 self
.name
= Match
[:-1].strip()
588 def Calc(HIDDEN_self
, **args
):
589 return args
[HIDDEN_self
.name
](*[arg
.Calc(**args
) for arg
in HIDDEN_self
.Args
])
592 class MathTreeOp(MathTree
):
594 def __init__(self
, level
, symbol
, *args
):
595 self
.ParenthesisBarrier
= 0
598 MathTree
.__init
__(self
, 2, *args
)
602 if isinstance(self
.Args
[0], MathTreeOp
) and\
603 self
.level
> self
.Args
[0].level
:
604 result
= result
+ "(" + str(self
.Args
[0]) + ")"
606 result
= result
+ str(self
.Args
[0])
607 result
= result
+ self
.symbol
608 if isinstance(self
.Args
[1], MathTreeOp
) and\
609 self
.level
>= self
.Args
[1].level
:
610 result
= result
+ "(" + str(self
.Args
[1]) + ")"
612 result
= result
+ str(self
.Args
[1])
615 def InitByParser(self
, arg
):
616 return arg
.MatchStr(self
.symbol
)
619 class MathTreeOpAdd(MathTreeOp
):
621 def __init__(self
, *args
):
622 MathTreeOp
.__init
__(self
, 1, "+", *args
)
624 def CalcDerivative(self
, arg
):
625 if self
.Args
[0].DependOn(arg
):
626 if self
.Args
[1].DependOn(arg
):
627 return MathTreeOpAdd(
628 self
.Args
[0].CalcDerivative(arg
),
629 self
.Args
[1].CalcDerivative(arg
))
631 return self
.Args
[0].CalcDerivative(arg
)
633 if self
.Args
[1].DependOn(arg
):
634 return self
.Args
[1].CalcDerivative(arg
)
636 def Calc(HIDDEN_self
, **args
):
637 return HIDDEN_self
.Args
[0].Calc(**args
) + HIDDEN_self
.Args
[1].Calc(**args
)
640 class MathTreeOpSub(MathTreeOp
):
642 def __init__(self
, *args
):
643 MathTreeOp
.__init
__(self
, 1, "-", *args
)
645 def CalcDerivative(self
, arg
):
646 if self
.Args
[0].DependOn(arg
):
647 if self
.Args
[1].DependOn(arg
):
648 return MathTreeOpSub(
649 self
.Args
[0].CalcDerivative(arg
),
650 self
.Args
[1].CalcDerivative(arg
))
652 return self
.Args
[0].CalcDerivative(arg
)
654 if self
.Args
[1].DependOn(arg
):
655 return MathTreeFunc1Neg(self
.Args
[1].CalcDerivative(arg
))
657 def Calc(HIDDEN_self
, **args
):
658 return HIDDEN_self
.Args
[0].Calc(**args
) - HIDDEN_self
.Args
[1].Calc(**args
)
661 class MathTreeOpMul(MathTreeOp
):
663 def __init__(self
, *args
):
664 MathTreeOp
.__init
__(self
, 2, "*", *args
)
666 def CalcDerivative(self
, arg
):
667 if self
.Args
[0].DependOn(arg
):
668 if self
.Args
[1].DependOn(arg
):
669 return MathTreeOpAdd(
672 self
.Args
[1].CalcDerivative(arg
)),
674 self
.Args
[0].CalcDerivative(arg
),
677 return MathTreeOpMul(
678 self
.Args
[0].CalcDerivative(arg
),
681 if self
.Args
[1].DependOn(arg
):
682 return MathTreeOpMul(
684 self
.Args
[1].CalcDerivative(arg
))
686 def Calc(HIDDEN_self
, **args
):
687 return HIDDEN_self
.Args
[0].Calc(**args
) * HIDDEN_self
.Args
[1].Calc(**args
)
690 class MathTreeOpDiv(MathTreeOp
):
692 def __init__(self
, *args
):
693 MathTreeOp
.__init
__(self
, 2, "/", *args
)
695 def CalcDerivative(self
, arg
):
696 if self
.Args
[0].DependOn(arg
):
697 if self
.Args
[1].DependOn(arg
):
698 return MathTreeOpMul(
701 self
.Args
[0].CalcDerivative(arg
),
705 self
.Args
[1].CalcDerivative(arg
))),
708 MathTreeValConst(-2.0)))
710 return MathTreeOpDiv(
711 self
.Args
[0].CalcDerivative(arg
),
714 if self
.Args
[1].DependOn(arg
):
715 return MathTreeOpMul(
717 MathTreeFunc1Neg(self
.Args
[0]),
720 MathTreeValConst(-2.0))),
721 self
.Args
[1].CalcDerivative(arg
))
723 def Calc(HIDDEN_self
, **args
):
724 return HIDDEN_self
.Args
[0].Calc(**args
) / HIDDEN_self
.Args
[1].Calc(**args
)
727 class MathTreeOpPow(MathTreeOp
):
729 def __init__(self
, *args
):
730 MathTreeOp
.__init
__(self
, 3, "^", *args
)
732 def InitByParser(self
, arg
):
733 pos
= arg
.MatchStr("^")
737 return arg
.MatchStr("**")
739 def CalcDerivative(self
, arg
):
740 if self
.Args
[0].DependOn(arg
):
741 if self
.Args
[1].DependOn(arg
):
742 return MathTreeOpMul(
748 MathTreeFunc1Log(self
.Args
[0]),
749 self
.Args
[1].CalcDerivative(arg
)),
753 self
.Args
[0].CalcDerivative(arg
),
756 return MathTreeOpMul(
763 MathTreeValConst(1.0))),
764 self
.Args
[0].CalcDerivative(arg
)))
766 if self
.Args
[1].DependOn(arg
):
767 return MathTreeOpMul(
772 MathTreeFunc1Log(self
.Args
[0])),
773 self
.Args
[1].CalcDerivative(arg
))
775 def Calc(HIDDEN_self
, **args
):
776 return HIDDEN_self
.Args
[0].Calc(**args
) ** HIDDEN_self
.Args
[1].Calc(**args
)
780 class UndefinedMathTreeParseError(Exception):
782 def __init__(self
, ParseStr
, MathTree
):
783 self
.ParseStr
= ParseStr
784 self
.MathTree
= MathTree
787 return "\n" + str(self
.ParseStr
)
790 class RightParenthesisExpectedMathTreeParseError(UndefinedMathTreeParseError
): pass
791 class RightParenthesisFoundMathTreeParseError(UndefinedMathTreeParseError
): pass
792 class CommaExpectedMathTreeParseError(UndefinedMathTreeParseError
): pass
793 class CommaFoundMathTreeParseError(UndefinedMathTreeParseError
): pass
794 class OperatorExpectedMathTreeParseError(UndefinedMathTreeParseError
): pass
795 class OperandExpectedMathTreeParseError(UndefinedMathTreeParseError
): pass
798 DefaultMathTreeOps
= (MathTreeOpPow
, MathTreeOpDiv
, MathTreeOpMul
, MathTreeOpSub
, MathTreeOpAdd
)
799 DefaultMathTreeFuncs
= (MathTreeFunc1Neg
, MathTreeFunc1Abs
, MathTreeFunc1Sgn
, MathTreeFunc1Sqrt
,
800 MathTreeFunc1Exp
, MathTreeFunc1Log
,
801 MathTreeFunc1Sin
, MathTreeFunc1Cos
, MathTreeFunc1Tan
,
802 MathTreeFunc1ASin
, MathTreeFunc1ACos
, MathTreeFunc1ATan
,
803 MathTreeFunc1SinD
, MathTreeFunc1CosD
, MathTreeFunc1TanD
,
804 MathTreeFunc1ASinD
, MathTreeFunc1ACosD
, MathTreeFunc1ATanD
,
807 DefaultMathTreeVals
= (MathTreeValConst
, MathTreeValVar
)
811 def __init__(self
, MathTreeOps
=DefaultMathTreeOps
,
812 MathTreeFuncs
=DefaultMathTreeFuncs
,
813 MathTreeVals
=DefaultMathTreeVals
):
814 self
.MathTreeOps
= MathTreeOps
815 self
.MathTreeFuncs
= MathTreeFuncs
816 self
.MathTreeVals
= MathTreeVals
818 def parse(self
, str):
819 return self
.ParseMathTree(ParseStr(str))
821 def ParseMathTree(self
, arg
):
823 Match
= arg
.MatchPattern(re
.compile(r
"\s*-(?![0-9\.])"))
825 Tree
= MathTreeFunc1Neg()
827 i
= arg
.MatchStr("(")
830 self
.ParseMathTree(arg
)
831 raise RightParenthesisExpectedMathTreeParseError(arg
, Tree
)
832 except RightParenthesisFoundMathTreeParseError
, e
:
833 if isinstance(e
.MathTree
, MathTreeOp
):
834 e
.MathTree
.ParenthesisBarrier
= 1
836 SubTree
= Tree
# XXX: four lines code dublication
837 while isinstance(SubTree
, MathTreeOp
) and len(SubTree
.Args
) == 2:
838 SubTree
= SubTree
.Args
[1]
839 SubTree
.AddArg(e
.MathTree
)
843 for FuncClass
in self
.MathTreeFuncs
:
845 if Func
.InitByParser(arg
):
847 SubTree
= Tree
# XXX: four lines code dublication
848 while isinstance(SubTree
, MathTreeOp
) and len(SubTree
.Args
) == 2:
849 SubTree
= SubTree
.Args
[1]
855 self
.ParseMathTree(arg
)
856 raise RightParenthesisExpectedMathTreeParseError(arg
, Tree
)
857 except CommaFoundMathTreeParseError
, e
:
859 Func
.AddArg(e
.MathTree
, NotLast
=1)
860 except ArgCountError
:
861 raise RightParenthesisExpectedMathTreeParseError(arg
, Tree
)
863 except RightParenthesisFoundMathTreeParseError
, e
:
865 Func
.AddArg(e
.MathTree
, Last
=1)
866 except ArgCountError
:
867 raise CommaExpectedMathTreeParseError(arg
, Tree
)
871 FuncExtern
= MathTreeFuncExtern()
872 if FuncExtern
.InitByParser(arg
):
874 SubTree
= Tree
# XXX: four lines code dublication
875 while isinstance(SubTree
, MathTreeOp
) and len(SubTree
.Args
) == 2:
876 SubTree
= SubTree
.Args
[1]
877 SubTree
.AddArg(FuncExtern
)
882 self
.ParseMathTree(arg
)
883 raise RightParenthesisExpectedMathTreeParseError(arg
, Tree
)
884 except CommaFoundMathTreeParseError
, e
:
885 FuncExtern
.AddArg(e
.MathTree
)
887 except RightParenthesisFoundMathTreeParseError
, e
:
888 FuncExtern
.AddArg(e
.MathTree
)
891 for ValClass
in self
.MathTreeVals
:
893 if Val
.InitByParser(arg
):
895 SubTree
= Tree
# XXX: four lines code dublication
896 while isinstance(SubTree
, MathTreeOp
) and len(SubTree
.Args
) == 2:
897 SubTree
= SubTree
.Args
[1]
903 raise OperandExpectedMathTreeParseError(arg
, Tree
)
906 i
= arg
.MatchStr(")")
908 raise RightParenthesisFoundMathTreeParseError(arg
, Tree
)
909 i
= arg
.MatchStr(",")
911 raise CommaFoundMathTreeParseError(arg
, Tree
)
912 for OpClass
in self
.MathTreeOps
:
914 if Op
.InitByParser(arg
):
917 while isinstance(SubTree
, MathTreeOp
) and\
918 Op
.level
> SubTree
.level
and\
919 not SubTree
.ParenthesisBarrier
:
920 SubTreeRoot
= SubTree
921 SubTree
= SubTree
.Args
[1]
924 SubTreeRoot
.Args
[1] = Op
930 raise OperatorExpectedMathTreeParseError(arg
, Tree
)