语法树中的位置

时间:2014-09-05 20:48:09

标签: parsing ocaml

在编写解析器时,我想记住发现的词法的位置,这样我就可以向程序员报告有用的错误消息,如“第23行的if-less else”或“第45行的意外字符,字符6“或”未定义的变量“或类似的东西。但是一旦我构建了语法树,我将以多种方式对其进行转换,优化或扩展某种宏。转换产生或重新排列没有有意义位置的词位。

因此,似乎表示语法树的类型应该有两种风格,一种具有装饰词位的位置和没有词位的味道。理想情况下,我们希望使用纯粹抽象的语法树,如OCaml book

中所定义
# type unr_op = UMINUS | NOT  ;;
# type bin_op = PLUS | MINUS | MULT | DIV | MOD  
             | EQUAL | LESS | LESSEQ | GREAT | GREATEQ | DIFF 
             | AND | OR  ;;
# type expression = 
     ExpInt of int 
   | ExpVar of string
   | ExpStr of string 
   | ExpUnr of unr_op * expression
   | ExpBin of expression * bin_op * expression  ;;
# type command = 
     Rem of string
   | Goto of int 
   | Print of expression
   | Input of string 
   | If of expression * int 
   | Let of string * expression  ;;
# type line = { num : int ; cmd : command }  ;;
# type program = line list  ;;

我们应该被允许在处理该树时完全忘记位置,并具有将expression映射回其位置(例如)的特殊功能,以便在紧急情况下使用。

在OCaml中定义此类型或处理词位位置的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

最好的方法是始终使用位置完全注释AST节点。例如:

type expression = {
  expr_desc : expr_desc;
  expr_loc : Lexing.position * Lexing.position; (* start and end *)
}

and expr_desc =
     ExpInt of int 
   | ExpVar of string
   | ExpStr of string 
   | ExpUnr of unr_op * expression
   | ExpBin of expression * bin_op * expression

我相信你的想法,保持AST没有位置并编写功能来检索缺失的位置并不是一个好主意。这样的函数应该要求通过AST节点的指针等价或类似的东西进行搜索,这不能真正扩展。

我强烈建议您查看OCaml编译器parser.mly,这是带位置的AST的完整示例。