Semantic Analysis#

The semantic analysis pass determines if a syntactically correct Fortran program is legal by enforcing the constraints of the language.

The input is a parse tree with a Program node at the root; and a “cooked” character stream, a contiguous stream of characters containing a normalized form of the Fortran source.

The semantic analysis pass takes a parse tree for a syntactically correct Fortran program and determines whether it is legal by enforcing the constraints of the language.

If the program is not legal, the results of the semantic pass will be a list of errors associated with the program.

If the program is legal, the semantic pass will produce a (possibly modified) parse tree for the semantically correct program with each name mapped to a symbol and each expression fully analyzed.

All user errors are detected either prior to or during semantic analysis. After it completes successfully the program should compile with no error messages. There may still be warnings or informational messages.

Phases of Semantic Analysis#

  1. Validate labels - Check all constraints on labels and branches

  2. Rewrite DO loops - Convert all occurrences of LabelDoStmt to DoConstruct.

  3. Name resolution - Analyze names and declarations, build a tree of Scopes containing Symbols, and fill in the Name::symbol data member in the parse tree

  4. Rewrite parse tree - Fix incorrect parses based on symbol information

  5. Expression analysis - Analyze all expressions in the parse tree and fill in Expr::typedExpr and Variable::typedExpr with analyzed expressions; fix incorrect parses based on the result of this analysis

  6. Statement semantics - Perform remaining semantic checks on the execution parts of subprograms

  7. Write module files - If no errors have occurred, write out .mod files for modules and submodules

If phase 1 or phase 2 encounter an error on any of the program units, compilation terminates. Otherwise, phases 3-6 are all performed even if errors occur. Module files are written (phase 7) only if there are no errors.

Validate labels#

Perform semantic checks related to labels and branches:

  • check that any labels that are referenced are defined and in scope

  • check branches into loop bodies

  • check that labeled DO loops are properly nested

  • check labels in data transfer statements

Rewrite DO loops#

This phase normalizes the parse tree by removing all unstructured DO loops and replacing them with DO constructs.

Name resolution#

The name resolution phase walks the parse tree and constructs the symbol table.

The symbol table consists of a tree of Scope objects rooted at the global scope. The global scope is owned by the SemanticsContext object. It contains a Scope for each program unit in the compilation.