sexta-feira, 8 de junho de 2012

PL/I - Parte I


1. INTRODUÇÃO

A linguagem PL/I (Programming Language One – Linguagem de Programação Um) foi criada no final da década de 50. Segundo suas características, é voltada para as áreas comercial, como por exemplo o COBOL (Common Business Oriented Language – Linguagem Comum Orientada aos Negócios) e científica, como o Fortran (Formula Translator – Tradutor de Fórmulas).

1.1. Folha de codificação PL/I

Na codificação PL/I, são consideradas apenas 80 colunas. Porém, assim como o COBOL, haverá distinção de áreas na codificação por parte do compilador. Observe a tabela abaixo:
Colunas
Funções
01
Controle de carro para Impressão da listagem do fonte
02-72
Livre para descrever todo o programa
73-80
Livre para sequenciar as linhas do programa ou documentar

Explicações:
Ä Durante a compilação do programa, será gerada uma listagem. O caracter constante da coluna 1 determinará uma ação (saltar página, por exemplo) a ser feita pelo compilador.
Ä Todos os comandos da linguagem PL/I serão efetivamente codificados nas colunas iniciadas pela 02, indo até a 72. Qualquer instrução fora dessas colunas será ignorada.
Ä As colunas de 73 a 80 são livres para qualquer tipo de comentário, pois são ignoradas pelo compilador.

1.2. Identificadores

Os identificadores PL/I são regidos da seguinte maneira:
Ä Pode conter apenas caracteres alfabéticos, numéricos e hífen (-);
Ä O primeiro caracter do identificador deverá ser sempre alfabéticos;
Ä Um identificador conterá no máximo 31 caracteres, havendo algumas exceções, como os nomes de procedimentos, que conterão no máximo 31 caracteres.

1.3. Conjunto de caracteres

Existem dois conjuntos de caracteres que são disponíveis para o PL/I: o de 48 e o de 60 caracteres. Isso se deve em virtude de diferentes versões da linguagem. O PL/I Básico utiliza o conjunto de 48 caracteres e as versões PL/I Full e Optimizing utilizam o conjunto de 60, mantendo compatibilidade com o de 48.
Quando se usa o conjunto de 60 caracteres não há palavras reservadas. No conjunto de 48, algumas são reservadas ao compilador para um fim específico, como por exemplo LE, GT, etc.
Observe a distribuição dos conjuntos:

29 caracteres alfabéticos
De 60
10 caracteres numéricos

21 caracteres especiais




27 caracteres alfabéticos
De 48
10 caracteres numéricos

11 caracteres especiais

Conjunto de caracteres:
Classificação
60 caracteres
48 caracteres
Descrição
Alfanuméricos
A a Z
$
@ e #
A a Z
$
Não disponível
Alfabético
Alfabético
Alfabético
0 a 9
0 a 9
Numérico










Especiais
=
+
-
*
/
(
)
,
.
%
:
;
¬
&
|
< 
> 
?
=
+
-
*
/
(
)
,
.
//
..
.,.
NOT
AND
OR
LT
GT
Não disponível
Não disponível
Branco
Igual
Adição
Subtração
Multiplicação - aster.
Divisão - barra
Abre parêntese
Fecha parêntese
Vírgula
Ponto
Apóstrofo
Porcentagem
Dois pontos
Ponto-e-vírgula
Não lógico
E lógico
Ou lógico
Menor que
Maior que
Travessão
Interrogação


1.4. Comandos PL/I

Todos os comandos PL/I serão sempre codificados conforme a sintaxe genérica a seguir:
<IDENTIFICADOR DE COMANDO> + <CORPO DE COMANDO> + <;>

Exemplo:
GOTO SEGUE;
DCL A DECIMAL FIXED;

Todas as linhas de comando lógicas PL/I serão finalizadas com ponto-e-vírgula (;). Na impossibilidade de ser codificada inteira em uma única linha física, basta passar para a de baixo e continuar a codificação. Vírgulas (,) serão utilizadas em algumas estruturas que forem mais extensas que uma linha, como por exemplo a instrução DECLARE que será vista mais adiante. Mesmo assim o ponto-e-vírgula deverá estar obrigatoriamente fechando a última linha.
Diferente do COBOL que admitia ponto apenas na última instrução de uma section o parágrafo, todas as instruções PL/I sem exceção deverão finalizar com ponto-e-vírgula.

