2016-06-02 8 views
0

Я хочу написать небольшой редактор для определенного языка. В редакторе мы сможем сделать indent одну или несколько строк (т. Е. Добавить белые пробелы в левой руке каждой строки); мы также сможем сделать весь код (т. е. изменить белые пробелы и новые строки в соответствующих местах).Обычный способ хранения позиций в форматировании

Учитывая, что мой внешний интерфейс ocamllex и ocamlyacc могут построить Abstract Syntax Tree (AST). Я хотел бы знать, какие общие способы хранения позиций элементов в AST.

Один из способов, я полагаю, заключается в том, чтобы добавить (start) position к каждому элементу AST. Например, если тип выражения определяется следующим образом:

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

Он станет:

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

Тогда, если мы знаем длину каждого элемента, мы можем сделать вывод, положение все в редакторе. Это обычный способ сделать это? Я не считаю это приятным ...

+0

Наши магазины инструментов DMS файл/строка/столбец в каждом узле дерева. Это мило. –

ответ

0

Вам не обязательно повторять position для каждого шаблона. Вы могли бы просто написать один в конце:

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

Как результат, для существующих функций над expression, вы можете просто добавить случай для E_loc, и не должны касаться существующих дел.

Для построения E_loc автоматически при разборе, вы можете добавить в .mly, например:

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]) }