11
votes

Où devrais-je dessiner la ligne entre Lxer et analyseur?

J'écris un lexer pour le protocole IMAP à des fins éducatives et je suis excité sur l'endroit où je devrais dessiner la ligne entre Lxer et analyseur. Prenez cet exemple d'une réponse du serveur IMAP:

(TknBackSlash)
(TknString "Answered")
(TknSpace)
(TknBackSlash)
(TknString "Deleted")


0 commentaires

3 Réponses :


0
votes

Je recommanderais d'éviter de séparer Lexer et analyseur - approches d'analyse modernes (comme piquets ) permet de mélanger la lexing et l'analyse. De cette façon, vous n'avez pas besoin de jetons du tout.


0 commentaires

1
votes

J'aurais d'abord proposé le CFG et quels que soient les terminaux nécessaires pour faire son travail est ce que le LXER devrait reconnaître; Sinon, vous devinez simplement à la bonne façon de goûter la chaîne.


0 commentaires

7
votes

En règle générale, vous ne voulez pas que la syntaxe lexicale se propage dans la grammaire, car il suffit de détailler. Par exemple, un lexer pour une programmation informatique Langauge comme C reconnaît certainement des chiffres, mais il est généralement inapproprié de produire des jetons hexnométriques et décimalnumber, car ce n'est pas important pour la grammaire.

Je pense que ce que vous voulez sont les jetons les plus abstraits qui permettent à votre grammaire de distinguer les cas d'intérêt par rapport à votre objectif. Vous devez me nourrir par confusion causé dans une partie de la grammaire, par choix que vous pourriez faire dans d'autres parties.

Si votre objectif est simplement de lire les valeurs du drapeau, vous n'avez pas besoin de distinguer entre eux et un TKNFLAG sans contenu associé serait suffisant.

Si votre objectif est de traiter les valeurs d'indicateur individuellement, vous devez savoir si vous avez reçu des indications de réponse et / ou supprimées. Comment ils sont orthographiés lexicalement est hors de propos; Je vais donc avec votre solution Tknansweredflag. Je viderais le TKNSpace, car dans une séquence de drapeaux, il doit y avoir des espaces intermédiaires (votre spécification le disons), alors j'essaierais d'éliminer l'utilisation des machines de supresses de la surepace WhitSpace que vous proposez.

À l'occasion, je rencontre des situations où il y a des dizaines de telles choses ressemblant à des drapeaux. Ensuite, votre grammaire commence à devenir encombrée si vous avez un jeton pour chacun. Si la grammaire n'a pas besoin de connaître des indicateurs spécifiques, vous devez disposer d'un TKNFLAG avec une valeur de chaîne associée. Si un petit sous-ensemble des drapeaux est nécessaire par la grammaire pour distinguer, mais la plupart d'entre eux ne sont pas, alors vous devriez faire des jetons: avoir des jetons individuels pour ces drapeaux qui comptent pour la grammaire et une prise de tout TKNFLAG avec une chaîne associée pour le reste .

En ce qui concerne la difficulté à avoir deux interprétations différentes: c'est l'une de ces compromis. Si vous avez cette question, alors vos jetons doivent soit avoir suffisamment de détails suffisants dans les deux endroits où ils sont nécessaires dans la grammaire afin que vous puissiez discriminer. Si "\" est pertinent comme un jeton ailleurs dans la grammaire, vous pourriez certainement produire à la fois Tkackslash et Tknanswered. Toutefois, si la façon dont quelque chose est traité dans une partie de la grammaire est différente d'une autre, vous pouvez souvent vous déplacer en utilisant un lexer piloté par mode. Pensez aux modes comme étant une machine à états finis, chacune avec un lexère associé (sous). Les transitions entre les modes sont déclenchées par des jetons qui sont des indices (vous devez avoir un jeton de drapeaux; il est précisément un tel indice que vous êtes sur le point de récupérer des valeurs d'indicateur). En mode, vous pouvez produire des jetons que d'autres modes ne produiraient pas; Ainsi, en un seul mode, vous pourriez produire des jetons "\", mais dans votre mode drapeau, vous n'auriez pas besoin de. Le support en mode est assez courant dans Lexers car ce problème est plus courant que vous pourriez vous attendre. Voir la documentation Flex pour un exemple.

Le fait que vous posiez la question montre que vous êtes sur la bonne voie pour faire un bon choix. Vous devez équilibrer l'objectif de la main-d'œuvre de minimiser les jetons (techniquement, vous pouvez analyser à l'aide d'un jeton pour le caractère de toujours ASCII!) Avec fondamental nécessite de discriminer suffisamment à vos besoins. Après avoir construit une douzaine de grammaires, ce compromis semble facile, mais je pense que les règles de pouce que j'ai fournies sont plutôt bonnes.


0 commentaires