А у меня "распознаватель = сканер + парсер" языка Component Pascal целиком содержится внутри одной процедуры Cp2cRecognizer.Do, а парсер модуля целиком содержится внутри вложенной в Cp2cRecognizer.Do процедуры Module:

## Код:
```
MODULE Cp2cRecognizer;
   ...
   PROCEDURE Do (context: Context)
      VAR
         ch: CHAR;
         symbol: INTEGER;
         symbolPos, currentPos: Position;
         charValue: CHAR;
         intValue: LONGINT;
         realValue: REAL;
         stringValue: String;
         dict: Dictionary;
  
      ...

      PROCEDURE GetSymbol;
      ...
      END GetSymbol;

      PROCEDURE Module;
         VAR name, libName: String;
         
         PROCEDURE^ TypeDefinition;
         PROCEDURE^ Expression;
         PROCEDURE^ Designator;
         PROCEDURE^ StatementSequence;
         PROCEDURE^ FormalParameters;

         PROCEDURE Import;
         BEGIN
         ...
         END Import;

         ...

      BEGIN (* Module *)
         ASSERT(symbol = symModule, 100);
         GetSymbol; Check(symIdent);
         IF symbol = symIdent THEN
         ...
         END
      END Module;

   BEGIN (* Do *)
      ASSERT(context # NIL, 20);
      dict := context.Dictionary();
      ASSERT(dict # NIL, 20);
      ch := chSpace; symbol := 0;
      symbolPos.pos := 0; symbolPos.row := 0; symbolPos.col := 0;
      currentPos.pos := 0; currentPos.row := 0; currentPos.col := 0;
      charValue := 0X; intValue := 0; realValue := 0;
      stringValue := dict.empty;
      GetSymbol; Check(symModule);
      IF symbol = symModule THEN Module END
   END Do;

END Cp2cRecognizer.
```


Вместе с процедурами генерирующими текстовые сообщения об ошибках Cp2cRecognizer содержит менее 1400 строчек.

Так что вложенные процедуры использованные по назначению рулят неописуемо.