Últimas Notícias

 

3 de Fevereiro

 

            Alguns grupos estão entregando compiladores que sinalizam erros em arquivos er-*.s, mas os erros sinalizados não correspondem aos erros dos arquivos. Isto será observado na correção dos trabalhos. Alguns poucos grupos praticamente ignoraram os testes semânticos relacionados à orientação a objetos, o que é gravíssimo. Veja se o seu compilador não faz isso. Selecionei alguns testes que são relacionados à orientação a objetos. São eles:

 

ok-sem05   ok-sem06   ok-sem08   ok-sem10

ok-ger09   ok-ger10   ok-ger11   ok-sin09

ok-sin14   er-sem07   er-sem27   er-sem29

er-sem30   er-sem31   er-sem32   er-sem33

er-sem35   er-sem37   er-sem38   er-sem46

er-sem47   er-sem52   er-sem53   er-sem54

 

 

30 de Janeiro

 

            Eu reescrevi o primeiro parágrafo do dia 28 de Janeiro. Leia-o novamente.

 

28 de Janeiro

 

            Vocês não precisam se preocupar com a entrevista do segundo trabalho. Quem realmente fez o trabalho vai bem na entrevista, a princípio tira 10. Em geral, quem não tira 0 tira 10.

 

            Os trabalhos deste semestre estão bons, bem acima do que eu esperava. Parabéns !!

 

            Estamos no final do semestre e vocês teriam pouco tempo de fazer um terceiro trabalho. Contudo, algumas pessoas precisarão de nota – os dois trabalhos não serão suficientes. Então deixo o terceiro trabalho opcional. Quem fizer apenas os dois primeiros trabalhos, a média será calculada como

      MF = (t1 + t2)/2

Quem fizer o terceiro trabalho terá a nota calculada como

      MF = (t1 + t2 + t3/2)/2.5

Onde 2.5 = 1 + 1 + 1/2

            O terceiro trabalho é simples. Faça um pequeno programa em Simples e traduza-o para C. O programa deve ter:

a) duas heranças. Então devem existir pelo menos três classes;

b) uma redefinição de método na subclasse. Isto é, se B herda de A e A possui método m, B deve ter um método m;

c) um envio de mensagem a self;

d) um envio de mensagem a super;

e) duas variáveis de instância em classes diferentes;

f) um envio de mensagem para uma variável;

g) a criação de um objeto;

A data de entrega é 10 de Fevereiro. Como entro de férias dia 15 e devo viajar logo em seguida, é importante que não atrasem a entrega deste trabalho.

            Se tiverem dificuldades, me procurem. Estou acreditando que vocês não gastarão mais do que duas horas para fazer este trabalho. É importantíssimo que vocês coloquem as letras dos itens acima ao lado da tradução feita em C.  A letra indicará que aquele item foi feito no trabalho. Assim, ó:

class B subclassOf A          // a)

    private:

        var n : integer;           // e)

    public:

        proc get() : integer     //  b)

            begin

            super.get();           //  d)

            ...

            end

    ...

end

 

            Um artigo explicando como traduzir Simples para C está disponível  na página Material de Aula. Não se esqueça de pegar as figuras 1 e 7. Como bem poucas pessoas farão o terceiro trabalho, eu cancelei a aula sobre a tradução Simples -> C. Vocês não terão dúvidas na tradução, que é um processo automático, com regras bem definidas. A única dúvida que pode haver é sobre ponteiros para funções. Por isso, explico melhor este tópico abaixo.

 

Em C, podemos declarar um ponteiro para função com a sintaxe

     void (*f)();

neste caso, f é um ponteiro para uma função sem parâmetros e que retorna void. f pode apontar para uma função compatível :

     f = maximo;

maximo é uma função declarada como

   void maximo() {

      puts(“Olá ! Eu sou o máximo”);

   }

maximo pode ser chamada a partir de f usando-se quaisquer das sintaxes abaixo.

     (*f)();      /* chama maximo */

     f();         /* chama maximo */

Veja o programa completo.

           

Podemos definir um tipo em C através de typedef:

   typedef

      int Number[10];

Agora Number é sinônimo de vetores inteiros:

    Number v;  //   v é um vetor de inteiros de 10 posições

 

Da mesma forma, podemos definir Func como um ponteiro para funções:

typedef

   void (*Func)();

 

Func f;

f = maximo;

f();   // chama maximo

 

Podemos definir também um vetor de ponteiros para funções:

Func v[] = {

   maximo,

   minimo

};

 

minimo é definida como

 

void minimo() {

   puts(“Oi. Sou o mínimo”);

}

 

