OVH Cloud OVH Cloud

Histoire de grammaire

12 réponses
Avatar
Eric
Bonjour,

il me faut parcourir une chaine pour en séparer ses composantes. Je ne sais
pas quelle fonctions de sscanf, strtok, ... je dosi utiliser. La chaine que
je dois parcourir, si je l'appelle <message>, à une structure en pseudo BNF
comme ceci :

<message> ::= [':' <command> <SPACE> ] <command> <params> <crlf>
<command> ::= <letter> { <letter> } | <number> <number> <number>
<SPACE> ::= ' ' { ' ' }
<params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]

<middle> ::= <Any *non-empty* sequence of octets not including SPACE
or NUL or CR or LF, the first of which may not be ':'>
<trailing> ::= <Any, possibly *empty*, sequence of octets not including
NUL or CR or LF>

<crlf> ::= CR LF

Mon problème est la gestion des paramètres optionnels (entre crochets),
notamment pour <param>. Comment programmer un tel "parser" ?

Cordialement.

10 réponses

1 2
Avatar
Fabien KOCIK
A mon avis, ce sera plus simple avec strtok.
Il faut essayer de modéliser l'automate qui reconnaît le langage puis
faire des fonctions adaptées à chaque état utilisant strtok.
Ces fonctions devront mener l'activité de parsing d'une partie de
la chaîne puis envoyer un code retour dès qu'elles identifient
une sortie de l'état qu'elles modélisent.
Une fonction principale devra alors déterminer quel
est l'état suivant du système à un temps t et appeler
la fonction adéquate.

@+ Fabien

"Eric" a écrit dans le message news:
3f28fddf$0$30404$
Bonjour,

il me faut parcourir une chaine pour en séparer ses composantes. Je ne
sais

pas quelle fonctions de sscanf, strtok, ... je dosi utiliser. La chaine
que

je dois parcourir, si je l'appelle <message>, à une structure en pseudo
BNF

comme ceci :

<message> ::= [':' <command> <SPACE> ] <command> <params> <crlf>
<command> ::= <letter> { <letter> } | <number> <number> <number>
<SPACE> ::= ' ' { ' ' }
<params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]

<middle> ::= <Any *non-empty* sequence of octets not including SPACE
or NUL or CR or LF, the first of which may not be ':'>
<trailing> ::= <Any, possibly *empty*, sequence of octets not including
NUL or CR or LF>

<crlf> ::= CR LF

Mon problème est la gestion des paramètres optionnels (entre crochets),
notamment pour <param>. Comment programmer un tel "parser" ?

Cordialement.




Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "Eric" wrote:

il me faut parcourir une chaine pour en séparer ses composantes. Je ne sais
pas quelle fonctions de sscanf, strtok, ... je dosi utiliser. La chaine que
je dois parcourir, si je l'appelle <message>, à une structure en pseudo BNF
comme ceci :


La réponse 'brute force', c'est lex/yacc ou flex/bison.

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Eric
La réponse 'brute force', c'est lex/yacc ou flex/bison.


C'est d'un analyseur lexical ou syntaxique donc j'ai besoin (i.e. flex ou
bison) ?

Avatar
Eric
La réponse 'brute force', c'est lex/yacc ou flex/bison.



C'est d'un analyseur lexical ou syntaxique donc j'ai besoin (i.e. flex ou
bison) ?

Avatar
Vincent Richard

j'ai une fonction pour reconnaître command
cette fonction va appeler deux fois la fonction pour reconnaître letter.
Si l'un d'eux échoue, on essaie de l'alternative qui est l'appel de trois
fois la fonction pour reconnaître number.


Il y a plus simple : calculer l'ensemble des premiers de chaque alternative
et tester le token courant pour savoir où aller.

Vincent

--
SL> Au fait elle est mieux ma signature maintenant ?
Oui. T'enlève encore les conneries que t'as écrit dedans et c'est bon.
-+- JB in <http://www.le-gnu.net> : Le neuneuttoyage par le vide -+-

Avatar
DINH Viêt Hoà


j'ai une fonction pour reconnaître command
cette fonction va appeler deux fois la fonction pour reconnaître letter.
Si l'un d'eux échoue, on essaie de l'alternative qui est l'appel de trois
fois la fonction pour reconnaître number.


Il y a plus simple : calculer l'ensemble des premiers de chaque alternative
et tester le token courant pour savoir où aller.


Certes, si l'on souhaite faire plus élaboré et faire le travail de lex &
yacc, on peut se documenter sur l'ouvrage suivant :

