La différence la plus importante est que lexing va traduire votre domaine d'entrée.
Un beau résultat de ceci est que
Vous n'avez pas à penser à des espaces plus. Dans une directe (non-lexing) de l'analyseur, vous devez saupoudrer space
des analyseurs dans tous les lieux où les espaces sont autorisés à être, qui est facile d'oublier et cela encombre votre code si l'espace doit séparer toutes vos jetons de toute façon.
Vous pouvez penser au sujet de votre entrée dans un morceau par morceau, ce qui est facile pour l'homme.
Toutefois, si vous effectuez lexing, vous obtenez les problèmes que
Vous ne pouvez pas utiliser le bon analyseurs sur String
plus - par exemple, pour l'analyse d'un nombre avec une Fonction de la bibliothèque parseFloat :: Parsec String s Float
(qui fonctionne sur une Chaîne de flux d'entrée), vous avez à faire quelque chose comme takeNextToken :: TokenParser String
et execute
le parseFloat
de l'analyseur sur elle, l'inspection de l'analyser résultat (habituellement Either ErrorMessage a
). C'est pénible à écrire et les limites de la composabilité.
Vous devez régler tous les messages d'erreur. Si votre analyseur sur les pions d'échec lors de la 20e jeton, où dans la chaîne d'entrée est qui? Vous devrez manuellement erreur sur la carte des emplacements de retour à la chaîne d'entrée, ce qui est fastidieux (en Parsec cela signifie pour régler tous SourcePos
des valeurs).
Rapport d'erreur est généralement pire. L'exécution string "hello" *> space *> float
sur de fausses entrée comme "hello4"
vais vous dire précisément qu'il est prévu des espaces manquants après l' hello
, tandis qu'un analyseur lexical sera juste affirment avoir trouvé un "invalid token"
.
Beaucoup de choses que l'on pourrait s'attendre à des unités atomiques et d'être séparés par un analyseur lexical sont en fait assez "trop dur" pour un lexer à identifier. Prenez par exemple les littéraux de Chaîne - soudain "hello world"
ne sont pas deux jetons "hello
et world"
(mais seulement, bien sûr, si les guillemets ne sont pas échappé, comme \"
) - alors que c'est très naturel pour un analyseur syntaxique, cela signifie que les règles complexes et pour des cas particuliers d'un analyseur lexical.
Vous ne pouvez pas ré-utiliser les analyseurs sur les jetons en tant que bien. Si vous définissez comment analyser un double d'un String
, l'exportation et le reste du monde peut l'utiliser; ils ne peuvent pas exécuter votre (spécialisée) de générateur de jetons d'abord.
Vous êtes coincé avec elle. Lors du développement de la langue à l'analyse, à l'aide d'un analyseur lexical pourrait vous conduire dans la prise de décisions rapides, fixer les choses que vous souhaiterez peut-être modifier par la suite. Par exemple, imaginez que vous avez défini une langue qui contient quelques - Float
jeton. À un certain point, vous voulez introduire les littéraux négatifs (-3.4
et - 3.4
) - cela pourrait ne pas être possible en raison de l'analyseur lexical de l'interprétation d'espaces comme jeton de séparateur. À l'aide d'un analyseur seule approche, vous pouvez rester plus souple, de faire des changements dans votre langue plus facile. Ce n'est pas vraiment surprenant, car un parser est un outil plus complexe qui, naturellement, encode les règles.
Pour résumer, je vous recommande d'écrire lexer-gratuit analyseurs pour la plupart des cas.
En fin de compte, un analyseur lexical est juste un "simplifiés"* l'analyseur, si vous avez besoin d'un analyseur de toute façon, de les combiner en un seul.
* À partir d'informatique de la théorie, nous savons que tous les langages réguliers sont également libre de tout contexte langues; lexers sont généralement réguliers, les analyseurs libre de tout contexte ou même contexte sensible (monadique analyseurs comme Parsec pouvez exprimer au contexte de la sensibilité).