web-dev-qa-db-fra.com

Comment construire un arbre de syntaxe abstraite

J'ai une idée générale de ce qu'est un AST, mais je veux savoir comment en construire un.

Si on vous donne une grammaire et un arbre d'analyse, comment construisez-vous l'AST?

Comment faire si on vous donne une grammaire et une expression?

62
neuromancer

Eh bien, tout d'abord, la grammaire est utilisée pour construire un arbre d'analyse à partir d'une expression. Donc, si vous avez déjà un arbre d'analyse, vous n'avez pas besoin de la grammaire.

Selon le travail effectué par votre analyseur, l'arborescence résultante formée à partir de l'analyse d'une expression peut déjà être une arborescence de syntaxe abstraite. Ou il peut s'agir d'un simple arbre d'analyse qui nécessite une deuxième passe pour construire l'ast.

Pour construire l'arbre d'analyse à partir d'une grammaire et d'une expression, vous devez d'abord convertir votre grammaire en code de travail. En règle générale, vous divisez le travail en un tokenizer qui divise le flux d'entrée représentant l'expression en une liste de jetons et un analyseur qui prend la liste des jetons et en construit un arbre d'analyse\ast.

Ainsi, l'expression 1 + 2*(3+4) peut être divisée en une liste de jetons comme ceci:

1 - int
+ - add_operator
2 - int
* - mul_operator
( - lparen
3 - int
+ - add_operator
4 - int
) - rparen

La première colonne est la valeur réelle du texte. Le second représente le type de jeton. Ces jetons sont introduits dans l'analyseur, qui est construit à partir de votre grammaire et reconnaît les jetons et construit l'arborescence d'analyse.

Alors, comment écrire le tokenizer lexical et l'analyseur réel? Vous pouvez rouler le vôtre à la main. Ou, plus communément, utilisez un générateur d'analyseur comme coco ou antlr ou Lex/yacc. Ces outils prennent une description de votre grammaire et génèrent le code d'un tokenzier et d'un analyseur. (Des générateurs de code existent pour la plupart des langues populaires et pour certaines impopulaires également.)

La façon dont vous construisez votre analyseur dépend fortement de la langue que vous utilisez. La façon dont vous écririez un analyseur en Haskell est entièrement différente de la façon dont vous le feriez, disons, en C.

42
HS.

Je répondrai à cela d'un point de vue général, sans essayer de parler de lexers et d'analyseurs.

Un arbre d'analyse contient des symboles non terminaux qui font partie d'une grammaire sans contexte et montrent la chaîne de productions pour obtenir une chaîne composée de symboles terminaux, récursivement ou non. Donc, lorsque vous avez l'arbre d'analyse, vous n'avez pas besoin de la grammaire - vous pouvez dériver la grammaire de l'arbre d'analyse.

Un AST ne contient aucun symbole non terminal. Il ne contient que des symboles.

Exemple:

 E
 |
 E + T
 |   |
 T   M * M
 |   |   |
 M   a   b
 |
 a

Ce qui est une version très rapide de l'affichage de a+a*b. Remarque, la façon dont l'arborescence de syntaxe abstraite est interprétée dépend de la priorité de l'arborescence, du type de parcours que vous effectuez (dans l'ordre, en précommande, en post-commande). Ce serait une fonction générale que vous codez dans votre arbre de recherche. Cependant, en général, le AST pour cet arbre d'analyse peut ressembler à ceci:

   +
 |   |
 a   * 
    | |
    a b
4
Dhruv Ghulati