OpenLaszlo est un logiciel "open source" et gratuit, pour développer des "RIA", "Rich Internet Applications". Un fichier source (suffixe .lzx) contient un mélange de XML (pour la partie statique des composants d'interface), et de de JavaScript (pour les aspects dynamiques). Il est compilé : soit pour le FlashPlayer, soit en code DHTML/JavaScript.
Le but est de montrer combien/comment les techniques actuelles du web dépendent des techniques de compilation, et d'en acquérir les rudiments. L'exercice traite bien sûr d'un sous-ensemble, simplifié, de OpenLaszlo:
tpnote.tgz
contenant les fichiers:
lex1.flex
lex2.flex
gram2.bison
lex3a.flex
lex3b.flex
gram3b.bison
lex3c.flex
gram3c.bison
lex4a.flex
gram4a.bison
lex4b.flex
(BONUS)gram4b.bison
(BONUS)lex4c.flex
(BONUS)gram4c.bison
(BONUS)Makefile
Pour la forme générale des balises OpenLaszlo (en ignorant le cas des balises de commentaires) on a deux possibilités :
<MotCleX .... />
Dans cette ecriture :
MotCle
est un nom de balise OpenLaszlo, p.ex. view
... etc <MotCleX .....> ... </MotCleX>
.
Par l'appariement MotCleX-MotCleX, elles délimitent des blocs, qui peuvent
à leur tour contenir d'autres balises ou blocs. Mais dans cette question 1,
on ne traite ni du bon appariement ni de la bonne structure d'un bloc
(c'est l'objet de la question 2), seulement des balises.
----------------- Exemple 1.lzx -------------- <canvas> <include /> <view> <window /> <view> <window> <view /> <button /> </window> </view> </view> </canvas> -----------------------------------------------
Mettre au point un analyseur lex1.flex
reconnaissant les balises
du fichier 1.lzx
------- Résultat après analyse de 1.lzx ------- [open canvas] [include] [open view] [window] [open view] [open window] [view] [button] [close window] [close view] [close view] [close canvas] -----------------------------------------------Indications
Mettre au point un analyseur lex2.flex
+ gram2.bison
[...]
" au niveau lexical,<...>
" au niveau syntaxique1.lzx
on devrait obtenir :
[<canvas>] [<include />]<Include><LonelyTag><Item> [<view>] [<window />]<Window><LonelyTag><Item> [<view>] [<window>] [<view />]<View><LonelyTag><Item> [<button />]<Button><LonelyTag><Item> [</window>]<Window><Block><Item> [</view>]<View><Block><Item> [</view>]<View><Block><Item> [</canvas>]<Canvas><Block><Item>Indications
<include />
=> INCLUDE
<canvas ...>
: OP_CANVAS
, et pour </canvas>
: CL_CANVAS
LonelyTag
peut être un INCLUDE
ou un BUTTON
ou un WINDOW
Block
est un bloc OP_VIEW/CL_VIEW
, un bloc OP_WINDOW/CL_WINDOW
ou un bloc OP_CANVAS/CL_CANVAS
window
peut être soit de type Block
soit de type LonelyTag
Item
peut être un LonelyTag
ou un Block
Items
En réalité (dans les parties de balise notées "..." en Question 1)
les balises ouvrantes ou isolées peuvent contenir des triplets :
NomAttribut="valeur"
.
Dans la question 4, nous donnons un exemple complet
(4.lxz
). Dans cette partie nous ne traiterons que les
aspects liés aux attributs.
Construire l'analyseur lex3a.flex
reconnaissant les seuls composants de triplets, provisoirement en dehors de toute balise.
Exemple d'entrée à traiter :
--------------- 3.dat ------------------------------------------ width="100%" height="100%" bgcolor="0xCCCCCC" href="resources.lzx" name="main" title="Details" resizable="true" text="Check" x="50" y="50" ------------------------------------------------------------------Indications
width
=> WIDTH
, x
=> X
, resizable
=> RESIZABLE
, ... etc
%token
.'%'
(inutile de vérifier que l'entier est sur [0,100])0x
INT_V
, PERCENT_V
, COLOR_V
, STRING_V
3.dat
, l'analyseur devrait produire :
[WIDTH] [=] [PERCENT_V] [HEIGHT] [=] [PERCENT_V] [BGCOLOR] [=] [COLOR_V] [HREF] [=] [STRING_V] [NAME] [=] [STRING_V] [=] [RESIZABLE] [=] [STRING_V] [TEXT] [=] [STRING_V] [X] [=] [INT_V] [Y] [=] [INT_V][*] Précisions pour le cas des chaînes
Mettre au point un analyseur lex3b.flex + gram3b.bison qui traite une liste d'atributs sous forme de triplets attribut/=/valeur. À chaque reconnaissance de triplet, l'analyseur syntaxique doit afficher: nom = type de la valeur
, par exemple X = INT_V
.
WIDTH
, HEIGHT
, ...) INT_V
, PERCENT_V
, COLOR_V
, STRING_V
AttrInt
, AttrColor
, AttrPercent
ou AttrString
.
AttrList
définit une liste d'attributsAttr
définit un attribut pouvant être soit AttrInt
, AttrColor
, AttrPercent
ou AttrString
X
et Y
à INT_V
,
WIDTH
et HEIGHT
à PERCENT_V
BGCOLOR
à COLOR_V
HREF
, NAME
, TITLE
, RESIZABLE
et TEXT
à STRING_V
------- Résultat après analyse de 3.dat ------- [width][=][PERCENT_V]<WIDTH = PERCENT_V>[height][=][PERCENT_V]<HEIGHT = PERCENT_V>[bgcolor][=][COLOR_V]<BGCOLOR = COLOR_V> [href][=][STRING_V]<HREF = STRING_V>[name][=][STRING_V]<NAME = STRING_V>[title][=][STRING_V]<TITLE = STRING_V>[resizable][=][STRING_V]<RESIZABLE = STRING_V> [text][=][STRING_V]<TEXT = STRING_V>[x][=][INT_V]<X = INT_V>[y][=][INT_V]<Y = INT_V> -----------------------------------------------
Développer l'analyseur lex3c.flex
et gram3c.bison
reprenant l'analyseur de la question précédente en remplaçant les types de valeur (INT_V
, STRING_V
...) par leur valeur.
INT_V
, STRING_V
, PERCENT_V
et COLOR_V
sont de type chaîne de caractères pour pouvoir traiter aussi bien "50"
que "resources.lzx"
------- Résultat après analyse de 3.dat ------- [width][=][PERCENT_V]<WIDTH = "100%">[height][=][PERCENT_V]<HEIGHT = "100%">[bgcolor][=][COLOR_V]<BGCOLOR = "0xCCCCCC"> [href][=][STRING_V]<HREF = "resources.lzx">[name][=][STRING_V]<NAME = "main">[title][=][STRING_V]<TITLE = "Details">[resizable][=][STRING_V]<RESIZABLE = "true"> [text][=][STRING_V]<TEXT = "Check">[x][=][INT_V]<X = "50">[y][=][INT_V]<Y = "50"> -----------------------------------------------
Remarque: si vous ne pouvez pas répondre à cette question, vous pouvez quand même faire la question 4.
En utilisant les analyseurs lex1.flex
et lex3a.flex
construits aux questions précédentes, construire l'analyseur lex4a.flex
reconnaissant en plus des balises les composantes des triplets attribut/=/valeur.
------------- Exemple : 4.lzx ------------------------------------------------ <canvas width="100%" height="100%" bgcolor="0xCCCCCC" > <include href="resources.lzx" /> <view name="main" width="100%" height="100%"> <window name="details" title="Details" width="50%" height="50%" resizable="true" /> <view> <button text="Check" width="50%" height="50%" x="50" y="50" /> </view> </view> </canvas> -------------------------------------------------------------------------------Indications
<
' ouvrant au '>
' fermant) car on supposait les attributs absents. Maintenant, on traite des triplets attribut/=/valeur, mais leur nombre n'est pas connu a priori.
<XXXX
">
" ou "/>
"[WIDTH] [=] [PERCENT_V]
-------- Résultat après analyse de 4.lzx ------------------------- [<canvas][width][=][PERCENT_V][height][=][PERCENT_V][bgcolor][=][COLOR_V][>] [<include][href][=][STRING_V][/>] [<view][name][=][STRING_V][width][=][PERCENT_V][height][=][PERCENT_V][>] [<window][name][=][STRING_V][title][=][STRING_V] [width][=][PERCENT_V][height][=][PERCENT_V][resizable][=][STRING_V][/>] [<view][>] [<button][text][=][STRING_V][width][=][PERCENT_V][height][=][PERCENT_V][x][=][INT_V][y][=][INT_V][/>] [</view>] [</view>] [</canvas>] ------------------------------------------------------------------
Mettre au point lex4b.flex
, gram4b.bison
pour articuler les analyseurs lexical + syntaxique avec une analyse syntaxique limitée : simple récupération des catégories lexicales.
lex4a.flex
BEG_OP
(BEG_OP_CANVAS
, BEG_OP_WINDOW
, ... etc)include
et button
: BEG_INCLUDE
et BEG_BUTTON
/>
" retourner une nouvelle catégorie END_TAG
>
" retourner '>
' soi-mêmeBEG_OP_CANVAS
l'analyseur syntaxique considère que c'est un BegOpCanvas
, et fait une impression de vérification.
Mettre au point lex4c.flex
, gram4c.bison
pour vérifier complètement la syntaxe de l'exemple 4.lzx
.
gram2.bison
en fonction des nouvelles catégories : p.ex. au lieu de OP_CANVAS
, il faut une notion syntaxique OpCanvas
, à definir comme succession OP_CANVAS AttribList '>'
gram3b.bison
prenant en compte les triplets attribut/=/valeur