(geração de compiladores incrementais)
Pretende-se criar um editor/compilador que assista e valide a escrita de agendas pessoais. As agendas em causa obedecem a uma determinada sintaxe apresentada a seguir e pretende-se que a ferramenta gerada force essa sintaxe e que como produto final gere um ficheiro HTML com a semântica pertinente.
A agenda é composta por um conjunto de entradas.
Cada entrada pode ser simples ou um grupo. Por sua vez, um grupo
é composto por um conjunto de entradas e assim "ad
infinitum".
Agenda --> AGENDA ident ItemList END '.'
ItemList --> Item ItemList
|
Item --> ident num num morada email url
| Grupo
Grupo --> GRUPO ident ItemList FIMGRUPO
root ag;
ag : Agenda(identificador itemlist)
;
list itemlist;
itemlist : ItemListNil()
| ItemListPair(item itemlist)
;
item : ItemNull()
| Single(identificador num num morada email url)
| Group(identificador itemlist)
;
identificador : IdentNull()
| Identifier(TEXTO)
;
morada : MoradaNull()
| Morada(TEXTO)
;
email : EmailNull()
| Email(TEXTO)
;
url : UrlNull()
| Url(TEXTO)
;
num : NumNull()
| Numero(NUMERO)
;
WHITESPACE: < [\ \t\n] >;
AGENDA: < "AGENDA:" >;
END: < "END." >;
GROUP: < "***(" >;
ENDGROUP: < "*)" >;
NUMERO: < [0-9\.\-\(\)]+ >;
TEXTO: < [a-zA-Z\/\~\:\@\.\-\_\?\!0-9\ ]+ >;
AG ::= (AGENDA Id ItemList END)
{$$.t = Agenda(Id.t, ItemList.t);};
ItemList ::= (Item) {$$.t = (Item.t :: ItemListNil);}
| (Item ItemList) {$$.t=(Item.t::ItemList$2.t);}
;
Item ::= ('+' Id Num Num Mor EM U)
{$$.t = Single(Id.t, Num$1.t, Num$2.t, Mor.t, EM.t, U.t);}
| (GROUP Id ItemList ENDGROUP)
{$$.t = Group(Id.t, ItemList.t);}
;
Id ::= (TEXTO) {$$.t = Identifier(TEXTO);};
Mor ::= (TEXTO) {$$.t = Morada(TEXTO);};
EM ::= (TEXTO) {$$.t = Email(TEXTO);};
U ::= (TEXTO) {$$.t = Url(TEXTO);};
Num ::= (NUMERO) {$$.t = Numero(NUMERO);};
AG {syn ag t;};
Item {syn item t;};
ItemList {syn itemlist t;};
Id {syn identificador t;};
Mor {syn morada t;};
EM {syn email t;};
U {syn url t;};
Num {syn num t;};
ag ~ AG.t;
item ~ Item.t;
itemlist ~ ItemList.t;
identificador ~ Id.t;
morada ~ Mor.t;
email ~ EM.t;
url ~ U.t;
num ~ Num.t;
ag : Agenda [ @ ::= "AGENDA: " @
" Registos: " itemlist.acount
"%t%n" @ "%b%nEND." ];
itemlist : ItemListNil [ @ ::= ]
| ItemListPair [ @ ::= @ ["%n"] @ ];
item : ItemNull [ @ ::= "<item>" ]
| Single [ @ ::= "--> " @
" : " @ " : " @ " : "
@ " : " @ " : " @ ]
| Group [ @ ::= "*** [" @ "]%t%t%n" @
"%b%b%n***%n" ];
identificador : IdentNull [ @ ::= "<identificador>" ]
| Identifier [ @ ::= @ ]
;
morada : MoradaNull [ @ ::= "<morada>" ]
| Morada [ @ ::= @ ]
;
email : EmailNull [ @ ::= "<email>" ]
| Email [ @ ::= @ ]
;
url : UrlNull [ @ ::= "<url>" ]
| Url [ @ ::= @ ]
;
num : NumNull [ @ ::= "<numero>" ]
| Numero [ @ ::= @ ]
;
view HTML;
ag : Agenda [ HTML ^ ::= "<HTML>%t%n"
"<TITLE>AGENDA:
" ^ "</TITLE>"
"<BODY>%t%n"
"<UL>%t%n"
^ "%b%n</UL>"
"%b%n</BODY>"
"%b%n</HTML>"
];
itemlist : ItemListNil [ HTML ^ ::= ]
| ItemListPair [ HTML ^ ::= ^ ["%n"] ^ ];
item : ItemNull [ HTML ^ ::= "<LI> <item>" ]
| Single [ HTML ^ ::= "<LI>
" ^ " : " ^ " : " ^
" : " ^ " : " ^ "
: " ^ ]
| Group [ HTML ^ ::= "<LI><I> " ^
"</I>%t%t%n<OL>%n"
^ "%n</OL>%b%b%n" ]
;
identificador : IdentNull [ HTML ^ ::=
"<identificador>" ]
| Identifier [ HTML ^ ::= ^ ];
morada : MoradaNull [ HTML ^ ::= "<morada>" ]
| Morada [ HTML ^ ::= ^ ];
email : EmailNull [ HTML ^ ::= "<email>" ]
| Email [ HTML ^ ::= "<A HREF=\"mailto:"
^ "\">email</A>" ];
url : UrlNull [ HTML ^ ::= "<url>" ]
| Url [ HTML ^ ::= "<A HREF=\"http://"
^ "\">homepage</A>" ];
num : NumNull [ HTML ^ ::= "<numero>" ]
| Numero [ HTML ^ ::= ^ ] ;
itemlist,item {inh INT bcount;
syn INT acount;
};
ag : Agenda { itemlist.bcount = 0; };
itemlist : ItemListNil { $$.acount = $$.bcount;}
| ItemListPair { item.bcount = itemlist$1.bcount;
itemlist$2.bcount = item.acount;
itemlist$1.acount = itemlist$2.acount;
};
item : ItemNull { $$.acount = $$.bcount; }
| Single { $$.acount = $$.bcount+1; }
| Group { itemlist.bcount = $$.bcount;
$$.acount = itemlist.acount; }
;