1.5. Comentários

Os textos de comentário em PL/I serão delimitados por barra – asterisco no início e asterisco – barra no final conforme a sintaxe a seguir:

/* (texto de comentário) */

Os comentários podem conter várias linhas, sendo que sempre serão respeitados os delimitadores.

2. VARIÁVEIS

A declaração das variáveis é feita através da setagem de seus atributos. Observe a seguir os atributos para variáveis numéricas:
Atributo
Descrição
BASE
Se a variável é decimal ou binária
ESCALA
Se a variável é decimal ou binária de ponto flutuante
MODO
Se a variável é real ou complexa
PRECISÃO
Grandeza da variável em relação ao comprimento em bytes que ela ocupará na memória

2.1. Comando DECLARE

A linguagem PL/I é muito flexiva. Isto nos traz muitos pontos positivos, mas também alguns inconvenientes. Um “problema” decorrido desta flexibilidade é a não obrigatoriedade da declaração de variáveis. Isso pode gerar problemas na documentação do programa, o que é muito desagradável quando de sua manutenção. Por este motivo, no decorrer deste curso todas as variáveis utilizadas em programas serão declaradas.
Outra flexibilidade da linguagem: diferente do COBOL, PL/I não exige uma área especial para a declaração dos dados que serão utilizados pelo programa. A qualquer ponto uma variável pode ser criada.
O comando DECLARE será utilizado para criar um identificador através da definição de seus atributos. Podemos dizer que PL/I é uma linguagem tipada. Isso porque haverá uma série de tipos de variáveis que serão utilizados para armazenar tipos diferentes de informações. Nesta parte da apostila veremos os tipos mais utilizados e que nos serão úteis no decorrer do curso.

Sintaxe:
DECLARE VARIÁVEIS E ATRIBUTOS

OBS: o comando DECLARE pode ser abreviado para DCL.

2.2. Real Decimal Fixed

Variável decimal de ponto fixo com precisão (p,q), onde p é o número total de dígitos e q é o número de dígitos da parte fracionária, sendo também chamado de fator de escala.. Terá no máximo 15 dígitos com ou sem sinal.
Exemplos
DECLARE    VALOR1 DECIMAL FIXED (4,1)
DCL               VALOR2 DECIMAL FIXED (5,2)

2.3. Real Binary Fixed

Variável real e binária de ponto fixo com precisão (p,q). Deve representar constantes que são strings de dígitos binários, com ou sem ponto decimal, de no máximo 31 dígitos e seguidos pela letra B.
Exemplo:

DCL    VALOR REAL BINARY FIXED (10,5)

OBS: O atributo BINARY pode ser abreviado para BIN.
(p,q)
Exemplo de valor
(5,0) OU (5)
00110B
(7,4)
110.1100B

2.4. Real Decimal Float

Variável decimal, real de ponto flutuante  e de precisão (p), onde p é o número de dígitos significativos a ser considerado. Deve representar strings de dígitos decimais, com ou sem sinal, de no máximo 16 dígitos seguidos por uma letra E, indicativa do expoente na base 10 e seu respectivo expoente.
Por exemplo:
20.E3 = 20 x 103 = 20000
11E2 = 11 x 102 = 1100

(p)
Exemplo de valor
(6)
1.23456E+04
(3)
1.23E+04

2.5. Real Binary Float

Mesmas características do atributo visto anteriormente, porém haverá um dígito B, no final da constante, especificando seu formato binário
Exemplo:

1101.1E+04B = 11011000B
-1001.E-02B = -10.01B

2.6. Character

Variável caracter de comprimento n, representando strings de caracteres. Estão limitadas a 32.767 bytes de comprimento.

Exemplo:

DECLARE     NOME                       CHARACTER           (40)
DCL               ENDERECO  CHAR                                    (45)

2.7. Atributo Initial

