37 votes

Comment fonctionne un analyseur (par exemple, HTML)?

Pour la commodité du raisonnement laisse supposer un analyseur HTML.

J'ai lu que c' tokenizes tout d'abord, et puis il analyse.

De quoi marquer veux dire?

L'analyseur de lire chaque caractère de chaque, la construction d'un multi-dimensionnelle tableau pour stocker la structure?

Par exemple, lire un < , puis commencer à capturer l'élément, et puis une fois qu'il répond à une clôture > (à l'extérieur d'un attribut), il est poussé sur un tableau de la pile quelque part?

Je suis intéressé pour l'amour de la connaissance (je suis curieux).

Si je devais lire à travers la source de quelque chose comme HTML Purificateur, est-ce que me donner une bonne idée de comment HTML est analysée?

57voto

Lie Ryan Points 24517

La segmentation peut être composé de quelques pas, par exemple, si vous avez ce code html:

<html>
    <head>
        <title>My HTML Page</title>
    </head>
    <body>
        <p style="special">
            This paragraph has special style
        </p>
        <p>
            This paragraph is not special
        </p>
    </body>
</html>

le tokenizer peut convertir cette chaîne à une liste à plat des principales jetons, de jeter des espaces (merci, SasQ pour la correction):

["<", "html", ">", 
     "<", "head", ">", 
         "<", "title", ">", "My HTML Page", "</", "title", ">",
     "</", "head", ">",
     "<", "body", ">",
         "<", "p", "style", "=", "\"", "special", "\"", ">",
            "This paragraph has special style",
        "</", "p", ">",
        "<", "p", ">",
            "This paragraph is not special",
        "</", "p", ">",
    "</", "body", ">",
"</", "html", ">"
]

il peut y avoir plusieurs jetons passe pour convertir une liste de jetons à une liste de plus en plus au niveau des jetons comme suit hypothétique analyseur HTML peut faire (et qui est toujours une liste à plat):

[("<html>", {}), 
     ("<head>", {}), 
         ("<title>", {}), "My HTML Page", "</title>",
     "</head>",
     ("<body>", {}),
        ("<p>", {"style": "special"}),
            "This paragraph has special style",
        "</p>",
        ("<p>", {}),
            "This paragraph is not special",
        "</p>",
    "</body>",
"</html>"
]

puis l'analyseur convertit la liste des jetons pour former un arbre ou un graphe qui représente la source du texte dans une manière qui est plus pratique pour accéder et manipuler par le programme:

("<html>", {}, [
    ("<head>", {}, [
        ("<title>", {}, ["My HTML Page"]),
    ]), 
    ("<body>", {}, [
        ("<p>", {"style": "special"}, ["This paragraph has special style"]),
        ("<p>", {}, ["This paragraph is not special"]),
    ]),
])

à ce stade, l'analyse est complète; et c'est ensuite à l'utilisateur d'interpréter l'arbre, de le modifier, etc.

30voto

Jerry Coffin Points 237758

Tout d'abord, vous devez être conscient que l'analyse HTML est particulièrement moche -- HTML a été en large (et divergents) utilisation avant d'être normalisé. Cela conduit à toutes sortes de laideur, telles que la norme en précisant que certaines constructions ne sont pas autorisées, mais alors la spécification du comportement requis pour ces constructions de toute façon.

Arriver à votre question directe: la segmentation est à peu près équivalent à la prise de l'anglais, et le décomposer en mots. En anglais, la plupart des mots sont consécutifs flux de lettres, éventuellement, y compris de l'apostrophe, trait d'union, etc. La plupart des mots sont entourés par des espaces, mais un point, point d'interrogation, point d'exclamation, etc., peut également signaler la fin d'un mot. De même pour le code HTML (ou autre) vous préciser quelques règles sur ce qui peut rendre d'un jeton (word) dans cette langue. Le morceau de code qui casse l'entrée en jetons est normalement connu comme l'analyseur lexical.

Au moins dans un cas normal, vous n'avez pas tout rompre l'entrée en jetons avant de commencer l'analyse. Plutôt, l'analyseur appelle l'analyseur lexical pour obtenir le prochain jeton lorsqu'il en a besoin. Lorsqu'elle est appelée, l'analyseur lexical regarde assez de l'entrée pour trouver un jeton, permet à l'analyseur, et non plus de l'entrée est sous forme de jeton jusqu'à ce que la prochaine fois que l'analyseur a besoin de plus d'entrée.

D'une manière générale, vous avez raison au sujet de la façon dont un analyseur fonctionne, mais (au moins dans un typique de l'analyseur), il utilise une pile lors de l'acte de l'analyse d'un énoncé, mais qu'il construit pour représenter une déclaration est normalement un arbre, et l'Arbre de Syntaxe Abstraite, aka AST), pas un tableau multidimensionnel.

En fonction de la complexité de l'analyse HTML, j'avais de la réserve à la recherche à un analyseur syntaxique pour elle jusqu'à ce que vous avez lu un peu les autres en premier. Si vous faites un peu de recherche, vous devriez être capable de trouver un juste nombre d'analyseurs/lexers pour des choses comme des expressions mathématiques qui sont probablement plus approprié comme une introduction (plus petit, plus simple, plus facile à comprendre, etc.)

9voto

Corbin March Points 18522

Ne manquez pas les normes du W3C notes sur l'analyse HTML5.

