Formalizing the Dynamic Semantics of Java

Propaganda
9
Controle de fluxo
 Seqüenciadores.
 Jumps.
 Escapes.
 Exceções.
7-1
Seqüenciadores (1)
 Qualquer comando formado pela composição de comandos
simples, seqüencial, condicional e iterativos tem um único
ponto de entrada e um único ponto de saída
 Fluxos de controle com único ponto de entrada e múltiplos
ponto de saída são muitas vezes desejados
7-2
Seqüenciadores (2)
 Um seqüenciador é uma construção que transfere o
controle para outro ponto do programa, denominado de
destino do seqüenciador
• Permite implementar fluxos de controle com múltiplas entradas e
saídas
• Exemplos: jumps, escapes e exceções
• Afetam radicalmente a semântica da linguagem
– O comando seqüencial C1;C2 só será seqüencial se C1 termina
normalmente. Caso C1 execute um seqüenciador, C1 termina
abruptamente, o que pode evitar a execução natural C2, dependendo
da destino do seqüenciador
• Alguns tipos de seqüenciadores podem carregar valores, que são
7-3
computados no lugar onde o seqüenciador é executado
Jumps (1)
 Um jump é um seqüenciador que transfere o controle para
um ponto específico de um programa
• goto L;
• Transfere o controle diretamente para o destino, o ponto do
programa denotado por L (label)
• Exemplo
– if (E1)
C1
else {
C2
goto X;
}
C3
while (E2) {
C4
X: C5
}
7-4
Jumps (1)
 O uso irrestrito de jumps permite qualquer comando ter
múltiplas entradas e saídas
• Resulta no código "espaguete"
– Difícil de entender e de manter
– A maioria das linguagens de programação suporta jumps, embora as
linguagens mais modernas, como Java, não os permitam
– Restringir o escopo de aplicação dos jumps
 Em C, um label não pode estar fora do escopo onde o goto é utilizado
7-5
Exemplo: jump para fora de um bloco de
comando
 Jumps para fora de um bloco de comando são mais complicados
• Destroem as variáveis locais do bloco antes de transferir o controle para o
destino!
• Código hipotético em C
•
char stop;
stop = '.';
do {
char ch;
ch = getchar();
if (ch == EOT) goto X;
putchar(ch);
} while (ch != stop);
printf("done");
X: ;
Variável ch destruída quando
da transferência do controle
para o destino X pelo goto
• Jumps para fora do corpo de um procedimento são ainda mais
complicados
– Destroem as vaiáveis locais e a ativação do procedimento antes da
transferência
7-6
Escapes (1)
 Um escape é um seqüenciador que termina a execução de
um comando ou procedimento delimitado textualmente
• Usados para programar fluxos de controle de uma única entrada e
múltiplas saídas
– O exit sequencer de Ada encerra a execução de laços de repetição
– loop
C1
exit when E;
C2
end loop;
– Nota-se que o loop tem uma única saída, mas o corpo do loop tem
duas saídas
7-7
Exemplo: seqüenciador exit em Ada

type Year_Diary is array (Month_Number, Day_Number) of Diary_Entry;
function search (diary: Year_Diary; this_year: Year_Number;
key_word: String) return Date is
-- Search diary for the first date whose entry matches key_word.
-- Return the matching date, or January 1 if there is no match.
match_date: Date := (this_year, 1, 1);
begin
search:
for m in Month_Number loop
for d in Day_Number loop
if matches(diary(m,d), key_word) then
match_date := (this_year, m, d);
exit search;
end if;
end loop;
end loop;
return match_date;
end;
7-8
Exemplo: seqüenciador break em Java
 O seqüenciador break em C, C++ e em Java permite que
qualquer comando composto –tipicamente loops e switch –
seja encerrado imediatamente

static Date search (DiaryEntry[][] diary; int thisYear;
String keyWord) {
Date matchDate = new Date(thisyear, 1, 1);
search:
for (int m = 1; m <= 12; m++) {
for (int d = 1; d <= 31; d++) {
if (diary[m][d].matches(keyWord)) {
matchDate = new Date(thisYear, m, d);
break search;
}
}
}
return matchDate;
}
7-9
Exemplo: seqüenciador return em C++
 O seqüenciador return é um escape que pode ocorrer em
qualquer lugar no corpo de um procedimento e o seu
destino é o fim do procedimento
• O return, quando usado no corpo de uma função, traz consigo o
valor a ser retornado
• Suportado nas linguagens C, C++, Java e Ada
• int gcd (int m, n) {
int p = m, q = n;
for (;;) {
int r = p % q;
if (r == 0) return q;
p = q; q = r;
}
}
7-10
Escapes (2)
 Escapes são restringidos de modo a que não transfiram o
