C.2. Conversão de declarações de elementos

Se o conteúdo do elemento que se está a derivar for estruturado vai ser necessário analisar a estrutura desse conteúdo antes de se fazer a conversão.

Primeiro, é preciso determinar o operador de ocorrência: zerone para zero ou uma ocorrências (operador ? do SGML), zeron para zero ou mais ocorrências (operador * do SGML) e onen para uma ou mais ocorrências (operador + do SGML). Se este não existir, passamos de imediato ao passo seguinte.

A seguir, analisa-se o operador de conexão: sequencial (seq) - os subelementos deverão aparecer todos pela ordem indicada; alternativa (or) - só um dos sublementos deverá aparecer.

Esta análise a dois passos vai-se repetir recursivamente para os sublementos até elementos atómicos serem atingidos (#PCDATA).

C.2.1. Elemento com estrutura singular

Se a expressão de conteúdo for formada por apenas um elemento (elem). A respectiva regra de derivação é:

         elemContent → elem

C.2.2. Operador de ocorrência zerone

No caso do sistema noticioso tínhamos:

<!ELEMENT News - - (Title, Begin-date, End-date?, Body?)>

O elemento Body pode aparecer zero ou uma vezes no conteúdo do elemento News, assim como o elemento End-date. Poderíamos tratar esta situação na gramática ao nível das derivações de News:

News → NewsAttList NewsContent

NewsContent → Grupo1

Grupo1 → Title Begin-date End-date Body
       | Title Begin-date End-date
       | Title Begin-date Body
       | Title Begin-date 

Desta maneira, temos de trabalhar com permutações, o que torna o processo muito complicado. A situação simplifica-se introduzindo um símbolo não-terminal para cada elemento (ou grupo de elementos numa sub-expressão de conteúdo) que tiver um operador de ocorrência a ele aplicado.

Assim, sempre que uma sub-expressão (SubExp) for afectada de um operador de ocorrência ?:

SubExp = A?
essa sub-expressão será denotada por um símbolo não-terminal de nome GrupoX_01, cujas produções para a sua derivação são:
          GrupoX_01 → GrupoX
                    | &egr;
             
          GrupoX → Conv(A)

Onde, GrupoX_01 corresponde à subexpressão inicial A? e GrupoX é o símbolo não-terminal que irá derivar a subexpressão que está afectada pelo indicador de ocorrência (para a derivação de sub-expressões convencionou-se que os nomes dos símbolos não-terminais seriam formados pela palavra Grupo seguida do valor de um contador interno, que é incrementado cada vez que se gera um novo nome, seguidos de um indicador do operador de ocorrência: 01,0n, ou 1n).

Neste ponto, o processo de conversão aplicar-se-ia recursivamente à sub-expressão A, como se pode observar pela última produção.

Voltando ao exemplo, a derivação de News será:

News → NewsAttList NewsContent

NewsContent → Title Begin-date Grupo1_01 Grupo2_01

Grupo1_01 → Grupo1
          | &egr;

Grupo1 → End-date

End-date → End-dateArrList End-dateContent
            
Grupo2_01 → Grupo2
          | &egr;

Grupo2 → Body

Body → BodyAttList BodyContent

C.2.3. Operador de ocorrência zeron

Novamente do caso do sistema noticioso, extrai-se outro exemplo para ilustrar esta regra, alterando-se ligeiramente fazendo com que Body seja composto por zero ou mais parágrafos:

<!ELEMENT Body - - (Para)*>

Aqui, o operador de ocorrência implica iteração o que vai traduzir em recursividade na gramática.

Assim, sempre que uma sub-expressão (SubExp) for afectada de um operador de ocorrência *:

SubExp = A*
essa sub-expressão será denotada por um símbolo não-terminal de nome GrupoX_0n, que deriva segundo as produções:
          GrupoX_0n → GrupoX  GrupoX_0n
                    | &egr;
             
          GrupoX → Conv(A)

A conversão da definição do elemento Body corresponde então ao conjunto seguinte de produções:

Body → Grupo3_0n

Grupo3_0n → Grupo3 Grupo3_0n
          | &egr;

Grupo3 → Para

C.2.4. Operador de ocorrência onen

Vamos usar o exemplo da regra anterior substituindo apenas o operador de ocorrência:

<!ELEMENT Body - - (Para)+>

A situação é tratada de forma idêntica à da regra anterior, sendo neste caso a sub-expressão A+ denotada pelo símbolo não-terminal GrupoX_1n que não pode derivar em vazio:

          GrupoX_1n → GrupoX  GrupoX_1n
                    | GrupoX
             
          GrupoX → Conv(A)

Donde, para o exemplo em causa se terá:

Body → Grupo3_1n

Grupo3_1n → Grupo3 Grupo3_1n
          | Grupo3

Grupo3 → Para

Como foi dito, depois da análise do operador de ocorrência faz-se a análise do operador de conexão que pode ser seq ou or; sejam, op1, ..., opn, os elementos (operandos) abrangidos por um desses operadores. Duas situações poderão ocorrer. As regras seguintes foram criadas para tratar estas situações.

C.2.5. Operador de conexão seq (sequência)

Os operandos de uma sequência têm que ser derivados na ordem em que se encontram na sequência. Assim, é fácil ver que a produção correspondente é:

          elemContent → Conv(op1) ... Conv(opn)


Exemplo C-3. Operador de conexão seq

Como já visto no sistema noticioso, o elemento News é composto por uma sequência de elementos, o que dá origem à seguinte produção:

         NewsContent → Title Begin-date Grupo_01 Grupo_02


C.2.6. Operador de conexão or (alternativa)

Os seus operandos são alternativas, assim só um corresponderá ao conteúdo do elemento.

As produções correspondentes serão:

          elemContent → Conv(op1)
                      | ...
                      | Conv(opn)