Package aloha :: Module aloha_parsers
[hide private]
[frames] | no frames]

Source Code for Module aloha.aloha_parsers

  1  ################################################################################ 
  2  # 
  3  # Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors 
  4  # 
  5  # This file is a part of the MadGraph5_aMC@NLO project, an application which  
  6  # automatically generates Feynman diagrams and matrix elements for arbitrary 
  7  # high-energy processes in the Standard Model and beyond. 
  8  # 
  9  # It is subject to the MadGraph5_aMC@NLO license which should accompany this  
 10  # distribution. 
 11  # 
 12  # For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch 
 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  from __future__ import division 
 21   
 22  from __future__ import absolute_import 
 23  from __future__ import print_function 
 24  import logging 
 25  import numbers 
 26  import os 
 27  import re 
 28  import sys 
 29  from six.moves import input 
 30  from six.moves import range 
 31   
 32   
 33  root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0] 
 34  sys.path.append(os.path.join(root_path)) 
 35   
 36  from . import aloha_lib 
 37  from .aloha_object import * 
 38  import vendor.ply.lex as lex 
 39  import vendor.ply.yacc as yacc 
 40  from aloha.aloha_lib import KERNEL 
 41  logger = logging.getLogger('aloha.parsers') 
 42   
 43  try: 
 44      import madgraph.various.misc as misc 
 45  except Exception: 
 46      import aloha.misc as misc 
 47   
 48   
 49  # PLY lexer class 
