2016-06-02 5 views
0

Je souhaite écrire un petit éditeur pour une langue spécifique. Dans l'éditeur, nous pourrons indent une ou plusieurs lignes (c'est-à-dire ajouter des blancs sur la main gauche de chaque ligne); nous serons également en mesure de format le code entier (c.-à-d., modifier les espaces blancs et les nouvelles lignes dans les endroits appropriés). Étant donné un programme, mon frontal par ocamllex et ocamlyacc pourrait construire un Abstract Syntax Tree (AST). Je voudrais savoir quels sont les moyens communs pour stocker des positions d'éléments dans AST.Manière courante de stocker des positions dans un formateur

Une façon dont je suppose est d'ajouter un (début) position à chaque élément de l'AST. Par exemple, si le type d'une expression est définie comme suit:

type expression = 
    ... 
    | E_int of int 
    | E_function_EEs of Function.t * (expression list) 

Il deviendra:

type expression = 
    ... 
    | E_int of position * int 
    | E_function_EEs of position * Function.t * (expression list) 

Ensuite, si nous savons que la longueur de chaque élément, nous pouvons en déduire la position de tout dans l'éditeur. Est-ce un moyen courant de le faire? Je ne le trouve pas agréable ...

+0

Nos magasins d'outils DMS fichier/ligne/colonne dans chaque nœud d'arborescence. C'est sympa. –

Répondre

0

Vous ne devez pas répéter position pour chaque modèle. Vous pourriez simplement écrire un à la fin:

type expression = 
    ... 
    | E_int of int 
    | E_function_EEs of Function.t * (expression list) 
    | E_loc of position * expression 

En conséquence, pour les fonctions existantes sur expression, vous pouvez simplement ajouter un cas pour E_loc et ne pas besoin de toucher les cas existants.

Pour construire E_loc automatiquement lors de l'analyse, vous pouvez ajouter à .mly par exemple:

loc(EXPRESSION): 
| t = EXPRESSION { E_loc (($startpos, $endpos), t) } 

(* immediate construction: *) 
expression: 
| INT { E_loc (($startpos, $endpos), E_int $1) } 

(* or delay construction: *) 
expression: 
| e0 = loc(expression) PLUS e1 = loc(expression) { E_function_EEs (Function.PLUS, [e0; e1]) }