controle para fora de procedimentos
• O objeto é evitar que escapes consigam encerrar a ativação de
procedimentos
– A exceção é o seqüenciador halt, que encerra a execução de todo um
programa, independente de onde esteja
 STOP em FORTRAN
 exit() em C, C++ e Java
 Halt() em Object Pascal
 Em geral carregam um valor indicando o motivo do término do
programa
7-11
Exceções (1)
 Uma situação anormal é aquela na qual um programa não
pode continuar normalmente
• Overflows aritméticos, divisão por zero, erro de e/s, ...
• Situações anormais específicas de aplicações
• Nestes casos, o que fazer?
– Abortar o programa
– Transferir o controle para um manipulador que tentará recuperar o
programa dessa situação
 Programas que conseguem se recuperar bem são denominados de
robustos
7-12
Exceções (2)
 Opções
• Manipuladores de erros
• Status flag
• Exceções
– Uma exceção é uma entidade que representa uma situação anormal
– Qualquer código que detecte uma situação anormal pode levantar
(throw) uma exceção apropriada
– Tal exceção pode ser subseqüentemente capturada (caught) em outra
parte do programa, onde uma estrutura denominada manipulador da
exceção (exception handler) tenta recuperar o programa da situação
anormal
– Exceções são compulsórias, não podendo ser ignoradas
– Suportadas inicialmente em PL/I
– Aperfeiçoadas em Ada, C++ e Java
7-13
Exceções (3)
 Exceções em Ada
• O seqüenciador raise e; levanta a exceção e
• As exceções são capturadas pelo comando manipulador de exceções
– begin
C0
exception
when e1 => C1
...
when en => Cn
end;
7-14
Exemplo: exceções em Ada (1)

type Annual_Rainfall is array (Month_Number) of Float;
procedure get_annual (input: in out File_Type;
rainfall: out Annual_Rainfall) is
r: Float;
begin
for m in Month_Number loop
begin
Levanta duas exceções:
get(input, r);
+ end_error
rainfall(m) := r;
+ data_error
exception
when data_error =>
put("Bad data for "); put(m);
skip_bad_data(input);
rainfall(m) := 0.0;
end;
end loop;
end;
7-15
Exemplo: exceções em Ada (2)

procedure main is
rainfall: Annual_Rainfall;
input: File_Type;
begin
open(input, ...);
get_annual(input, rainfall);
... // process the data in rainfall
exception
when end_error =>
put("Annual rainfall data is incomplete");
end;
7-16
Exceções (4)
 Propriedades das exceções
• Se um subcomando levanta uma exceção, o comando que o contém
também levantará essa exceção, a menos que ele seja um comando
manipulador de exceções apto a capturar essa exceção
• Se o corpo de um procedimento levanta uma exceção, o chamada
do procedimento correspondente também levantará essa exceção
• Um comando que levanta uma exceção é encerrado abruptamente e
não poderá ter retomada sua execução do ponto em que parou
• Certas exceções são pré-definidas, podendo ser levantadas por
operações também pré-definidas
• Outras exceções podem ser declaradas pelo programador e podem
ser levantadas explicitamente
7-17
Exceções (5)
 Em C++ e em Java, as exceções são tratadas como objetos
– try
C0
catch (E1 i1)
C1
...
catch (En in)
Cn
finally
Cf
• Em Java todo método deve especificar as exceções que ele pode
levantar
– Caso são sejam especificadas, elas devem ser capturadas pelo método
7-18
Exemplo: exceções em Java (1)
• static float readFloat(BufferedReader input)
throws IOException, NumberFormatException {
...
if (...)
throw new IOException("Fim da entrada encontrado");
String literal = ...;
float f = Float.parseFloat(literal);
return f;
}
• static float[] readAnnual(BufferedReader input) throws IOException {
float[] rainfall = new float[12];
for (int m = 0; m < 12; m++) {
try {
float r = readFloat(input);
rainfall[m] = r;
}
catch (NumberFormatException e) {
System.out.println(e.getMessage()+" é dado inválido para "+m);
rainfall[m] = 0.0;
}
}
7-19
return rainfall;
}
Exemplo: exceções em Java (2)
• static void main() {
float[] rainfall;
try {
BufferedReader input ...;
rainfall = readAnnual(input);
...
}
catch (IOException e) {
System.out.println("Dados incompletos");
}
}
7-20
Download