12 ''' A simple Fortran expression parser. Note that this does not parse Fortran,
13 only legal Fortran expressions. '''
15 import pyparsing
as pparse
17 pparse.ParserElement.enablePackrat()
21 '''Base class for all expression tree nodes'''
25 ''' The recursive collection of names enables the dependencies of
26 expressions to be analysed. '''
27 self.
namesnames = set()
29 if isinstance(tok, ExpressionNode):
30 self.
namesnames.update(tok.names)
37 '''Expression node for a parenthesised expression.'''
39 ExpressionNode.__init__(self, toks)
41 self.
exprexpr = toks[1]
44 return "Grouping(['('," + repr(self.
exprexpr) +
",')'])"
47 return "(" + str(self.
exprexpr) +
")"
51 '''Expression node for one or more binary operators with the same
54 For some reason, operator tokens come in a list of lists.'''
56 ExpressionNode.__init__(self, toks[0])
71 _str =
"BinaryOperator([["+repr(self.
operandsoperands[0])
73 _str +=
", " + repr(sym) +
", " + repr(opd)
78 return str(self.
operandsoperands[0]) + \
79 "".join([
" "+str(sym)+
" "+str(opd)
for sym, opd
in
84 """Expression node for Fortran colon array slicings."""
86 ExpressionNode.__init__(self, toks)
106 except StopIteration:
112 _str += repr(self.
startstart)+
", "
115 _str +=
", "+repr(self.
stopstop)
117 _str +=
", ':', "+repr(self.
stridestride)
122 _str = str(self.
startstart)+
":"+str(self.
stopstop)
124 _str +=
":"+str(self.
stridestride)
129 '''Expression node for a Fortran variable or function call.'''
131 ExpressionNode.__init__(self, toks)
133 self.
namename = toks[0]
141 self.
argsargs = toks[2:-1]
147 _str =
"FunctionVar(['" + self.
namename +
"'"
151 _str +=
", ".join([repr(a)
for a
in self.
argsargs]) +
","
157 _str = str(self.
namename)
160 if self.
argsargs
is not None:
161 _str +=
", ".join([str(a)
for a
in self.
argsargs])
167 '''Expression node for a Fortran literal array.'''
169 ExpressionNode.__init__(self, toks)
170 self.
exprexpr = toks[1:-1]
172 def __getitem__(self, idx):
173 return self.
exprexpr[idx]
176 return len(self.
exprexpr)
179 _str =
"LiteralArray(['[',"
181 _str +=
", ".join([repr(a)
for a
in self.
exprexpr])
186 _str =
"[" + str(self.
exprexpr[0])
187 for tok
in self.
exprexpr[1:]:
194 ''' Expression node for a Fortran named argument. '''
196 ExpressionNode.__init__(self, toks)
199 self.
_name_name = toks[0]
208 first_char = toks[2][0]
209 if first_char
in [
"'",
'"']:
212 self.
_quote_quote = toks[2][0]
213 self.
_value_value = toks[2][1:-1]
217 self.
_value_value = toks[2]
221 if self.
_quote_quote ==
"'":
222 _str = f
"NamedArg(['{self._name}', '=', \"'{self._value}'\"])"
224 _str = f
'NamedArg(["{self._name}", "=", \'"{self._value}"\'])'
226 _str = f
"NamedArg(['{self._name}', '=', '{self._value}'])"
230 _str = str(self.
_name_name) +
"="
234 _str += str(self.
_value_value)
239 ''' Returns the name of the variable (LHS) involved in a
241 return self.
_name_name
245 ''' Returns the value (RHS) of the named argument '''
250 ''' Returns True if the RHS of the named argument is a string '''
251 return self.
_quote_quote
is not None
258 VAR_NAME = pparse.Word(pparse.alphas, pparse.alphanums+
"_")
259 NAME = VAR_NAME | pparse.Literal(
".false.") | pparse.Literal(
".true.")
262 DERIVED_TYPE_COMPONENT = pparse.Combine(VAR_NAME +
"%" + VAR_NAME)
265 UNSIGNED = pparse.Word(pparse.nums)
269 KIND = pparse.Word(
"_", exact=1) + (VAR_NAME | UNSIGNED)
273 SIGNED = pparse.Word(
"+-"+pparse.nums, pparse.nums)
274 INTEGER = pparse.Combine(SIGNED + pparse.Optional(KIND))
276 POINT = pparse.Literal(
".")
279 REAL = pparse.Combine(
280 (SIGNED + POINT + pparse.Optional(UNSIGNED) | POINT + UNSIGNED) +
281 pparse.Optional(pparse.Word(
"dDeE", exact=1) + SIGNED) +
282 pparse.Optional(KIND))
285 LPAR = pparse.Literal(
"(")
286 RPAR = pparse.Literal(
")")
288 LIT_ARRAY_START = pparse.Literal(
"[") | pparse.Literal(
"(/")
289 LIT_ARRAY_END = pparse.Literal(
"]") | pparse.Literal(
"/)")
291 EXPR = pparse.Forward()
294 COLON = pparse.Literal(
":")
295 SLICING = pparse.Optional(EXPR) + COLON + pparse.Optional(EXPR) + \
296 pparse.Optional(COLON+pparse.Optional(EXPR))
297 SLICING.setParseAction(
lambda strg, loc, toks: [
Slicing(toks)])
299 VAR_OR_FUNCTION = (DERIVED_TYPE_COMPONENT | NAME) + pparse.Optional(
300 LPAR + pparse.Optional(pparse.delimitedList(SLICING | EXPR)) + RPAR)
301 VAR_OR_FUNCTION.setParseAction(
lambda strg, loc, toks: [
FunctionVar(toks)])
303 LITERAL_ARRAY = LIT_ARRAY_START + pparse.delimitedList(EXPR) + LIT_ARRAY_END
304 LITERAL_ARRAY.setParseAction(
lambda strg, loc, toks: [
LiteralArray(toks)])
308 OPTIONAL_VAR = VAR_NAME +
"=" + ((NAME | REAL | INTEGER) |
309 pparse.QuotedString(
"'",
310 unquoteResults=
False) |
311 pparse.QuotedString(
'"',
312 unquoteResults=
False))
315 OPTIONAL_VAR.setParseAction(
lambda strg, loc, toks: [
NamedArg(toks)])
317 GROUP = LPAR + EXPR + RPAR
318 GROUP.setParseAction(
lambda strg, loc, toks: [
Grouping(toks)])
323 OPERAND = (GROUP | OPTIONAL_VAR | VAR_OR_FUNCTION | REAL | INTEGER |
327 OPERATOR = pparse.infixNotation(
329 ((pparse.Literal(
"**"), 2, pparse.opAssoc.RIGHT,
331 (pparse.Literal(
"*") | pparse.Literal(
"/"), 2, pparse.opAssoc.LEFT,
333 (pparse.Literal(
"+") | pparse.Literal(
"-"), 2, pparse.opAssoc.LEFT,
337 EXPR << (OPERATOR | OPERAND)
340 FORT_EXPRESSION = pparse.StringStart() + EXPR + pparse.StringEnd()