Repository: stfc/fparser

Issue:
[fparser2][Fortran2008] Missing attribute CONTIGUOUS
Fortran2008 introduced the `CONTIGUOUS` attribute in [R437](https://j3-fortran.org/doc/year/10/10-007r1.pdf#page=84), [R502](https://j3-fortran.org/doc/year/10/10-007r1.pdf#page=105) which fparser2 cannot handle currently:
```
>>> from fparser.two.parser import ParserFactory
>>> from fparser.common.readfortran import FortranStringReader
>>> code = '''
... module contiguous_ptr
... type some_type
...   integer, pointer, contiguous :: ptr(:) => null()
... end type some_type
... end module contiguous_ptr
... '''
>>> parser = ParserFactory().create(std='f2008')
>>> reader = FortranStringReader(code)
>>> ast = parser(reader)
Traceback (most recent call last):
  File "...src/fparser/two/Fortran2003.py", line 236, in __new__
    return Base.__new__(cls, string)
  File "...src/fparser/two/utils.py", line 407, in __new__
    raise NoMatchError(errmsg)
fparser.two.utils.NoMatchError: at line 4
>>>  integer, pointer, contiguous :: ptr(:) => null()
```

I could attempt to provide a PR patching this feature but I need some hand holding in how to do this in the desired way as it affects multiple things:
- `Fortran2003.Component_Attr_Spec` needs the additional match against `CONTIGUOUS`? 
- `Fortran2003.Attr_Spec`, too. But here the pattern is defined in `pattern_tools`.
- Whether/how to enforce [C448](https://j3-fortran.org/doc/year/10/10-007r1.pdf#page=84) and [C530](https://j3-fortran.org/doc/year/10/10-007r1.pdf#page=111)?

Additionally, R437 and R503 introduce the attribute `CODIMENSION`. Would it be necessary to add this as well, when I'm "touching the relevant rule"?

Discussion:
codecov-io: # [Codecov](https://codecov.io/gh/stfc/fparser/pull/249?src=pr&el=h1) Report
> Merging [#249](https://codecov.io/gh/stfc/fparser/pull/249?src=pr&el=desc) into [master](https://codecov.io/gh/stfc/fparser/commit/b4df8e57b832b7049257aff02cb6c700d79a2476?src=pr&el=desc) will **decrease** coverage by `0.09%`.
> The diff coverage is `95.18%`.

[![Impacted file tree graph](https://codecov.io/gh/stfc/fparser/pull/249/graphs/tree.svg?width=650&token=x0abs66TST&height=150&src=pr)](https://codecov.io/gh/stfc/fparser/pull/249?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##           master     #249     +/-   ##
=========================================
- Coverage   90.21%   90.11%   -0.1%     
=========================================
  Files          34       34             
  Lines       12107    12189     +82     
=========================================
+ Hits        10922    10984     +62     
- Misses       1185     1205     +20
```


| [Impacted Files](https://codecov.io/gh/stfc/fparser/pull/249?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/fparser/two/pattern\_tools.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvdHdvL3BhdHRlcm5fdG9vbHMucHk=) | `93.57% <100%> (+0.05%)` | :arrow_up: |
| [src/fparser/two/Fortran2008.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvdHdvL0ZvcnRyYW4yMDA4LnB5) | `97.72% <95.06%> (-2.28%)` | :arrow_down: |
| [src/fparser/common/tests/test\_utils.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvY29tbW9uL3Rlc3RzL3Rlc3RfdXRpbHMucHk=) | `99.13% <0%> (-0.87%)` | :arrow_down: |
| [src/fparser/common/sourceinfo.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvY29tbW9uL3NvdXJjZWluZm8ucHk=) | `99.14% <0%> (-0.86%)` | :arrow_down: |
| [src/fparser/common/tests/test\_sourceinfo.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvY29tbW9uL3Rlc3RzL3Rlc3Rfc291cmNlaW5mby5weQ==) | `95.86% <0%> (-0.83%)` | :arrow_down: |
| [src/fparser/common/readfortran.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvY29tbW9uL3JlYWRmb3J0cmFuLnB5) | `92.37% <0%> (-0.74%)` | :arrow_down: |
| [src/fparser/common/utils.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvY29tbW9uL3V0aWxzLnB5) | `78.11% <0%> (-0.43%)` | :arrow_down: |
| [src/fparser/two/utils.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvdHdvL3V0aWxzLnB5) | `93.77% <0%> (-0.41%)` | :arrow_down: |
| [src/fparser/common/tests/test\_readfortran.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvY29tbW9uL3Rlc3RzL3Rlc3RfcmVhZGZvcnRyYW4ucHk=) | `98.53% <0%> (-0.21%)` | :arrow_down: |
| [src/fparser/two/Fortran2003.py](https://codecov.io/gh/stfc/fparser/pull/249/diff?src=pr&el=tree#diff-c3JjL2ZwYXJzZXIvdHdvL0ZvcnRyYW4yMDAzLnB5) | `92.42% <0%> (-0.07%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/stfc/fparser/pull/249?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/stfc/fparser/pull/249?src=pr&el=footer). Last update [b4df8e5...6d0ddc3](https://codecov.io/gh/stfc/fparser/pull/249?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

rupertford: Back to @reuterbal 
reuterbal: @rupertford I don't know if you received emails about the above comments: https://github.com/stfc/fparser/pull/249#discussion_r388215617
If you find time the time, could you share some thoughts?
rupertford: > @rupertford I don't know if you received emails about the above comments: [#249 (comment)](https://github.com/stfc/fparser/pull/249#discussion_r388215617)
> If you find time the time, could you share some thoughts?

Yes @reuterbal, I had read them and thought it all sounded complicated so went off and did something else, then forgot I was meant to reply :-). I think I now understand what you've done and what the issues are and have made a suggestion as a response to the original comment. Many thanks for the great work.
reuterbal: I think all requested changes are addressed now.
The change to the lookup of `match` with the accompanying switch from `STRINGBase` to `Base` as parent class is implemented in 6ccab21. If you would like to see this in a separate PR I can easily cherry-pick that out. 
Let me know please what you want to have in regard to testing constraints.
reuterbal: Thank you. I have implemented the requested changes but not yet looked at testing constraints. However, I have noticed that attrib_spec is not matched correctly when parsing a program, module or subroutine (e.g., example from #247) if one of the newly added keywords is included together with another attribute, e.g.
```
integer, pointer, contiguous :: a
```
fails to match, while
```
integer, contiguous :: a
```
works fine (ignoring that it is nonsense for now).
I guess I'm doing something wrong with generating the `Attrib_Spec_List` but haven't found out what, yet. I'll return to that on Monday.
reuterbal: Inspecting the initialization of the class list in `parser.py`, it turns out there is no F2008 variant of `Attr_Spec_List` generated (and thus the F2003 variant is used). The reason for that is that there is no class in `Fortran2008.py` which has `Attr_Spec` in their `use_names` or `subclass_names`.

This could be fixed, for example, by creating a corresponding empty subclass of `Type_Declaration_Stmt`:
```
class Type_Declaration_Stmt(Type_Declaration_Stmt_2003):
    pass
```
which then triggers generating a `Attr_Spec_List`.

However, with that I can't get any Declarations to parse successfully anymore and I'm at loss why that is. Do you have any better ideas for that?

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 69f2c6a..5e77548 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,9 @@ Modifications by (in alphabetical order):
 * J. Tiira, University of Helsinki, Finland
 * P. Vitt, University of Siegen, Germany
 
+03/06/2020 PR #249. Adds support for Fortran2008 CONTIGUOUS and
+           CODIMENSION keywords.
+
 ## Release 0.0.11 (15/05/2020) ##
 
 09/04/2020 PR #254. Fix for >1 character pre-processor macro identifiers.
diff --git a/doc/fparser2.rst b/doc/fparser2.rst
index b8e1370..2404d23 100644
--- a/doc/fparser2.rst
+++ b/doc/fparser2.rst
@@ -42,8 +42,8 @@ Fortran 2003. This is implemented in the Fortran2003.py `file`__ and
 contains an entirely separate parser to fparser1 that includes rules
 for Fortran 2003 syntax. Support for Fortran 2008 is being added in
 the Fortran2008.py `file`__ which extends the Fortran2003 rules
-appropriately. At this time Fortran2008 support is limited to
-submodules.
+appropriately. At this time fparser2 supports submodules, co-arrays
+and the continguous keyword in Fortran2008.
 
 __ https://github.com/stfc/fparser/blob/master/src/fparser/two/Fortran2003.py
 __ https://github.com/stfc/fparser/blob/master/src/fparser/two/Fortran2008.py
diff --git a/src/fparser/two/Fortran2003.py b/src/fparser/two/Fortran2003.py
index 8270671..ecc3a6c 100644
--- a/src/fparser/two/Fortran2003.py
+++ b/src/fparser/two/Fortran2003.py
@@ -1661,10 +1661,42 @@ class Component_Def_Stmt(Base):  # R439
 
 
 class Data_Component_Def_Stmt(Type_Declaration_StmtBase):  # R440
-    """
+    '''
+    Fortran 2003 rule 440
     <data-component-def-stmt> is <declaration-type-spec> [
              [ , <component-attr-spec-list> ] :: ] <component-decl-list>
-    """
+
+    Associated constraints are:
+
+    "C436 (R440)  No component-attr-spec shall appear more than once in a given
+          component-def-stmt."
+    "C437 (R440)  A component declared with the CLASS keyword shall have the
+          ALLOCATABLE or POINTER attribute."
+    "C438 (R440)  If the POINTER attribute is not specified for a component,
+          the declaration-type-spec in the component-def-stmt shall be CLASS(*)
+          or shall specify an intrinsic type or a previously defined derived
+          type."
+    "C439 (R440)  If the POINTER attribute is specified for a component, the
+          declaration-type-spec in the component-def-stmt shall be CLASS(*) or
+          shall specify an intrinsic type or any accessible derived type
+          including the type being defined."
+    "C440 (R440)  If the POINTER or ALLOCATABLE attribute is specified, each
+          component-array-spec shall be a deferred-shape-spec-list."
+    "C441 (R440)  If neither the POINTER attribute nor the ALLOCATABLE
+          attribute is specified, each component-array-spec shall be an
+          explicit-shape-spec-list."
+    "C443 (R440)  A component shall not have both the ALLOCATABLE and the
+          POINTER attribute."
+    "C446 (R440)  If component-initialization appears, a double-colon separator
+          shall appear before the component-decl-list."
+    "C447 (R440)  If => appears in component-initialization, POINTER shall
+          appear in the component-attr-spec-list. If = appears in
+          component-initialization, POINTER or ALLOCATABLE shall not appear in
+          the component-attr-spec-list."
+
+    C436-C441, C443, C446-C447 are currently not checked - issue #258.
+
+   '''
     subclass_names = []
     use_names = ['Declaration_Type_Spec', 'Component_Attr_Spec_List',
                  'Component_Decl_List']
@@ -1697,10 +1729,25 @@ class Component_Attr_Spec(STRINGBase):  # R441
     """
     subclass_names = ['Access_Spec', 'Dimension_Component_Attr_Spec']
     use_names = []
+    attributes = ['POINTER', 'ALLOCATABLE']
 
-    @staticmethod
-    def match(string):
-        return STRINGBase.match(['POINTER', 'ALLOCATABLE'], string)
+    @classmethod
+    def match(cls, string):
+        '''Implements the matching for component attribute specifications.
+
+        Note that this is implemented as a `classmethod` (not a
+        `staticmethod`), using attribute keywords from the list provided
+        as a class property. This allows expanding this list for
+        Fortran 2008 without having to reimplement the matching.
+
+        :param str string: the string to match as an attribute.
+
+        :return: None if there is no match, otherwise a 1-tuple \
+            containing the matched attribute string.
+        :rtype: NoneType or (str,)
+
+        '''
+        return STRINGBase.match(cls.attributes, string)
 
 
 class Component_Decl(Base):  # R442
@@ -2520,10 +2567,71 @@ class Ac_Do_Variable(Base):  # R472
 
 
 class Type_Declaration_Stmt(Type_Declaration_StmtBase):  # R501
-    """
+    '''
+    Fortran 2003 rule 501
     <type-declaration-stmt> = <declaration-type-spec> [
         [ , <attr-spec> ]... :: ] <entity-decl-list>
-    """
+
+    Associated constraints are:
+
+    "C507 (R501)  The same attr-spec shall not appear more than once in a given
+          type-declaration-stmt."
+    "C509 (R501)  An entity declared with the CLASS keyword shall be a dummy
+          argument or have the ALLOCATABLE or POINTER attribute."
+    "C510 (R501)  An array that has the POINTER or ALLOCATABLE attribute shall
+          be specified with an array-spec that is a deferred-shape-spec-list."
+    "C511 (R501)  An array-spec for an object-name that is a function result
+          that does not have the ALLOCATABLE or POINTER attribute shall be an
+          explicit-shape-spec-list."
+    "C512 (R501)  If the POINTER attribute is specified, the ALLOCATABLE,
+          TARGET, EXTERNAL, or INTRINSIC attribute shall not be specified."
+    "C513 (R501)  If the TARGET attribute is specified, the POINTER, EXTERNAL,
+          INTRINSIC, or PARAMETER attribute shall not be specified."
+    "C514 (R501)  The PARAMETER attribute shall not be specified for a dummy
+          argument, a pointer, an allocatable entity, a function, or an object
+          in a common block."
+    "C515 (R501)  The INTENT, VALUE, and OPTIONAL attributes may be specified
+          only for dummy arguments."
+    "C516 (R501)  The INTENT attribute shall not be specified for a dummy
+          procedure without the POINTER attribute."
+    "C517 (R501)  The SAVE attribute shall not be specified for an object that
+          is in a common block, a dummy argument, a procedure, a function
+          result, an automatic data object, or an object with the PARAMETER
+          attribute."
+    "C519 (R501)  An entity in an entity-decl-list shall not have the EXTERNAL
+          or INTRINSIC attribute specified unless it is a function."
+    "C522 (R501)  The initialization shall appear if the statement contains a
+          PARAMETER attribute."
+    "C523 (R501)  If initialization appears, a double-colon separator shall
+          appear before the entity-decl-list."
+    "C526 (R501)  If the VOLATILE attribute is specified, the PARAMETER,
+          INTRINSIC, EXTERNAL, or INTENT(IN) attribute shall not be specified."
+    "C527 (R501)  If the VALUE attribute is specified, the PARAMETER, EXTERNAL,
+          POINTER, ALLOCATABLE, DIMENSION, VOLATILE, INTENT(INOUT), or
+          INTENT(OUT) attribute shall not be specified."
+    "C528 (R501)  If the VALUE attribute is specified, the length type
+          parameter values shall be omitted or specified by initialization
+          expressions."
+    "C529 (R501)  The VALUE attribute shall not be specified for a dummy
+          procedure."
+    "C530 (R501)  The ALLOCATABLE, POINTER, or OPTIONAL attribute shall not be
+          specified for adummy argument of a procedure that has
+          aproc-language-binding-spec."
+    "C532 (R501)  If a language-binding-spec is specified, the entity declared
+          shall be an interoperable variable."
+    "C533 (R501)  If a language-binding-spec with a NAME= specifier appears,
+          the entity-decl-list shall consist of a single entity-decl."
+    "C534 (R503)  The PROTECTED attribute is permitted only in the
+          specification part of a module."
+    "C535 (R501)  The PROTECTED attribute is permitted only for a procedure
+          pointer or named variable that is not in a common block."
+    "C536 (R501)  If the PROTECTED attribute is specified, the EXTERNAL,
+          INTRINSIC, or PARAMETER attribute shall not be specified."
+
+    C507, C509-C517, C519, C522-C523, C526-C530, C532-C533, C535-C536 are
+    currently not checked - issue #259.
+
+    '''
     subclass_names = []
     use_names = ['Declaration_Type_Spec', 'Attr_Spec_List', 'Entity_Decl_List']
 
@@ -4522,7 +4630,7 @@ class Level_1_Expr(UnaryOpBase):  # R702
     match = staticmethod(match)
 
 
-class Defined_Unary_Op(STRINGBase):  # pylint: disable=invalid-name
+class Defined_Unary_Op(Base):  # pylint: disable=invalid-name
     '''
     Fortran 2003 rule R703
 
@@ -4757,7 +4865,7 @@ class Expr(BinaryOpBase):  # R722
     match = staticmethod(match)
 
 
-class Defined_Binary_Op(STRINGBase):  # pylint: disable=invalid-name
+class Defined_Binary_Op(Base):  # pylint: disable=invalid-name
     '''
     Fortran 2003 rule R723
 
diff --git a/src/fparser/two/Fortran2008.py b/src/fparser/two/Fortran2008.py
index 917c1fa..e567194 100644
--- a/src/fparser/two/Fortran2008.py
+++ b/src/fparser/two/Fortran2008.py
@@ -1,4 +1,4 @@
-# Modified work Copyright (c) 2018 Science and Technology
+# Modified work Copyright (c) 2018-2020 Science and Technology
 # Facilities Council
 # Original work Copyright (c) 1999-2008 Pearu Peterson
 
@@ -73,10 +73,22 @@
 # pylint: disable=eval-used
 # pylint: disable=exec-used
 # pylint: disable=unused-import
-from fparser.two.Fortran2003 import Program_Unit as Program_Unit_2003
-from fparser.two.Fortran2003 import EndStmtBase, BlockBase, SequenceBase, \
-    Base, Specification_Part, Module_Subprogram_Part, Implicit_Part, \
-    Implicit_Part_Stmt, Declaration_Construct, Use_Stmt, Import_Stmt
+from fparser.common.splitline import string_replace_map
+from fparser.two import pattern_tools as pattern
+
+from fparser.two.utils import STRINGBase, BracketBase, WORDClsBase, \
+    SeparatorBase, Type_Declaration_StmtBase
+from fparser.two.Fortran2003 import (
+    EndStmtBase, BlockBase, SequenceBase, Base, Specification_Part,
+    Module_Subprogram_Part, Implicit_Part, Implicit_Part_Stmt,
+    Declaration_Construct, Use_Stmt, Import_Stmt, Declaration_Type_Spec,
+    Entity_Decl_List, Component_Decl_List)
+# Import of F2003 classes that are updated in this standard.
+from fparser.two.Fortran2003 import (
+    Program_Unit as Program_Unit_2003, Attr_Spec as Attr_Spec_2003,
+    Type_Declaration_Stmt as Type_Declaration_Stmt_2003,
+    Component_Attr_Spec as Component_Attr_Spec_2003,
+    Data_Component_Def_Stmt as Data_Component_Def_Stmt_2003)
 
 
 class Program_Unit(Program_Unit_2003):  # R202
@@ -96,6 +108,424 @@ class Program_Unit(Program_Unit_2003):  # R202
     subclass_names.append("Submodule")
 
 
+class Data_Component_Def_Stmt(Data_Component_Def_Stmt_2003):  # R436
+    '''
+    Fortran 2008 rule 436
+    data-component-def-stmt is declaration-type-spec [
+             [ , component-attr-spec-list ] :: ] component-decl-list
+
+    The implementation of this rule does not add anything to the Fortran 2003
+    variant but reimplements the match method identical to Fortran 2003 as
+    otherwise the generated Fortran 2008 variant of `Component_Attr_Spec_List`
+    would not be used. Unfortunately, the required `attr_spec_list_cls` can not
+    simply be provided as a class property since the relevant class is only
+    generated at the end of this file using the `use_names` class property of
+    this class.
+
+    Associated constraints are:
+
+    "C439 (R436)  No component-attr-spec shall appear more than once in a given
+          component-def-stmt."
+    "C440 (R436)  If neither the POINTER nor the ALLOCATABLE attribute is
+          specified, the declaration-type-spec in the component-def-stmt shall
+          specify an intrinsic type or a previously defined derived type."
+    "C441 (R436)  If the POINTER or ALLOCATABLE attribute is specified, each
+          component-array-spec shall be a deferred-shape-spec-list."
+    "C442 (R436)  If a coarray-spec appears, it shall be a
+          deferred-coshape-spec-list and the component shall have the
+          ALLOCATABLE attribute."
+    "C443 (R436)  If a coarray-spec appears, the component shall not be of type
+          C_PTR or C_FUNPTR."
+    "C445 (R436)  If neither the POINTER nor the ALLOCATABLE attribute is
+          specified, each component-array-spec shall be an
+          explicit-shape-spec-list."
+    "C447 (R436)  A component shall not have both the ALLOCATABLE and POINTER
+          attributes."
+    "C448 (R436)  If the CONTIGUOUS attribute is specified, the component shall
+          be an array with the POINTER attribute."
+    "C457 (R436)  If component-initialization appears, a double-colon separator
+          shall appear before the component-decl-list."
+    "C458 (R436)  If component-initialization appears, every type parameter and
+          array bound of the component shall be a colon or constant expression.
+    "C459 (R436)  If => appears in component-initialization, POINTER shall
+          appear in the component-attr-spec-list. If = appears in
+          component-initialization, neither POINTER nor ALLOCATABLE shall
+          appear in the component-attr-spec-list."
+
+    C439-C443, C445, C447-C448, C457-C459 are currently not checked
+    - issue #258.
+
+    '''
+
+    @staticmethod
+    def match(string):
+        '''Implements the matching of a data component definition statement.
+
+        :param str string: the reader or string to match as a data \
+                           component definition statement.
+
+        :return: a 3-tuple containing declaration type specification, \
+                 component attribute specification and component declaration \
+                 list if there is a match or None if there is no match.
+        :rtype: `NoneType` or \
+            (:py:class:`fparser.two.Fortran2003.Declaration_Type_Spec`, \
+             :py:class:`fparser.two.Fortran2008.Component_Attr_Spec_List`, \
+             :py:class:`fparser.two.Fortran2003.Component_Decl_List`)
+
+        '''
+        return Type_Declaration_StmtBase.match(
+            Declaration_Type_Spec, Component_Attr_Spec_List,
+            Component_Decl_List, string)
+
+
+class Component_Attr_Spec(Component_Attr_Spec_2003):  # R437
+    '''
+    Fortran 2008 rule R437
+    component-attr-spec is access-spec
+                           or ALLOCATABLE
+                           or CODIMENSION lbracket coarray-spec rbracket
+                           or CONTIGUOUS
+                           or DIMENSION ( component-array-spec )
+                           or POINTER
+
+    In the spec above, lbracket and rbracket are left and right square
+    brackets `[]` but not printed explicitly to avoid misinterpretation
+    as optional parts.
+
+    This rule adds CODIMENSION and CONTIGUOUS attributes to Fortran2003's R441.
+
+    '''
+    subclass_names = Component_Attr_Spec_2003.subclass_names[:]
+    subclass_names.append('Codimension_Attr_Spec')
+    attributes = Component_Attr_Spec_2003.attributes[:]
+    attributes.append('CONTIGUOUS')
+
+
+class Type_Declaration_Stmt(Type_Declaration_Stmt_2003):  # R501
+    '''
+    Fortran 2008 rule 501
+    type-declaration-stmt is declaration-type-spec [ [ , attr-spec ] ... :: ]
+                             entity-decl-list
+
+    The implementation of this rule does not add anything to the Fortran 2003
+    variant but reimplements the match method identical to Fortran 2003 as
+    otherwise the generated Fortran 2008 variant of `Attr_Spec_List` would not
+    be used. Unfortunately, the required `attr_spec_list_cls` can not simply be
+    provided as a class property since the relevant class is only generated
+    at the end of this file using the `use_names` class property of this class.
+
+    Associated constraints are:
+
+    "C501 (R501)  The same attr-spec shall not appear more than once in a given
+          type-declaration-stmt."
+    "C502 (R501)  If a language-binding-spec with a NAME= specifier appears,
+          the entity-decl-list shall consist of a single entity-decl."
+    "C503 (R501)  If a language-binding-spec is specified, the entity-decl-list
+          shall not contain any procedure names."
+    "C505 (R501)  If initialization appears, a double-colon separator shall
+          appear before the entity-decl-list."
+
+    C501-C503, C505 are currently not checked - issue #259.
+
+    '''
+
+    @staticmethod
+    def match(string):
+        '''Implements the matching of a type declaration statement.
+
+        :param str string: the reader or string to match as a type \
+                           declaration statement.
+
+        :return: a 3-tuple containing declaration type specification, \
+                 attributespecification and entity declaration list \
+                 if there is a match or None if there is no match.
+        :rtype: `NoneType` or \
+            (:py:class:`fparser.two.Fortran2003.Declaration_Type_Spec`, \
+             :py:class:`fparser.two.Fortran2008.Attr_Spec_List`, \
+             :py:class:`fparser.two.Fortran2003.Entity_Decl_List`)
+
+        '''
+        return Type_Declaration_StmtBase.match(
+            Declaration_Type_Spec, Attr_Spec_List, Entity_Decl_List, string)
+
+
+class Codimension_Attr_Spec(WORDClsBase):  # R502.d
+    '''
+    codimension-attr-spec is CODIMENSION lbracket coarray-spec rbracket
+
+    In the spec above, lbracket and rbracket are left and right square
+    brackets `[]` but not printed explicitly to avoid misinterpretation
+    as optional parts.
+
+    '''
+    subclass_names = []
+    use_names = ['Coarray_Bracket_Spec']
+
+    @staticmethod
+    def match(string):
+        '''
+        Implements the matching for the CODIMENSION attribute.
+
+        :param str string: the string to match as the attribute.
+
+        :return: `None` if there is no match, otherwise a 2-tuple \
+                 containing `CODIMENSION` as a string and the matched \
+                 coarray-spec..
+        :rtype: `NoneType` or \
+            (`str`, :py:class:`fparser.two.Fortran2008.Coarray_Bracket_Spec`,)
+
+        '''
+        return WORDClsBase.match(
+            'CODIMENSION', Coarray_Bracket_Spec, string, colons=False,
+            require_cls=True)
+
+
+class Coarray_Bracket_Spec(BracketBase):  # R502.d.0
+    '''
+    coarray-bracket-spec is lbracket coarray-spec rbracket
+
+    In the spec above, lbracket and rbracket are left and right square
+    brackets `[]` but not printed explicitly to avoid misinterpretation
+    as optional parts.
+
+    '''
+    subclass_names = []
+    use_names = ['Coarray_Spec']
+
+    @staticmethod
+    def match(string):
+        '''
+        Implements the matching for the coarray specification
+        including the square brackets.
+
+        :param str string: the string to match as the specification.
+
+        :return: `None` if there is no match, otherwise a 3-tuple \
+                 containing the left bracket, the matched coarray-spec, \
+                 and the right bracket.
+        :rtype: `NoneType` or \
+            (`str`, :py:class:`fparser.two.Fortran2008.Coarray_Spec`, `str`)
+
+        '''
+        return BracketBase.match('[]', Coarray_Spec, string)
+
+
+class Attr_Spec(Attr_Spec_2003):  # R502
+    '''
+    Fortran 2008 rule R502
+    attr-spec is access-spec
+                 or ALLOCATABLE
+                 or ASYNCHRONOUS
+                 or CODIMENSION lbracket coarray-spec rbracket
+                 or CONTIGUOUS
+                 or DIMENSION ( array-spec )
+                 or EXTERNAL
+                 or INTENT ( intent-spec )
+                 or INTRINSIC
+                 or language-binding-spec
+                 or OPTIONAL
+                 or PARAMETER
+                 or POINTER
+                 or PROTECTED
+                 or SAVE
+                 or TARGET
+                 or VALUE
+                 or VOLATILE
+
+    In the spec above, lbracket and rbracket are left and right square
+    brackets `[]` but not printed explicitly to avoid misinterpretation
+    as optional parts.
+
+    This rule adds CODIMENSION and CONTIGUOUS attributes to Fortran2003's R503.
+
+    '''
+    subclass_names = Attr_Spec_2003.subclass_names[:]
+    subclass_names.append('Codimension_Attr_Spec')
+    use_names = []
+
+    @staticmethod
+    def match(string):
+        '''
+        Implements the matching for attributes of types.
+
+        :param str string: the string to match as attribute.
+
+        :return: `None` if there is no match, otherwise a 1-tuple \
+                 containing the matched string.
+        :rtype: `NoneType` or (`str`,)
+
+        '''
+        return STRINGBase.match(pattern.abs_attr_spec_f08, string)
+
+
+class Coarray_Spec(Base):  # R509
+    '''
+    Fortran 2008 rule R509
+    coarray-spec is deferred-coshape-spec-list
+                    or explicit-coshape-spec-list
+
+    '''
+    subclass_names = ['Explicit_Coshape_Spec',
+                      'Deferred_Coshape_Spec_List']
+
+
+class Deferred_Coshape_Spec(SeparatorBase):  # R510
+    '''
+    Fortran 2008 rule R510
+    deferred-coshape-spec is :
+
+    '''
+    subclass_names = []
+
+    @staticmethod
+    def match(string):
+        '''
+        Implements the matching for deferred coarray shape specification.
+
+        :param str string: the string to match as deferred shape.
+
+        :return: `None` if there is no match, otherwise a 2-tuple \
+                 containing `None`.
+        :rtype: `NoneType` or (`None`, `None`)
+
+        '''
+        if string == ':':
+            return (None, None)
+        return None
+
+
+class Explicit_Coshape_Spec(SeparatorBase):  # R511
+    '''
+    Fortran 2008 rule R511
+    explicit-coshape-spec is [ coshape-spec-list , ] [ lower-cobound : ] *
+
+    Associated constraint is:
+
+    "C529 (R511)  A lower-cobound or upper-cobound that  is  not  a  constant
+          expression shall appear only in a subprogram, BLOCK construct, or
+          interface body."
+
+    C529 is currently not checked - issue #259.
+
+    '''
+    subclass_names = []
+    use_names = ['Coshape_Spec_List', 'Lower_Cobound']
+
+    @staticmethod
+    def match(string):
+        '''
+        Implements the matching for explicit coarray shape specification.
+
+        :param str string: the string to match as deferred shape.
+
+        :return: `None` if there is no match, otherwise a 2-tuple \
+                 containing matched coshape-spec-list or `None` and \
+                 matched lower-cobound or `None`.
+        :rtype: `NoneType` or \
+            (:py:class:`fparser.two.Fortran2008.Coshape_Spec_List` or `None`, \
+             :py:class:`fparser.two:Fortran2008.Lower_Cobound` or `None`)
+
+        '''
+        if not string.endswith('*'):
+            return None
+        line = string[:-1].rstrip()
+        if not line:
+            return (None, None)
+        if line.endswith(':'):
+            line, repmap = string_replace_map(line[:-1].rstrip())
+            sep_pos = line.rfind(',')
+            if sep_pos == -1:
+                return (None, Lower_Cobound(repmap(line)))
+            return (Coshape_Spec_List(repmap(line[:sep_pos].rstrip())),
+                    Lower_Cobound(repmap(line[sep_pos+1:].lstrip())))
+        if not line.endswith(','):
+            return None
+        line = line[:-1].rstrip()
+        return (Coshape_Spec_List(line), None)
+
+    def tostr(self):
+        '''
+        Converts the explicit coarray shape specification to string.
+
+        :return: the shape specification as string.
+        :rtype: str
+
+        '''
+        s = ''
+        if self.items[0]:
+            s += str(self.items[0]) + ', '
+        if self.items[1]:
+            s += str(self.items[1]) + ' : '
+        s += '*'
+        return s
+
+
+class Coshape_Spec(SeparatorBase):  # R511.a
+    '''
+    coshape-spec is [ lower-cobound : ] upper-cobound
+
+    '''
+    subclass_names = []
+    use_names = ['Lower_Cobound', 'Upper_Cobound']
+
+    @staticmethod
+    def match(string):
+        '''
+        Implements the matching for a coarray shape.
+
+        :param str string: the string to match as shape.
+
+        :return: `None` if there is no match, otherwise a 2-tuple with \
+                 lower bound if given or `None`, and upper bound.
+        :rtype: `NoneType` or \
+            (`None`, :py:class:`fparser.two.Fortran2008.Upper_Cobound`) or \
+            (:py:class:`fparser.two.Fortran2008.Lower_Cobound`, \
+             :py:class:`fparser.two.Fortran2008.Upper_Cobound`)
+
+        '''
+        line, repmap = string_replace_map(string)
+        if ':' not in line:
+            return (None, Upper_Cobound(string))
+        lower, upper = line.split(':', 1)
+        lower = lower.rstrip()
+        upper = upper.lstrip()
+        if not upper:
+            return None
+        if not lower:
+            return None
+        return (Lower_Cobound(repmap(lower)), Upper_Cobound(repmap(upper)))
+
+    def tostr(self):
+        '''
+        Converts the Shape specification to string.
+
+        :return: the shape specification as string.
+        :rtype: str
+
+        '''
+        if self.items[0] is None:
+            return str(self.items[1])
+        return SeparatorBase.tostr(self)
+
+
+class Lower_Cobound(Base):  # R512
+    '''
+    Fortran 2008 rule R512
+    lower-cobound is specification-expr
+
+    '''
+    subclass_names = ['Specification_Expr']
+
+
+class Upper_Cobound(Base):  # R513
+    '''
+    Fortran 2008 rule R513
+    upper-cobound is specification-expr
+
+    '''
+    subclass_names = ['Specification_Expr']
+
+
 class Specification_Part_C1112(Specification_Part):  # C1112
     '''Fortran 2008 constraint C1112
     C1112 A submodule specification-part shall not contain a
diff --git a/src/fparser/two/pattern_tools.py b/src/fparser/two/pattern_tools.py
index 10b68cb..5aad9f8 100644
--- a/src/fparser/two/pattern_tools.py
+++ b/src/fparser/two/pattern_tools.py
@@ -474,6 +474,14 @@ attr_spec = Pattern(
     flags=re.I)
 abs_attr_spec = abs(attr_spec)
 
+attr_spec_f08 = Pattern(
+    '<attr-spec>',
+    r'({})'.format('|'.join(  # extend attr_spec with attribute CONTIGUOUS
+        sorted(attr_spec.pattern.strip('()').split('|') + ['CONTIGUOUS'])
+    )),
+    flags=re.I)
+abs_attr_spec_f08 = abs(attr_spec_f08)
+
 dimension = Pattern('<dimension>', r'DIMENSION', flags=re.I)
 abs_dimension = abs(dimension)
 
diff --git a/src/fparser/two/utils.py b/src/fparser/two/utils.py
index dc85cfe..e929597 100644
--- a/src/fparser/two/utils.py
+++ b/src/fparser/two/utils.py
@@ -320,7 +320,7 @@ class Base(ComparableMixin):
             parent_cls.append(cls)
 
         # Get the class' match method if it has one
-        match = cls.__dict__.get('match')
+        match = getattr(cls, 'match') if hasattr(cls, 'match') else None
 
         if isinstance(string, FortranReaderBase) and \
            match and not issubclass(cls, BlockBase):


Test patch:
diff --git a/src/fparser/two/tests/fortran2008/conftest.py b/src/fparser/two/tests/fortran2008/conftest.py
index 8617aef..e2d2ccb 100644
--- a/src/fparser/two/tests/fortran2008/conftest.py
+++ b/src/fparser/two/tests/fortran2008/conftest.py
@@ -44,3 +44,14 @@ from fparser.two.parser import ParserFactory
 def f2008_create():
     '''Create a fortran 2008 parser class hierarchy'''
     _ = ParserFactory().create(std="f2008")
+
+
+@pytest.fixture
+def f2008_parser():
+    '''Create a Fortran 2008 parser class hierarchy and return the parser
+    for usage in tests.
+
+    :return: a Program class (not object) for use with the Fortran reader.
+    :rtype: :py:class:`fparser.two.Fortran2003.Program`
+    '''
+    return ParserFactory().create(std='f2008')
diff --git a/src/fparser/two/tests/fortran2008/test_attr_spec_r502.py b/src/fparser/two/tests/fortran2008/test_attr_spec_r502.py
new file mode 100644
index 0000000..60c129e
--- /dev/null
+++ b/src/fparser/two/tests/fortran2008/test_attr_spec_r502.py
@@ -0,0 +1,173 @@
+# Copyright (c) 2020 Science and Technology Facilities Council
+
+# All rights reserved.
+
+# Modifications made as part of the fparser project are distributed
+# under the following license:
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Test Fortran 2008 rule R502.
+
+    attr-spec is access-spec
+                 or ALLOCATABLE
+                 or ASYNCHRONOUS
+                 or CODIMENSION lbracket coarray-spec rbracket
+                 or CONTIGUOUS
+                 or DIMENSION ( component-array-spec )
+                 or EXTERNAL
+                 or INTENT ( intent-spec )
+                 or INTRINSIC
+                 or language-binding-spec
+                 or OPTIONAL
+                 or PARAMETER
+                 or POINTER
+                 or PROTECTED
+                 or SAVE
+                 or TARGET
+                 or VALUE
+                 or VOLATILE
+'''
+
+import pytest
+from fparser.two.Fortran2008 import (
+    Attr_Spec, Codimension_Attr_Spec, Deferred_Coshape_Spec, Coshape_Spec)
+from fparser.two import Fortran2003
+from fparser.api import get_reader
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('mixed_case_ref', [
+    'ALlOCaTABLE', 'ASYNChroNOUS', 'CONTIGUOUs', 'eXTERNAL', 'INtRINsIC',
+    'OPTIOnAL', 'PARAmeTER', 'PoInTeR', 'pROTECTEd', 'SAvE', 'TargeT',
+    'VALUE', 'VOLATILE'
+])
+def test_attr_spec(mixed_case_ref):
+    '''Test the parsing of common attributes provided as mixed case, upper
+    case and lower case strings.'''
+    for manip in [str, str.upper, str.lower]:
+        obj = Attr_Spec(manip(mixed_case_ref))
+        assert isinstance(obj, Attr_Spec), repr(obj)
+        assert str(obj) == mixed_case_ref.upper()
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', [
+    '', 'CONTIGUOS', ' SAVE', 'TARGET ', 'VA LUE', 'POINNTER', ' DIMENSION(:)'
+])
+def test_invalid_attr_spec(attr):
+    '''Test that invalid or misspelled attributes raise exceptions.'''
+    with pytest.raises(Fortran2003.NoMatchError):
+        _ = Attr_Spec(attr)
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr, ref', [
+    ('DIMENSION   (:)', 'DIMENSION(:)'),
+    ('dimenSION(  : )', 'DIMENSION(:)'),
+    ('DIMENSION (5)', 'DIMENSION(5)'),
+    ('DIMENSION (2:)', 'DIMENSION(2 :)'),
+    ('dimension (1:5, 2, 3:4)', 'DIMENSION(1 : 5, 2, 3 : 4)')
+])
+def test_attr_spec_dimension(attr, ref):
+    '''Test the parsing of dimension attribute in attr_spec.'''
+    obj = Attr_Spec(attr)
+    assert isinstance(obj, Fortran2003.Dimension_Attr_Spec), repr(obj)
+    assert str(obj) == ref
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr, ref', [
+    ('codimension[*]', 'CODIMENSION [*]'),
+    ('CODIMENSION   [:]', 'CODIMENSION [:]'),
+    ('COdimenSION[  : ]', 'CODIMENSION [:]'),
+    ('coDIMENSIon [ *]', 'CODIMENSION [*]'),
+    ('CoDimension [1:*]', 'CODIMENSION [1 : *]'),
+    (' CODIMENSION [1:5, *]   ', 'CODIMENSION [1 : 5, *]'),
+    ('codimension [1:5, 2, 3:*]', 'CODIMENSION [1 : 5, 2, 3 : *]')
+])
+def test_attr_spec_codimension(attr, ref):
+    '''Test the parsing of codimension attribute in attr_spec.'''
+    obj = Attr_Spec(attr)
+    assert isinstance(obj, Codimension_Attr_Spec), repr(obj)
+    assert str(obj) == ref
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', [
+    'codimension[1:5]', 'codimension[3:]', 'codimension[:5]',
+    'codimension[,,]', 'codimension[1, 5, 3 *]', 'co dimension[*]',
+    'coodimension[*]', 'codimension[]', 'codimensions[*]', 'codimension',
+    'codimension[[*]', 'codimension[[:]]', 'codimension[][]'
+])
+def test_invalid_attr_spec_codimension(attr):
+    '''Test that invalid codimension attribute in attr_spec raise exception.'''
+    with pytest.raises(Fortran2003.NoMatchError):
+        _ = Attr_Spec(attr)
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr, ref', [
+    ('codimension[*]', 'CODIMENSION [*]'),
+    ('CODIMENSION   [:]', 'CODIMENSION [:]'),
+    ('COdimenSION[  : ]', 'CODIMENSION [:]'),
+    ('coDIMENSIon [ *]', 'CODIMENSION [*]'),
+    (' CODIMENSION [1:5, *]   ', 'CODIMENSION [1 : 5, *]'),
+    ('codimension [1:5, 2, 3:*]', 'CODIMENSION [1 : 5, 2, 3 : *]')
+])
+def test_codimension_attr_spec(attr, ref):
+    '''Test the parsing of codimension attributes.'''
+    obj = Codimension_Attr_Spec(attr)
+    assert isinstance(obj, Codimension_Attr_Spec), repr(obj)
+    assert str(obj) == ref
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', [
+    'codimension[1:5]', 'codimension[3:]', 'codimension[:5]',
+    'codimension[,,]', 'codimension[1, 5, 3 *]', 'co dimension[*]',
+    'coodimension[*]', 'codimension[]', 'codimensions[*]', 'codimension',
+    'codimension[[*]', 'codimension[[:]]', 'codimension[][]'
+])
+def test_invalid_codimension_attr_spec(attr):
+    '''Test that invalid codimension attributes raise exception.'''
+    with pytest.raises(Fortran2003.NoMatchError):
+        _ = Codimension_Attr_Spec(attr)
+
+
+def test_attr_spec_list_parser(f2008_parser):
+    '''Test that Attr_Spec_List is generated correctly and used by a parser.'''
+    code = '''
+SUBROUTINE FOO(i)
+  INTEGER, CONTIGUOUS, INTENT(IN) :: i(10)
+  INTEGER :: j
+END SUBROUTINE
+    '''.strip()
+    reader = get_reader(code)
+    result = f2008_parser(reader)
+    assert str(result) == code
diff --git a/src/fparser/two/tests/fortran2008/test_coarray_spec_r509.py b/src/fparser/two/tests/fortran2008/test_coarray_spec_r509.py
new file mode 100644
index 0000000..9751513
--- /dev/null
+++ b/src/fparser/two/tests/fortran2008/test_coarray_spec_r509.py
@@ -0,0 +1,71 @@
+# Copyright (c) 2020 Science and Technology Facilities Council
+
+# All rights reserved.
+
+# Modifications made as part of the fparser project are distributed
+# under the following license:
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Test Fortran 2008 rule R509
+
+    coarray-spec is deferred-coshape-spec-list
+                    or explicit-coshape-spec-list
+
+'''
+
+import pytest
+from fparser.two.Fortran2008 import (
+    Coarray_Spec, Deferred_Coshape_Spec_List, Explicit_Coshape_Spec)
+from fparser.two import Fortran2003
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr, _type', [
+    ('*', Explicit_Coshape_Spec),
+    ('5 :*', Explicit_Coshape_Spec),
+    ('1:  3  ,  a: *', Explicit_Coshape_Spec),
+    (' 1 ,  2,3:*', Explicit_Coshape_Spec),
+    ('1:2,3,*', Explicit_Coshape_Spec),
+    (':', Deferred_Coshape_Spec_List)
+])
+def test_coarray_spec(attr, _type):
+    '''Test that coarray_spec are parsed correctly.'''
+    obj = Coarray_Spec(attr)
+    assert isinstance(obj, _type), repr(obj)
+    ref = attr.replace(' ', '').replace(':', ' : ').replace(',', ', ').strip()
+    assert str(obj) == ref
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', [
+    '1:3', '', ':b', 'a:', ':*', '', '1:,*', '1,,*', '::', '5'])
+def test_invalid_coarray_spec(attr):
+    '''Test that invalid coarray_spec raise exception.'''
+    with pytest.raises(Fortran2003.NoMatchError):
+        _ = Coarray_Spec(attr)
diff --git a/src/fparser/two/tests/fortran2008/test_component_attr_spec_r437.py b/src/fparser/two/tests/fortran2008/test_component_attr_spec_r437.py
new file mode 100644
index 0000000..143a837
--- /dev/null
+++ b/src/fparser/two/tests/fortran2008/test_component_attr_spec_r437.py
@@ -0,0 +1,124 @@
+# Copyright (c) 2020 Science and Technology Facilities Council
+
+# All rights reserved.
+
+# Modifications made as part of the fparser project are distributed
+# under the following license:
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Test Fortran 2008 rule R437.
+
+    component-attr-spec = access-spec
+                          or ALLOCATABLE
+                          or CODIMENSION lbracket coarray-spec rbracket
+                          or CONTIGUOUS
+                          or DIMENSION ( component-array-spec )
+                          or POINTER
+'''
+
+import pytest
+from fparser.two.Fortran2003 import (
+    Access_Spec, Dimension_Component_Attr_Spec, NoMatchError)
+from fparser.two.Fortran2008 import Component_Attr_Spec, Codimension_Attr_Spec
+from fparser.api import get_reader
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('mixed_case_ref', ['ALlOCaTABLE', 'CONTIGUOUs',
+                                            'PoInTeR'])
+def test_component_attr_spec(mixed_case_ref):
+    '''Test the parsing of component attributes provided as mixed case, upper
+    case and lower case strings.'''
+    for manip in [str, str.upper, str.lower]:
+        obj = Component_Attr_Spec(manip(mixed_case_ref))
+        assert isinstance(obj, Component_Attr_Spec), repr(obj)
+        assert str(obj) == mixed_case_ref.upper()
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', ['', ' ALLOCATABLE', 'POINTER ', 'POIN TER',
+                                  'CONTIGOUS', 'ALOCATABLE', 'FOO'])
+def test_invalid_component_attr_spec(attr):
+    '''Test that invalid or misspelled component attributes raise exception.'''
+    with pytest.raises(NoMatchError):
+        _ = Component_Attr_Spec(attr)
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr, ref', [
+    ('DIMENSION   (:)', 'DIMENSION(:)'),
+    ('dimenSION(  : )', 'DIMENSION(:)'),
+    ('DIMENSION (5)', 'DIMENSION(5)'),
+    ('dimension (1:5, 2, 3:4)', 'DIMENSION(1 : 5, 2, 3 : 4)')
+])
+def test_component_attr_spec_dimension(attr, ref):
+    '''Test the parsing of dimension attribute in component_attr_spec.'''
+    obj = Component_Attr_Spec(attr)
+    assert isinstance(obj, Dimension_Component_Attr_Spec), repr(obj)
+    assert str(obj) == ref
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr, ref', [
+    ('codimension[*]', 'CODIMENSION [*]'),
+    ('CODIMENSION   [:]', 'CODIMENSION [:]'),
+    ('COdimenSION[  : ]', 'CODIMENSION [:]'),
+    ('coDIMENSIon [ *]', 'CODIMENSION [*]'),
+    (' CODIMENSION [1:5, *]   ', 'CODIMENSION [1 : 5, *]'),
+    ('codimension [1:5, 2, 3:*]', 'CODIMENSION [1 : 5, 2, 3 : *]')
+])
+def test_component_attr_spec_codimensions(attr, ref):
+    '''Test the parsing of codimension attribute in component_attr_spec.'''
+    obj = Component_Attr_Spec(attr)
+    assert isinstance(obj, Codimension_Attr_Spec), repr(obj)
+    assert str(obj) == ref
+
+
+@pytest.mark.usefixtures("f2008_create")
+def test_private_attr():
+    '''Tests the parsing of private attribute.'''
+    obj = Component_Attr_Spec('private')
+    assert isinstance(obj, Access_Spec), repr(obj)
+    assert str(obj) == 'PRIVATE'
+
+
+def test_component_attr_spec_list_parser(f2008_parser):
+    '''Test that Component_Attr_Spec_List is generated correctly
+    and used by the F2008 parser.'''
+    code = '''
+MODULE FOO
+  TYPE :: GRID_TYPE
+    REAL, ALLOCATABLE, CODIMENSION [:, :, :] :: GRID(:, :, :)
+    REAL :: BAR
+  END TYPE GRID_TYPE
+END MODULE FOO
+    '''.strip()
+    reader = get_reader(code)
+    result = f2008_parser(reader)
+    assert str(result) == code
diff --git a/src/fparser/two/tests/fortran2008/test_data_component_def_stmt_r436.py b/src/fparser/two/tests/fortran2008/test_data_component_def_stmt_r436.py
new file mode 100644
index 0000000..8b42d18
--- /dev/null
+++ b/src/fparser/two/tests/fortran2008/test_data_component_def_stmt_r436.py
@@ -0,0 +1,42 @@
+# Copyright (c) 2020 Science and Technology Facilities Council
+
+# All rights reserved.
+
+# Modifications made as part of the fparser project are distributed
+# under the following license:
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Test Fortran 2008 rule 436
+
+  data-component-def-stmt is declaration-type-spec [
+           [ , component-attr-spec-list ] :: ] component-decl-list
+
+R436 (and its Fortran 2003 counterpart R440) are currently untested (see #465).
+
+'''
diff --git a/src/fparser/two/tests/fortran2008/test_deferred_coshape_spec_r510.py b/src/fparser/two/tests/fortran2008/test_deferred_coshape_spec_r510.py
new file mode 100644
index 0000000..1d90a10
--- /dev/null
+++ b/src/fparser/two/tests/fortran2008/test_deferred_coshape_spec_r510.py
@@ -0,0 +1,59 @@
+# Copyright (c) 2020 Science and Technology Facilities Council
+
+# All rights reserved.
+
+# Modifications made as part of the fparser project are distributed
+# under the following license:
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Test Fortran 2008 rule R510
+
+    deferred-coshape-spec is :
+
+'''
+
+import pytest
+from fparser.two.Fortran2008 import Deferred_Coshape_Spec
+from fparser.two import Fortran2003
+
+
+@pytest.mark.usefixtures("f2008_create")
+def test_deferred_coshape_spec():
+    '''Test parsing of deferred_coshape_spec.'''
+    obj = Deferred_Coshape_Spec(':')
+    assert isinstance(obj, Deferred_Coshape_Spec), repr(obj)
+    assert str(obj) == ':'
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', ['', ' :', ': ', '  : ', '::', '5'])
+def test_invalid_deferred_coshape_spec(attr):
+    '''Test that invalid deferred_coshape_spec raise exception.'''
+    with pytest.raises(Fortran2003.NoMatchError):
+        _ = Deferred_Coshape_Spec(attr)
diff --git a/src/fparser/two/tests/fortran2008/test_explicit_coshape_spec_r511.py b/src/fparser/two/tests/fortran2008/test_explicit_coshape_spec_r511.py
new file mode 100644
index 0000000..b5514f8
--- /dev/null
+++ b/src/fparser/two/tests/fortran2008/test_explicit_coshape_spec_r511.py
@@ -0,0 +1,88 @@
+# Copyright (c) 2020 Science and Technology Facilities Council
+
+# All rights reserved.
+
+# Modifications made as part of the fparser project are distributed
+# under the following license:
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Test Fortran 2008 rule R511
+
+    explicit-coshape-spec is [ coshape-spec-list , ] [ lower-cobound : ] *
+
+'''
+
+import pytest
+from fparser.two.Fortran2008 import (
+    Explicit_Coshape_Spec, Coshape_Spec, Coshape_Spec_List)
+from fparser.two import Fortran2003
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr, types', [
+    ('*', (type(None), type(None))),
+    ('5 :*', (type(None), Fortran2003.Int_Literal_Constant)),
+    ('1:  3  ,  a: *', (Coshape_Spec_List, Fortran2003.Name)),
+    (' 1 ,  2,3:*', (Coshape_Spec_List, Fortran2003.Int_Literal_Constant)),
+    ('1:2,3,*', (Coshape_Spec_List, type(None))),
+])
+def test_explicit_coshape_spec(attr, types):
+    '''Test that explicit_coshape_spec are parsed correctly.'''
+    obj = Explicit_Coshape_Spec(attr)
+    assert isinstance(obj, Explicit_Coshape_Spec), repr(obj)
+    assert isinstance(obj.items[0], types[0])
+    assert isinstance(obj.items[1], types[1])
+    ref = attr.replace(' ', '').replace(':', ' : ').replace(',', ', ')
+    assert str(obj) == ref
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', [
+    '1:3', ':', ':b', 'a:', ':*', '', '1:,*', '1,,*'])
+def test_invalid_explicit_coshape_spec(attr):
+    '''Test that invalid explicit_coshape_spec raise exception.'''
+    with pytest.raises(Fortran2003.NoMatchError):
+        _ = Explicit_Coshape_Spec(attr)
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', ['a', '10', '1:3', ' 5 : 123 ', '2:   b   '])
+def test_coshape_spec(attr):
+    '''Test that coshape_spec are parsed correctly.'''
+    obj = Coshape_Spec(attr)
+    assert isinstance(obj, Coshape_Spec), repr(obj)
+    assert str(obj) == attr.replace(' ', '').replace(':', ' : ')
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', [':', 'a:', ':b', '*', '', '1::3'])
+def test_invalid_coshape_spec(attr):
+    '''Test that invalid coshape_spec raise exception.'''
+    with pytest.raises(Fortran2003.NoMatchError):
+        _ = Coshape_Spec(attr)
diff --git a/src/fparser/two/tests/fortran2008/test_lower_cobound_r512.py b/src/fparser/two/tests/fortran2008/test_lower_cobound_r512.py
new file mode 100644
index 0000000..061e4df
--- /dev/null
+++ b/src/fparser/two/tests/fortran2008/test_lower_cobound_r512.py
@@ -0,0 +1,67 @@
+# Copyright (c) 2020 Science and Technology Facilities Council
+
+# All rights reserved.
+
+# Modifications made as part of the fparser project are distributed
+# under the following license:
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Test Fortran 2008 rule R512
+
+    lower-cobound is specification-expr
+
+'''
+
+import pytest
+from fparser.two.Fortran2008 import Lower_Cobound
+from fparser.two import Fortran2003
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr, _type', [
+    ('aaa', Fortran2003.Name),
+    ('aAa', Fortran2003.Name),
+    ('1', Fortran2003.Int_Literal_Constant),
+    ('5  + 7', Fortran2003.Level_2_Expr),
+    ('3-9', Fortran2003.Level_2_Expr)
+])
+def test_lower_cobound(attr, _type):
+    '''Test that lower_cobound is parsed correctly.'''
+    obj = Lower_Cobound(attr)
+    assert isinstance(obj, _type), repr(obj)
+    ref = attr.replace(' ', '').replace('+', ' + ').replace('-', ' - ')
+    assert str(obj) == ref
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', ['', '*'])
+def test_invalid_lower_cobound(attr):
+    '''Test that invalid lower_cobound raise exception.'''
+    with pytest.raises(Fortran2003.NoMatchError):
+        _ = Lower_Cobound(attr)
diff --git a/src/fparser/two/tests/fortran2008/test_type_declaration_stmt_r501.py b/src/fparser/two/tests/fortran2008/test_type_declaration_stmt_r501.py
new file mode 100644
index 0000000..bbaa2f9
--- /dev/null
+++ b/src/fparser/two/tests/fortran2008/test_type_declaration_stmt_r501.py
@@ -0,0 +1,89 @@
+# Copyright (c) 2020 Science and Technology Facilities Council
+
+# All rights reserved.
+
+# Modifications made as part of the fparser project are distributed
+# under the following license:
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Test Fortran 2008 rule R501.
+
+    type-declaration-stmt is declaration-type-spec [ [ , attr-spec ] ... :: ]
+                             entity-decl-list
+
+'''
+
+from fparser.two.Fortran2008 import Type_Declaration_Stmt
+
+
+def test_type_declaration_stmt():  # R501
+    '''
+    Tests copied from Fortran 2003.
+
+    '''
+    tcls = Type_Declaration_Stmt
+    obj = tcls('integer a')
+    assert isinstance(obj, tcls), repr(obj)
+    assert str(obj) == 'INTEGER :: a'
+    assert (repr(obj) ==
+            "Type_Declaration_Stmt(Intrinsic_Type_Spec('INTEGER', "
+            "None), None, Entity_Decl_List(',', (Entity_Decl(Name('a'), None, "
+            "None, None),)))")
+
+    obj = tcls('integer ,dimension(2):: a*3')
+    assert isinstance(obj, tcls), repr(obj)
+    assert str(obj) == 'INTEGER, DIMENSION(2) :: a*3'
+
+    obj = tcls('real a')
+    assert isinstance(obj, tcls), repr(obj)
+    assert str(obj) == 'REAL :: a'
+    assert (repr(obj) ==
+            "Type_Declaration_Stmt(Intrinsic_Type_Spec('REAL', None), None, "
+            "Entity_Decl_List(',', (Entity_Decl(Name('a'), None, None, "
+            "None),)))")
+
+    obj = tcls('REAL A( LDA, * ), B( LDB, * )')
+    assert isinstance(obj, tcls), repr(obj)
+    assert str(obj) == 'REAL :: A(LDA, *), B(LDB, *)'
+
+    obj = tcls('DOUBLE PRECISION   ALPHA, BETA')
+    assert isinstance(obj, tcls), repr(obj)
+    assert str(obj) == 'DOUBLE PRECISION :: ALPHA, BETA'
+
+    obj = tcls('logical,parameter:: T=.true.')
+    assert isinstance(obj, tcls), repr(obj)
+    assert str(obj) == 'LOGICAL, PARAMETER :: T = .TRUE.'
+
+    obj = tcls('character(n),private:: x(n)')
+    assert isinstance(obj, tcls), repr(obj)
+    assert str(obj) == 'CHARACTER(LEN = n), PRIVATE :: x(n)'
+
+    obj = tcls('character(lenmax),private:: x(n)')
+    assert isinstance(obj, tcls), repr(obj)
+    assert str(obj) == 'CHARACTER(LEN = lenmax), PRIVATE :: x(n)'
diff --git a/src/fparser/two/tests/fortran2008/test_upper_cobound_r513.py b/src/fparser/two/tests/fortran2008/test_upper_cobound_r513.py
new file mode 100644
index 0000000..4303b34
--- /dev/null
+++ b/src/fparser/two/tests/fortran2008/test_upper_cobound_r513.py
@@ -0,0 +1,67 @@
+# Copyright (c) 2020 Science and Technology Facilities Council
+
+# All rights reserved.
+
+# Modifications made as part of the fparser project are distributed
+# under the following license:
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''Test Fortran 2008 rule R513
+
+    upper-cobound is specification-expr
+
+'''
+
+import pytest
+from fparser.two.Fortran2008 import Upper_Cobound
+from fparser.two import Fortran2003
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr, _type', [
+    ('aaa', Fortran2003.Name),
+    ('aAa', Fortran2003.Name),
+    ('1', Fortran2003.Int_Literal_Constant),
+    ('5  + 7', Fortran2003.Level_2_Expr),
+    ('3-9', Fortran2003.Level_2_Expr)
+])
+def test_upper_cobound(attr, _type):
+    '''Test that upper_cobound is parsed correctly.'''
+    obj = Upper_Cobound(attr)
+    assert isinstance(obj, _type), repr(obj)
+    ref = attr.replace(' ', '').replace('+', ' + ').replace('-', ' - ')
+    assert str(obj) == ref
+
+
+@pytest.mark.usefixtures("f2008_create")
+@pytest.mark.parametrize('attr', ['', '*'])
+def test_invalid_upper_cobound(attr):
+    '''Test that invalid upper_cobound raise exception.'''
+    with pytest.raises(Fortran2003.NoMatchError):
+        _ = Upper_Cobound(attr)