Podendo ser abreviado para INIT, tal atributo serve para inicializar as variáveis criadas, assim como a cláusula VALUE da linguagem COBOL.
Exemplos:

DCL    NOME                       CHAR(30)                 INIT(‘ ’),
            VALOR         DEC(3,2)                    INIT(0),
            VLBIN           BIN FIXED(4)          INIT(1011B);

Observe que um único comando DECLARE pode ser utilizado para declarar diversas variáveis normalmente.

2.8. Label

É uma variável especial, que poderá apenas assumir valores de rótulos de comandos. Será utilizada durante a lógica do programa para ocasionar desvios no fluxo de execução. Os valores (constantes labels) armazenados em variáveis desse tipo somente poderão fazer referência a rótulos do mesmo procedimento em que a variável foi declarada.
Com este recurso, pode-se criar situações semelhantes com o GO TO DEPPENDING ON do COBOL.
Observe nos exemplos abaixo que  as variáveis do tipo ainda podem utilizar uma outra forma de inicialização de valores:

DCL    ROT1  LABEL,
            ROT2  LABEL INIT (GRAVA),
            ROT3  LABEL(LE,GRAVA,REGRAVA),
            ROT4 LABEL(LE,GRAVA,ORDENA,IMPRIME) INIT (LE);

O atributo LABEL permite ainda a especificação de quais nomes de rótulos poderão ser armazenados pela variável durante a execução do programa.

2.9. Declaração parcial de variáveis

Se faltar um mais atributos em um comando DECLARE, podemos dizer que a variável foi parcialmente declarada e assumirá os atributos defaults definidos pelo compilador conforme segue:
Ä Se não for declarada a BASE          ð será assumido DECIMAL
Ä Se não for declarada a ESCALA     ð será assumido FLOAT
Ä Se não for declarado o MODO        ð será assumido REAL
Ä Se não for declarada a PRECISÃO ð será assumido os defaults da tabela a seguir:


Base e Escala
Precisão
BINARY FIXED
(15,0)
DECIMAL FIXED
(5,0)
BINARY FLOAT
(21)
DECIMAL FLOAT
(6)

2.10. Variáveis não declaradas

Quando uma variável não é declarada, o compilador, ao “perceber” uma movimentação, associação ou comparação desta variável irá declará-la automaticamente seguindo as regras:
Ä  Toda e qualquer variável não declarada será numérica;
Ä  Se a primeira letra da variável for I, J, K, L, M ou N, ela será uma half-word, binária, sinalizada e de ponto flutuante;
Ä  Se não começar com uma das letras citadas, será decimal de ponto flutuante, sinalizada com precisão de 6 casas na mantissa.
Sempre que tal situação ocorrer, o compilador irá avisar informando que determinada variável não foi declarada explicitamente e está sendo assumida como um tipo default.


2.11. Variáveis PIC (PICTURE)

Variáveis picture são numéricas, decimais zonadas e sinalizadas ou não. são as mesmas PIC do COBOL, limitadas a 15 dígitos em PL/I. Na verdade, trata-se de uma característica propositalmente semelhante à linguagem COBOL, onde a sintaxe de declaração será:

DCL    NÍVEL           VARIÁVEL  PIC ‘(nn)9V(nn)9’

As máscaras de impressão ‘Z’ para brancos, ‘,’ (vírgula),’.’ (ponto), ‘-’ (sinal negativo) e ‘+’ (sinal positivo) são válidas também. Vale lembrar que o V que separa a parte inteira da parte fracionária é apenas lógico, não ocupando espaço físico na memória e não implica na impressão de uma vírgula ou ponto decimal quando a variável é mostrada.


