【问题标题】:Meaning of 'pos' in syntax tree语法树中“pos”的含义
【发布时间】:2018-08-02 02:48:13
【问题描述】:

刚开始学习SML,被下面的代码搞糊涂了:

type pos = int
datatype prog= Prog of statement option
    and statement =... some code..
    and expression =
         VarExp of symbol * pos
         | IntExp of int * pos
         | BoolExp of bool * pos
         | BopExp of exp * oper * exp * pos
         | UopExp of oper * exp * pos

我无法理解的是pos 的用法。签名不应该像BopExp of exp * oper * exp 而不是BopExp of exp * oper * exp * pos 吗?

【问题讨论】:

  • 一个疯狂的猜测是pos 代表某种位置(行号或字符偏移或其他东西),可能是为了能够产生合理的错误消息。如果您阅读类型的解释和使用,很可能会变得清楚。
  • 这可能是ML-YACC 的代码。 pos 用于错误报告。
  • 当解析器发现解析错误时,它需要告诉程序员错误出现在哪里。我认为这就是为什么我们需要pos

标签: functional-programming sml smlnj ml


【解决方案1】:

自从 John、molbdnilo 和 Tai 已经在 cmets 中回答你说 pos 可能是某种位置,表明句法元素的文本表示存在于 pos文件中的第 em> 个字符,这里还有一些想法:

语法树可能带有各种信息的注释。解析器通常保留错误报告的位置。静态类型检查器也是如此,但它也可能保留推断的类型信息,这些信息可以传递给自身或后续代码生成阶段。

你可以做的是参数化你的语法树:

datatype 'a prog = Prog of 'a stmt list
and 'a stmt = AssignStmt of symbol * 'a exp * 'a
            | PrintStmt of 'a exp * 'a
and 'a exp = VarExp of symbol * 'a
           | IntExp of int * 'a
           | BoolExp of bool * 'a
           | BopExp of 'a exp * oper * 'a exp * 'a
           | UopExp of oper * 'a exp * 'a

然后像 x := 2 + true; 这样的程序可能首先被解析和注释为 pos prog

type pos = int
val hello = Prog [AssignStmt ("x", BopExp (IntExp (2, 6), "+",
                                           BoolExp (true, 10),
                                           6),
                              0)
                 ]

表示赋值位于位置 0,表达式 2 + true 位于位置 6,整数 2 位于位置 6,布尔值 true 在位置 10。当您进行类型检查时,您可能需要一个 (pos × typ) prog

type typ = Int | Bool | None | Conflict of typ list * typ
val hello = Prog [AssignStmt ("x", BopExp (IntExp (2, (6, Int)), "+",
                                           BoolExp (true, (10, Bool)),
                                           (6, Conflict ([Int, Bool], Int)),
                              (0, None)
                 ]

保留位置信息以进行正确的错误报告(如果存在类型错误,这仍然是必需的),但也保留有关存在冲突类型的位置的信息,例如Conflict ([Int, Bool], Int) 的意思是,虽然它预期 Int,但由于IntBool 的类型冲突,它无法推导出它。

然后,您只需要一个用于位置、类型、寄存器的语法树定义,无论您想出什么来注释您的语法元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-08
    • 2012-03-23
    • 2021-03-05
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 2019-12-03
    相关资源
    最近更新 更多