diff options
author | Pearu Peterson <pearu.peterson@gmail.com> | 2006-10-22 21:42:46 +0000 |
---|---|---|
committer | Pearu Peterson <pearu.peterson@gmail.com> | 2006-10-22 21:42:46 +0000 |
commit | 0de69a4aa425c8f472e86f18795ba537893d292e (patch) | |
tree | 8a271f24589c733c54b04bf803428315b6952849 /numpy/f2py/lib | |
parent | 0397a0569f57e5d2ab4e032840ee4131e1f0f93f (diff) | |
download | numpy-0de69a4aa425c8f472e86f18795ba537893d292e.tar.gz |
F2PY G3: implementingg Fortran expression parser cont.
Diffstat (limited to 'numpy/f2py/lib')
-rw-r--r-- | numpy/f2py/lib/parser/expressions.py | 845 | ||||
-rw-r--r-- | numpy/f2py/lib/parser/pattern_tools.py | 131 | ||||
-rw-r--r-- | numpy/f2py/lib/parser/test_expressions.py | 361 |
3 files changed, 1173 insertions, 164 deletions
diff --git a/numpy/f2py/lib/parser/expressions.py b/numpy/f2py/lib/parser/expressions.py index 141bf8a17..a63db55d5 100644 --- a/numpy/f2py/lib/parser/expressions.py +++ b/numpy/f2py/lib/parser/expressions.py @@ -1,15 +1,15 @@ #!/usr/bin/env python """ +Fortran expressions. -Copyright 2006 Pearu Peterson all rights reserved, -Pearu Peterson <pearu@cens.ioc.ee> +----- Permission to use, modify, and distribute this software is given under the terms of the NumPy License. See http://scipy.org. NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - -$Date: $ -Pearu Peterson +Author: Pearu Peterson <pearu@cens.ioc.ee> +Created: Oct 2006 +----- """ import re @@ -30,103 +30,27 @@ class DefinedOp: def __str__(self): return '.%s.' % (self.letters) def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.letters) -class NoChildAllowed: - pass -class NoChildAllowedError(Exception): - pass class NoMatchError(Exception): pass - -## class Designator(Primary): -## """ -## <designator> = <object-name> -## | <array-element> -## | <array-section> -## | <structure-component> -## | <substring> -## <array-element> = <data-ref> -## <array-section> = <data-ref> [ ( <substring-range> ) ] -## <data-ref> = <part-ref> [ % <part-ref> ]... -## <part-ref> = <part-name> [ ( <section-subscript-list> ) ] -## <substring> = <parent-string> ( <substring-range> ) -## <parent-string> = <scalar-variable-name> -## | <array-element> -## | <scalar-structure-component> -## | <scalar-constant> -## <substring-range> = [ <scalar-int-expr> ] : [ <scalar-int-expr> ] -## <structure-component> = <data-ref> -## """ - - - -## class LiteralConstant(Constant): -## """ -## <constant> = <int-literal-constant> -## | <real-literal-constant> -## | <complex-literal-constant> -## | <logical-literal-constant> -## | <char-literal-constant> -## | <boz-literal-constant> -## """ - -## class SignedIntLiteralConstant(LiteralConstant): -## """ -## <signed-int-literal-constant> = [ <sign> ] <int-literal-constant> -## <sign> = + | - -## """ -## match = re.compile(r'\A[+-]\s*\d+\Z').match - -## def init(self, string): -## Base.init(self, string) -## self.content = [string[0], IntLiteralConstant(string[1:].lstrip())] -## return -## def tostr(self): -## return '%s%s' % tuple(self.content) - -## class NamedConstant(Constant): -## """ -## <named-constant> = <name> -## """ - -## class Name(Designator, NamedConstant, NoChildAllowed): -## """ -## <name> = <letter> [ <alpha-numeric-character> ]... -## """ -## match = re.compile(r'\A'+name_pat+r'\Z',re.I).match - -## class IntLiteralConstant(SignedIntLiteralConstant, NoChildAllowed): -## """ -## <int-literal-constant> = <digit-string> [ _ <kind-param> ] -## <kind-param> = <digit-string> -## | <scalar-int-constant-name> -## <digit-string> = <digit> [ <digit> ]... -## """ -## match = compose_pattern([digit_string_pat, '_', kind_param_pat],r'\s*') - -## compose_pattern('int-literal-constant','digit-string','_','kind-param') - -## class DigitString(IntLiteralConstant, NoChildAllowed): -## """ -## <digit-string> = <digit> [ <digit> ]... -## """ -## match = re.compile(r'\A\d+\Z').match - +class NoSubClasses: + pass class Base(object): subclasses = {} def __new__(cls, string): - if hasattr(cls,'match'): - match = cls.match - result = match(string) + match = cls.__dict__.get('match', None) + if match is not None: + result = cls.match(string) else: result = None if isinstance(result, tuple): obj = object.__new__(cls) obj.string = string - obj.init(*result) + if cls.__dict__.has_key('init'): + obj.init(*result) return obj elif isinstance(result, Base): return result @@ -140,6 +64,8 @@ class Base(object): raise AssertionError,`result` raise NoMatchError,'%s: %r' % (cls.__name__, string) + default_match = staticmethod(lambda string: None) + findall = staticmethod(re.compile(r'(_F2PY_STRING_CONSTANT_\d+_|F2PY_EXPR_TUPLE_\d+)').findall) def match_binary_operand_right(lhs_cls, op_pattern, rhs_cls, string): @@ -148,9 +74,9 @@ class Base(object): if t is None: return lhs, op, rhs = t for k in Base.findall(lhs): - lhs = lhs.replace(k, repman[k]) + lhs = lhs.replace(k, repmap[k]) for k in Base.findall(rhs): - rhs = rhs.replace(k, repman[k]) + rhs = rhs.replace(k, repmap[k]) lhs_obj = lhs_cls(lhs) rhs_obj = rhs_cls(rhs) return lhs_obj, t[1], rhs_obj @@ -163,9 +89,9 @@ class Base(object): lhs, op, rhs = t if lhs: for k in Base.findall(lhs): - lhs = lhs.replace(k, repman[k]) + lhs = lhs.replace(k, repmap[k]) for k in Base.findall(rhs): - rhs = rhs.replace(k, repman[k]) + rhs = rhs.replace(k, repmap[k]) rhs_obj = rhs_cls(rhs) if lhs: lhs_obj = lhs_cls(lhs) @@ -180,9 +106,9 @@ class Base(object): if t is None: return lhs, op, rhs = t for k in Base.findall(lhs): - lhs = lhs.replace(k, repman[k]) + lhs = lhs.replace(k, repmap[k]) for k in Base.findall(rhs): - rhs = rhs.replace(k, repman[k]) + rhs = rhs.replace(k, repmap[k]) lhs_obj = lhs_cls(lhs) rhs_obj = rhs_cls(rhs) return lhs_obj, t[1], rhs_obj @@ -194,12 +120,33 @@ class Base(object): if t is None: return lhs, op, rhs = t for k in Base.findall(rhs): - rhs = rhs.replace(k, repman[k]) + rhs = rhs.replace(k, repmap[k]) assert not lhs,`lhs` rhs_obj = rhs_cls(rhs) return t[1], rhs_obj match_unary_operand = staticmethod(match_unary_operand) + def match_list_of(subcls, string): + line, repmap = string_replace_map(string) + lst = [] + for p in line.split(','): + p = p.strip() + for k in Base.findall(p): + p = p.replace(k,repmap[k]) + lst.append(subcls(p)) + return tuple(lst) + match_list_of = staticmethod(match_list_of) + + def init_list(self, *items): + self.items = items + return + + def tostr_list(self): + return ', '.join(map(str,self.items)) + + def torepr_list(self): + return '%s(%s)' % (self.__class__.__name__,', '.join(map(repr,self.items))) + def init_binary_operand(self, lhs, op, rhs): self.lhs = lhs self.op = op @@ -229,6 +176,9 @@ class Base(object): def tostr_primary(self): return str(self.primary) + def tostr_string(self): + return str(self.string) + def torepr_binary_operand(self): return '%s(%r, %r, %r)' % (self.__class__.__name__,self.lhs, self.op, self.rhs) @@ -241,6 +191,15 @@ class Base(object): def torepr_primary(self): return '%s(%r)' % (self.__class__.__name__,self.primary) + def torepr_string(self): + return '%s(%r)' % (self.__class__.__name__,self.string) + + def tostr_number(self): + if self.items[1] is None: return str(self.items[0]) + return '%s_%s' % (self.items[0],self.items[1]) + def torepr_number(self): + return '%s(%r,%r)' % (self.__class__.__name__, self.items[0],self.items[1]) + def __str__(self): if self.__class__.__dict__.has_key('tostr'): return self.tostr() @@ -414,33 +373,707 @@ class Primary(Level_1_Expr): <type-param-inquiry> = <designator> % <type-param-name> """ + + +class Array_Constructor(Primary): + """ + <array-constructor> = (/ <ac-spec> /) + | <left-square-bracket> <ac-spec> <right-square-bracket> + + """ + def match(string): + if string[:2]+string[-2:]=='(//)': + return '(/',Ac_Spec(string[2:-2].strip()),'/)' + if string[:1]+string[-1:]=='[]': + return '[',Ac_Spec(string[1:-1].strip()),']' + return + match = staticmethod(match) + init = Base.init_list + def tostr(self): return ''.join(map(str,self.items)) + def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items))) + +class Ac_Spec(Base): + """ + <ac-spec> = <type-spec> :: + | [ <type-spec> :: ] <ac-value-list> + """ + def match(string): + if string.endswith('::'): + return Type_Spec(string[:-2].rstrip()),None + line, repmap = string_replace_map(string) + i = line.find('::') + if i==-1: + return None, Ac_Value_List(string) + ts = line[:i].rstrip() + line = line[i+2:].lstrip() + for k in Base.findall(ts): + ts = ts.replace(k,repmap[k]) + for k in Base.findall(line): + line = line.replace(k,repmap[k]) + return Type_Spec(ts),Ac_Value_List(line) + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if self.items[0] is None: + return str(self.items[1]) + if self.items[1] is None: + return str(self.items[0]) + ' ::' + return str(self.items[0]) + ' :: ' + str(self.items[1]) + def torepr(self): + return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1]) + +class Ac_Value_List(Base): + """ + <ac-value-list> = <ac-value> [ , <ac-value> ]... + """ + def match(string): + return Base.match_list_of(Ac_Value, string) + match = staticmethod(match) + init = Base.init_list + tostr = Base.tostr_list + torepr = Base.torepr_list + +class Ac_Value(Base): + """ + <ac-value> = <expr> + | <ac-implied-do> + """ + extra_subclasses = [Expr] + +class Ac_Implied_Do(Ac_Value): + """ + <ac-implied-do> = ( <ac-value-list> , <ac-implied-do-control> ) + """ + def match(string): + if string[0]+string[-1] != '()': return + line, repmap = string_replace_map(string[1:-1].strip()) + i = line.rfind('=') + if i==-1: return + j = line[:i].rfind(',') + assert j!=-1 + s1 = line[:j].rstrip() + s2 = line[j+1:].lstrip() + for k in Base.findall(s1): + s1 = s1.replace(k,repmap[k]) + for k in Base.findall(s2): + s2 = s2.replace(k,repmap[k]) + return Ac_Value_List(s1),Ac_Implied_Do_Control(s2) + match = staticmethod(match) + init = Base.init_list + def tostr(self): return '(%s, %s)' % tuple(self.items) + def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1]) + +class Ac_Implied_Do_Control(Base): + """ + <ac-implied-do-control> = <ac-do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ] + """ + def match(string): + i = string.find('=') + if i==-1: return + s1 = string[:i].rstrip() + line, repmap = string_replace_map(string[i+1:].lstrip()) + t = line.split(',') + if not (2<=len(t)<=3): return + t = [Scalar_Int_Expr(s.strip()) for s in t] + return Ac_Do_Variable(s1), t + match = staticmethod(match) + init = Base.init_list + def tostr(self): return '%s = %s' % (self.items[0], ', '.join(map(str,self.items[1]))) + def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1]) + +class Scalar_Int_Expr(Base): + """ + <scalar-int-expr> = <expr> + """ + extra_subclasses = [Expr] + +class Ac_Do_Variable(Base): + """ + <ac-do-variable> = <scalar-int-variable> + <ac-do-variable> shall be a named variable + """ + +class Type_Spec(Base): + """ + <type-spec> = <intrinsic-type-spec> + | <derived-type-spec> + """ + +class Intrinsic_Type_Spec(Type_Spec): + """ + <intrinsic-type-spec> = INTEGER [ <kind-selector> ] + | REAL [ <kind-selector> ] + | DOUBLE COMPLEX + | COMPLEX [ <kind-selector> ] + | CHARACTER [ <char-selector> ] + | LOGICAL [ <kind-selector> ] + + Extensions: + | DOUBLE PRECISION + | BYTE + """ + def match(string): + if string[:7].upper()=='INTEGER': + t = string[:7].upper() + line = string[7:].lstrip() + if line: return t,Kind_Selector(line) + return t,None + elif string[:4].upper()=='REAL': + t = string[:4].upper() + line = string[4:].lstrip() + if line: return t,Kind_Selector(line) + return t,None + elif string[:7].upper()=='COMPLEX': + t = string[:7].upper() + line = string[7:].lstrip() + if line: return t,Kind_Selector(line) + return t,None + elif string[:7].upper()=='LOGICAL': + t = string[:7].upper() + line = string[7:].lstrip() + if line: return t,Kind_Selector(line) + return t,None + elif string[:9].upper()=='CHARACTER': + t = string[:9].upper() + line = string[9:].lstrip() + if line: return t,Char_Selector(line) + elif string[:6].upper()=='DOUBLE': + line = string[6:].lstrip().upper() + if line=='COMPLEX': + return 'DOUBLE COMPLEX',None + if line=='PRECISION': + return 'DOUBLE PRECISION',None + elif string.upper()=='BYTE': + return 'BYTE',None + return + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if self.items[1] is None: return str(self.items[0]) + return '%s%s' % tuple(self.items) + def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1]) + +class Kind_Selector(Base): + """ + <kind-selector> = ( [ KIND = ] <scalar-int-initialization-expr> ) + Extensions: + | * <char-length> + """ + def match(string): + if string[0]+string[-1] != '()': + if not string.startswith('*'): return + return '*',Char_Length(string[1:].lstrip()) + line = string[1:-1].strip() + if line[:4].upper()=='KIND': + line = line[4:].lstrip() + if not line.startswith('='): return + line = line[1:].lstrip() + return '(',Scalar_Int_Initialization_Expr(line),')' + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if len(self.items)==2: return '%s%s' % tuple(self.items) + return '%sKIND = %s%s' % tuple(self.items) + + def torepr(self): + if len(self.items)==2: + return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1]) + return '%s(%r, %r, %r)' % (self.__class__.__name__, self.items[0], self.items[1], self.items[2]) + +class Char_Selector(Base): + """ + <char-selector> = <length-selector> + | ( LEN = <type-param-value> , KIND = <scalar-int-initialization-expr> ) + | ( <type-param-value> , [ KIND = ] <scalar-int-initialization-expr> ) + | ( KIND = <scalar-int-initialization-expr> [ , LEN = <type-param-value> ] ) + """ + def match(string): + if string[0]+string[-1] != '()': return + line, repmap = string_replace_map(string[1:-1].strip()) + if line[:3].upper()=='LEN': + line = line[3:].lstrip() + if not line.startswith('='): return + line = line[1:].lstrip() + i = line.find(',') + if i==-1: return + v = line[:i].rstrip() + line = line[i+1:].lstrip() + if line[:4].upper()!='KIND': return + line = line[4:].lstrip() + if not line.startswith('='): return + line = line[1:].lstrip() + for k in Base.findall(v): v = v.replace(k,repmap[k]) + for k in Base.findall(line): line = line.replace(k,repmap[k]) + return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line) + elif line[:4].upper()=='KIND': + line = line[4:].lstrip() + if not line.startswith('='): return + line = line[1:].lstrip() + i = line.find(',') + if i==-1: return None,Scalar_Int_Initialization_Expr(line) + v = line[i+1:].lstrip() + line = line[:i].rstrip() + if v[:3].upper()!='LEN': return + v = v[3:].lstrip() + if not v.startswith('='): return + v = v[1:].lstrip() + return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line) + else: + i = line.find(',') + if i==-1: return + v = line[:i].rstrip() + line = line[i+1:].lstrip() + if line[:4].upper()=='KIND': + line = line[4:].lstrip() + if not line.startswith('='): return + line = line[1:].lstrip() + return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line) + return + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if self.items[0] is None: + return '(KIND = %s)' % (self.items[1]) + return '(LEN = %s, KIND = %s)' % (self.items[0],self.items[1]) + def torepr(self): + return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1]) + +class Lenght_Selector(Char_Selector): + """ + <length-selector> = ( [ LEN = ] <type-param-value> ) + | * <char-length> [ , ] + """ + def match(string): + if string[0]+string[-1] == '()': + line = string[1:-1].strip() + if line[:3].upper()=='LEN': + line = line[3:].lstrip() + if not line.startswith('='): return + line = line[1:].lstrip() + return '(',Type_Param_Value(line),')' + if not string.startswith('*'): return + line = string[1:].lstrip() + if string[-1]==',': line = line[:-1].rstrip() + return '*',Char_Length(line) + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if len(self.items)==2: return '%s%s' % tuple(self.items) + return '%sLEN = %s%s' % tuple(self.items) + def torepr(self): + if len(self.items)==2: + return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1]) + return '%s(%r, %r, %r)' % (self.__class__.__name__, self.items[0],self.items[1],self.items[2]) + +class Char_Length(Base): + """ + <char-length> = ( <type-param-value> ) + | scalar-int-literal-constant + """ + def match(string): + if string[0]+string[-1] == '()': + return '(',Type_Param_Value(string[1:-1].strip()),')' + return Scalar_Int_Literal_Constant(string), + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if len(self.items)==1: return str(self.items[0]) + return '%s%s%s' % tuple(self.items) + def torepr(self): + if len(self.items)==1: + return '%s(%r)' % (self.__class__.__name__, self.items[0]) + return '%s(%r, %r, %r)' % (self.__class__.__name__, self.items[0],self.items[1],self.items[2]) + + +Scalar_Int_Expr = Expr +Scalar_Int_Initialization_Expr = Expr + +class Type_Param_Value(Base): + """ + <type-param-value> = <scalar-int-expr> + | * + | : + """ + extra_subclasses = [Scalar_Int_Expr] + def match(string): + if string in ['*',':']: return string, + return + match = staticmethod(match) + def init(self, value): self.value = value + def tostr(self): return str(self.value) + def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.value) + +class Derived_Type_Spec(Type_Spec): + """ + <derived-type-spec> = <type-name> [ ( <type-param-spec-list> ) ] + <type-param-spec> = [ <keyword> = ] <type-param-value> + """ + class Constant(Primary): """ <constant> = <literal-constant> | <named-constant> """ + +class Designator(Primary): + """ + <designator> = <object-name> + | <array-element> + | <array-section> + | <structure-component> + | <substring> + <array-element> = <data-ref> + <array-section> = <data-ref> [ ( <substring-range> ) ] + <data-ref> = <part-ref> [ % <part-ref> ]... + <part-ref> = <part-name> [ ( <section-subscript-list> ) ] + <substring> = <parent-string> ( <substring-range> ) + <parent-string> = <scalar-variable-name> + | <array-element> + | <scalar-structure-component> + | <scalar-constant> + <substring-range> = [ <scalar-int-expr> ] : [ <scalar-int-expr> ] + <structure-component> = <data-ref> + """ + + +class Literal_Constant(Constant): + """ + <literal-constant> = <int-literal-constant> + | <real-literal-constant> + | <complex-literal-constant> + | <logical-literal-constant> + | <char-literal-constant> + | <boz-literal-constant> + """ + +class Int_Literal_Constant(Literal_Constant): + """ + <int-literal-constant> = <digit-string> [ _ <kind-param> ] + """ def match(string): - if pattern.abs_constant.match(string): - return (string,) + m = pattern.abs_int_literal_constant_named.match(string) + if m is None: return + return m.group('value'),m.group('kind_param') + match = staticmethod(match) + init = Base.init_list + tostr = Base.tostr_number + torepr = Base.torepr_number + +Scalar_Int_Literal_Constant = Int_Literal_Constant + +class Real_Literal_Constant(Literal_Constant): + """ + """ + def match(string): + m = pattern.abs_real_literal_constant_named.match(string) + if m is None: return + return m.group('value'),m.group('kind_param') + match = staticmethod(match) + init = Base.init_list + tostr = Base.tostr_number + torepr = Base.torepr_number + +class Complex_Literal_Constant(Literal_Constant): + """ + <complex-literal-constant> = ( <real-part>, <imag-part> ) + <real-part> = <imag-part> = <signed-int-literal-constant> + | <signed-real-literal-constant> + | <named-constant> + """ + def match(string): + if string[0]+string[-1]!='()': return + if not pattern.abs_complex_literal_constant.match(string): + return + r,i = string[1:-1].split(',') + return Real_Part(r.strip()), Imag_Part(i.strip()) + match = staticmethod(match) + init = Base.init_list + def tostr(self): return '(%s, %s)' % (self.items[0], self.items[1]) + def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1]) + +class Real_Part(Base): + """ + <real-part> = <signed-int-literal-constant> + | <signed-real-literal-constant> + | <named-constant> + """ + def match(string): + clses = [Int_Literal_Constant, Real_Literal_Constant] + if string[0] in '+-': + sign = string[0] + string = string[1:].lstrip() + + else: + sign = None + clses.append(Named_Constant) + obj = None + for cls in clses: + try: + obj = cls(string) + except NoMatchError: + pass + if obj is None: + return + return sign, obj + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if self.items[0] is None: return str(self.items[1]) + return '%s%s' % (self.items[0], self.items[1]) + def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1]) + +class Imag_Part(Real_Part): + """ + <imag-part> = <real-part> + """ + match = staticmethod(Real_Part.match) + init = Real_Part.init + tostr = Real_Part.tostr + torepr = Real_Part.torepr + +class Char_Literal_Constant(Literal_Constant): + """ + <char-literal-constant> = [ <kind-param> _ ] ' <rep-char> ' + | [ <kind-param> _ ] \" <rep-char> \" + """ + def match(string): + if string[-1] not in '"\'': return + if string[-1]=='"': + abs_a_n_char_literal_constant_named = pattern.abs_a_n_char_literal_constant_named2 + else: + abs_a_n_char_literal_constant_named = pattern.abs_a_n_char_literal_constant_named1 + line, repmap = string_replace_map(string) + m = abs_a_n_char_literal_constant_named.match(line) + if m is None: return + kind_param = m.group('kind_param') + line = m.group('value') + for k in Base.findall(line): + line = line.replace(k,repmap[k]) + return line, kind_param + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if self.items[1] is None: return self.items[0] + return '%s_%s' % (self.items[1], self.items[0]) + def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1]) + +class Logical_Literal_Constant(Literal_Constant): + """ + <logical-literal-constant> = .TRUE. [ _ <kind-param> ] + | .FALSE. [ _ <kind-param> ] + """ + def match(string): + m = pattern.abs_logical_literal_constant_named.match(string) + if m is None: return + return m.group('value'), m.group('kind_param') + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if self.items[1] is None: return self.items[0] + return '%s_%s' % (self.items[0], self.items[1]) + def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1]) + +class Boz_Literal_Constant(Literal_Constant): + """ + <boz-literal-constant> = <binary-constant> + | <octal-constant> + | <hex-constant> + """ + + +class Binary_Constant(Boz_Literal_Constant): + """ + <binary-constant> = B ' <digit> [ <digit> ]... ' + | B \" <digit> [ <digit> ]... \" + """ + def match(string): + if pattern.abs_binary_constant.match(string): return (string,) return match = staticmethod(match) - init = Base.init_primary - tostr = Base.tostr_primary - torepr = Base.torepr_primary + tostr = Base.tostr_string + torepr = Base.torepr_string +class Octal_Constant(Boz_Literal_Constant): + """ + <octal-constant> = O ' <digit> [ <digit> ]... ' + | O \" <digit> [ <digit> ]... \" + """ + def match(string): + if pattern.abs_octal_constant.match(string): return (string,) + return + match = staticmethod(match) + tostr = Base.tostr_string + torepr = Base.torepr_string + +class Hex_Constant(Boz_Literal_Constant): + """ + <hex-constant> = Z ' <digit> [ <digit> ]... ' + | Z \" <digit> [ <digit> ]... \" + """ + def match(string): + if pattern.abs_hex_constant.match(string): return (string,) + return + match = staticmethod(match) + tostr = Base.tostr_string + torepr = Base.torepr_string + +class Named_Constant(Constant): + """ + <named-constant> = <name> + """ + + +class Object_Name(Designator): + """ + <object-name> = <name> + """ + +class Function_Reference(Primary): + """ + <function-reference> = <procedure-designator> ( [ <actual-arg-spec-list> ] ) + """ + def match(string): + if string[-1] != ')': return None + line, repmap = string_replace_map(string) + i = line.rfind('(') + if i == -1: return + lhs = line[:i].lstrip() + if not lhs: return + rhs = line[i+1:-1].strip() + for k in Base.findall(lhs): + lhs = lhs.replace(k, repmap[k]) + for k in Base.findall(rhs): + rhs = rhs.replace(k, repmap[k]) + lhs_obj = Procedure_Designator(lhs) + if rhs: + rhs_obj = Actual_Arg_Spec_List(rhs) + else: + rhs_obj = None + return lhs_obj,'(',rhs_obj,')' + match = staticmethod(match) + init = Base.init_list + def tostr(self): + if self.items[2] is None: return '%s()' % (self.items[0]) + return '%s(%s)' % (self.items[0],self.items[2]) + torepr = Base.torepr_list + + +class Procedure_Designator(Base): + """ + <procedure-designator> = <procedure-name> + | <proc-component-ref> + | <data-ref> % <binding-name> + """ + +class Actual_Arg_Spec_List(Base): + """ + <actual-arg-spec-list> = <actual-arg-spec> [ , <actual-arg-spec> ]... + """ + def match(string): + return Base.match_list_of(Actual_Arg_Spec, string) + match = staticmethod(match) + init = Base.init_list + tostr = Base.tostr_list + torepr = Base.torepr_list + +def try_cls(cls, string): + try: + return cls(string) + except NoMatchError: + pass + return + +class Actual_Arg_Spec(Base): + """ + <actual-arg-spec> = [ <keyword> = ] <actual-arg> + """ + def match(string): + if pattern.keyword_equal.match(string): + i = string.find('=') + assert i!=-1,`string` + kw = Keyword(string[:i].rstrip()) + string = string[i+1:].lstrip() + else: + kw = None + return kw, Actual_Arg(string) + + match = staticmethod(match) + def init(self,kw,arg): + self.keyword = kw + self.actual_arg =arg + return + def tostr(self): + if self.keyword is not None: + return '%s = %s' % (self.keyword, self.actual_arg) + return str(self.actual_arg) + def torepr(self): + return '%s(%s, %s)' % (self.__class__.__name__, self.keyword, self.actual_arg) + +class Keyword(Base): + """ + <keyword> = <name> + """ + +class Actual_Arg(Actual_Arg_Spec): + """ + <actual-arg> = <expr> + | <variable> + | <procedure-name> + | <proc-component-ref> + | <alt-return-spec> + <alt-return-spec> = * <label> + <variable> = <designator> + <proc-component-ref> = <variable> % <procedure-component-name> + """ + extra_subclasses = [Expr] + +class Procedure_Name(Procedure_Designator, Actual_Arg): + """ + <procedure-name> = <name> + """ + +class Parenthesis(Primary): + """ + ( <expr> ) + """ + def match(string): + if string[0]+string[-1]=='()': + return '(',Expr(string[1:-1].strip()),')' + return None + match = staticmethod(match) + init = Base.init_binary_operand + tostr = Base.tostr_binary_operand + torepr = Base.torepr_binary_operand + +class Name(Object_Name, Named_Constant, Procedure_Name, Keyword, Ac_Do_Variable): + """ + <name> = <letter> [ <alphanumeric_character> ]... + """ + def match(string): + if pattern.abs_name.match(string): + return string, + return + match = staticmethod(match) + tostr = Base.tostr_string + torepr = Base.torepr_string + ClassType = type(Base) for clsname in dir(): cls = eval(clsname) if isinstance(cls, ClassType) and issubclass(cls, Base): + extra_subclasses = cls.__dict__.get('extra_subclasses',[]) + if extra_subclasses: + try: + l = Base.subclasses[cls.__name__] + except KeyError: + Base.subclasses[cls.__name__] = l = [] + l.extend(extra_subclasses) for basecls in cls.__bases__: + if basecls is Base: continue if issubclass(basecls, Base): try: Base.subclasses[basecls.__name__].append(cls) except KeyError: Base.subclasses[basecls.__name__] = [cls] - - -print Constant('a') -print `Constant('1')` -print `Base('+1')` -print `Base('c-1*a/b')` +#import pprint +#pprint.pprint(Base.subclasses) diff --git a/numpy/f2py/lib/parser/pattern_tools.py b/numpy/f2py/lib/parser/pattern_tools.py index 23a77b33a..4f6d8b990 100644 --- a/numpy/f2py/lib/parser/pattern_tools.py +++ b/numpy/f2py/lib/parser/pattern_tools.py @@ -21,10 +21,13 @@ class Pattern: ~p1 -> [ <p1> ] ~~p1 -> [ <p1> ]... ~~~p1 -> <p1> [ <p1> ]... - ~~~~p1 -> <p1> [ <p1> ]... + ~~~~p1 -> ~~~p1 abs(p1) -> whole string match of <p1> p1.named(name) -> match of <p1> has name p1.match(string) -> return string match with <p1> + p1.flags(<re.I,..>) + p1.rsplit(..) + p1.lsplit(..) """ _special_symbol_map = {'.': '[.]', '*': '[*]', @@ -41,19 +44,27 @@ class Pattern: '}': '\}', '>': '[>]', '<': '[<]', + '=': '[=]' } - def __init__(self, label, pattern, optional=0): + def __init__(self, label, pattern, optional=0, flags=0): self.label = label self.pattern = pattern self.optional = optional + self._flags = flags return + def flags(self, *flags): + f = self._flags + for f1 in flags: + f = f | f1 + return Pattern(self.label, self.pattern, optional=self.optional, flags=f) + def get_compiled(self): try: return self._compiled_pattern except AttributeError: - self._compiled_pattern = compiled = re.compile(self.pattern) + self._compiled_pattern = compiled = re.compile(self.pattern, self._flags) return compiled def match(self, string): @@ -69,10 +80,10 @@ class Pattern: compiled = self.get_compiled() t = compiled.split(string) if len(t) < 3: return - rhs = t[-1] - pattern_match = t[-2] + rhs = t[-1].strip() + pattern_match = t[-2].strip() assert abs(self).match(pattern_match),`pattern_match` - lhs = ''.join(t[:-2]) + lhs = (''.join(t[:-2])).strip() return lhs, pattern_match, rhs def lsplit(self, string): @@ -85,14 +96,14 @@ class Pattern: compiled = self.get_compiled() t = compiled.split(string) # can be optimized if len(t) < 3: return - lhs = t[0] - pattern_match = t[1] - rhs = ''.join(t[2:]) + lhs = t[0].strip() + pattern_match = t[1].strip() + rhs = (''.join(t[2:])).strip() assert abs(self).match(pattern_match),`pattern_match` return lhs, pattern_match, rhs def __abs__(self): - return Pattern(self.label, r'\A' + self.pattern+ r'\Z') + return Pattern(self.label, r'\A' + self.pattern+ r'\Z',flags=self._flags) def __repr__(self): return '%s(%r, %r)' % (self.__class__.__name__, self.label, self.pattern) @@ -101,54 +112,61 @@ class Pattern: label = '( %s OR %s )' % (self.label, other.label) if self.pattern==other.pattern: pattern = self.pattern + flags = self._flags else: pattern = '(%s|%s)' % (self.pattern, other.pattern) - return Pattern(label, pattern) + flags = self._flags | other._flags + return Pattern(label, pattern, flags=flags) def __and__(self, other): if isinstance(other, Pattern): label = '%s%s' % (self.label, other.label) pattern = self.pattern + other.pattern + flags = self._flags | other._flags else: assert isinstance(other,str),`other` label = '%s%s' % (self.label, other) pattern = self.pattern + other - return Pattern(label, pattern) + flags = self._flags + return Pattern(label, pattern, flags=flags) def __rand__(self, other): assert isinstance(other,str),`other` label = '%s%s' % (other, self.label) pattern = other + self.pattern - return Pattern(label, pattern) + return Pattern(label, pattern, flags=self._flags) def __invert__(self): if self.optional: if self.optional==1: - return Pattern(self.label + '...', self.pattern[:-1] + '*', 2) + return Pattern(self.label + '...', self.pattern[:-1] + '*', optional=2,flags=self._flags) if self.optional==2: - return Pattern('%s %s' % (self.label[1:-4].strip(), self.label), self.pattern[:-1] + '+', 3) + return Pattern('%s %s' % (self.label[1:-4].strip(), self.label), self.pattern[:-1] + '+', + optional=3, flags=self._flags) return self label = '[ %s ]' % (self.label) pattern = '(%s)?' % (self.pattern) - return Pattern(label, pattern, 1) + return Pattern(label, pattern, optional=1, flags=self._flags) def __add__(self, other): if isinstance(other, Pattern): label = '%s %s' % (self.label, other.label) pattern = self.pattern + r'\s*' + other.pattern + flags = self._flags | other._flags else: assert isinstance(other,str),`other` label = '%s %s' % (self.label, other) other = self._special_symbol_map.get(other, other) pattern = self.pattern + r'\s*' + other - return Pattern(label, pattern) + flags = self._flags + return Pattern(label, pattern, flags = flags) def __radd__(self, other): assert isinstance(other,str),`other` label = '%s %s' % (other, self.label) other = self._special_symbol_map.get(other, other) pattern = other + r'\s*' + self.pattern - return Pattern(label, pattern) + return Pattern(label, pattern, flags=self._flags) def named(self, name = None): if name is None: @@ -157,45 +175,54 @@ class Pattern: else: label = '<%s>' % (name) pattern = '(?P%s%s)' % (label.replace('-','_'), self.pattern) - return Pattern(label, pattern) + return Pattern(label, pattern, flags=self._flags) def rename(self, label): if label[0]+label[-1]!='<>': label = '<%s>' % (label) - return Pattern(label, self.pattern, self.optional) + return Pattern(label, self.pattern, optional=self.optional, flags=self._flags) # Predefined patterns -letter = Pattern('<letter>','[a-zA-Z]') -name = Pattern('<name>', r'[a-zA-Z]\w*') +letter = Pattern('<letter>','[A-Z]',flags=re.I) +name = Pattern('<name>', r'[A-Z]\w*',flags=re.I) digit = Pattern('<digit>',r'\d') underscore = Pattern('<underscore>', '_') -hex_digit = Pattern('<hex-digit>',r'[\da-fA-F]') +binary_digit = Pattern('<binary-digit>',r'[01]') +octal_digit = Pattern('<octal-digit>',r'[0-7]') +hex_digit = Pattern('<hex-digit>',r'[\dA-F]',flags=re.I) digit_string = Pattern('<digit-string>',r'\d+') -hex_digit_string = Pattern('<hex-digit-string>',r'[\da-fA-F]+') +binary_digit_string = Pattern('<binary-digit-string>',r'[01]+') +octal_digit_string = Pattern('<octal-digit-string>',r'[0-7]+') +hex_digit_string = Pattern('<hex-digit-string>',r'[\dA-F]+',flags=re.I) sign = Pattern('<sign>',r'[+-]') -exponent_letter = Pattern('<exponent-letter>',r'[ED]') +exponent_letter = Pattern('<exponent-letter>',r'[ED]',flags=re.I) -alphanumeric_character = Pattern('<alphanumeric-character>','\w') # [a-z0-9_] +alphanumeric_character = Pattern('<alphanumeric-character>',r'\w') # [A-Z0-9_] special_character = Pattern('<special-character>',r'[ =+-*/\()[\]{},.:;!"%&~<>?,\'`^|$#@]') character = alphanumeric_character | special_character kind_param = digit_string | name +kind_param_named = kind_param.named('kind-param') signed_digit_string = ~sign + digit_string int_literal_constant = digit_string + ~('_' + kind_param) signed_int_literal_constant = ~sign + int_literal_constant -binary_constant = '[Bb]' + ("'" & digit_string & "'" | '"' & digit_string & '"') -octal_constant = '[Oo]' + ("'" & digit_string & "'" | '"' & digit_string & '"') -hex_constant = '[Zz]' + ("'" & hex_digit_string & "'" | '"' & hex_digit_string & '"') +int_literal_constant_named = digit_string.named('value') + ~ ('_' + kind_param_named) + +binary_constant = ('B' + ("'" & binary_digit_string & "'" | '"' & binary_digit_string & '"')).flags(re.I) +octal_constant = ('O' + ("'" & octal_digit_string & "'" | '"' & octal_digit_string & '"')).flags(re.I) +hex_constant = ('Z' + ("'" & hex_digit_string & "'" | '"' & hex_digit_string & '"')).flags(re.I) boz_literal_constant = binary_constant | octal_constant | hex_constant exponent = signed_digit_string significand = digit_string + '.' + ~digit_string | '.' + digit_string real_literal_constant = significand + ~(exponent_letter + exponent) + ~ ('_' + kind_param) | \ digit_string + exponent_letter + exponent + ~ ('_' + kind_param) +real_literal_constant_named = (significand + ~(exponent_letter + exponent) |\ + digit_string + exponent_letter + exponent).named('value') + ~ ('_' + kind_param_named) signed_real_literal_constant = ~sign + real_literal_constant named_constant = name @@ -203,33 +230,59 @@ real_part = signed_int_literal_constant | signed_real_literal_constant | named_c imag_part = real_part complex_literal_constant = '(' + real_part + ',' + imag_part + ')' -char_literal_constant = ~( kind_param + '_') + "'.*'" | ~( kind_param + '_') + '".*"' +a_n_rep_char = Pattern('<alpha-numeric-rep-char>',r'\w') +rep_char = Pattern('<rep-char>',r'.') +char_literal_constant = ~( kind_param + '_') + ("'" + ~~rep_char + "'" | '"' + ~~rep_char + '"' ) +a_n_char_literal_constant_named1 = ~( kind_param_named + '_') + (~~~("'" + ~~a_n_rep_char + "'" )).named('value') +a_n_char_literal_constant_named2 = ~( kind_param_named + '_') + (~~~('"' + ~~a_n_rep_char + '"' )).named('value') -logical_literal_constant = '[.](TRUE|FALSE)[.]' + ~ ('_' + kind_param) +logical_literal_constant = ('[.](TRUE|FALSE)[.]' + ~ ('_' + kind_param)).flags(re.I) +logical_literal_constant_named = Pattern('<value>',r'[.](TRUE|FALSE)[.]',flags=re.I).named() + ~ ('_' + kind_param_named) literal_constant = int_literal_constant | real_literal_constant | complex_literal_constant | logical_literal_constant | char_literal_constant | boz_literal_constant constant = literal_constant | named_constant int_constant = int_literal_constant | boz_literal_constant | named_constant char_constant = char_literal_constant | named_constant -abs_constant = abs(constant) + power_op = Pattern('<power-op>','[*]{2}') mult_op = Pattern('<mult-op>','[*/]') add_op = Pattern('<add-op>','[+-]') concat_op = Pattern('<concat-op>','[/]{}') -rel_op = Pattern('<rel-op>','([.](EQ|NE|LT|LE|GT|GE)[.])|[=]{2}|/[=]|[<]|[<][=]|[>]|[=][>]') -not_op = Pattern('<not-op>','[.]NOT[.]') -and_op = Pattern('<and-op>','[.]AND[.]') -or_op = Pattern('<or-op>','[.]OR[.]') -equiv_op = Pattern('<equiv-op>','[.](EQV|NEQV)[.]') +rel_op = Pattern('<rel-op>','([.](EQ|NE|LT|LE|GT|GE)[.])|[=]{2}|/[=]|[<]|[<][=]|[>]|[=][>]',flags=re.I) +not_op = Pattern('<not-op>','[.]NOT[.]',flags=re.I) +and_op = Pattern('<and-op>','[.]AND[.]',flags=re.I) +or_op = Pattern('<or-op>','[.]OR[.]',flags=re.I) +equiv_op = Pattern('<equiv-op>','[.](EQV|NEQV)[.]',flags=re.I) intrinsic_operator = power_op | mult_op | add_op | concat_op | rel_op | not_op | and_op | or_op | equiv_op extended_intrinsic_operator = intrinsic_operator -defined_unary_op = Pattern('<defined-unary-op>','[.][a-zA-Z]+[.]') -defined_binary_op = Pattern('<defined-binary-op>','[.][a-zA-Z]+[.]') +defined_unary_op = Pattern('<defined-unary-op>','[.][A-Z]+[.]',flags=re.I) +defined_binary_op = Pattern('<defined-binary-op>','[.][A-Z]+[.]',flags=re.I) defined_operator = defined_unary_op | defined_binary_op | extended_intrinsic_operator label = Pattern('<label>','\d{1,5}') +keyword = name +keyword_equal = keyword + '=' + +abs_constant = abs(constant) +abs_literal_constant = abs(literal_constant) +abs_int_literal_constant = abs(int_literal_constant) +abs_int_literal_constant_named = abs(int_literal_constant_named) +abs_real_literal_constant = abs(real_literal_constant) +abs_real_literal_constant_named = abs(real_literal_constant_named) +abs_complex_literal_constant = abs(complex_literal_constant) +abs_logical_literal_constant = abs(logical_literal_constant) +abs_char_literal_constant = abs(char_literal_constant) +abs_boz_literal_constant = abs(boz_literal_constant) +abs_name = abs(name) +abs_a_n_char_literal_constant_named1 = abs(a_n_char_literal_constant_named1) +abs_a_n_char_literal_constant_named2 = abs(a_n_char_literal_constant_named2) +abs_logical_literal_constant_named = abs(logical_literal_constant_named) +abs_binary_constant = abs(binary_constant) +abs_octal_constant = abs(octal_constant) +abs_hex_constant = abs(hex_constant) + def _test(): assert name.match('a1_a') assert abs(name).match('a1_a') diff --git a/numpy/f2py/lib/parser/test_expressions.py b/numpy/f2py/lib/parser/test_expressions.py index 3f4722019..9b7e8673b 100644 --- a/numpy/f2py/lib/parser/test_expressions.py +++ b/numpy/f2py/lib/parser/test_expressions.py @@ -4,36 +4,359 @@ from numpy.testing import * from expressions import * -class test_Base(NumpyTestCase): +class test_Type_Spec(NumpyTestCase): + + def check_kind_selector(self): + cls = Kind_Selector + a = cls('(1)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(KIND = 1)') + assert_equal(repr(a),"Kind_Selector('(', Int_Literal_Constant('1',None), ')')") + + a = cls('(kind=1+2)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(KIND = 1 + 2)') + + a = cls('* 1') + assert isinstance(a,cls),`a` + assert_equal(str(a),'*1') + + def check_type_param_value(self): + cls = Type_Param_Value + a = cls('*') + assert isinstance(a,cls),`a` + assert_equal(str(a),'*') + assert_equal(repr(a),"Type_Param_Value('*')") + + a = cls(':') + assert isinstance(a,cls),`a` + assert_equal(str(a),':') + + a = cls('1+2') + assert isinstance(a,Level_2_Expr),`a` + assert_equal(str(a),'1 + 2') + + def check_char_length(self): + cls = Char_Length + a = cls('1') + assert isinstance(a,cls),`a` + assert_equal(str(a),'1') + assert_equal(repr(a),"Char_Length(Int_Literal_Constant('1',None))") + + a = cls('(1)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(1)') + + a = cls('(*)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(*)') + + a = cls('(:)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(:)') + + def check_lenght_selector(self): + cls = Lenght_Selector + a = cls('( len = *)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(LEN = *)') + assert_equal(repr(a),"Lenght_Selector('(', Type_Param_Value('*'), ')')") + + a = cls('*2,') + assert isinstance(a,cls),`a` + assert_equal(str(a),'*2') + + def check_char_selector(self): + cls = Char_Selector + a = cls('(len=2, kind=8)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(LEN = 2, KIND = 8)') + assert_equal(repr(a),"Char_Selector(Int_Literal_Constant('2',None), Int_Literal_Constant('8',None))") + + + a = cls('(2, kind=8)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(LEN = 2, KIND = 8)') + + a = cls('(2, 8)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(LEN = 2, KIND = 8)') + + a = cls('(kind=8)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(KIND = 8)') + + a = cls('(kind=8,len=2)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(LEN = 2, KIND = 8)') + + def check_intrinsic_type_spec(self): + cls = Intrinsic_Type_Spec + a = cls('INTEGER') + assert isinstance(a,cls),`a` + assert_equal(str(a),'INTEGER') + assert_equal(repr(a), "Intrinsic_Type_Spec('INTEGER', None)") + + a = cls('Integer*2') + assert isinstance(a,cls),`a` + assert_equal(str(a),'INTEGER*2') + + a = cls('real*2') + assert isinstance(a,cls),`a` + assert_equal(str(a),'REAL*2') + + a = cls('logical*2') + assert isinstance(a,cls),`a` + assert_equal(str(a),'LOGICAL*2') + + a = cls('complex*2') + assert isinstance(a,cls),`a` + assert_equal(str(a),'COMPLEX*2') + + a = cls('character*2') + assert isinstance(a,cls),`a` + assert_equal(str(a),'CHARACTER*2') + + a = cls('double complex') + assert isinstance(a,cls),`a` + assert_equal(str(a),'DOUBLE COMPLEX') + + a = cls('double precision') + assert isinstance(a,cls),`a` + assert_equal(str(a),'DOUBLE PRECISION') + +class test_Array_Constructor(NumpyTestCase): + + def check_ac_implied_do_control(self): + cls = Ac_Implied_Do_Control + a = cls('n = 3, 5') + assert isinstance(a,cls),`a` + assert_equal(str(a),'n = 3, 5') + assert_equal(repr(a),"Ac_Implied_Do_Control(Name('n'), [Int_Literal_Constant('3',None), Int_Literal_Constant('5',None)])") + + a = cls('n = 3+1, 5, 1') + assert isinstance(a,cls),`a` + assert_equal(str(a),'n = 3 + 1, 5, 1') + + def check_ac_value_list(self): + cls = Ac_Value_List + a = cls('a, b') + assert isinstance(a,cls),`a` + assert_equal(str(a),'a, b') + assert_equal(repr(a),"Ac_Value_List(Name('a'), Name('b'))") + + a = cls('a') + assert isinstance(a,cls),`a` + assert_equal(str(a),'a') + + def check_ac_implied_do(self): + cls = Ac_Implied_Do + a = cls('( a, b, n = 1, 5 )') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(a, b, n = 1, 5)') + assert_equal(repr(a),"Ac_Implied_Do(Ac_Value_List(Name('a'), Name('b')), Ac_Implied_Do_Control(Name('n'), [Int_Literal_Constant('1',None), Int_Literal_Constant('5',None)]))") + + def check_ac_spec(self): + cls = Ac_Spec + a = cls('integer ::') + assert isinstance(a,cls),`a` + assert_equal(str(a),'INTEGER ::') + assert_equal(repr(a),"Ac_Spec(Intrinsic_Type_Spec('INTEGER', None), None)") + + a = cls('integer :: a,b') + assert isinstance(a,cls),`a` + assert_equal(str(a),'INTEGER :: a, b') + + a = cls('a,b') + assert isinstance(a,cls),`a` + assert_equal(str(a),'a, b') + + a = cls('integer :: a, (a, b, n = 1, 5)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'INTEGER :: a, (a, b, n = 1, 5)') + +class test_Constant(NumpyTestCase): def check_name(self): a = Name('a') assert isinstance(a,Name),`a` + a = Name('a2') + assert isinstance(a,Name),`a` a = Designator('a') assert isinstance(a,Name),`a` a = Constant('a') assert isinstance(a,Name),`a` - a = Base('a') - assert isinstance(a,Name),`a` - a = NamedConstant('a') - assert isinstance(a,Name),`a` - a = Constant('a') + a = Expr('a') assert isinstance(a,Name),`a` def check_int_literal_constant(self): - a = IntLiteralConstant('1') - assert isinstance(a,IntLiteralConstant),`a` - a = LiteralConstant('1') - assert isinstance(a,IntLiteralConstant),`a` - a = Constant('1') - assert isinstance(a,IntLiteralConstant),`a` - a = Base('1') - assert isinstance(a,IntLiteralConstant),`a` - a = Base('+1') - assert isinstance(a,SignedIntLiteralConstant),`a` - a = IntLiteralConstant('0') - assert isinstance(a,IntLiteralConstant),`a` - #a = NamedConstant('1') # raise NoMatch error + cls = Int_Literal_Constant + a = cls('1') + assert isinstance(a,cls),`a` + assert_equal(str(a),'1') + assert_equal(repr(a),"%s('1',None)" % (cls.__name__)) + + a = cls('21_2') + assert isinstance(a,cls),`a` + assert_equal(str(a),'21_2') + assert_equal(repr(a),"%s('21','2')" % (cls.__name__)) + + a = cls('21_SHORT') + assert isinstance(a,cls),`a` + assert_equal(str(a),'21_SHORT') + + a = cls('21_short') + assert isinstance(a,cls),`a` + assert_equal(str(a),'21_short') + + a = cls('1976354279568241_8') + assert isinstance(a,cls),`a` + assert_equal(str(a),'1976354279568241_8') + + def check_real_literal_constant(self): + cls = Real_Literal_Constant + a = cls('12.78') + assert isinstance(a,cls),`a` + assert_equal(str(a),'12.78') + assert_equal(repr(a),"%s('12.78',None)" % (cls.__name__)) + + a = cls('12.78_8') + assert isinstance(a,cls),`a` + assert_equal(str(a),'12.78_8') + assert_equal(repr(a),"%s('12.78','8')" % (cls.__name__)) + + a = cls('12.') + assert isinstance(a,cls),`a` + assert_equal(str(a),'12.') + + a = cls('1.6E3') + assert isinstance(a,cls),`a` + assert_equal(str(a),'1.6E3') + + a = cls('1.6E3_8') + assert isinstance(a,cls),`a` + assert_equal(str(a),'1.6E3_8') + + a = cls('1.6D3') + assert isinstance(a,cls),`a` + assert_equal(str(a),'1.6D3') + + a = cls('1.6E-3') + assert isinstance(a,cls),`a` + assert_equal(str(a),'1.6E-3') + a = cls('1.6E+3') + assert isinstance(a,cls),`a` + assert_equal(str(a),'1.6E+3') + + a = cls('3E4') + assert isinstance(a,cls),`a` + assert_equal(str(a),'3E4') + + a = cls('.123') + assert isinstance(a,cls),`a` + assert_equal(str(a),'.123') + + a = cls('1.6E-3') + assert isinstance(a,cls),`a` + assert_equal(str(a),'1.6E-3') + + a = cls('10.9E7_QUAD') + assert isinstance(a,cls),`a` + assert_equal(str(a),'10.9E7_QUAD') + + a = cls('10.9e-17_quad') + assert isinstance(a,cls),`a` + assert_equal(str(a),'10.9e-17_quad') + + def check_complex_literal_constant(self): + cls = Complex_Literal_Constant + a = cls('(1.0, -1.0)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(1.0, -1.0)') + assert_equal(repr(a),"%s(Real_Part(None, Real_Literal_Constant('1.0',None)), Imag_Part('-', Real_Literal_Constant('1.0',None)))" % (cls.__name__)) + + a = cls('(3,3.1E6)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(3, 3.1E6)') + + a = cls('(4.0_4, 3.6E7_8)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(4.0_4, 3.6E7_8)') + + a = cls('( 0., PI)') + assert isinstance(a,cls),`a` + assert_equal(str(a),'(0., PI)') + + def check_char_literal_constant(self): + cls = Char_Literal_Constant + a = cls('NIH_"DO"') + assert isinstance(a,cls),`a` + assert_equal(str(a),'NIH_"DO"') + assert_equal(repr(a),'Char_Literal_Constant(\'"DO"\', \'NIH\')') + + a = cls("'DO'") + assert isinstance(a,cls),`a` + assert_equal(str(a),"'DO'") + assert_equal(repr(a),'Char_Literal_Constant("\'DO\'", None)') + + a = cls("'DON''T'") + assert isinstance(a,cls),`a` + assert_equal(str(a),"'DON''T'") + + a = cls('"DON\'T"') + assert isinstance(a,cls),`a` + assert_equal(str(a),'"DON\'T"') + + a = cls('""') + assert isinstance(a,cls),`a` + assert_equal(str(a),'""') + + a = cls("''") + assert isinstance(a,cls),`a` + assert_equal(str(a),"''") + + a = cls('"hey ha(ada)\t"') + assert isinstance(a,cls),`a` + assert_equal(str(a),'"hey ha(ada)\t"') + + def check_logical_literal_constant(self): + cls = Logical_Literal_Constant + a = cls('.TRUE.') + assert isinstance(a,cls),`a` + assert_equal(str(a),'.TRUE.') + assert_equal(repr(a),"%s('.TRUE.', None)" % (cls.__name__)) + + a = cls('.True.') + assert isinstance(a,cls),`a` + assert_equal(str(a),'.True.') + + a = cls('.FALSE.') + assert isinstance(a,cls),`a` + assert_equal(str(a),'.FALSE.') + + a = cls('.TRUE._HA') + assert isinstance(a,cls),`a` + assert_equal(str(a),'.TRUE._HA') + + def check_boz_literal_constant(self): + cls = Boz_Literal_Constant + bcls = Binary_Constant + a = cls('B"01"') + assert isinstance(a,bcls),`a` + assert_equal(str(a),'B"01"') + assert_equal(repr(a),"%s('B\"01\"')" % (bcls.__name__)) + + ocls = Octal_Constant + a = cls('O"017"') + assert isinstance(a,ocls),`a` + assert_equal(str(a),'O"017"') + assert_equal(repr(a),"%s('O\"017\"')" % (ocls.__name__)) + zcls = Hex_Constant + a = cls('Z"01A"') + assert isinstance(a,zcls),`a` + assert_equal(str(a),'Z"01A"') + assert_equal(repr(a),"%s('Z\"01A\"')" % (zcls.__name__)) + if __name__ == "__main__": NumpyTest().run() |