Analyse lexicale & syntaxique avec Boost::Spirit

Analyse lexicale & syntaxique avec Boost::Spirit - C++ - Programmation

Marsh Posté le 09-09-2009 à 14:00:59    

Bonjour,
 
Je suis en train d'essayer de parser du code source Caml à l'aide de Boost::Spirit. (L'objectif étant à terme de convertir le code Caml en métaprog C++ à l'aide de boost::mpl)
J'ai eu l'occasion de voir cette idée que très récemment, donc je ne suis que sur le début...  
Pour le moment, je commence par la phase où il y a pas trop besoin de réfléchir: parser le Caml...
 
Globalement, le parsage avec boost:spirit marche pas trop mal. J'ai juste 3 sourcis:
 
(Le code source est dispo là: http://www.mediafire.com/?gdcyuwwx1mm )
 
* Le premier est le suivant: je comprend pas bien pourquoi, mais j'ai des erreurs bizare sous gcc 4.4.1-1 sous Arch Linux alors que sous Win / VS 9.0 SP 1 pas de souci

Citation :


....
Parser.hpp:379:79: attention : caractère(s) nul(s) ignoré(s)
Parser.hpp:380:1: attention : caractère(s) nul(s) ignoré(s)
Parser.hpp:381:1: attention : caractère(s) nul(s) ignoré(s)
Parser.hpp:382:1: attention : caractère(s) nul(s) ignoré(s)
Parser.hpp:383:1: attention : caractère(s) nul(s) ignoré(s)
Parser.hpp:383:3: attention : caractère(s) nul(s) ignoré(s)
Parser.hpp:384:1: attention : caractère(s) nul(s) ignoré(s)
Parser.hpp:385:1: attention : caractère(s) nul(s) ignoré(s)
Parser.hpp:386:1: attention : caractère(s) nul(s) ignoré(s)
Parser.hpp:387:1: attention : caractère(s) nul(s) ignoré(s)
In file included from main.cpp:2:
Parser.hpp:15: erreur: ‘v’ does not name a type
Parser.hpp:29: erreur: expected unqualified-id before ‘/’ token
In file included from main.cpp:2:
Parser.hpp:37: erreur: ‘t’ does not name a type


Et les lignes désignées par le compilateur me semblent vraiment sans aucun problèmes... (par ex: la 15 c'est juste un commentaire :/ )
 
* mon deuxième souci est sur le parsage des chaines de caractères pour les noms de fonctions et variable...
Basiquement l'expression régulière est  

Code :
  1. ([a...z] | '_' )([a...z] | '_' | [0-9] | ''' )*


soit dans boost::spirit

Code :
  1. +( letter | ch_p('_') ) >> *(letter | digit_p | ch_p('_') | ch_p('\''))
  2. letter = letterUpCase | letterLowCase;
  3. letterUpCase = range<>('A','Z');
  4. letterLowCase = range<>('a','z');


Mais ce que je comprend pas c'est qu'il a l'air de me prendre aussi les espaces... du coup, si je rentre un truc du genre:

Code :
  1. test as test2


il me parse toute la chaine "test as test2" comme le nom d'une variable :/  
Dans la doc de Spirit, il y a des info pour ne pas tenir compte des espaces dans des cas particulier (comme pour gérer les nombres du type "12 000" ) Mais j'ai rien trouvé pour résoudre mon problème... Si vous avez une idée...
 
* Le troisième souci que j'ai est au niveau de certaines expressions du type:

Code :
  1. expr -> constante
  2.         | variable
  3.         | "(" expr " )"
  4.         | "begin" expr "end"
  5.         | "if" expr "then" expr ["else" expr]
  6. ...
  7.         | expr operateur expr
  8.         | expr (expr)+
  9.         | expr ; expr
  10.         | expr "::" expr


Le souci étant sur la deuxième partie: avec Spirit, ce type de cas conduit sur de la récursion infinie. Il est nécessaire d'avoir autre chose que l'expression en première partie. Du coup, je me dit qu'il fraudait faire quelque chose du genre:

Code :
  1. expr -> constante
  2.         | variable
  3.         | "(" expr " )"
  4.         | "begin" expr "end"
  5.         | "if" expr "then" expr ["else" expr]
  6. ...
  7.         | variable operateur expr
  8.         | "(" expr " )" operateur expr
  9.         | "begin" expr "end" operateur expr
  10.         | "if" expr "then" expr ["else" expr] operateur expr
  11. ...


Mais comme j'ai pas envie de me taper les !4 * n expressions... j'avais pensé à ça: (en Spirit)

Code :
  1. startExpr = longest_d[
  2.                 constant
  3.                 |  value_name
  4.                 | "(" >> expr >> " )"
  5.                 | "begin" >> expr >> "end"
  6.                 | "[" >> expr >> *( ";" >> expr) >> "]"
  7.                 | "if" >> expr >> "then" >> expr >> !("else" >> expr)
  8.                 | "match" >> expr >> "with" >> pattern_matching
  9.                 | "let" >> !(str_p("rec" )) >> let_binding >> "in" >> expr
  10.                 | "function" >> pattern_matching
  11.                 | "fun" >> multiple_matching
  12.                 ];
  13.         startExpr2 = longest_d[
  14.                 startExpr
  15.                 | startExpr >> "::" >> expr
  16.                 | startExpr >> +(expr)
  17.                 | startExpr >> ";" >> expr
  18.                 | startExpr >> infix_op >> expr
  19.                 ];
  20.         expr = longest_d[
  21.                 startExpr2
  22.                 | startExpr2 >> "::" >> expr
  23.                 | startExpr2 >> +(expr)
  24.                 | startExpr2 >> ";" >> expr
  25.                 | startExpr2 >> infix_op >> expr
  26.                 ];


 
Mais cela n'a pas l'air de bien marcher: quand j'associe une règle a exécuter lors de la reconnaissance des constantes pour vérifier une expression du type "3 + 4 ;;" J'ai l'impression de voir toutes les tentative d'association qu'il a fait. Du coup, il m'appelle plein de fois la règle associé à la reconnaissance du 3 et 4... (un exemple de ce pb est directement visible dans le code source complet posté ci dessus)
 
(la solution où je tapais tout avait l'air de marcher... mais bon, c'est pas vraiment une solution... Je ferai comment le jours où j'aurai 7 règles récursive comme ceci..)
 
Bon globalement à part la question des noms de variables je suis capable de vérifier si ce qui est tapé vérifie la grammaire de Caml. Mais je me demandais si vous auriez une idée pour résoudre mes derniers problèmes...
 
Merci!


Message édité par Amonchakai le 09-09-2009 à 14:10:34
Reply

Marsh Posté le 09-09-2009 à 14:00:59   

Reply

Marsh Posté le 09-09-2009 à 16:06:30    

Je te conseillerais d eposter sur la ML Boost.Spirit ou Joel et Harmut sauront te repondre si tu leur file un exemple simple compilable.

 

2ement, tu fais ça pour qui ? Car j'ai exactement le mm projet dans mes cartons ...


Message édité par Joel F le 09-09-2009 à 16:07:00
Reply

Marsh Posté le 09-09-2009 à 16:59:46    

Bonjour,
 
O.K. merci pour votre réponse, je vais préparer des exemples compilable qui illustrent mes différents problèmes et je les posterai sur la ML de Boost.Spirit. Honnêtement, quand j'ai créé ce topic je pensais précisément à vous, en espérant que vous ayez une solution...
 
Pour la question "pour qui est ce que je fais ça?", en fait je fais cela pour moi. En réalité, j'ai trouvé cela sur votre site dans la section "offre de stage" (d'où le fait que cela soit dans vos carton)... Je trouvais que cela était vraiment une très bonne idée (et que j'aimerai également avoir cet outil...). Donc je souhaiterai mener a bien ce projet.
 
Je tiendrai à jour ce topic pour donner les réponse que j'aurai eu a ce sujet (et aussi demander des conseil sur le design pour la génération du code).  
 
Merci!

Reply

Marsh Posté le 09-09-2009 à 17:59:50    

Amonchakai a écrit :


O.K. merci pour votre réponse, je vais préparer des exemples compilable qui illustrent mes différents problèmes et je les posterai sur la ML de Boost.Spirit. Honnêtement, quand j'ai créé ce topic je pensais précisément à vous, en espérant que vous ayez une solution...


 
C'est la gloire :D
 

Amonchakai a écrit :


Pour la question "pour qui est ce que je fais ça?", en fait je fais cela pour moi. En réalité, j'ai trouvé cela sur votre site dans la section "offre de stage" (d'où le fait que cela soit dans vos carton)... Je trouvais que cela était vraiment une très bonne idée (et que j'aimerai également avoir cet outil...). Donc je souhaiterai mener a bien ce projet.


 
Hahaha je me disais aussi  :whistle:  
 

Amonchakai a écrit :


Je tiendrai à jour ce topic pour donner les réponse que j'aurai eu a ce sujet (et aussi demander des conseil sur le design pour la génération du code).  


OK, n'hesite pas non plus à passer par mail/MP ca sera peut etre plus efficace ;)

Reply

Marsh Posté le 10-09-2009 à 20:22:54    

Joel F a écrit :


OK, n'hesite pas non plus à passer par mail/MP ca sera peut etre plus efficace ;)


 
Ah non ! On veut voir le contenu intéressant ici ! [:ddr555]

Reply

Marsh Posté le 11-09-2009 à 07:00:47    

@Evadream -jbd- : haha, pas de problèmes
 
Bon j'ai résolu les problèmes 1. et 3.  
 
Le 1. c'était juste une histoire d'un malencontreux caractère du a un copier/coller de la grammaire Caml depuis la doc de caml...
 
Pour le 3. on m'a recommandé sur la ML de boost::spirit d'éliminer la récursivité à droite comme cela:

Code :
  1. expr_start =
  2.            constant
  3.         || value_name
  4.         || "(" >> expr >> " )"
  5.         || "begin" >> expr >> "end"
  6.         || "[" >> expr >> *( ";" >> expr) >> "]"
  7.         || "if" >> expr >> "then" >> expr >> !("else" >> expr)
  8.         || "match" >> expr >> "with" >> pattern_matching
  9.         || "let" >> !(lexeme["rec"]) >> let_binding >> "in" >> expr
  10.         || "function" >> pattern_matching
  11.         || "fun" >> multiple_matching
  12.         ;
  13. expr_rest =
  14.         "::" >> expr
  15.         || ";" >> expr
  16.         || infix_op >> expr
  17.         ;
  18. expr = expr_start >> *expr_rest;


 
Ce qui semble marcher parfaitement.
 
Pour le pb 2. (les noms de variables), on m'a recommander de quitter la version "classique" de spirit pour passer en V2.1.  
Bon, j'avoue me galérer sur le passage à l'autre version: la doc n'est pas vraiment touffue (vu que cette version est encore en béta) Et puis les temps de compilation sont devenu énormément long (mon pauvre petit X40 a bien du mal...)  
 
Bref, je posterai les résultats quand tout sera réglé!

Reply

Marsh Posté le 11-09-2009 à 07:04:13    

cherche dans le gmane boost. Joel a posté un lien vers leur doc a jour de memoire.
 
Apres, moi dans mon optique, je voulais aps forcement lexer tt caml mais un sous ensemble strictement necessaire.

Reply

Marsh Posté le 11-09-2009 à 07:14:03    

Oui, c'est bon je l'ai trouvée:
http://www.boost.org/doc/libs/1_40 [...] uick_start
 
Après en ce qui concerne la grammaire de caml, je me suis restreint à ce qui est décrit ici:
http://www.fil.univ-lille1.fr/~lev [...] TPAst.html
 
Cela me semble suffisant (du moins dans un premier temps)

Reply

Marsh Posté le 11-09-2009 à 09:02:29    

OK :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed