6.2 ESTRUTURA DA MÁQUINA-FERRAMENTA E CNC-C
6.2.2 Item 2 Compilador
6.2.2.1 Front-end do compilador desenvolvido
A front-end faz a análise sintática do código fonte STEP-NC e em seguida a análise semântica. Caso nenhum erro seja encontrado, o usuário receberá as instâncias em Java dos objetos definidos no código fonte de entrada.
Para que o compilador consiga relacionar as entidades da STEP-NC com objetos Java, ele precisa ser carregado com um esquema de classes. Esse esquema é um conjunto de classes Java definindo modelos de dados EXPRESS quaisquer, inclusive STEP-NC. Essas classes instanciadas serão a saída da front-end, pois elas são fáceis de serem manipuladas por qualquer tipo de aplicação. Um exemplo básico de como um modelo EXPRESS é representado em Java
6.2 Estrutura da Máquina-Ferramenta e CNC-C2 95
pode ser visto na Figura 6.2. No diagrama desta imagem, o pacote family é providenciado pelo usuário, enquanto o pacote datatypes é parte da front-end. Neste exemplo, aparece apenas a classe TYPE<?> no pacote datatypes, mas outros dados já estão implementados, como LIST<?> e Enumeration.
Figura 6.2: Representação de um modelo EXPRESS e um modelo UML usado para mapear Java
Fonte: Hasegawa et al. (2011)
Uma visão geral da front-end pode ser vista na arquitetura apresentada na Figura 6.3. Esta arquitetura mostra: duas classes instanciáveis pelos usuários, a StepNCCompiler e a StepNCLoa- der, a separação da análise sintática com a análise semântica, o uso de TO (Transaction Objects) para troca de dados entre elas, e um conjunto de exceptions.
A Figura 6.4 mostra os objetos usados para trocar informações entre os componentes do compilador e o usuário. EntityTO é a representação interna de uma entidade da STEP-NC, onde ela armazena o número, o nome, a linha da declaração e uma lista de atributos. Fora do compilador ela é usada apenas para representar os tipos da seção de cabeçalho.
Durante a execução do compilador, podem ser encontrados erros. Esses erros podem ser como um arquivo de esquema corrompido, ou erros sintáticos e/ou semânticos no código fonte. Quando algum tipo de erro ocorrer, o compilador gera uma exceção. Na Figura 6.5 é mostrada uma imagem onde em InternalStepNCCompilerException são listados os erros juntamente com seus identificadores. Essa exception contém informações suficientes para informar ao usuário onde o erro ocorreu, facilitando a depuração. As Exceptions também podem ser lançadas de dentro das classes de um esquema, para isso se usa a SchemaStepNCCompilerException, sendo útil para replicar os efeitos das WHERE RULES, ou seja, restrições para os dados introduzidos, como por exemplo, o tipo POSITIVE_LENGTH_MEASURE da STEP-NC tem uma WHERE RULE que impõe que o valor numérico de entrada seja obrigatoriamente positivo. Se for introduzido um
6.2 Estrutura da Máquina-Ferramenta e CNC-C2 96
Figura 6.3: Arquitetura do compilador desenvolvido
Fonte: Hasegawa et al. (2011) valor negativo, uma SchemaStepNCCompilerException é lançada.
O componente da análise sintática é visto na Figura 6.6. A interface define o método runSyntacticAnalysis, o qual tem como entrada o código fonte STEP-NC e como saída uma instância do objeto StepSectionsTO. Este objeto está descrito na Figura 6.4 e consiste em um conjunto de EntityTO para cada seção da STEP-NC. Este método implementado faz uso da StepNCParser, que é uma classe que encapsula a biblioteca JavaCC (JAVACC, 2012) com JJTree(JJTREE, 2012). O gerador de parser JavaCC é implementado em Java, provendo boa compatibilidade com aplicações Java. JavaCC usa o método top-down para verificação da gramática, e é capaz de gerar uma árvore sintática com o uso da JJTree. Ela também faz o relato de erros sintáticos encontrados no código fonte. Um exemplo de uma árvore sintática gerada pelo JavaCC juntamente com JJTree pode ser vista na Figura 6.7.
A componente da análise semântica pode ser vista na Figura 6.8. O construtor da classe SemanticAnalysis depende do StepNCLoader pois nessa fase todas as EntityTO da seção de
6.2 Estrutura da Máquina-Ferramenta e CNC-C2 97
Figura 6.4: Objetos usados para trocar mensagens entre componentes do compilador e o usuário
Fonte: Hasegawa et al. (2011)
dados serão convertidas em instâncias das classes Java do esquema usado. Neste processo de conversão iniciado pelo método runSemanticAnalysis, várias verificações semânticas são feitas. Caso algum erro seja encontrado, uma exceção interna será lançada, conforme Figura 6.5. Este método irá retornar o objeto final que será repassado ao usuário, que é uma instância da classe CompilerResultTO, vista na Figura 6.4.
As únicas classes acessíveis ao programador são a StepNCCompiler e a StepNCLoader, como mostrado no diagrama de classes da Figura 6.9. A StepNCLoader é responsável por carregar na memória do compilador o esquema de classes do usuário, e também manter um buffer de acesso a essas classes para o compilador, agilizando o tempo de processamento. A StepNCCompiler é a classe principal, pois é ela quem irá receber a StepNCLoader e o código fonte da STEP-NC do programador, e com o método Compile retorna o resultado.
O diagrama de sequência da Figura 6.10 mostra a interação do programador com o compila- dor. Em três passos é possível compilar qualquer esquema EXPRESS, basta carregar o esquema com a StepNCLoader, carregar o compilador com o loader criado e iniciar a StepNCCompiler com o código fonte que deseja analisar. Para tratamento de erros, basta colocar operações de try/catchdo Java sobre o método Compile.
6.2 Estrutura da Máquina-Ferramenta e CNC-C2 98
Figura 6.5: Exceptions do compilador
Fonte: Hasegawa et al. (2011)
método runSemanticAnalysis, nesta ordem, como mostra o diagrama de sequência na Figura 6.11. A execução do método seguinte pode ser interrompida caso algum componente encontre um erro.
O método runSyntacticAnalysis começa invocando o método run da StepNCParser, como mostra o diagrama de sequência na Figura 6.12. Como descrito anteriormente, a StepNCParser encapsula o JavaCC, por isso, este método irá fazer toda a análise léxica e sintática do compilador e retornar ao nó raiz ( Start ) da árvore sintática. Caso nenhum erro léxico ou sintático seja encontrado, o método runSyntacticAnalysis continua seu algoritmo percorrendo todos os nós da árvore sintática, criando a EntityTO. Por último, o método runSyntacticAnalysis retorna uma instância do objeto StepSectionsTO composta pelas duas Collections, uma da seção do cabeçalho e outra da seção dados.
6.2 Estrutura da Máquina-Ferramenta e CNC-C2 99
Figura 6.6: Componente da análise sintática
Fonte: Hasegawa et al. (2011)
Figura 6.7: Árvore sintática gerada pelo JavaCC + JJTree
Fonte: Hasegawa et al. (2011)
O processo de converter a árvore sintática para um conjunto de EntityTO é auxiliado por métodos especializados encontrados dentro da classe EntityTO. Esses métodos recebem como entrada o nó da entidade e com isso retira todas as informações necessárias para popular uma instância de EntityTO, como visto na Figura 6.13.
A última fase da compilação é marcada pelo método runSemanticAnalysis, Figura 6.14. Este método recebe como entrada o resultado do método runSyntacticAnalysis e retorna a linguagem alvo. Ele mantém uma lista de entidades que ainda não foram instanciadas e enquanto existirem
6.2 Estrutura da Máquina-Ferramenta e CNC-C2 100
Figura 6.8: Componente da análise semântica
Fonte: Hasegawa et al. (2011)
Figura 6.9: Diagrama de classes mostrando as classes principais
Fonte: Hasegawa et al. (2011)
entidades nesta lista, ele vai escolher uma delas e fazer várias verificações nela. Caso todas as verificações estejam de acordo, ele irá então instanciar essa entidade e retirá-la desta lista. Esse processo pode ser entendido como uma conversão entre um objeto EntityTO para uma classe equivalente do esquema do programador.