This patch adds the following semantic checks:

- None of expr, and expr_list (as applicable) may access the same storage location as x
- Atomic update statement should be of the form
`x = x operator expr`or`x = expr operator x`or`x = intrinsic_procedure(x, expr_list)`or`x = intrinsic_procedure(expr_list, x)` - expr_list is a comma-separated, non-empty list of scalar expressions. If intrinsic_procedure_name refers to IAND, IOR, or IEOR, exactly one expression must appear in expr_list

For the first check, the number of times the LHS variable's symbol occurs on the RHS of the assignment statement is counted. If >1 occurrences of the symbol occur, error is reported.

For the second check, the position of LHS variable's symbol in the symbol vector of the RHS is checked. If proper format of the atomic update statement is followed, then the symbol should occur either at the front or at the end of the symbol vector.

For the third check, the implementation used the fact that the entire evaluated expression's `Rank()` becomes non-zero if any symbol with non-zero `Rank()` is used in that expression. Note that the patch does not check explicitly check "comma-separated" list as well as whether `expr_list` is non-empty. These are automatically checked by Fortran language semantic checks. For example, Fortran language semantics verify that IAND/IOR/IEOR should have exactly two arguments. Similarly, the semantics verify that MAX/MIN etc should have at least two arguments.

This patch also adds tests for the following checks:

- The expression
`x operator expr`must be numerically equivalent to`x operator (expr)`. This requirement is satisfied if the operators in expr have precedence greater than operator, or by using parentheses around expr or subexpressions of expr. - The expression
`expr operator x`must be numerically equivalent to`(expr) operator x`. This requirement is satisfied if the operators in expr have precedence equal to or greater than operator, or by using parentheses around expr or subexpressions of expr.

This patch does not need to separately check for these as this is ensured by either parentheses in the source code or by the interplay of operator precedence and associativity (both of which are handled by Fortran language semantics).