Observe as declarações a seguir:
Declaração
Descrição da variável
1)       PIC ‘9(15)’ ou PIC ‘(15)9’
2)       15 dígitos inteiros sem sinal
3)       PIC ‘V(15)9’ ou PIC ‘V9(15)’
4)       15 dígitos decimais sem sinal
5)       PIC ‘9(08)V9(07)’
6)       15 dígitos, 8 inteiros e 7 decimais sem sinal
7)       PIC ‘ZZZ.ZZ9’
8)       Máscara de impressão (não pode ser utilizada em operações)
9)       PIC ‘S99.999’
10)   Máscara de impressão, indica se o número é positivo ou negativo. O sinal aparecerá.
11)   PIC ‘+99.999’
12)   Máscara de impressão, só se número for positivo o sinal “+” aparecerá.
13)   PIC ‘-99.999’
14)   Máscara de impressão, só se o número for negativo, o sinal “-” aparecerá.
15)   PIC ‘99/99/999’
16)   Máscara de impressão utilizada para datas.
17)   PIC ‘99B99B9999’
18)   Máscara de impressão utilizada para datas.

Agora suponha o valor 123456789.012345 submetido às pictures:
Picture
Resultado
1)        
123456789
2)        
012345
3)        
23456789.012345
4)        
+56.789
5)        
+56.789
6)        
+56.789
7)        
56.789
8)        
23/45/6789
9)        
23 45 6789

3. COMANDOS DE ENTRADA E SAÍDA

3.1. Comando LIST

É um comando simples de E/S que permite a leitura de dados para variáveis através do dispositivo de entrada padrão do sistema operacional e a exibição de variáveis / expressões no dispositivo padrão de saída.
Sintaxe:

Para entrada    ð GET LIST (lista de variáveis);
Para saída       ð PUT LIST (lista de variáveis e/ou expressões);

Exemplos

GET LIST (A, B, C);
Lê três valores armazenando-os nas variáveis A, B e C.
PUT LIST (‘O VALOR DE A ’, A);
Exibe a string entre apóstrofes, seguido do conteúdo da variável A.
PUT PAGE;
Salta para a primeira linha da página seguinte.
PUT PAGE LIST (‘LUIZ’);
Imprime a palavra LUIZ na primeira linha da página seguinte.
PUT SKIP;
Salta uma linha.
PUT SKIP LIST (‘G&P’);
Salta uma linha e imprime G&P.
PUT SKIP (-1) LIST (‘BAURU’);
Posiciona o carro na primeira coluna da linha atual e imprime a palavra BAURU
PUT LINE(15) LIST(‘SÃO PAULO’);
Imprime SÃO PAULO na 15a linha da página

3.2. Comando EDIT

Semelhante ao comando anterior. A grande diferença é que o comando EDIT permitirá que os dados sejam acompanhados de uma lista de formatos para edição.
Sintaxe:
Para entrada    ð GET EDIT (lista de variáveis) (lista de formatos)
                                               (lista de variáveis) (lista de formatos)
Para saída       ð GET EDIT (lista de variáveis) (lista de formatos)
                                               (lista de variáveis) (lista de formatos)

A lista de formatos é uma lista de códigos, denominados itens de FORMAT, separados por vírgula, que se referem a cada um dos tipos de variáveis, em ordem. Teremos os itens de FORMAT DE CONTROLE, que são os mesmos vistos no comando EDIT (PAGE, SKIP(n) e LINE(n)) e os itens de FORMAT DE DADOS que são os responsáveis por determinar a maneira como os dados serão apresentados.

Os itens de format de dados são:
a)      PICTURE FORMAT ð o formato é P‘especificação’, onde especificação corresponde ao atributo PICTURE já visto antes.
Exemplo

DCL B DEC FIXED (6,2);
B = 1000;
PUT EDIT (B) (P‘9.999V,99´);

b)     FIXED POINT FORMAT ð a forma é F(w,d,p), onde w representa o tamanho do campo, d o número de dígitos que seguem o ponto decimal e p um fator de escala, podendo ser positivo ou negativo, representado multiplicar ou dividir o valor inteiro por 10p. d e p são opcionais. Observe os exemplos:
Valor interno
FORMAT
Resultado
+2567.89
F(4)
2568
-2891.432
F(5)
-2891
-2891.432
F(7)
-2891
-2891.432
F(8,3)
2891.432
-2891.432
F(8,2)
-2891.43
+1234.5678
F(3)
235
-5641.21
F(11,3,2)
-564121.000
1204.129
F(10,1,2)
120412.9