Agora, v é um vetor de ponteiros para funções. Ou melhor, v é um vetor de ponteiros para funções que não têm parâmetros nem retornam nada. Então v[0] é um ponteiro para uma função:

    v[0]();   //   chama maximo

    v[1]();   //   chama minimo

    (*v[0])();  // chama maximo

    (*v[1])();  // chama minimo

 

Até agora vimos apenas funções sem parâmetros e sem tipo de retorno. E se tivermos uma função

   int addOne(int i) {

      return i + 1;

   }

?

Vejamos:

 

void (*f)();

f = addOne;   // oops ...

f();  // oops ...

 

Na atribuição, há um erro de tipos. Estamos atribuindo uma função com um parâmetro e valor de retorno para um ponteiro para uma função sem parâmetros e sem valor de retorno. Temos que usar um cast:

     f = (void (*)()  )  addOne;

O tipo “void (*)()” lê-se “ponteiro para uma função sem parâmetro retornando void”. Na chamada de f, há outro erro. Estamos chamando a função sem passar o parâmetro. f aponta para addOne que espera um parâmetro. Temos que converter f para o tipo de addOne antes de chamar esta função:

     n = ((int (*)(int)  ) f)(1);

O tipo “int (*)(int)”  é um ponteiro para uma função que tem um inteiro como parâmetro e retorna valor inteiro. O código completo deste exemplo está aqui.

 

            Podemos colocar funções de vários tipos em um único vetor:

Func v[] = {

   maximo,

   addOne,

   minimo

};

...

v[0]();   // chama maximo

n = ((int (*)(int)  )  v[1])(5);   //  chama addOne passando 5 como parâmetro

v[2]();  // chama minimo

 

Estudando detalhadamente o exemplo acima, descobrimos que há um erro de tipos na inicialização de v. Cada elemento de v deve ser do tipo Func, função sem parâmetros retornando void. Mas addOne possui um parâmetro e retorna int. Então devemos usar um cast:

Func v[] = {

   maximo,

   (int (*)(int) ) addOne,

   minimo

};

 

É so.

 

 

23 de Janeiro

 

            A expressão “true > false” é semânticamente correta em Simples. A sua tradução para Java resulta no mesmo código, “true > false”. Contudo, Java não considera esta expressão correta, embora devesse considerar. Não se preocupem com este problema. Resolvê-lo seria complicado e então vamos deixar as coisas assim mesmo.

 

 

20 de Janeiro

 

            Pessoal, alguém me lembrou que há uma falha na gramática de Simples, apontada no dia 11 de Novembro do ano passado. A falha está na produção ReceiverMessage. Eu pedi para vocês consertarem este problema no próximo trabalho, que é o segundo. Para testar esta produção, fiz mais um teste, dado abaixo. As pessoas que já entregaram o trabalho poderão entregar nova versão que contempla este erro, se já não o prevêem.

 

/*

 

  ok-sin14.s

 

  testa se aceita envio de mensagens a variáveis de instância, como

     self.p.set(0, 0);

*/

 

class Point

   private:

      var x, y : integer;

   public:

      proc set( x, y : integer )

         begin

         self.x = x;

         self.y = y;

         end

      proc getX() : integer

         begin

         return self.x;

         end

      proc getY() : integer

         begin

         return self.y;

         end

end

 

 

class Program

   private:

      var p : Point;

   public:

      proc run()

         begin

         self.p = Point.new();

         self.p.set(0, 0);

         end

end

 

 

15 de Janeiro

 

            A entrega do segundo trabalho foi adiada para o dia 24 de Janeiro. Depois desta data começarei a descontar nota por atraso, provavelmente um ponto a cada três dias. Mas não descontarei a nota dos 14 primeiros trabalhos entregues, mesmo se entregues depois do dia 24.

            A nota do segundo trabalho será baseada na entrevista. Farei aproximadamente 10 perguntas. Quem responder a pelo menos 8 ficará com 10 como nota da entrevista. Quem responder menos ficará com uma nota proporcional. A nota do segundo trabalho será calculada como   T*E/10, onde T é a nota dada ao trabalho (sem a entrevista) e E é a nota da entrevista. Observem que se alguém tirar zero na entrevista, a nota de todo o grupo será zero. É uma avaliação severa que pretende impedir que apenas um ou dois dos integrantes do grupo trabalhem enquanto que o restante nada faça. Reafirmo que a nota do trabalho será a mesma para todos os integrantes do grupo.

 

17 de Dezembro

           

            Quando o compilador sinalizar um erro, ele não deve imprimir a pilha de execução com printStackTrace, um método de Exception. Isto deve ser feito apenas na fase de depuração do programa.

 

            A data da entrega do segundo trabalho foi adiada para o dia 17 de Janeiro.

 

 

