• [^] # Re: Séparateur ?

    Posté par . En réponse au message YACC: retour-chariot comme séparateur. Évalué à 2.

    Alors à vue de nez :

    Ton lexon « commentaires » ne spécifie absolument pas qu'il est censé s'arrêter en bout de ligne. De cette façon, il pourrait bouffer tout ton fichier. Essaie de mettre un $ après "//".* ...

    Je te déconseille d'utiliser return '\n' puisque tu es censé renvoyer un token défini, codé par un entier. Ton '\n' pourrait en fait passer pour le dixième lexon défini et là, pour retrouver le bug ...

    En fait le problème qu'il y a à gérer le séparateur dans la grammaire, c'est que ça l'alourdit.

    Non, pas si c'est bien géré. En rédigeant une grammaire propre, tu peux presque n'avoir à le spécifier qu'une seule fois.

    De plus il faut distinguer la notion de séparateur et de terminateur.

    En fait, non, justement. Et cela à cause du fait que la lecture de ton source est purement linéaire. On ne revient pas sur ce qui a été lu. En réalité, ton problème est de reconnaître sans ambigüité les cas où tes instructions sont proprement clôturées. Et elles peuvent l'être par trois choses différentes : Un caractère donné (par exemple, le point-virgule), un retour à la ligne, ou la fin du fichier.

    C'est donc cette dernière qu'il faut reconnaître au niveau lexical et Lex te propose un mot-clé spécial pour cela : <<EOF>>

    Néanmoins, le séparateur-terminateur est bel est bien un élément grammatical, ne serait-ce que parce qu'il est principalement contextuel , mais également parce qu'il peut prendre plusieurs formes.

    Dès lors, ta grammaire est très simple à exprimer. une expression correcte est une « instruction dûement et proprement terminée », qui donc s'écrit :

    %token TERM

    expression: instruction TERM { Execute (1ドル); }


    avec TERM :

    [;\n] return TERM;
    <<EOF>> return TERM;


    Enfin, pour que plusieurs séparateurs puissent se succéder, qu'ils s'agisse de ; ou de retours à la ligne, il faut faire l'hypothèse que l'on fait tous implicitement quand on regarde du C ou autre langage qui le permette : le séparateur clôt une instruction vide. La grammaire devient alors :

    expression
    : TERM { /* non-opération */ }
    | instruction TERM { Execute (1ドル); }




    J'ajoute que ta grammaire serait ambigüe si le WHEN était optionnel et postérieur à ton RESIZE. Par contre, si c'est en préfixe, la clause RESIZE qui suit est obligatoire et lève l'ambigüité. Mais il faut toujours écrire d'une part la grammaire d'une instruction propre et d'autre part, celle qui définit comment ces instructions peuvent s'enchaîner dans une script. Ce n'est pas le cas de la tienne actuellement : ton script: embarque en vrac toutes sortes de définitions, sans les lier forcément entre elles. Et ceci pourrait te causer des problèmes pour les interpréter après les avoir reconnues.