Pour une introduction intéressante à la numérisation/lexing, prendre un coup d'oeil à la Génération Efficace de Table-Driven Scanners. Il montre comment la numérisation est finalement entraîné par la théorie des automates. Une collection d'expressions régulières est transformé en un seul ADN . L'ADN est ensuite transformé en un DFA pour faire des transitions d'état déterministe. Le document décrit une méthode pour transformer les DFA dans une table de transition.

Un point clé: les scanners utiliser une expression régulière pour la théorie, mais probablement ne pas utiliser les expression régulière bibliothèques. Pour de meilleures performances, des transitions d'état sont codées comme des géants cas de déclarations ou en transition tables.

Les Scanners de garantir que les bons mots(tokens) sont utilisés. Analyseurs de garantir les mots sont utilisés dans la bonne combinaison et l'ordre. Les Scanners utiliser l'expression régulière et la théorie des automates. Des analyseurs de l'utilisation de la grammaire de la théorie, en particulier au contexte de libre-grammaires.

Un couple d'analyse des ressources:

7voto

SasQ Points 2332

HTML et XML la syntaxe (et autres basée sur SGML) sont assez difficile à analyser, et ils ne rentrent pas bien dans les lexing scénario, car ils ne sont pas réguliers. Dans l'analyse de la théorie, un régulier de la grammaire est celui qui n'a pas de récursivité, qui est auto-similaire, imbriqués les modèles, ou des parenthèses comme des wrappers qui correspondent les uns aux autres. Mais le HTML/XML/SGML-les langages n' ont imbriquées modèles: les tags peuvent être imbriquées. La syntaxe avec l'imbrication des motifs est supérieur au niveau de l'Chomsky classification: il est libre de tout contexte ou même en fonction du contexte.

Mais pour en revenir à votre question à propos de lexer:
Chaque syntaxe se compose de deux sortes de symboles non-terminaux (ceux qui détendez-vous dans d'autres règles de syntaxe) et des terminaux (ceux qui sont "atomique" - ils sont les feuilles de l'arbre de syntaxe et de ne pas se détendre en quoi que ce soit d'autre). Terminal symboles sont souvent juste des jetons. Les jetons sont pompés un par un à partir de l'analyseur lexical et adaptés à la borne correspondante de symboles.

Ces terminaux (jetons) ont souvent régulier de la syntaxe, ce qui est plus facile à reconnaître (et c'est pourquoi il est pris en compte pour l'analyseur lexical, ce qui est plus spécialisé pour les grammaires régulières et pourrait le faire plus rapidement qu'en utilisant l'approche plus générale de la non-régulière, grammaires).

Donc, pour écrire un analyseur lexical pour le HTML/XML/SGML-comme la langue, vous avez besoin de trouver des pièces de la syntaxe qui sont atomiques suffisant et régulier, pour être traitées facilement par l'analyseur lexical. Et ici, le problème se pose, car il n'est pas au premier abord évident que les pièces sont présentes. J'ai du mal avec ce problème depuis longtemps.

Mais le Mensonge Ryan ci-dessus ont fait un très bon travail dans la reconnaissance de ces pièces. Bravo pour lui! Les types de jeton sont les suivantes:

  • TagOpener: < lexeme, utilisés pour le démarrage des balises.
  • TagCloser: > lexeme, utilisé pour les étiquettes de fin.
  • ClocingTagMarker: / lexeme utilisé dans les balises de fermeture.
  • Nom: séquence alphanumérique commençant par la lettre, utilisé pour les noms de balises et d'attributs de noms.
  • Valeur: Texte qui peut contenir une variété de différents caractères, espaces etc. Utilisée pour les valeurs des attributs.
  • Est égal à: = lexeme, utilisé pour séparer les noms d'attribut à partir de ses valeurs.
  • Citation: ' lexeme, utilisé pour délimiter les valeurs d'attribut.
  • Apostrophe: " lexeme, utilisé pour délimiter les valeurs d'attribut.
  • En clair: le texte ne contenant pas d' < caractère directement et ne sont pas couverts par les types ci-dessus.

Vous pouvez également avoir quelques jetons pour les références d'entité, comme &nbsp; ou &amp;. Probablement:

  • EntityReference: un lexeme composé d' & suivie par certains caractères alphanumériques et s'est terminée avec ;.

Pourquoi j'ai utilisé séparer les jetons pour ' et " et pas un jeton de la valeur de l'attribut? Parce que la syntaxe normale ne pouvait pas reconnaître lequel de ces caractères doit la fin de la séquence, tout dépend du caractère qui a démarré (caractère de fin correspondre au caractère de départ). Cette "parenthesizing" est considéré comme non réguliers de la syntaxe. J'ai donc le promouvoir à un niveau supérieur à l'Analyseur. Il serait de son travail avec ces jetons (de début et de fin) ensemble (ou pas du tout, pour de simples valeurs d'attribut ne contenant pas d'espaces).

Après coup: Malheureusement, certains de ces jetons peuvent se produire qu'à l'intérieur d'autres marques. Ainsi, l'utilisation de contextes lexicaux est nécessaire, ce qui après tout est un autre état de la machine de contrôle de l'état des machines en reconnaissant notamment les jetons. Et c'est pourquoi j'ai dit que SGML-comme les langues ne rentre pas bien dans le schéma de l'analyse lexicale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X