9 de Dezembro

 

            Os grupos que ainda não fizeram a entrevista deverão fazê-lo até Quarta feira da semana que vem, dia 18, impreterivelmente.

            Algumas pessoas foram bem mal na entrevista mas mesmo assim receberam uma nota razoável no trabalho. Estas mesmas pessoas (as que foram mal) serão escolhidas para a segunda entrevista. Nos outros grupos será feito um sorteio. Eu serei mais rígido ao dar a nota do segundo trabalho, que é baseada no trabalho e na entrevista.

 

2 de Dezembro

 

            A maioria dos grupos não utilizou a tabela de símbolos para fazer o trabalho. Assim, ao encontrar um comando

                       x = y;

o compilador utiliza uma das estratégias abaixo:

1) representa x como String. A classe AssignmentStatement seria

   class AssignmentStatement {

      private String    leftSide;

      private Expr      rightSide;

      ...

   }

 

2) representa x como uma variável, mas cria esta variável ao encontrar x :

   // lexer.getValue() retorna “x”

   Variable left = new Variable( (String ) lexer.getValue() );

   return new AssignmentStatement( left, expr() ); 

 

A classe AssignmentStatement seria

 

   class AssignmentStatement {

      private Variable  leftSide;

      private Expr      rightSide;

      ...

   }

 

            Para o segundo trabalho, análise semântica, você deve procurar por variável “x” na tabela de símbolos, que te retornará um objeto de Variable. É este objeto que deve ser passado ao construtor de AssignmentStatement:

 

   // lexer.getValue() retorna “x”

   Object obj = st.getInLocal( (String ) lexer.getValue() );

   if ( obj == null ) error.signal(“...”);

   if ( ! (obj instanceof Variable) ) error.signal(“...”);

   Variable left = (Variable ) obj;

   return new AssignmentStatement( left, expr() );

 

A classe AssignmentStatement deve ser como mostrado acima, no último exemplo.

 

Outros casos relacionados ao acima:

       a)  o tipo de uma variável deve ser representado por um objeto e não por uma String. Isto é, Variable deve ser declarada como

      class Variable {

         private String name;

         private Type type;

         ...

      }

       b)  a superclasse da classe corrente (variável de instância superclasse de ClassDec) deve ser representado por um objeto. Assim, ClassDec deveria ser declarado como

      class ClassDec {

         private ClassDec superclasse;

         ...

      }

 

            Os únicos lugares onde deve-se criar objetos de Variable, InstanceVariable e Parameter é na declaração das variáveis correspondentes. E nunca se deve representar variáveis por Strings --- utilize objetos de Variable e suas subclasses. O mesmo se aplica a ClassDec e ao tipo de variáveis.

 

            A capa do segundo trabalho foi modificada e agora possui uma pergunta relativa ao tópico exposto acima.

 

            A prograd  solicita a todos os alunos que respondam os questionários de avaliação das disciplinas que estão disponíveis em

 

                        www.ufscar.br / Nexos / Avaliação / Alunos,
 
Esta página ficará disponível até o dia 9 de Dezembro.
 
 

28 de Novembro

 

            A maioria dos compiladores signaliza uma exceção depois de mostrar um erro. Esta exceção deve ser capturada em um bloco try no programa main. A impressão da pilha de chamadas (com e.printStackTrace()) deve ser utilizada apenas na fase de depuração do compilador e não deve estar presente no compilador entregue ao professor.

 

            Pessoal, para vocês testarem o código em Java gerado pelo compilador, utilize a seguinte classe Main:

 

 

public class Main {

    public static void main(String []args) {

       (new Program()).run();

    }

}

 

Esta classe deve ser gerada no mesmo diretório onde são colocadas as outras classes criadas pelo compilador.

 

20 de Novembro

 

            Modifiquei o programa Degree. Agora ele toma um parâmetro, o número de testes que você está utilizando. Para o y.bat, do primeiro trabalho, utilize

         java Degree 96

Para o segundo trabalho, x.bat, utilize

         java Degree 150

 

 

18 de Novembro

 

            Considerando que quase ninguém entregou o trabalho na Segunda, estou mudando a data de entrega do trabalho para Sexta dia 22. Lembre-se de que é mais importante entregar um trabalho funcionando do que entregá-lo no prazo. Desde que você também não exagere no atraso da entrega do trabalho, naturalmente.

            Os arquivos y.bat e x.bat utilizavam o arquivo ok-ger13.s, que testa classes shell, que não existem em Simples. Portanto, desconsiderem este teste. Se possível, pegue os novos arquivos y.bat e x.bat que não utilizam este arquivo de teste. Estes arquivos estão em “Material de Aula”.

 

