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 p[0] = 'pow(' + p1 + ',' + p3 + ')'
544
546 "expression : COMPLEX '(' expression ',' expression ')'"
547 p[0] = 'std::complex<double>(' + p[3] + ',' + p[5] + ')'
548
550 '''expression : CSC group
551 | SEC group
552 | ACSC group
553 | ASEC group
554 | TAN group
555 | ATAN group
556 | RE group
557 | IM group
558 | ARG group
559 | SQRT group
560 | CONJ group
561 | REGLOG group
562 | REGLOGP group
563 | REGLOGM group'''
564 if p[1] == 'csc': p[0] = '1./cos' + p[2]
565 elif p[1] == 'sec': p[0] = '1./sin' + p[2]
566 elif p[1] == 'acsc': p[0] = 'asin(1./' + p[2] + ')'
567 elif p[1] == 'asec': p[0] = 'acos(1./' + p[2] + ')'
568 elif p[1] in ['atan', 'cmath.atan']: p[0] = 'atan' +p[2]
569 elif p[1] in ['tan', 'cmath.tan']: p[0] = 'tan' +p[2]
570 elif p[1] == 're': p[0] = 'real' + p[2]
571 elif p[1] == 'im': p[0] = 'imag' + p[2]
572 elif p[1] == 'arg':p[0] = 'arg' + p[2]
573 elif p[1] == 'cmath.sqrt' or p[1] == 'sqrt': p[0] = 'sqrt' + p[2]
574 elif p[1] == 'complexconjugate': p[0] = 'conj' + p[2]
575 elif p[1] == 'reglog': p[0] = 'reglog' + p[2]
576 elif p[1] == 'reglogp': p[0] = 'reglogp' + p[2]
577 elif p[1] == 'reglogm': p[0] = 'reglogm' + p[2]
578
580 ''' expression : expression RE2 '''
581
582 if p[2] == '.real':
583 if p[1].startswith('('):
584 p[0] = 'real' +p[1]
585 else:
586 p[0] = 'real(%s)' % p[1]
587 elif p[2] == '.imag':
588 if p[1].startswith('('):
589 p[0] = 'imag' +p[1]
590 else:
591 p[0] = 'imag(%s)' % p[1]
592
593
595 '''expression : PI'''
596 p[0] = 'M_PI'
597
599 """An ad hoc parser for UFO algebraic expressions with if statement, outputting
600 Python-style code, with the conditional 'if' expressions simplified using
601 pre-defined set of variables specified when instanciating this parser."""
602
603 logical_equiv = {'==':'==',
604 '>=':'>=',
605 '<=':'<=',
606 '!=':'!=',
607 '>':'>',
608 '<':'<',
609 'or':' or ',
610 'and':' and '}
611
613 """Initialize the lex and yacc"""
614
615 self.changes_performed = 0
616
617 if len(args) > 0:
618 if isinstance(args[0],dict):
619 self.defined_variables = copy.copy(args[0])
620 elif isinstance(args[0],str):
621 try:
622 self.defined_variables = eval(args[0])
623 except:
624 raise ModelError, 'The expression "%s"'%str(args[0])+\
625 " given as defined variables for the UFOExpressionParserPythonIF"+\
626 " does not have a correct syntax."
627 if not isinstance(self.defined_variables, dict):
628 raise ModelError, 'The argument "%s"'%str(args[0])+\
629 " given as defined variables for the UFOExpressionParserPythonIF"+\
630 " is not a dictionary."
631 else:
632 raise ModelError, "The argument %s"%str(args[0])+\
633 " given as defined variables for the UFOExpressionParserPythonIF"+\
634 " must be either a dictionary or a string."
635 args = args[1:]
636 for key, value in self.defined_variables.items():
637 if not isinstance(key,str) or \
638 not any(isinstance(value,t) for t in [float,complex,int]):
639
640 del self.defined_variables[key]
641
642 else:
643
644
645
646 self.defined_variables = None
647
648 super(UFOExpressionParserPythonIF,self).__init__(*args, **kw)
649
650 - def parse(self, *args, **kw):
651 """ Wrapper around the parse function so as to also return the number
652 of if substitutions made."""
653 self.changes_performed = 0
654 new_expression = super(UFOExpressionParserPythonIF,self).parse(*args, **kw)
655 return new_expression, self.changes_performed
656
658 "expression : NUMBER"
659 p[0] = p[1]
660
662 "expression : VARIABLE"
663 p[0] = p[1]
664
666 'expression : expression POWER expression'
667 p[0] = p[1] + "**" + p[3]
668
670 "expression : expression IF boolexpression ELSE expression "
671 if self.defined_variables is None:
672 p[0] = '%s if %s else %s'%(p[1],p[3],p[5])
673 return
674 try:
675 p[0] = '%s'%p[1] if eval(p[3],self.defined_variables) else '%s'%p[5]
676 self.changes_performed += 1
677 except Exception:
678 p[0] = '%s if %s else %s'%(p[1],p[3],p[5])
679
681 "expression : expression IF expression ELSE expression "
682 if self.defined_variables is None:
683 p[0] = '%s if %s!=0.0 else %s'%(p[1],p[3],p[5])
684 return
685 try:
686 p[0] = '%s'%p[1] if eval(p[3]+'!= 0.0',self.defined_variables) else '%s'%p[5]
687 self.changes_performed += 1
688 except Exception:
689 p[0] = '%s if %s!=0.0 else %s'%(p[1],p[3],p[5])
690
692 "expression : COND '(' expression ',' expression ',' expression ')'"
693
694
695 p[0] = 'cond('+p[3]+','+p[5]+','+p[7]+')'
696
698 "expression : COMPLEX '(' expression ',' expression ')'"
699 p[0] = 'complex(' + p[3] + ',' + p[5] + ')'
700
702 "expression : RECMS '(' boolexpression ',' expression ')'"
703 p[0] = 'recms('+p[3]+','+p[5]+')'
704
706 '''expression : CSC group
707 | SEC group
708 | ACSC group
709 | ASEC group
710 | RE group
711 | IM group
712 | ARG group
713 | SQRT group
714 | TAN group
715 | ATAN group
716 | CONJ group
717 | REGLOG group
718 | REGLOGP group
719 | REGLOGM group'''
720 if p[1] == 'csc': p[0] = 'csc' + p[2]
721 elif p[1] == 'sec': p[0] = 'sec' + p[2]
722 elif p[1] == 'acsc': p[0] = 'acsc' + p[2]
723 elif p[1] == 'asec': p[0] = 'asec' + p[2]
724 elif p[1] in ['tan','cmath.tan']: p[0] = 'tan' + p[2]
725 elif p[1] in ['atan','cmath.atan']: p[0] = 'atan' + p[2]
726 elif p[1] == 're': p[0] = 're' + p[2]
727 elif p[1] == 'im': p[0] = 'im' + p[2]
728 elif p[1] == 'arg': p[0] = 'arg' + p[2]
729 elif p[1] == 'cmath.sqrt' or p[1] == 'sqrt': p[0] = 'cmath.sqrt' + p[2]
730 elif p[1] == 'complexconjugate': p[0] = 'complexconjugate' + p[2]
731 elif p[1] == 'reglog': p[0] = 'reglog' + p[2]
732 elif p[1] == 'reglogp': p[0] = 'reglogp' + p[2]
733 elif p[1] == 'reglogm': p[0] = 'reglogm' + p[2]
734
736 ''' expression : expression RE2 '''
737 p[0] = p[1]+p[2]
738
740 '''expression : PI'''
741 p[0] = 'cmath.pi'
742
743
744
745
746 if __name__ == '__main__':
747
748 if len(sys.argv) == 1:
749 print "Please specify a parser: fortran, mpfortran or c++"
750 exit()
751 if sys.argv[1] == "fortran":
752 calc = UFOExpressionParserFortran()
753 elif sys.argv[1] == "mpfortran":
754 calc = UFOExpressionParserMPFortran()
755 elif sys.argv[1] == "c++":
756 calc = UFOExpressionParserCPP()
757 elif sys.argv[1] == "aloha":
758 calc = UFOExpressionParserCPP()
759 elif sys.argv[1] == "pythonif":
760 if len(sys.argv) > 2:
761 calc = UFOExpressionParserPythonIF(sys.argv[2])
762 else:
763 calc = UFOExpressionParserPythonIF()
764 else:
765 print "Please specify a parser: fortran, mpfortran, c++ or pythonif"
766 print "You gave", sys.argv[1]
767 if len(sys.argv) > 2:
768 print "with the second argument",sys.argv[2]
769 exit()
770
771 while 1:
772 try:
773 s = raw_input('calc > ')
774 except EOFError:
775 break
776 if not s: continue
777 print calc.parse(s)
778