Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Analyse syntaxique d'une instruction Panoramic Mer 8 Déc 2010 - 23:47 | |
| Dans ma recherche pour produire un pré-processeur à Panoramic capable de générer des commandes comme SUBROUTINE...END_SUB, FUNCTION...END_FUNCTION, CALL etc, telles que décrites dans d'autres posts de ce forum, j'ai écrit un petit programme d'analyse syntaxique d'une instruction de Panoramic. C'est sans prétention. Le programme est destiné à être utilise sous forme de sous-programme, par gosub, dans mon programme pré-processeur à venir. Mais certains d'entre vous réfléchissent aussi à une analyse du code source. Je me suis dit que ce module pourrait intéresser l'un ou l'autre. - Code:
-
' programme "analyse syntaxique.bas" ' ' Ce programme prend une ligne de Panoramic et l'analyse. ' Il isole tous les éléments: mots-clé, commandes, variables, labels ' et constantes numériques et texte.
label ana, suite, change, log_it dim x$,p%,m1%,m2%,m3%,swit%,valeur,lettres$,offset% dim items$(400),start%(400),size%(400),type%(400),n_item%, libtyp$(9)
lettres$ = "abcdefghijklmnopqrstuvwxyz0123456789%$_#" libtyp$(0) = "Inconnu" libtyp$(1) = "Valeur" libtyp$(2) = "Chaîne" libtyp$(3) = "Nom" libtyp$(4) = "" libtyp$(5) = "" libtyp$(6) = "" libtyp$(7) = "Séparation" libtyp$(8) = "Vide" libtyp$(9) = "Invalide"
width 0,700 : height 0,600 caption 0,"Analyseur d'expressions Panoramic"
alpha 2 : top 2,20 : left 2,10 : caption 2,"Expression à analyser" edit 1 : top 1,40 : left 1,10 : width 1,660 : font_size 1,12 : on_change 1,change button 10 : top 10,80 : left 10,10 : caption 10,"Analyser..." : on_click 10,ana
alpha 21 : top 21,110 : left 21,10 : caption 21,"Items" list 31 : top 31,130 : left 31,10 : height 31,400 : width 31,150 : font_size 31,12 alpha 22 : top 22,110 : left 22,180 : caption 22,"Début" list 32 : top 32,130 : left 32,180 : height 32,400 : width 32,150 : font_size 32,12 alpha 23 : top 23,110 : left 23,350 : caption 23,"Longueur" list 33 : top 33,130 : left 33,350 : height 33,400 : width 33,150 : font_size 33,12 alpha 24 : top 24,110 : left 24,520 : caption 24,"Type" list 34 : top 34,130 : left 34,520 : height 34,400 : width 34,150 : font_size 34,12 end
change: n_item% = 0 clear 31 : clear 32 : clear 33 : clear 34 return
suite: if p%>=len(x$) x$ = "²" else offset% = offset% + p% - 2 x$ = "²"+right$(x$,len(x$)-p%+1) if x$="" ana: x$ = "²"+text$(1)+")" offset% = -2 end_if end_if ' x$ = string à analyser ' p% = pointeur dans string ' mx% = marqueurs x=1,2,3,...
m1% = 2 if len(x$)=1 swit% = 8 else p% = 2 swit% = 0 ' swit%: 0=inconnu 1=numeric 2=string 3=nom 7=":" 8=vide 9=invalide repeat select swit% case 0 if mid$(x$,p%,1)=":" swit% = 7 p% = p% + 1 exit_repeat end_if if numeric(mid$(x$,m1%,p%-m1%+1))=1 swit% = 1 else if mid$(x$,p%,1)="'" swit% = 8 exit_repeat end_if if lower$(mid$(x$,p%,3))="rem" if (mid$(x$,p%+3,1)=")") or(mid$(x$,p%+3,1)=" ") swit% = 8 exit_repeat end_if end_if if mid$(x$,p%,1)=chr$(34) swit% = 2 m1% = p% else if instr("(),:<=>+-*/ ",mid$(x$,p%,1))=0 if instr(lettres$,lower$(mid$(x$,p%,1)))>0 swit% = 3 else swit% = 9 end_if else m1% = m1% + 1 end_if end_if end_if case 1 if mid$(x$,p%,1)=" " exit_repeat end_if if numeric(mid$(x$,m1%,p%-m1%+1))=1 else if mid$(x$,m1%-1,1)="-" then m1% = m1% - 1 exit_repeat end_if case 2 if mid$(x$,p%,1)=chr$(34) p% = p% + 1 exit_repeat end_if case 3 if instr(lettres$,lower$(mid$(x$,p%,1)))>0 else exit_repeat end_if end_select p% = p% + 1 until p%>len(x$) end_if
select swit% case 0 case 1 valeur = 0 if (p%>2) or (mid$(x$,m1%,1)<>"-") then valeur = val(mid$(x$,m1%,p%-m1%)) n_item% = n_item% + 1 items$(n_item%) = str$(valeur) start%(n_item%) = m1% + 1 + offset% size%(n_item%) = p%-m1% type%(n_item%) = 1 gosub log_it case 2 n_item% = n_item% + 1 items$(n_item%) = mid$(x$,m1%+1,p%-m1%-2) start%(n_item%) = m1% + 2 + offset% size%(n_item%) = p%-m1%-2 type%(n_item%) = 2 gosub log_it case 3 n_item% = n_item% + 1 items$(n_item%) = mid$(x$,m1%,p%-m1%) start%(n_item%) = m1%+1 + offset% size%(n_item%) = p%-m1% type%(n_item%) = 3 gosub log_it case 7 n_item% = n_item% + 1 items$(n_item%) = ":" start%(n_item%) = m1% + 1 + offset% size%(n_item%) = 1 type%(n_item%) = 7 gosub log_it case 8 case 9 message "invalide: ["+mid$(x$,m1%,p%-m1%-2)+"] ->"+str$(p%-1)+" "+x$ end_select if swit%<8 then goto suite return
log_it: item_add 31,items$(n_item%) item_add 32,str$(start%(n_item%)) item_add 33,str$(size%(n_item%)) item_add 34,str$(type%(n_item%)) + " = " + libtyp$(type%(n_item%)) return
On saisit la la zone edit en haut du programme une ligne Panoramic, ou on la colle par couper/coller à partir de l'éditeur. Puis on clique sur le bouton "Analyser. Le programme affiche alors tous les éléments (token) de la ligne: mots-clé, commandes, variables, labels, constantes numériques ou texte, avec leur position de début, leur longueur et leur type. On peut donner des lignes composées par ":", avec des commentaires etc. Tout aorès REM ou ' est ignoré, mais le programme reconnait les chaînes de caractères et considère ainsi que a$ = " code: rem ou ' introduit un commentaire" est une seule constante de type chaîne. Il ne fait pas la distinction entre mot-clé, variable label ou fonction: pour lui, ce sont tous des "noms". Les résultats sont affichés dans 4 listes et mémorisés dans 3 tableaux que l'on peut exploiter après. On peut, par exemple, comparer le contenu de la première colonne (Items, variable items$(200) ), avec la liste des mots-clé de Panoramic fourni par un autre programme que j'ai mis en ligne. si le mot-clé est dim ou label, on peut mettre les noms suivants dans une table de variables ou labels définis, etc J'ai longtemps cherché comment faire cela, et j'ai finalement pris une décision: Je ne refais pas le compilateur !Ceci veut dire que je ne teste pas la validité syntaxique d'une ligne: Panoramic le fait mieux que moi et le fera toujours mieux. Je pars du principe qu'il s'agit d'une ligne Panoramic valide, en ce qui concerne la syntaxe, les mots-clé, leurs paramètres, les variables et leur type etc. Je ne travaille que sur des chaînes de caractères, mais je tiens compte des délimiteurs possibles en Panoramic, et en particulier les guillemets et les introducteurs de commentaire. J'ignore si les parenthèses correspondent, si un string est affecté à une variable integer, etc.
Dernière édition par Klaus le Jeu 9 Déc 2010 - 14:04, édité 3 fois | |
|
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Analyse syntaxique d'une instruction Panoramic Ven 10 Déc 2010 - 10:01 | |
| Pourquoi pas ? Ce serait comme un langage de "scripting" utilisable dans un programme Panoramic.
Le programme actuel extrait les éléments de base (token) et établit une première classification grossière: constante numérique, string ou nom. Un nom peut être un mot-cle, une variable ou un label. Un mot-clé peut être une commande Panoramic ou une fonction.
Maintenant, tel que c'est fait, ce n'est pas réservé à Panoramic. Seule spécificité empruntée à Panoramic: les lignes composées dont déparées par un ":". A part cela, ce module peut être utilisé pour d'autres syntaxes, à définir.
Tous les signes spéciaux '()=+-*/<>, ainsi que les espaces sont simplement ignorés, sauf dans une constante string qui peut tout contenir.
Mais il y a un hic: tel que le programme est fait, et je l'ai indiqué dans mon post initial, il ne fait pas de contrôle sur la validité syntaxique de la ligne. C'est juste un moyen d'extraire les mots-clé pour pouvoir les retravailler. Pour réaliser un langage scripte, il faudrait aller plus loin en profondeur pour comprendre la structure de la ligne. | |
|