Compilers: Principles, Techniques, and Tools
de Alfred V. Aho, Jeffrey D. Ullman, Ravi Sethi

http://www.amazon.fr/exec/obidos/ASIN/0201100886/qid59665404/sr=1-7/ref=sr_1_0_7/402-8989957-1957754

ISBN : 0201100886

--
DINH V. Hoa,

"Il faut savoir arrêter l'alcool de temps en temps" -- MAB


Avatar
Jean-Marc Bourguet
DINH Viêt Hoà writes:


La réponse 'brute force', c'est lex/yacc ou flex/bison.


C'est d'un analyseur lexical ou syntaxique donc j'ai besoin (i.e. flex ou
bison) ?


les 2, lex pour découper en mot et symboles.
yacc pour reconnaître les motifs donnés par la grammaire.


Si j'ai bonne memoire, sa grammaire est reguliere (autrement dit lex
suffit, mais bon pour quelque chose d'aussi simple, ecrire tout a la
main c'est plus rapide, surtout si on ne connait pas ces outils).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
Arnaud Debaene
Eric wrote:
Bonjour,

il me faut parcourir une chaine pour en séparer ses composantes. Je
ne sais pas quelle fonctions de sscanf, strtok, ... je dosi utiliser.
La chaine que je dois parcourir, si je l'appelle <message>, à une
structure en pseudo BNF comme ceci :

<message> ::= [':' <command> <SPACE> ] <command> <params> <crlf>
<command> ::= <letter> { <letter> } | <number> <number> <number>
<SPACE> ::= ' ' { ' ' }
<params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]

<middle> ::= <Any *non-empty* sequence of octets not including SPACE
or NUL or CR or LF, the first of which may not be ':'>
<trailing> ::= <Any, possibly *empty*, sequence of octets not
including NUL or CR or LF>

<crlf> ::= CR LF

Mon problème est la gestion des paramètres optionnels (entre
crochets), notamment pour <param>. Comment programmer un tel "parser"
?


Pourquoi ne pas utiliser n'importe quel moteur d'expressions régulières?

Arnaud

Avatar
Vincent Lascaux
Bonjour,

il me faut parcourir une chaine pour en séparer ses composantes. Je ne
sais

pas quelle fonctions de sscanf, strtok, ... je dosi utiliser. La chaine
que

je dois parcourir, si je l'appelle <message>, à une structure en pseudo
BNF

comme ceci :

<message> ::= [':' <command> <SPACE> ] <command> <params> <crlf>
<command> ::= <letter> { <letter> } | <number> <number> <number>
<SPACE> ::= ' ' { ' ' }
<params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]

<middle> ::= <Any *non-empty* sequence of octets not including SPACE
or NUL or CR or LF, the first of which may not be ':'>
<trailing> ::= <Any, possibly *empty*, sequence of octets not including
NUL or CR or LF>

<crlf> ::= CR LF


Une alternative à ce qui a été dit sur lex et yacc (qui est probablement
trop lourd pour votre probleme) est l'utilisation d'une regexp.
Je ne maitrise pas totalement cet outil, mais je me lance dans l'ecriture
d'une regexp qui match votre probleme :

(:([A-z]+|d{3}))? *([A-z]+|d{3}) *((:[^rn]*)|^:[^ rn]+)rn

Ca a vraiment l'air horrible, j'ai moi même du mal à me relire, mais ca se
traduit assez simplement de l'expression BNF (mais il y a surement des
fautes vu que je suis pas un expert en regexp :-))

Avatar
Patrick Mézard
il me faut parcourir une chaine pour en séparer ses composantes. Je ne
sais

pas quelle fonctions de sscanf, strtok, ... je dosi utiliser. La chaine
que

je dois parcourir, si je l'appelle <message>, à une structure en pseudo
BNF

comme ceci :

<message> ::= [':' <command> <SPACE> ] <command> <params> <crlf>
<command> ::= <letter> { <letter> } | <number> <number> <number>
<SPACE> ::= ' ' { ' ' }
<params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]

<middle> ::= <Any *non-empty* sequence of octets not including SPACE
or NUL or CR or LF, the first of which may not be ':'>
<trailing> ::= <Any, possibly *empty*, sequence of octets not including
NUL or CR or LF>

<crlf> ::= CR LF

Mon problème est la gestion des paramètres optionnels (entre crochets),
notamment pour <param>. Comment programmer un tel "parser" ?

Cordialement.


On a parlé de YACC et autres jusqu'ici, mais si tu as un compilateur du
troisième millénaire tu peux aussi essayer ça :
http://spirit.sourceforge.net/

Patrick Mézard

1 2