50 -class UFOExpressionParser(object):
51 """A base class for parsers for algebraic expressions coming from UFO.""" 52 53 parsed_string = "" 54
55 - def __init__(self, **kw):
56 """Ininitialize the lex and yacc""" 57 58 modname = self.__class__.__name__ 59 self.debugfile = os.path.devnull 60 self.tabmodule = os.path.join(root_path, "iolibs", modname + "_" + "parsetab.py") 61 lex.lex(module=self, debug=0) 62 yacc.yacc(module=self, debug=0, debugfile=self.debugfile, 63 tabmodule=self.tabmodule)
64
65 - def parse(self, buf):
66 """Parse the string buf""" 67 yacc.parse(buf) 68 return self.parsed_string
69 70 # List of tokens and literals 71 tokens = ( 72 'POWER', 'CSC', 'SEC', 'ACSC', 'ASEC', 73 'SQRT', 'CONJ', 'RE', 'IM', 'PI', 'COMPLEX', 'FUNCTION', 74 'VARIABLE', 'NUMBER' 75 ) 76 literals = "=+-*/(),'" 77 78 # Definition of tokens 79
80 - def t_CSC(self, t):
81 r'(?<!\w)csc(?=\()' 82 return t
83 - def t_SEC(self, t):
84 r'(?<!\w)sec(?=\()' 85 return t
86 - def t_ACSC(self, t):
87 r'(?<!\w)acsc(?=\()' 88 return t
89 - def t_ASEC(self, t):
90 r'(?<!\w)asec(?=\()' 91 return t
92 - def t_SQRT(self, t):
93 r'cmath\.sqrt' 94 return t
95 - def t_PI(self, t):
96 r'cmath\.pi' 97 return t
98 - def t_CONJ(self, t):
99 r'complexconjugate' 100 return t
101 - def t_IM(self, t):
102 r'(?<!\w)im(?=\()' 103 return t
104 - def t_RE(self, t):
105 r'(?<!\w)re(?=\()' 106 return t
107 - def t_COMPLEX(self, t):
108 r'(?<!\w)complex(?=\()' 109 return t
110 - def t_FUNCTION(self, t):
111 r'(cmath\.){0,1}[a-zA-Z_][0-9a-zA-Z_]*(?=\()' 112 return t
113 - def t_VARIABLE(self, t):
114 r'[a-zA-Z_][0-9a-zA-Z_]*' 115 return t
116 117 t_NUMBER = r'([0-9]+\.[0-9]*|\.[0-9]+|[0-9]+)([eE][+-]{0,1}[0-9]+){0,1}' 118 t_POWER = r'\*\*' 119 120 t_ignore = " \t" 121 122 re_cmath_function = re.compile("cmath\.(?P<name>[0-9a-zA-Z_]+)") 123
124 - def t_newline(self, t):
125 r'\n+' 126 t.lexer.lineno += t.value.count("\n")
127
128 - def t_error(self, t):
129 logger.error("Illegal character '%s'" % t.value[0]) 130 t.lexer.skip(1)
131 132 # Build the lexer
133 - def build(self,**kwargs):
134 self.lexer = lex.lex(module=self, **kwargs)
135 136 # Definitions for the PLY yacc parser 137 138 # Parsing rules 139 precedence = ( 140 ('left','='), 141 ('left','+','-'), 142 ('left','*','/'), 143 ('right','UMINUS'), 144 ('left','POWER'), 145 ('right','CSC'), 146 ('right','SEC'), 147 ('right','ACSC'), 148 ('right','ASEC'), 149 ('right','SQRT'), 150 ('right','CONJ'), 151 ('right','RE'), 152 ('right','IM'), 153 ('right','FUNCTION'), 154 ('right','COMPLEX') 155 ) 156 157 # Dictionary of parser expressions
158 - def p_statement_expr(self, p):
159 'statement : expression' 160 self.parsed_string = p[1]
161
162 - def p_expression_binop(self, p):
163 '''expression : expression '=' expression 164 | expression '+' expression 165 | expression '-' expression 166 | expression '*' expression 167 | expression '/' expression''' 168 p[0] = p[1] + p[2] + p[3]
169
170 - def p_expression_uminus(self, p):
171 "expression : '-' expression %prec UMINUS" 172 p[0] = '-' + p[2]
173
174 - def p_group_parentheses(self, p):
175 "group : '(' expression ')'" 176 p[0] = '(' + p[2] +')'
177
178 - def p_expression_group(self, p):
179 "expression : group" 180 p[0] = p[1]
181 182
183 - def p_error(self, p):
184 if p: 185 try: 186 print(p) 187 print(p[:]) 188 print(p.value) 189 except: 190 pass 191 raise Exception("Syntax error at '%s' in '%s'" % (p.value, self.f)) 192 else: 193 logger.error("Syntax error at EOF") 194 self.parsed_string = "Error"
195 196
197 -class ALOHAExpressionParser(UFOExpressionParser):
198 199 aloha_object = ['P', 'PBar', 'PVec','Gamma','Gamma5','Sigma','Mass','PSlash', 200 'OverMass2','Width','Scalar','Spinor','Vector', 201 'Spin2','Spin32','C','Epsilon','Metric','Identity', 202 'ProjM','ProjP','Coup','Norm', 'EPSL', 'EPST1', 'EPST2', 'PT', 203 'UFP', 'UFM', 'UFPC', 'UFMC', 204 'VFP', 'VFM', 'VFPC', 'VFMC', 205 'Tnorm', 'TnormZ'] 206
207 - def p_expression_pi(self, p):
208 '''expression : PI''' 209 KERNEL.has_pi = True 210 p[0] = 'Param(\'PI\')'
211
212 - def p_expression_power(self, p):
213 'expression : expression POWER expression' 214 215 obj = p[1] 216 if '(' in p[1]: 217 obj = p[1].split('(',1)[0] 218 219 if obj in self.aloha_object: 220 p2 = [x for i,x in enumerate(p) if i>0] 221 p[0] = ''.join(p2) 222 else: 223 new = aloha_lib.KERNEL.add_function_expression('pow', eval(p[1]), eval(p[3])) 224 p[0] = str(new)
225 226
227 - def p_expression_variable(self, p):
228 "expression : VARIABLE" 229 p[0] = 'Param(\'%s\')' % p[1]
230
231 - def p_expression_variable2(self, p):
232 "expression : '\\'' VARIABLE '\\''" 233 p[0] = '\'%s\'' % p[2]
234
235 - def p_expression_expression(self, p):
236 "expression : '\\'' expression '\\''" 237 p[0] = '\'%s\'' % p[2]
238
239 - def p_expression_complex(self, p):
240 "expression : COMPLEX '(' expression ',' expression ')'" 241 p[0] = 'complex(' + p[3] + ',' + p[5] + ')'
242
243 - def p_expression_number(self, p):
244 "expression : NUMBER" 245 p[0] = p[1] 246 if float(p[1]) == int(float(p[1])) and float(p[1]) < 1000: 247 p[0] = str(int(float(p[1])))
248
249 - def p_expression_func(self, p):
250 '''expression : CSC group 251 | SEC group 252 | ACSC group 253 | ASEC group 254 | RE group 255 | IM group 256 | SQRT group 257 | CONJ group''' 258 259 new = aloha_lib.KERNEL.add_function_expression(p[1], eval(p[2])) 260 p[0] = str(new)
261
262 - def p_expression_function(self, p):
263 """expression : FUNCTION '(' expression ')' 264 expression : FUNCTION '(' expression ',' expression ')' 265 expression : FUNCTION '(' expression ',' expression ',' expression ')' 266 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ')' 267 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ')' 268 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 269 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 270 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 271 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 272 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 273 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 274 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 275 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 276 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 277 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 278 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 279 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 280 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 281 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 282 expression : FUNCTION '(' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ',' expression ')' 283 """ 284 if p[1] in self.aloha_object: 285 p[0] = ''.join(p[1:]) 286 return 287 288 p1 = p[1] 289 re_groups = self.re_cmath_function.match(p1) 290 if re_groups: 291 p1 = re_groups.group("name") 292 args = [eval(p[2*i+1]) for i in range(1, len(p)//2)] 293 new = aloha_lib.KERNEL.add_function_expression(p1, *args) 294 p[0] = str(new)
295
296 - def p_expression_binop(self, p):
297 '''expression : expression '=' expression 298 | expression '+' expression 299 | expression '-' expression 300 | expression '*' expression 301 | expression '/' expression''' 302 if p[2] != '/' or p[3].isdigit() or p[3].endswith('.'): 303 p[0] = p[1] + p[2] + p[3] 304 else: 305 denom = eval(p[3]) 306 if isinstance(denom, numbers.Number): 307 p[0] = p[1] + '*' + str(1/denom) 308 else: 309 new = aloha_lib.KERNEL.add_function_expression('/', denom) 310 p[0] = p[1] + ' * ' + str(new)
311 312 313 314 315 # Main program, allows to interactively test the parser 316 if __name__ == '__main__': 317 318 319 calc = ALOHAExpressionParser() 320 while 1: 321 try: 322 s = input('calc > ') 323 except EOFError: 324 break 325 if not s: continue 326 logger.info(calc.parse(s)) 327