12 de Novembro

 

            Nas observações, há uma sugestão de como fazer a classe ClassDec que representa uma classe:

 

class ClassDec

   public ClassDec( String name ) {

      this.name = name;

   }

   private String name, superclassName;

   private InstanceVariableList instanceVariableList;

   private MethodList publicMethodList, privateMethodList;

   // métodos públicos get e set para obter e iniciar as variáveis acima,

   // entre outros métodos

}

 

Nesta classe, superclassName representa a superclasse e é do tipo String. É melhor colocar a superclasse como do tipo ClassDec:

 

private ClassDec superclass;

public void setSuperclass( ClassDec superclass ) {

   this.superclass = superclass;

}

 

 

11 de Novembro

 

            Apenas um grupo veio na minha sala na fase de acompanhamento dos trabalhos. Que pena. Todos os grupos deverão marcar entrevistas que acontecerão entre os dias 18 e 28 de Novembro.  Na hora da entrevista, selecionarei um dos elementos do grupo para ser entrevistado. A nota do trabalho dependerá da entrevista. Todos os elementos do grupo deverão ter conhecimentos sobre todo o trabalho.

            Marquem o quanto antes a entrevista. Estou disponível todas as tardes depois das 14 horas, exceto Quartas, quando saio às 16:15. Os horários das entrevistas serão marcados em intervalos de meia hora. Assim, você poderá escolher entre os horários 14:00, 14:30, 15:00, etc. Se não houver horários disponíveis durante o dia, poderemos marcar a entrevista para depois das 18 h.

            Lembre-se de que os trabalhos só serão aceitos com a folha de capa e com o envio do código por email. 

 

            Há uma falha na gramática da linguagem Simples. Onde se lê

 

ReceiverMessage ::= super | Id | self

 

deve ser lido

 

ReceiverMessage ::= super | Id | self | self  “.” Id

 

Contudo, só cobraremos o reconhecimento desta regra extra no próximo trabalho.

            A gramática que vocês estão usando não permite instruções do tipo

        self.x.m();

onde x é uma variável de instância. Como não podemos usar

        x.m();

que variáveis de instância (VI)  devem ser prefixadas por self, então não podemos chamar um método de uma VI.

 

 

18 de Outubro

 

            Mudei a forma de calcular a média. Agora utilizaremos pesos nos trabalhos:

                     MF = T1*p1 + T2*p2 + T3*p3

A princípio os pesos serão iguais entre si. Mas se não houver tempo de fazer o último trabalho, este terá o peso diminuído. Note que o cálculo da nota de cada trabalho envolve uma entrevista com um dos elementos do grupo.

            Ainda não recebi nenhum email marcando reuniões comigo para o acompanhamento dos trabalhos. É importante o acompanhamento para que vocês não deixem para fazer o trabalho na última hora.

 

14 de Outubro

           

            Pessoal, em primeiro lugar, desculpem-me por não termos tido aula na Segunda dia 7. A DICA não reservou sala para a disciplina, ao contrário dos anos anteriores. Fiquei sabendo que não havia sala reservada na Sexta feira anterior e imediatamente tentei reservar uma sala para as aulas. Segundo uma funcionária da DICA, não havia salas disponíveis naquele momento, e eu teria que esperar a liberação de algumas salas de aula, o que ocorre na primeira semana pois muitos professores não ocupam as salas que reservam. Decidi cancelar as aulas já que tudo o que eu iria dizer estava disponível na página da disciplina.

 

            Gostaria que os grupos me procurassem para que eu possa acompanhar o andamento dos trabalhos. Façam assim: a partir do dia 21 de Outubro, procurem-me na minha sala (à tarde) ou me enviem um email para marcarmos um horário. Eu verei o que o grupo já fez e farei sugestões ou responderei a dúvidas. Só isso. Não é necessário que todos os elementos do grupo estejam presentes. Esta fase de acompanhamento termina no dia 8 de Novembro, uma semana antes da data da entrega do trabalho. Este acompanhamento é importantíssimo, pois ele permitirá correções de rota logo no início do trabalho, o que lhes poupará tempo e paciência. É provável que os grupos que fizerem este acompanhamento sejam dispensados da entrevista.

            Naturalmente, qualquer pessoa ou grupo pode vir a qualquer hora na minha sala para tirar dúvidas, mesmo antes de 21 de Outubro ou depois de 8 de Novembro. Eu estarei na Universidade todas as tardes. Na Quarta-feira, até às 16:15. Alguns poucos dias estarei aqui de manhã.

 

7 de Outubro

 

            Leia atentamente todas as observações da página Observações antes de começar a fazer o seu trabalho.