c)      FLOATING POINT FORMAT ð no formato E(w,d,s), onde w representa o comprimento do campo, d o número de dígitos que seguem o ponto decimal e s o número de dígitos que devem aparecer antes do símbolo E, indicativo do expoente. Observe os exemplos:
Valor interno
FORMAT
Resultado
+397.7841
E(16,5)
397.78410E+00
+397.7841
E(16,6)
397.784100 E+00
+397.7841
E(16,7)
397.7841000 E+00
+397.7841
E(16,8)
397.78410000 E+00
+397.7841
E(16,9)
39.778410000 E+01
+397.7841
E(16,10)
3.9778410000E+02
+397.7841
E(16,11)
.39778410000E+03
+397.7841
E(16,10,12)
39.7784100000E+01
+397.7841
E(16,10,11)
3.9778410000E+02
+397.7841
E(16,10,10)
.3977841000E+03

d)     CHARACTER STRING FORMAT ð cuja forma é A(w), onde w representa o comprimento do campo, cujo atributo foi declarado como CHAR(n). Observe os exemplos a seguir:

Valor interno
FORMAT
Resultado
‘ABCDEF’
A ou A(6)
ABCDEF
‘ABCDEF’
A(5)
ABCDE
‘ABCDEF’
A(8)
ABCDEF
BCD’
A(6)
BCD
‘ABCDEFGH’
A(3)
ABC

e)      Format Remoto
Os formatos podem ser definidos em um rótulo de comando para serem utilizados em outras partes (remotamente) do programa. O formato será R(label). Observe os exemplos:

FORMATO: FORMAT(A(5),SKIP,F(7,4),F(4));
...
            GET EDIT(V1,V2,V3)   (R(FORMATO));
...
            PUT LINE(5) EDIT (A,B,C) (R(FORMATO));

4. BLOCOS

4.1. Procedure (procedimento)

São blocos de instruções que podem receber valores como argumentos através de uma área de entrada, realizar um determinado processamento  e ainda retornar valores ao procedimento chamador através de uma área de saída. Funcionam de forma bastante semelhante aos programas chamados com a instrução CALL do COBOL (em PL/I o comando de chamada também será CALL). Veremos mais tarde informações detalhadas sobre procedimentos.

4.2. Procedimento principal

Todo programa escrito em PL/I apresentará obrigatoriamente um procedimento principal que será automaticamente invocado pelo sistema operacional depois que o programa foi compilado. Este procedimento poderá invocar outros em tempo de execução.
O formato da procedure principal que iniciará o programa será sempre:

: PROC OPTIONS(MAIN);

Todos os comandos do programa serão codificados após esta linha de declaração. Ao final dos comandos o procedimento principal deve ser encerrado utilizando o formato a seguir:

END ;

Todos os demais procedimentos que forem codificados no programa deverão estar antes do END da procedure principal.
Para exemplificar o que foi dito, suponha a codificação de um programa chamado PROG01 conforme segue:

PROG01: PROCEDURE (PARM) OPTIONS (MAIN);
  PUT SKIP(‘OLA, BEM VINDOS A G&P’);
END PROG01;

Explicação:
Ä PROG01 ð É o nome do programa identificado na JCL, devendo conter no máximo 07 caracteres, corresponde à procedure principal;
Ä PROCEDURE OPTIONS (MAIN) ð Deve ser o primeiro comando obrigatório do programa. A palavra chave PROCEDURE pode ser abreviada para PROC.
Ä (PARM) ð São parâmetros passados pelo cartão JCL. Sua codificação é opcional.
Ä END ð Indica o término do programa. É obrigatório, devendo sempre ser indicado o nome.

4.3. Blocos de comandos

Um bloco é uma seqüência de comandos que define uma área do programa. Será utilizado em diversos comandos e estruturas do programa e poderá assumir um dos formatos a seguir:

DO;
            COMANDO 1;
            COMANDO 2;
            ...
            COMANDO N;
END;

ou


BEGIN;
            COMANDO 1;
            COMANDO 2;
            ...
            COMANDO N;
END;

A utilização de um destes dois conjuntos dependerá do comando ou estrutura utilizado.

