我想为特定语言编写一个小编辑器。在编辑器中,我们将能够indent
一行或几行(即在每行的左侧添加空格);我们还可以format
整个代码(即,改变适当位置的空格和换行符)。
鉴于某个程序,ocamllex
和ocamlyacc
的前端可以构建Abstract Syntax Tree (AST)
。我想知道在AST中存储元素位置的常用方法是什么。
我猜测的一种方法是将(开始)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 :(得分: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]) }