| Anotação Estrutural de Documentos e sua Semântica | ||
|---|---|---|
| Prev | Apêndice C. Conversão de DTDs para Gramáticas | Next |
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).
Se a expressão de conteúdo for formada por apenas um elemento (elem). A respectiva regra de derivação é:
elemContent → elem
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 BodyContentNovamente 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 → ParaVamos 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 → ParaComo 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.
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
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)