1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Parsers for algebraic expressions coming from UFO, outputting into
17 different languages/frameworks (Fortran and Pythia8). Uses the PLY 3.3
18 Lex + Yacc framework"""
19
20 import logging
21 import os
22 import re
23 import sys
24 import copy
25
26 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
27 sys.path.append(os.path.join(root_path, os.path.pardir))
28
29 import madgraph.various.misc as misc
30
31 from madgraph import MadGraph5Error
32 import vendor.ply.lex as lex
33 import vendor.ply.yacc as yacc
34 import models.check_param_card as check_param_card
35
36 logger = logging.getLogger('madgraph.ufo_parsers')
37
38
39
41 """Appropriate Error for a wrong parsing"""
42
44 """A base class for parsers for algebraic expressions coming from UFO."""
45
46 parsed_string = ""
47 logical_equiv = {}
48
50 """Initialize the lex and yacc"""
51
52 modname = self.__class__.__name__
53 self.debugfile = os.path.devnull
54 self.tabmodule = os.path.join(root_path, "iolibs", modname + "_" + "parsetab.py")
55 lex.lex(module=self, debug=0)
56 self.y=yacc.yacc(module=self, debug=0, debugfile=self.debugfile,
57 tabmodule=self.tabmodule)
58
63
64
65 tokens = (
66 'LOGICAL','LOGICALCOMB','POWER', 'CSC', 'SEC', 'ACSC', 'ASEC', 'TAN', 'ATAN',
67 'SQRT', 'CONJ', 'RE', 'RE2', 'IM', 'PI', 'COMPLEX', 'FUNCTION', 'IF','ELSE',
68 'VARIABLE', 'NUMBER','COND','REGLOG', 'REGLOGP', 'REGLOGM','RECMS','ARG'
69 )
70 literals = "=+-*/(),"
71
72
73
75 r'(?<!\w)csc(?=\()'
76 return t
78 r'(?<!\w)sec(?=\()'
79 return t
81 r'(?<!\w)acsc(?=\()'
82 return t
84 r'(?<!\w)tan(?=\()|(?<!\w)cmath.tan(?=\()'
85 return t
87 r'(?<!\w)atan(?=\()|(?<!\w)cmath.atan(?=\()'
88 return t
90 r'(?<!\w)asec(?=\()'
91 return t
93 r'(?<!\w)reglog(?=\()'
94 return t
96 r'(?<!\w)reglogp(?=\()'
97 return t
99 r'(?<!\w)reglogm(?=\()'
100 return t
102 r'(?<!\w)recms(?=\()'
103 return t
105 r'(?<!\w)cond(?=\()'
106 return t
108 r'(?<!\w)arg(?=\()'
109 return t
111 r'(?<!\w)if\s'
112 return t
114 r'(?<!\w)else\s'
115 return t
117 r'==|!=|<=|>=|<|>'
118 return t
120 r'(?<!\w)and(?=[\s\(])|(?<!\w)or(?=[\s\(])'
121 return t
123 r'cmath\.sqrt'
124 return t
126 r'cmath\.pi'
127 return t
129 r'complexconjugate'
130 return t
132 r'(?<!\w)im(?=\()'
133 return t
135 r'(?<!\w)re(?=\()'
136 return t
138 r'\.real|\.imag'
139 return t
140
142 r'(?<!\w)complex(?=\()'
143 return t
145 r'(cmath\.){0,1}[a-zA-Z_][0-9a-zA-Z_]*(?=\()'
146 return t
148 r'[a-zA-Z_][0-9a-zA-Z_]*'
149 return t
150
151 t_NUMBER = r'([0-9]+\.[0-9]*|\.[0-9]+|[0-9]+)([eE][+-]{0,1}[0-9]+){0,1}j{0,1}'
152 t_POWER = r'\*\*'
153
154 t_ignore = " \t"
155
156 re_cmath_function = re.compile("cmath\.(?P<name>[0-9a-zA-Z_]+)")
157
159 r'\n+'
160 t.lexer.lineno += t.value.count("\n")
161
163 logger.error("Illegal character '%s'" % t.value[0])
164 t.lexer.skip(1)
165
166
167 - def build(self,**kwargs):
168 self.lexer = lex.lex(module=self, **kwargs)
169
170
171
172 precedence = (
173 ('right', 'LOGICALCOMB'),
174 ('right', 'LOGICAL'),
175 ('right','IF'),
176 ('right','ELSE'),
177 ('left','='),
178 ('left','+','-'),
179 ('left','*','/'),
180 ('left', 'RE2'),
181 ('right','UMINUS'),
182 ('left','POWER'),
183 ('right','REGLOG'),
184 ('right','REGLOGP'),
185 ('right','REGLOGM'),
186 ('right','RECMS'),
187 ('right','ARG'),
188 ('right','CSC'),
189 ('right','SEC'),
190 ('right','ACSC'),
191 ('right','ASEC'),
192 ('right','SQRT'),
193 ('right','CONJ'),
194 ('right','RE'),
195 ('right','IM'),
196 ('right','FUNCTION'),
197 ('right','COMPLEX'),
198 ('right','COND'),
199 )
200
201
205
207 '''expression : expression '=' expression
208 | expression '+' expression
209 | expression '-' expression
210 | expression '*' expression
211 | expression '/' expression'''
212 p[0] = p[1] + p[2] + p[3]
213
215 '''boolexpression : expression LOGICAL expression'''
216 if p[2] not in self.logical_equiv:
217 p[0] = p[1] + p[2] + p[3]
218 else:
219 p[0] = p[1] + self.logical_equiv[p[2]] + p[3]
220
222 '''boolexpression : boolexpression LOGICALCOMB boolexpression'''
223 if p[2] not in self.logical_equiv:
224 p[0] = p[1] + p[2] + p[3]
225 else:
226 p[0] = p[1] + self.logical_equiv[p[2]] + p[3]
227
229 "expression : '-' expression %prec UMINUS"
230 p[0] = '-' + p[2]
231
233 "group : '(' expression ')'"
234 p[0] = '(' + p[2] +')'
235
237 "boolexpression : '(' boolexpression ')'"
238 p[0] = '(' + p[2] +')'
239
241 "expression : group"
242 p[0] = p[1]
243
245 "expression : FUNCTION '(' expression ')'"
246 p1 = p[1]
247 re_groups = self.re_cmath_function.match(p1)
248 if re_groups:
249 p1 = re_groups.group("name")
250 p[0] = p1 + '(' + p[3] + ')'
251
253 "expression : FUNCTION '(' expression ',' expression ')'"
254 p1 = p[1]
255 re_groups = self.re_cmath_function.match(p1)
256 if re_groups:
257 p1 = re_groups.group("name")
258 p[0] = p1 + '(' + p[3] + ',' + p[5] + ')'
259
266
268 """A parser for UFO algebraic expressions, outputting
269 Fortran-style code."""
270
271
272
273
274 logical_equiv = {'==':'.EQ.',
275 '>=':'.GE.',
276 '<=':'.LE.',
277 '!=':'.NE.',
278 '>':'.GT.',
279 '<':'.LT.',
280 'or':'.OR.',
281 'and':'.AND.'}
282
284 "expression : NUMBER"
285 if p[1].endswith('j'):
286 p[0] = ('DCMPLX(0d0, %e)' % float(p[1][:-1])).replace('e', 'd')
287 else:
288 p[0] = ('%e' % float(p[1])).replace('e', 'd')
289
291 "expression : VARIABLE"
292 p[0] = p[1].lower()
293
295 'expression : expression POWER expression'
296 try:
297 p3 = float(p[3].replace('d','e'))
298
299 if p3 == int(p3):
300 p3 = str(int(p3))
301 p[0] = p[1] + "**" + p3
302 else:
303 p[0] = p[1] + "**" + p[3]
304 except Exception:
305 p[0] = p[1] + "**" + p[3]
306
308 "expression : expression IF boolexpression ELSE expression "
309 p[0] = 'CONDIF(%s,DCMPLX(%s),DCMPLX(%s))' % (p[3], p[1], p[5])
310
312 "expression : expression IF expression ELSE expression "
313 p[0] = 'CONDIF(DCMPLX(%s).NE.(0d0,0d0),DCMPLX(%s),DCMPLX(%s))'\
314 %(p[3], p[1], p[5])
315
317 "expression : COND '(' expression ',' expression ',' expression ')'"
318 p[0] = 'COND(DCMPLX('+p[3]+'),DCMPLX('+p[5]+'),DCMPLX('+p[7]+'))'
319
321 "expression : RECMS '(' boolexpression ',' expression ')'"
322 p[0] = 'RECMS('+p[3]+',DCMPLX('+p[5]+'))'
323
325 "expression : COMPLEX '(' expression ',' expression ')'"
326 p[0] = 'DCMPLX(' + p[3] + ',' + p[5] + ')'
327
329 '''expression : CSC group
330 | SEC group
331 | ACSC group
332 | ASEC group
333 | RE group
334 | IM group
335 | ARG group
336 | SQRT group
337 | CONJ group
338 | REGLOG group
339 | REGLOGP group
340 | REGLOGM group
341 | TAN group
342 | ATAN group'''
343
344 if p[1] == 'csc': p[0] = '1d0/sin' + p[2]
345 elif p[1] == 'sec': p[0] = '1d0/cos' + p[2]
346 elif p[1] == 'acsc': p[0] = 'asin(1./' + p[2] + ')'
347 elif p[1] == 'asec': p[0] = 'acos(1./' + p[2] + ')'
348 elif p[1] in ['atan', 'cmath.atan'] : p[0] = 'atan(dble' + p[2]+')'
349 elif p[1] in ['tan', 'cmath.tan'] : p[0] = 'tan(dble' + p[2]+')'
350 elif p[1] == 're': p[0] = 'dble' + p[2]
351 elif p[1] == 'im': p[0] = 'dimag' + p[2]
352 elif p[1] == 'arg': p[0] = 'arg(DCMPLX'+p[2]+')'
353 elif p[1] == 'cmath.sqrt' or p[1] == 'sqrt': p[0] = 'sqrt(dcmplx' + p[2]+')'
354 elif p[1] == 'complexconjugate': p[0] = 'conjg(DCMPLX' + p[2]+')'
355 elif p[1] == 'reglog': p[0] = 'reglog(DCMPLX' + p[2] +')'
356 elif p[1] == 'reglogp': p[0] = 'reglogp(DCMPLX' + p[2] + ')'
357 elif p[1] == 'reglogm': p[0] = 'reglogm(DCMPLX' + p[2] + ')'
358
359
361 ''' expression : expression RE2 '''
362
363 if p[2] == '.real':
364 if p[1].startswith('('):
365 p[0] = 'dble' +p[1]
366 else:
367 p[0] = 'dble(%s)' % p[1]
368 elif p[2] == '.imag':
369 if p[1].startswith('('):
370 p[0] = 'dimag' +p[1]
371 else:
372 p[0] = 'dimag(%s)' % p[1]
373
375 '''expression : PI'''
376 p[0] = 'pi'
377
379 """A parser for UFO algebraic expressions, outputting
380 Fortran-style code for quadruple precision computation."""
381
382 mp_prefix = check_param_card.ParamCard.mp_prefix
383
384
385
386
388 "expression : NUMBER"
389
390 if p[1].endswith('j'):
391 p[0] = 'CMPLX(0.000000e+00_16, %e_16 ,KIND=16)' % float(p[1][:-1])
392 else:
393 p[0] = '%e_16' % float(p[1])
394
396 "expression : VARIABLE"
397
398 p[0] = (self.mp_prefix+p[1]).lower()
399
401 'expression : expression POWER expression'
402 try:
403 p3 = float(p[3].replace('_16',''))
404
405 if p3 == int(p3):
406 p3 = str(int(p3))
407 p[0] = p[1] + "**" + p3
408 else:
409 p[0] = p[1] + "**" + p[3]
410 except Exception:
411 p[0] = p[1] + "**" + p[3]
412
414 "expression : expression IF boolexpression ELSE expression "
415 p[0] = 'MP_CONDIF(%s,CMPLX(%s,KIND=16),CMPLX(%s,KIND=16))' % (p[3], p[1], p[5])
416
418 "expression : expression IF expression ELSE expression "
419 p[0] = 'MP_CONDIF(CMPLX(%s,KIND=16).NE.(0.0e0_16,0.0e0_16),CMPLX(%s,KIND=16),CMPLX(%s,KIND=16))'\
420 %(p[3], p[1], p[5])
421
423 "expression : COMPLEX '(' expression ',' expression ')'"
424 p[0] = 'CMPLX(' + p[3] + ',' + p[5] + ',KIND=16)'
425
427 "expression : COND '(' expression ',' expression ',' expression ')'"
428 p[0] = 'MP_COND(CMPLX('+p[3]+',KIND=16),CMPLX('+p[5]+\
429 ',KIND=16),CMPLX('+p[7]+',KIND=16))'
430
432 "expression : RECMS '(' boolexpression ',' expression ')'"
433 p[0] = 'MP_RECMS('+p[3]+',CMPLX('+p[5]+',KIND=16))'
434
436 '''expression : CSC group
437 | SEC group
438 | ACSC group
439 | ASEC group
440 | RE group
441 | IM group
442 | ARG group
443 | SQRT group
444 | CONJ group
445 | REGLOG group
446 | REGLOGP group
447 | REGLOGM group
448 | TAN group
449 | ATAN group'''
450
451 if p[1] == 'csc': p[0] = '1e0_16/cos' + p[2]
452 elif p[1] == 'sec': p[0] = '1e0_16/sin' + p[2]
453 elif p[1] == 'acsc': p[0] = 'asin(1e0_16/' + p[2] + ')'
454 elif p[1] == 'asec': p[0] = 'acos(1e0_16/' + p[2] + ')'
455 elif p[1] in ['atan', 'cmath.atan'] : p[0] = 'atan(real' + p[2]+')'
456 elif p[1] in ['tan', 'cmath.tan']: p[0] = 'tan(real' + p[2]+')'
457 elif p[1] == 're': p[0] = 'real' + p[2]
458 elif p[1] == 'im': p[0] = 'imag' + p[2]
459 elif p[1] == 'arg': p[0] = 'mp_arg(CMPLX(' + p[2] + ',KIND=16))'
460 elif p[1] == 'cmath.sqrt' or p[1] == 'sqrt': p[0] = 'sqrt(CMPLX(' + p[2] + ',KIND=16))'
461 elif p[1] == 'complexconjugate': p[0] = 'conjg(CMPLX(' + p[2] + ',KIND=16))'
462 elif p[1] == 'reglog': p[0] = 'mp_reglog(CMPLX(' + p[2] +',KIND=16))'
463 elif p[1] == 'reglogp': p[0] = 'mp_reglogp(CMPLX(' + p[2] + ',KIND=16))'
464 elif p[1] == 'reglogm': p[0] = 'mp_reglogm(CMPLX(' + p[2] + ',KIND=16))'
465
467 ''' expression : expression RE2 '''
468
469 if p[2] == '.real':
470 if p[1].startswith('('):
471 p[0] = 'real' +p[1]
472 else:
473 p[0] = 'real(%s)' % p[1]
474 elif p[2] == '.imag':
475 if p[1].startswith('('):
476 p[0] = 'imag' +p[1]
477 else:
478 p[0] = 'imag(%s)' % p[1]
479
480
482 '''expression : PI'''
483 p[0] = self.mp_prefix+'pi'
484
486 """A parser for UFO algebraic expressions, outputting
487 C++-style code."""
488
489 logical_equiv = {'==':'==',
490 '>=':'>=',
491 '<=':'<=',
492 '!=':'!=',
493 '>':'>',
494 '<':'<',
495 'or':'||',
496 'and':'&&'}
497
498
499
500
502 'expression : NUMBER'
503
504 if p[1].endswith('j'):
505 p[0] = 'std::complex<double>(0., %e)' % float(p[1][:-1])
506 else:
507 p[0] = ('%e' % float(p[1])).replace('e', 'd')
508
509
510 p[0] = p[1]
511
512 if float(p[1]) == int(float(p[1])) and float(p[1]) < 1000:
513 p[0] = str(int(float(p[1]))) + '.'
514
516 'expression : VARIABLE'
517 p[0] = p[1]
518
520 "expression : expression IF boolexpression ELSE expression "
521 p[0] = '(%s ? %s : %s)' % (p[3], p[1], p[5])
522
524 "expression : expression IF expression ELSE expression "
525 p[0] = '(%s ? %s : %s)' % (p[3], p[1], p[5])
526
528 "expression : COND '(' expression ',' expression ',' expression ')'"
529 p[0] = 'COND('+p[3]+','+p[5]+','+p[7]+')'
530
532 "expression : RECMS '(' boolexpression ',' expression ')'"
533 p[0] = 'RECMS('+p[3]+','+p[5]+')'
534
536 'expression : expression POWER expression'
537 p1=p[1]
538 p3=p[3]
539 if p[1][0] == '(' and p[1][-1] == ')':
540 p1 = p[1][1:-1]
541 if p[3][0] == '(' and p[3][-1] == ')':
542 p3 = p[3][1:-1]
543 if float(p3) == 2:
544 p[0] = '((' + p1 + ')*(' + p1 + '))'
545 elif float(p3) == 3:
546 p[0] = '((' + p1 + ')*(' + p1 + ')*(' + p1 + '))'
547 elif float(p3) == 4:
548 p[0] = '((' + p1 + ')*(' + p1 + ')*(' + p1 + ')*(' + p1 + '))'
549 elif float(p3) == 0.5 or p3 == '0.5' or p3 == '1./2' or p3 == '1/2.' or p3 == '1./2.':
550 p[0] = 'sqrt(' + p1 + ')'
551 elif float(p3) == 1./3 or p3 == '1./3' or p3 == '1/3.' or p3 == '1./3.':
552 p[0] = 'cbrt(' + p1 + ')'
553 else:
554 p[0] = 'pow(' + p1 + ',' + p3 + ')'
555
557 "expression : COMPLEX '(' expression ',' expression ')'"
558 p[0] = 'std::complex<double>(' + p[3] + ',' + p[5] + ')'
559
561 '''expression : CSC group
562 | SEC group
563 | ACSC group
564 | ASEC group
565 | TAN group
566 | ATAN group
567 | RE group
568 | IM group
569 | ARG group
570 | SQRT group
571 | CONJ group
572 | REGLOG group
573 | REGLOGP group
574 | REGLOGM group'''
575 if p[1] == 'csc': p[0] = '1./cos' + p[2]
576 elif p[1] == 'sec': p[0] = '1./sin' + p[2]
577 elif p[1] == 'acsc': p[0] = 'asin(1./' + p[2] + ')'
578 elif p[1] == 'asec': p[0] = 'acos(1./' + p[2] + ')'
579 elif p[1] in ['atan', 'cmath.atan']: p[0] = 'atan' +p[2]
580 elif p[1] in ['tan', 'cmath.tan']: p[0] = 'tan' +p[2]
581 elif p[1] == 're': p[0] = 'real' + p[2]
582 elif p[1] == 'im': p[0] = 'imag' + p[2]
583 elif p[1] == 'arg':p[0] = 'arg' + p[2]
584 elif p[1] == 'cmath.sqrt' or p[1] == 'sqrt': p[0] = 'sqrt' + p[2]
585 elif p[1] == 'complexconjugate': p[0] = 'conj' + p[2]
586 elif p[1] == 'reglog': p[0] = 'reglog' + p[2]
587 elif p[1] == 'reglogp': p[0] = 'reglogp' + p[2]
588 elif p[1] == 'reglogm': p[0] = 'reglogm' + p[2]
589
591 ''' expression : expression RE2 '''
592
593 if p[2] == '.real':
594 if p[1].startswith('('):
595 p[0] = 'real' +p[1]
596 else:
597 p[0] = 'real(%s)' % p[1]
598 elif p[2] == '.imag':
599 if p[1].startswith('('):
600 p[0] = 'imag' +p[1]
601 else:
602 p[0] = 'imag(%s)' % p[1]
603
604
606 '''expression : PI'''
607 p[0] = 'M_PI'
608
610 """An ad hoc parser for UFO algebraic expressions with if statement, outputting
611 Python-style code, with the conditional 'if' expressions simplified using
612 pre-defined set of variables specified when instanciating this parser."""
613
614 logical_equiv = {'==':'==',
615 '>=':'>=',
616 '<=':'<=',
617 '!=':'!=',
618 '>':'>',
619 '<':'<',
620 'or':' or ',
621 'and':' and '}
622
624 """Initialize the lex and yacc"""
625
626 self.changes_performed = 0
627
628 if len(args) > 0:
629 if isinstance(args[0],dict):
630 self.defined_variables = copy.copy(args[0])
631 elif isinstance(args[0],str):
632 try:
633 self.defined_variables = eval(args[0])
634 except:
635 raise ModelError, 'The expression "%s"'%str(args[0])+\
636 " given as defined variables for the UFOExpressionParserPythonIF"+\
637 " does not have a correct syntax."
638 if not isinstance(self.defined_variables, dict):
639 raise ModelError, 'The argument "%s"'%str(args[0])+\
640 " given as defined variables for the UFOExpressionParserPythonIF"+\
641 " is not a dictionary."
642 else:
643 raise ModelError, "The argument %s"%str(args[0])+\
644 " given as defined variables for the UFOExpressionParserPythonIF"+\
645 " must be either a dictionary or a string."
646 args = args[1:]
647 for key, value in self.defined_variables.items():
648 if not isinstance(key,str) or \
649 not any(isinstance(value,t) for t in [float,complex,int]):
650
651 del self.defined_variables[key]
652
653 else:
654
655
656
657 self.defined_variables = None
658
659 super(UFOExpressionParserPythonIF,self).__init__(*args, **kw)
660
661 - def parse(self, *args, **kw):
662 """ Wrapper around the parse function so as to also return the number
663 of if substitutions made."""
664 self.changes_performed = 0
665 new_expression = super(UFOExpressionParserPythonIF,self).parse(*args, **kw)
666 return new_expression, self.changes_performed
667
669 "expression : NUMBER"
670 p[0] = p[1]
671
673 "expression : VARIABLE"
674 p[0] = p[1]
675
677 'expression : expression POWER expression'
678 p[0] = p[1] + "**" + p[3]
679
681 "expression : expression IF boolexpression ELSE expression "
682 if self.defined_variables is None:
683 p[0] = '%s if %s else %s'%(p[1],p[3],p[5])
684 return
685 try:
686 p[0] = '%s'%p[1] if eval(p[3],self.defined_variables) else '%s'%p[5]
687 self.changes_performed += 1
688 except Exception:
689 p[0] = '%s if %s else %s'%(p[1],p[3],p[5])
690
692 "expression : expression IF expression ELSE expression "
693 if self.defined_variables is None:
694 p[0] = '%s if %s!=0.0 else %s'%(p[1],p[3],p[5])
695 return
696 try:
697 p[0] = '%s'%p[1] if eval(p[3]+'!= 0.0',self.defined_variables) else '%s'%p[5]
698 self.changes_performed += 1
699 except Exception:
700 p[0] = '%s if %s!=0.0 else %s'%(p[1],p[3],p[5])
701
703 "expression : COND '(' expression ',' expression ',' expression ')'"
704
705
706 p[0] = 'cond('+p[3]+','+p[5]+','+p[7]+')'
707
709 "expression : COMPLEX '(' expression ',' expression ')'"
710 p[0] = 'complex(' + p[3] + ',' + p[5] + ')'
711
713 "expression : RECMS '(' boolexpression ',' expression ')'"
714 p[0] = 'recms('+p[3]+','+p[5]+')'
715
717 '''expression : CSC group
718 | SEC group
719 | ACSC group
720 | ASEC group
721 | RE group
722 | IM group
723 | ARG group
724 | SQRT group
725 | TAN group
726 | ATAN group
727 | CONJ group
728 | REGLOG group
729 | REGLOGP group
730 | REGLOGM group'''
731 if p[1] == 'csc': p[0] = 'csc' + p[2]
732 elif p[1] == 'sec': p[0] = 'sec' + p[2]
733 elif p[1] == 'acsc': p[0] = 'acsc' + p[2]
734 elif p[1] == 'asec': p[0] = 'asec' + p[2]
735 elif p[1] in ['tan','cmath.tan']: p[0] = 'tan' + p[2]
736 elif p[1] in ['atan','cmath.atan']: p[0] = 'atan' + p[2]
737 elif p[1] == 're': p[0] = 're' + p[2]
738 elif p[1] == 'im': p[0] = 'im' + p[2]
739 elif p[1] == 'arg': p[0] = 'arg' + p[2]
740 elif p[1] == 'cmath.sqrt' or p[1] == 'sqrt': p[0] = 'cmath.sqrt' + p[2]
741 elif p[1] == 'complexconjugate': p[0] = 'complexconjugate' + p[2]
742 elif p[1] == 'reglog': p[0] = 'reglog' + p[2]
743 elif p[1] == 'reglogp': p[0] = 'reglogp' + p[2]
744 elif p[1] == 'reglogm': p[0] = 'reglogm' + p[2]
745
747 ''' expression : expression RE2 '''
748 p[0] = p[1]+p[2]
749
751 '''expression : PI'''
752 p[0] = 'cmath.pi'
753
754
755
756
757 if __name__ == '__main__':
758
759 if len(sys.argv) == 1:
760 print "Please specify a parser: fortran, mpfortran or c++"
761 exit()
762 if sys.argv[1] == "fortran":
763 calc = UFOExpressionParserFortran()
764 elif sys.argv[1] == "mpfortran":
765 calc = UFOExpressionParserMPFortran()
766 elif sys.argv[1] == "c++":
767 calc = UFOExpressionParserCPP()
768 elif sys.argv[1] == "aloha":
769 calc = UFOExpressionParserCPP()
770 elif sys.argv[1] == "pythonif":
771 if len(sys.argv) > 2:
772 calc = UFOExpressionParserPythonIF(sys.argv[2])
773 else:
774 calc = UFOExpressionParserPythonIF()
775 else:
776 print "Please specify a parser: fortran, mpfortran, c++ or pythonif"
777 print "You gave", sys.argv[1]
778 if len(sys.argv) > 2:
779 print "with the second argument",sys.argv[2]
780 exit()
781
782 while 1:
783 try:
784 s = raw_input('calc > ')
785 except EOFError:
786 break
787 if not s: continue
788 print calc.parse(s)
789