4.4. Label ou Rótulo de comando

Não é considerado um componente de comando. Pode ser utilizado pelo programador simplesmente para identificar partes de uma programa ou causar desvios com o comando GOTO. O rótulo em um programa será sempre seguido de dois pontos (:) e sem espaços, conforme formato a seguir:

CALCULA:
            A = B + 1;
            C = A * B / 2 + D;

4.5. Desvios

Em um procedimento PL/I os comandos são executados na seqüência em foram codificados. Havendo vários labels, estes também terão seus comandos executados em ordem sequencial.
No entanto, o fluxo de execução do programa pode perfeitamente ser alterado através de comandos que ocasionam desvios.

4.6. Comando GOTO

O comando GOTO será utilizado para ocasionar um desvio incondicional do ponto que está sendo executado do programa para um outro label especificado.
Sintaxe:

GOTO

Lembre-se que GOTO é um comando de programação linear e fere as regras de programação estruturada, pela simples configuração de lógica desta. Assim sendo, pode ser eventualmente utilizado, desde que com disciplina, sem que não prejudique a clareza e o bom entendimento da lógica do programa.

4.7. Comando CALL

 Desvia o fluxo de execução para a procedure especificada, retornando para a linha imediatamente posterior à chamada.
Sintaxe:

CALL ;

O procedimento será codificado da seguinte maneira:

: PROC;
            COMANDO 1;
            COMANDO 2;
            ...
            COMANDO N;
END ;

As variáveis definidas no procedimento principal do programa poderão ser normalmente utilizadas nas demais procedures.
Exemplo:

PROG02: PROC OPTIONS (MAIN);
            DCL (A, B, C) FIXED(4);

            CALL ACESSA;
            C = A + B;
            PUT SKIP(2) LIST(A, B);

   ACESSA: PROC;
               GET LIST(A, B);
   END ACESSA:

END PROG02;

Observe no exemplo dado, um estilo diferente de declaração de variáveis. As variáveis são todas colocadas entre parênteses, separadas por vírgula e depois os atributos são codificados.

4.8. Procedimento com argumentos

Argumentos (também chamados de parâmetros) são valores enviados para um procedimento afim de serem processados e resultar em um novo valor.
Os procedimentos em PL/I recebem informações de forma semelhante ao COBOL. São declaradas diversas variáveis que serão utilizadas como:
Área de entrada ð utilizada para o envio de informações ao procedimento.
Área de saída ð utilizada para obter o resultado do processamento pelo procedimento.
O comando RETURN é colocado antes do END da procedure. Pode ser considerado seu fim lógico e a formatação dos parâmetros de saída.

Sintaxe:
Na chamada:

CALL PROCEDIMENTO(A1,A2,A3, ...,AN);


No procedimento:

PROCEDIMENTO: PROC(A1, A2, A3,..., AN);.
            DCL A1, A2, ..., AN
            ...
            RETURN;
END PROCEDIMENTO;

Exemplo:

PROG03: PROC OPTIONS (MAIN);
            DCL (A, B, C) FIXED(5);
            GET LIST(A,B);
            CALL SOMA(A, B,C);
            PUT LIST (C);

            SOMA PROC(P1,P2,P3);
                        DCL (P1,P2,P3) FIXED(5);
                        P3 = P1 + P2;
                        RETURN;
            END SOMA;

END PROG03;

4.9. Funções

São parecidas com os procedimentos. Será diferente a maneira como os argumentos serão enviados e como o resultado será recebido. Neste caso, faremos uso do comando RETURN, para enviar um valor de volta ao procedimento chamador.
O comando RETURN tem a sintaxe:

RETURN (VARIÁVEL) ou RETURN (EXPRESSÃO)

Observe o exemplo:

PROG04: PROC OPTIONS (MAIN);
            DCL    (A, B, C) FIXED (5);
            GET LIST (A,B);
            C = SOMA(A,B);

            SOMA: PROC(P1,P2);
                        DCL (P1,P2) FIXED(5);
                        RETURN (P1 + P2);
            SOMA END;

END PROG04;


Nenhum comentário:

Postar um comentário